INN commit: branches/2.4 (doc/pod/mailpost.pod frontends/mailpost.in)
INN Commit
Russ_Allbery at isc.org
Sat Apr 26 08:28:09 UTC 2008
Date: Saturday, April 26, 2008 @ 01:28:08
Author: iulius
Revision: 7795
* Fix a bug when mailpost either couldn't find the pathtmp directory or
couldn't write to it;
* Add documentation for -h, -n and -o;
* Add a list of known headers;
* Clarify the use of -b;
* Fix <pathdb>/mailpost-msgid.db which is <pathtmp>/mailpost-msgid.dir and
<pathtmp>/mailpost-msgid.pag;
* Fix the usage of [newsgroups] which is not optional;
* It is $Database and not $lockfile in dbmopen/close;
* Better formatting of error mails;
* Typos.
Modified:
branches/2.4/doc/pod/mailpost.pod
branches/2.4/frontends/mailpost.in
-----------------------+
doc/pod/mailpost.pod | 119 +++++++++++++++++++++++++++++------------
frontends/mailpost.in | 137 ++++++++++++++++++++++++------------------------
2 files changed, 154 insertions(+), 102 deletions(-)
Modified: doc/pod/mailpost.pod
===================================================================
--- doc/pod/mailpost.pod 2008-04-26 08:18:20 UTC (rev 7794)
+++ doc/pod/mailpost.pod 2008-04-26 08:28:08 UTC (rev 7795)
@@ -1,49 +1,55 @@
=head1 NAME
-mailpost - feed an email message into a news group
+mailpost - Feed an e-mail message into a newsgroup
=head1 SYNOPSIS
-B<mailpost> [B<-a> I<addr>] [B<-b> I<database>] [B<-c> I<wait-time>]
+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<-p> I<port>] [B<-r> I<addr>] [B<-x> I<header>[B<:>I<header>...]]
-[I<newsgroups> ...]
+[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 email message from stdin
-and feeds it to inews for posting to a news server. I<newsgroups> is a
-whitespace-separated list of group names to which to post the article.
+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 inews, it checks that the article has not
+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 and puts ``X-'' in front of unknown headers).
+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 articles it handles), then the article will be silently dropped. Other
-errors will cause the article to be mailed to the newsmaster.
+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 mailpost is run by sendmail(8) via an alias entry:
+Normally, B<mailpost> is run by sendmail(8) via an alias entry:
-local-mail-wreck-bikes: "|<pathbin in inn.conf>/mailpost
- -d local local.mail.rec.bicycles.racing"
+ 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.
+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 mailpost process doesn't have write access to the news tmp
-directory (the value of I<pathtmp> in inn.conf(5)).
+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>
@@ -51,40 +57,86 @@
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.
+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
+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 articles in a
+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 inews.
+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>[:I<header>...]
+=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 inews(1) without
-having "X-" prepended.
+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
@@ -92,14 +144,9 @@
$Id$
-=head1 FILES
+=head1 SEE ALSO
-<pathdb in inn.conf>/mailpost-msgid.db database file
+active(5), inews(1), inn.conf(5), nnrpd(8), uwildmat(3).
-=head1 BUGS
+=cut
-Is lacking in configurability.
-
-=head1 SEE ALSO
-
-active(5), inn.conf(5), nnrpd(8), uwildmat(3).
Modified: frontends/mailpost.in
===================================================================
--- frontends/mailpost.in 2008-04-26 08:18:20 UTC (rev 7794)
+++ frontends/mailpost.in 2008-04-26 08:28:08 UTC (rev 7795)
@@ -1,21 +1,24 @@
#! /usr/bin/perl
# fixscript will replace this line with require innshellvars.pl
-# mailpost - yet another mail-to-news filter
+# mailpost - Yet another mail-to-news filter
+#
+# $Id$
+#
# 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 [$Id$]
+# 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 Getopt::Std;
use IPC::Open3;
use IO::Select;
use Sys::Syslog;
-use strict ;
+use strict;
my $debugging = 0 ;
my $tmpfile ;
@@ -23,8 +26,8 @@
my $msg ;
END {
- unlink ($tmpfile) if $tmpfile ; # incase we die()
- unlink ($tmpfile2) if $tmpfile2 ; # incase we die()
+ unlink ($tmpfile) if $tmpfile ; # in case we die()
+ unlink ($tmpfile2) if $tmpfile2 ; # in case we die()
}
my $LOCK_SH = 1;
@@ -40,9 +43,9 @@
$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" ;
+ " [ -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 ) ;
+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 ;
@@ -58,7 +61,7 @@
my $WhereTo = $opt_o || $Submit ;
my $Mailname = $inn::fromhost ;
-# can't use $inn::tmpdir as we're usually not running as news
+# Can't use $inn::pathtmp as we're usually not running as news.
my $Tmpdir = "/var/tmp" ;
if ($debugging || $opt_n) {
@@ -70,10 +73,10 @@
#
-# our command-line argument(s) are the list of newsgroups to post to.
+# 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.)
+# 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.
@@ -114,11 +117,11 @@
$newsgroups = join ",", @ARGV ;
-die "usage: $0 newsgroup [newsgroup]\n" unless $newsgroups;
+die "usage: $0 newsgroup [newsgroup ...]\n" unless $newsgroups;
#
-# do the header. our input is a mail message, with or without the From_
+# Do the header. Our input is a mail message, with or without the From.
#
#$message_id = sprintf("<mailpost.%d.%d@%s>", time, $$, $Hostname);
@@ -166,7 +169,7 @@
last unless defined $_ ;
chomp ;
- # gather up a single header with possible continuation lines into $line
+ # Gather up a single header with possible continuation lines into $line.
if (/^\s+/) {
if (! $line) {
$msg = "First line with leading whitespace!" ;
@@ -178,11 +181,11 @@
next ;
}
- # On the first header $line will be undefined.
- ($_, $line) = ($line, $_) ; # swap $line and $_ ;
+ # 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
+ next if /^$/ ; # Only on first header will this happen.
push @errorText, "($_)\n";
@@ -246,14 +249,14 @@
next ;
}
- # strip out news trace headers since otherwise posting may fail. other
- # trace headers will be renamed to add 'X-' so we don't have to worry
- # about them.
+ # 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's not already there.
+ # Random unknown header. Prepend 'X-' if it is not already there.
$_ = "X-$_" unless /^X-/sio ;
$weird_mail_hdrs .= "$_\n";
}
@@ -268,7 +271,7 @@
}
$real_news_hdrs .= "Subject: ${subject}\n";
-$real_news_hdrs .= "Message-ID: ${msgIdHdr}\n" if defined($message_id);
+$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);
@@ -278,20 +281,20 @@
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
+# 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 = "cant open temp file ($tmpfile): $!" ;
+ $msg = "can't open temp file ($tmpfile): $!" ;
$tmpfile = undef ;
- syslog "err", "$msg\n" unless $debugging || -t STDERR ;
- open TMPFILE, "|" . sprintf ($Sendmail, $Maintainer) ||
+ 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
+Subject: mailpost failure ($newsgroups): $msg
-------- Article Contents
@@ -308,61 +311,61 @@
my $rest;
$rest .= $_ while (<STDIN>);
-$rest =~ s/\n*$/\n/g; # Remove trailing \n except very last
+$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.
+ # 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.
+## 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)")
+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
+# 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 match above.
+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";
+push @errorText, "(TAS Message-ID database for $message_id)\n";
my $lockfile = sprintf("%s.lock", $Database);
-open LOCKFILE, "<$lockfile" ||
- open LOCKFILE, ">$lockfile" ||
+open(LOCKFILE, "<$lockfile") ||
+ open(LOCKFILE, ">$lockfile") ||
mailArtAndDie ("can't open $lockfile: $!") ;
my $i ;
for ($i = 0 ; $i < 5 ; $i++) {
- flock LOCKFILE, $LOCK_EX && last ;
+ 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 $lockfile: $!");
+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) ;
+ $newsgroups = &append_newsgroups($DATABASE{$message_id}, $newsgroups) ;
syslog "err", "crosspost $newsgroups\n" if $debugging ;
}
@@ -371,43 +374,43 @@
mailArtAndDie ("TAS didn't set $message_id") unless defined $DATABASE{$message_id};
-dbmclose %DATABASE || mailArtAndDie ("can't dbmclose $lockfile: $!") ;
+dbmclose(%DATABASE) || mailArtAndDie ("can't dbmclose $Database: $!") ;
-flock LOCKFILE, $LOCK_UN || mailArtAndDie ("can't unlock $lockfile: $!");
+flock(LOCKFILE, $LOCK_UN) || mailArtAndDie ("can't unlock $lockfile: $!");
close LOCKFILE ;
-## for crosspost
+## For crosspost.
if ($opt_c) {
if (fork() != 0) {
- undef $tmpfile; # dont unlink $tmpfile
+ undef $tmpfile; # Don't unlink $tmpfile.
exit 0;
}
sleep $opt_c ;
- open LOCKFILE, "<$lockfile" ||
- open LOCKFILE, ">$lockfile" ||
+ open(LOCKFILE, "<$lockfile") ||
+ open(LOCKFILE, ">$lockfile") ||
mailArtAndDie ("can't open $lockfile: $!") ;
my $i ;
for ($i = 0 ; $i < 5 ; $i++) {
- flock LOCKFILE, $LOCK_EX && last ;
+ 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 $lockfile: $!");
+ 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 $lockfile: $!") ;
+ dbmclose(%DATABASE) || mailArtAndDie ("can't dbmclose $Database: $!") ;
- flock LOCKFILE, $LOCK_UN || mailArtAndDie ("can't unlock $lockfile: $!");
+ flock(LOCKFILE, $LOCK_UN) || mailArtAndDie ("can't unlock $lockfile: $!");
close LOCKFILE ;
if (defined($dup)) {
@@ -415,11 +418,11 @@
exit 0 ;
}
- # replace Newsgroups
- open TMPFILE, "$tmpfile" || mailArtAndDie ("cannot open temp file ($tmpfile): $!") ;
+ # 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 = "cant open temp file ($tmpfile2): $!" ;
+ $msg = "can't open temp file ($tmpfile2): $!" ;
$tmpfile2 = undef ;
die $msg ;
}
@@ -438,18 +441,18 @@
my $rest;
$rest .= $_ while (<TMPFILE>);
- $rest =~ s/\n*$/\n/g; # Remove trailing \n except very last
+ $rest =~ s/\n*$/\n/g; # Remove trailing \n except very last.
print TMPFILE2 $rest;
close TMPFILE2 ;
close TMPFILE ;
- rename $tmpfile2, $tmpfile || mailArtAndDie ("cannot rename $tmpfile2 $tmpfile: $!") ;
+ rename($tmpfile2, $tmpfile) || mailArtAndDie ("can't rename $tmpfile2 $tmpfile: $!") ;
$tmpfile2 = undef ;
}
if (!open INEWS, "$WhereTo < $tmpfile 2>&1 |") {
- mailArtAndDie ("cant start: $WhereTo: $!") ;
+ mailArtAndDie ("can't start $WhereTo: $!") ;
}
my @inews = <INEWS> ;
@@ -470,18 +473,19 @@
print STDERR $msg,"\n" if -t STDERR ;
- open SENDMAIL, "|" . sprintf ($Sendmail,$Maintainer) ||
+ open(SENDMAIL, "|" . sprintf ($Sendmail,$Maintainer)) ||
die "die($msg): sendmail: $!\n" ;
print SENDMAIL <<"EOF" ;
To: $Maintainer
-Subject: mailpost failure ($newsgroups): $msg
-
+Subject: mailpost failure ($newsgroups)
+
$msg
+
EOF
if ($tmpfile && -f $tmpfile) {
print SENDMAIL "\n-------- Article Contents\n\n" ;
- open FILE, "<$tmpfile" || die "open($tmpfile): $!\n" ;
+ open(FILE, "<$tmpfile") || die "open($tmpfile): $!\n" ;
print SENDMAIL while <FILE> ;
close FILE ;
} else {
@@ -491,12 +495,12 @@
# unlink $tmpfile ;
- exit (0) ; # using a non-zero exit may cause problems.
+ exit (0) ; # Using a non-zero exit may cause problems.
}
#
-# take 822-format name (either "comment <addr> comment" or "addr (comment)")
+# Take 822-format name (either "comment <addr> comment" or "addr (comment)")
# and return in always-qualified 974-format ("addr (comment)").
#
sub fix_sender_addr {
@@ -531,7 +535,7 @@
}
#
-# delete leading and trailing blanks
+# Delete leading and trailing blanks.
#
sub dltb {
@@ -552,9 +556,10 @@
if ( !grep($_ eq $newsgroup, at orig)) {
push @orig, $newsgroup ;
} else {
-# mailArtAndDie ("Duplicated Newsgroups: $newsgroup") ;
+# mailArtAndDie ("Duplicate Newsgroups: $newsgroup") ;
}
}
return join ",", @orig ;
}
+
More information about the inn-committers
mailing list