X-Git-Url: https://code.th-h.de/?p=usenet%2Fyapfaq.git;a=blobdiff_plain;f=yapfaq.pl;h=d4e381eec37e472e9489f6e7e45b7b6b33faaeaa;hp=23f7e5ae7f3e8e2b2596036d9f86507844edc3be;hb=13ce8c26a3ae0e0d875905741c354c889e2a7903;hpb=d60c2d5fdfb9bde091cd788893dd5c7e442a58e0 diff --git a/yapfaq.pl b/yapfaq.pl index 23f7e5a..d4e381e 100644 --- a/yapfaq.pl +++ b/yapfaq.pl @@ -1,6 +1,6 @@ #! /usr/bin/perl -W # -# yapfaq Version 0.6 by Thomas Hochstein +# yapfaq Version 0.7 by Thomas Hochstein # (Original author: Marc Brockschmidt) # # This script posts any project described in its config-file. Most people @@ -12,15 +12,20 @@ # It can be redistributed and/or modified under the same terms under # which Perl itself is published. -my $Version = "0.6.2"; +my $Version = "0.8-prelease"; +# Please do not change this setting! +# You may override the default .rc file (.yapfaqrc) by using "-c .rc file" my $RCFile = '.yapfaqrc'; +# Valid configuration variables for use in a .rc file my @ValidConfVars = ('NNTPServer','NNTPUser','NNTPPass','Sender','ConfigFile', 'UsePGP','pgp','PGPVersion','PGPSigner','PGPPass', 'PathtoPGPPass','pgpbegin','pgpend','pgptmpf','pgpheader'); -################################### Defaults ################################## -my %Config = (NNTPServer => "localhost", +################################### Defaults ################################### +# Please do not change anything in here! +# Use a runtime configuration file (.yapfaqrc by default) to override defaults. +my %Config = (NNTPServer => "", NNTPUser => "", NNTPPass => "", Sender => "", @@ -50,7 +55,7 @@ my @PGPorderheaders = ('from', 'newsgroups', 'subject', 'control', 'content-transfer-encoding', 'summary', 'keywords', 'cancel-lock', 'cancel-key', 'also-control', 'x-pgp', 'user-agent'); -############################# End of Configuration ############################# +################################# Main program ################################# use strict; use Net::NNTP; @@ -62,7 +67,7 @@ my ($TDY, $TDM, $TDD) = Today(); #TD: Today's date # read commandline options my %Options; -getopts('Vhvpdt:f:s:', \%Options); +getopts('Vhvpdt:f:c:s:', \%Options); # -V: print version / copyright information if ($Options{'V'}) { print "$0 v $Version\nCopyright (c) 2003 Marc Brockschmidt \nCopyright (c) 2010 Thomas Hochstein \n"; @@ -78,7 +83,12 @@ if ($Options{'h'}) { my ($Faq) = $Options{'f'} if ($Options{'f'}); # read runtime configuration (configuration variables) -readrc (\$RCFile,\%Config) if -f $RCFile; +$RCFile = $Options{'c'} if ($Options{'c'}); +if (-f $RCFile) { + readrc (\$RCFile,\%Config); +} else { + warn "$0: W: .rc file $RCFile does not exist!\n"; +} # read configuration (configured FAQs) my @Config; @@ -161,7 +171,7 @@ sub readconfig{ my ($File, $Config, $Faq) = @_; my ($LastEntry, $Error, $i) = ('','',0); - print "Reading configuration.\n" if($Options{'v'}); + print "Reading configuration from $$File.\n" if($Options{'v'}); open FH, "<$$File" or die "$0: E: Can't open $$File: $!"; while () { @@ -202,10 +212,12 @@ sub readconfig{ $Error .= "E: The Posting-frequency for your project \"$$Config[$i]{'name'}\" is invalid.\n" } unless(!$$Config[$i]{'expires'} || $$Config[$i]{'expires'} =~ /^\s*\d+\s*[dwmy]\s*$/) { - warn "$0: W: The Expires for your project \"$$Config[$i]{'name'}\" is invalid - set to 3 month.\n"; + warn "$0: W: The Expires for your project \"$$Config[$i]{'name'}\" is invalid - set to 3 month.\n"; + $$Config[$i]{'expires'} = '3m'; # set default (3 month) if expires is unset or invalid } - unless(defined($$Config[$i]{'mid-format'}) && $$Config[$i]{'mid-format'} =~ /^<\S+\@\S{2,}\.\S{2,}>$/) { - warn "$0: W: The Expires for your project \"$$Config[$i]{'name'}\" seems to be invalid - set to default.\n"; + unless(!$$Config[$i]{'mid-format'} || $$Config[$i]{'mid-format'} =~ /^<\S+\@\S{2,}\.\S{2,}>$/) { + warn "$0: W: The Message-ID format for your project \"$$Config[$i]{'name'}\" seems to be invalid - set to default.\n"; + $$Config[$i]{'mid-format'} = '<%n-%d.%m.%y@'.hostfqdn.'>'; # set default if mid-format is invalid } } $Error .= "-" x 25 . 'program terminated' . "-" x 25 . "\n" if $Error; @@ -227,6 +239,21 @@ sub calcdelta { } return ($NYear, $NMonth, $NDay); } + +################################ updatestatus ############################### +# Takes a MID and a status file name +# and writes status information to disk + +sub updatestatus { + my ($ActName, $File, $date, $MID) = @_; + + print "$$ActName: Save status information.\n" if($Options{'v'}); + + open (FH, ">$$File.cfg") or die "$0: E: Can't open $$File.cfg: $!"; + print FH "##;; Lastpost: $date\n"; + print FH "##;; LastMID: $MID\n"; + close FH; +} ################################## postfaq ################################## # Takes a filename and many other vars. @@ -242,13 +269,15 @@ sub postfaq { #Prepare MID: $$TDM = ($$TDM < 10 && $$TDM !~ /^0/) ? "0" . $$TDM : $$TDM; $$TDD = ($$TDD < 10 && $$TDD !~ /^0/) ? "0" . $$TDD : $$TDD; + my $Timestamp = time; $MID = $$MIDF; - $MID = '<%n-%d.%m.%y@'.hostfqdn.'>' if !defined($MID); + $MID = '<%n-%d.%m.%y@'.hostfqdn.'>' if !defined($MID); # set to default if unset $MID =~ s/\%n/$$ActName/g; $MID =~ s/\%d/$$TDD/g; $MID =~ s/\%m/$$TDM/g; $MID =~ s/\%y/$$TDY/g; + $MID =~ s/\%t/$Timestamp/g; #Now get the body: open (FH, "<$$File"); @@ -316,18 +345,13 @@ sub postfaq { # post article print "$$ActName: Posting article ...\n" if($Options{'v'}); - post(\@Article); - - # Test mode? - return if($Options{'t'}); - - # otherwise: update status data - print "$$ActName: Save status information.\n" if($Options{'v'}); - - open (FH, ">$$File.cfg") or die "$0: E: Can't open $$File.cfg: $!"; - print FH "##;; Lastpost: $day.$month.$year\n"; - print FH "##;; LastMID: $MID\n"; - close FH; + my $failure = post(\@Article); + + if ($failure) { + print "$$ActName: Posting failed, ERROR.dat may have more information.\n" if($Options{'v'} && (!defined($Options{'t'}) || $Options{'t'} !~ /console/i)); + } else { + updatestatus($ActName, $File, "$day.$month.$year", $MID) if !defined($Options{'t'}); + } } ################################## post ################################## @@ -337,42 +361,49 @@ sub postfaq { sub post { my ($ArticleR) = @_; + my ($failure) = -1; - # Test mode? + # test mode - print article to console if(defined($Options{'t'}) and $Options{'t'} =~ /console/i) { print "-----BEGIN--------------------------------------------------\n"; - print @$ArticleR; + print @$ArticleR; print "------END---------------------------------------------------\n"; - return; - } - - # pipe to script? - if(defined($Options{'s'})) { + # pipe article to script + } elsif(defined($Options{'s'})) { open (POST, "| $Options{'s'}") or die "$0: E: Cannot fork $Options{'s'}: $!\n"; print POST @$ArticleR; close POST; - return; - } - - my $NewsConnection = Net::NNTP->new($Config{'NNTPServer'}, Reader => 1) or die "$0: E: Can't connect to news server '$Config{'NNTPServer'}'!\n"; - $NewsConnection->authinfo ($Config{'NNTPUser'}, $Config{'NNTPPass'}) if (defined($Config{'NNTPUser'})); - $NewsConnection->post(); - $NewsConnection->datasend (@$ArticleR); - $NewsConnection->dataend(); - - # Posting failed? Save to ERROR.dat - if (!$NewsConnection->ok()) { - open FH, ">>ERROR.dat"; - print FH "\nPosting failed! Saving to ERROR.dat. Response from news server:\n"; - print FH $NewsConnection->code(); - print FH $NewsConnection->message(); - print FH "\n"; - print FH @$ArticleR; - print FH "-" x 80, "\n"; - close FH; + if ($? == 0) { + $failure = 0; + } else { + warn "$0: W: $Options{'s'} exited with status ", ($? >> 8), "\n"; + $failure = $?; + } + # post article + } else { + my $NewsConnection = Net::NNTP->new($Config{'NNTPServer'}, Reader => 1) or die "$0: E: Can't connect to news server '$Config{'NNTPServer'}'!\n"; + $NewsConnection->authinfo ($Config{'NNTPUser'}, $Config{'NNTPPass'}) if (defined($Config{'NNTPUser'})); + $NewsConnection->post(); + $NewsConnection->datasend (@$ArticleR); + $NewsConnection->dataend(); + + if ($NewsConnection->ok()) { + $failure = 0; + # Posting failed? Save to ERROR.dat + } else { + warn "$0: W: Posting failed!\n"; + open FH, ">>ERROR.dat"; + print FH "\nPosting failed! Saving to ERROR.dat. Response from news server:\n"; + print FH $NewsConnection->code(); + print FH $NewsConnection->message(); + print FH "\n"; + print FH @$ArticleR; + print FH "-" x 80, "\n"; + close FH; + } + $NewsConnection->quit(); } - - $NewsConnection->quit(); + return $failure; } #-------- sub getpgpcommand @@ -548,7 +579,7 @@ yapfaq - Post Usenet FAQs I<(yet another postfaq)> =head1 SYNOPSIS -B [B<-hvpd>] [B<-t> I | CONSOLE] [B<-f> I] [B<-s> I] +B [B<-Vhvpd>] [B<-t> I | CONSOLE] [B<-f> I] [B<-s> I] [B<-c> I<.rc file>] =head1 REQUIREMENTS @@ -584,7 +615,8 @@ headers as defined in its config file (by default F). F consists of one or more blocks, separated by C<=====> on a single line, each containing the configuration for one FAQ as a set -of definitions in the form of I. +of definitions in the form of I. Everything after a "#" +sign is ignored so you may comment your configuration file. =over 4 @@ -612,7 +644,7 @@ or Ionths> or Iears>. This value must be set. -=item B = I