Skip to content

Commit

Permalink
scanspool: Add -r flag to remove articles in error
Browse files Browse the repository at this point in the history
see #288
  • Loading branch information
Julien-Elie committed Jan 20, 2024
1 parent 88eb9b2 commit 845caa2
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 9 deletions.
11 changes: 6 additions & 5 deletions doc/pod/news.pod
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ as a format like C<Jul 29 04:15:01> was expected.

=item *

B<scanspool> now detects empty files in a tradspool news spool, correctly
parses continuation lines in header fields, and can automatically remove
articles reported to have a problem (when run with the new B<-r> flag).

=item *

Fixed a hang when posting articles if COMPRESS DEFLATE is active but TLS
is not. Thanks to Enrik Berkhan for the patch for B<nnrpd>.

Expand Down Expand Up @@ -99,11 +105,6 @@ Jesse Rehmer for the bug report and Bo Lindbergh for the fix.

=item *

B<scanspool> now detects empty files in a tradspool news spool, and correctly
parses continuation lines in header fields.

=item *

B<innd> no longer malfunctions nor throttles when the maximum number of file
descriptors supported by the system is reached. If needing to use more file
descriptors than the default system limit, a new C<LARGE_FD_SETSIZE> option
Expand Down
11 changes: 10 additions & 1 deletion doc/pod/scanspool.pod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ scanspool - Perform a sanity scan over all articles in news spool

=head1 SYNOPSIS

B<scanspool> [B<-cnv>] [B<-a> I<active-file>] [B<-s> I<spool-dir>]
B<scanspool> [B<-cnrv>] [B<-a> I<active-file>] [B<-s> I<spool-dir>]

=head1 DESCRIPTION

Expand Down Expand Up @@ -91,6 +91,15 @@ scan the Newsgroups header field of the articles.

Don't throttle B<innd> while scanning.

=item B<-r>

Remove articles reported to have a problem. To see the list of articles in
question, run B<scanspool> without this flag first.

Be warned that using this flag may result in inaccessible articles if articles
are removed whereas they are perfectly valid articles. Have a look at them to
ensure they can be safely removed, and then use this flag.

=item B<-s> I<spool-dir>

The root of the spool tree; I<patharticles> is the default.
Expand Down
46 changes: 43 additions & 3 deletions frontends/scanspool.in
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,15 @@ $VERSION =~ s/INN //;
$0 =~ s!.*/!!;

my $usage = "Usage:
$0 [-cnv] [-a active-file] [-s spool-dir]
$0 [-cnrv] [-a active-file] [-s spool-dir]
Perform a sanity scan over all articles in <patharticles>
Options:
-a active-file active file to use (default <pathdb>/active)
-c check article filenames, don't scan the articles
-n don't throttle innd
-r remove articles reported to have a problem
-s spool-dir spool tree (default <patharticles>)
-v verbose mode
verbose messages begin with a tab
Expand All @@ -123,7 +124,7 @@ my $reason = "running scanspool"; # throttle reason
# parse args
#
my %opt;
getopts("a:s:vcn", \%opt) || die $usage;
getopts("a:cnrs:v", \%opt) || die $usage;
$active = $opt{'a'} if defined $opt{'a'};
$spool = $opt{'s'} if defined $opt{'s'};

Expand Down Expand Up @@ -252,6 +253,26 @@ sub problem {
return;
}

# rm_file - remove a file
#
# Remove the file given as argument, if the -r flag is used.
# Otherwise, it is a no-op.
# Report a fatal error to stderr and exit if the removal fails.
#
# usage:
# rm_file(filename)
#
sub rm_file {
my ($filename) = @_;

if (defined $opt{'r'}) {
unlink("$filename") or fatal(4, "cannot remove $filename");
problem("$filename: successfully removed");
}

return;
}

# fatal - report a fatal error to stderr and exit
#
# Print a message to stderr. The message has the program name prepended
Expand Down Expand Up @@ -308,6 +329,7 @@ sub check_spool {
my $aline; # header line from an article
my $newsgroupsField; # in a continuation line, reading Newsgroups
my @group; # array of groups from the Newsgroups header field
my $remove; # mark an article as to be removed
my $FINDFILE; # find command pipe handle

# if verbose, say what we are doing
Expand Down Expand Up @@ -367,12 +389,14 @@ sub check_spool {
if (!defined $gname2type{$artgrp} || $gname2type{$artgrp} =~ /[=jx]/o)
{
if ($preverrgrp ne $artgrp) {
problem("$artgrp: not an active group directory");
problem("$artgrp: not an active group directory (probably "
. "a removed newsgroup; see articles with -v)");
$preverrgrp = $artgrp;
}
if (defined $opt{'v'}) {
problem("$filename: article found in non-active directory");
}
rm_file($filename);
next;
}

Expand All @@ -381,18 +405,26 @@ sub check_spool {
$artnum =~ s#^.+/##o;
if ($artnum =~ m/^0/o) {
problem("$filename: article basename starts with a 0");
rm_file($filename);
next if defined $opt{'r'};
}
if (defined $gname2type{$artgrp}) {
if ($lowart{$artgrp} > $highart{$artgrp}) {
problem("$filename: active indicates group should be empty");
rm_file($filename);
next if defined $opt{'r'};
} elsif ($artnum < $lowart{$artgrp}) {
problem("$filename: article number is too low "
. "(first article has number $lowart{$artgrp} "
. "in the active file)");
rm_file($filename);
next if defined $opt{'r'};
} elsif ($artnum > $highart{$artgrp}) {
problem("$filename: article number is too high "
. "(last article has number $highart{$artgrp} "
. "in the active file");
rm_file($filename);
next if defined $opt{'r'};
}
}

Expand All @@ -407,6 +439,7 @@ sub check_spool {

if (-z "$filename") {
problem("WARNING: $filename: empty file");
rm_file($filename);
next;
}

Expand All @@ -419,6 +452,7 @@ sub check_spool {

@group = ();
$newsgroupsField = 0;
$remove = 0;

# read until the Newsgroups header field is found
AREADLINE:
Expand All @@ -440,6 +474,7 @@ sub check_spool {
} elsif ($aline =~ /^\r?\n$/o) {
# end of headers
problem("WARNING: $filename: no Newsgroups header field");
$remove++;
last;
} else {
# do not continue parsing the headers as we have just found out
Expand All @@ -448,6 +483,7 @@ sub check_spool {
}
if (eof $ARTICLE) {
problem("WARNING: $filename: article with no body");
$remove++;
}
}

Expand All @@ -469,11 +505,15 @@ sub check_spool {
# no group or group alias was found
problem("$filename: does not belong in $artgrp"
. " according to its Newsgroups header field");
$remove++;
}
}

# close the article
close $ARTICLE;

# remove the article if asked to
rm_file($filename) if $remove > 0;
}

# all done with the find
Expand Down

0 comments on commit 845caa2

Please sign in to comment.