for k in $pas; do eval "$k=''"; export $k; done
DIVERTPOSTINGS=''
+MODLOGSEARCH=false
+MODLOGDOWNLOAD=false
. settings
export GROUP ABBREV INFOHEADER MODEMAIL GROUPURL REJECTIONSLIST
-export DIVERTPOSTINGS
+export DIVERTPOSTINGS MODLOGSEARCH MODLOGDOWNLOAD
. ../global-settings
export ROOTBASEDIR CGIBASEURL DOMAIN SLIMYDOMAIN OURUSER ADMIN
$MessageNumber =~ s/^.*::$Prefix\///;
$MessageNumber =~ /(\d+)/;
$MessageNumber = $1;
+ $ENV{'WEBSTUMP_MESSAGENUM'}= $MessageNumber;
$MessageFile = "$MNG_ROOT/tmp/messages/$MessageNumber";
(
echo Path: "$PATH_SUFFIX"
- cat $MNG_ROOT/etc/added-headers | grep ': '
+ perl <$MNG_ROOT/etc/added-headers -ne '
+ next unless m/\:/;
+ s/\[REFERENCE\]/[$ENV{"WEBSTUMP_MESSAGENUM"}]/g
+ if defined $ENV{"WEBSTUMP_MESSAGENUM"};
+ print or die $!;
+ '
# I do grep above because a lot of users inserts empty
# lines in the added headers.
if [ "x$REASON" = xdiscard ]; then return; fi
(
+ eventheader="reject $REASON"
+ if [ "x$WEBSTUMP_MESSAGENUM" != x ]; then
+ eventheader="[$WEBSTUMP_MESSAGENUM] $eventheader"
+ fi
cat $MESSAGE | formail -rt -I "Reply-To: $BOARD" \
-I "Errors-To: $MUNGED_ADDRESS" \
- -I "X-Webstump-Event: reject $REASON" \
+ -I "X-Webstump-Event: $eventheader" \
$MAILOUT_REJECT_FORMAIL_ARGS
(
echo "$EXPLANATION"
# Subject, newsgroup, ShortDirectoryName, decision, comment
sub process_approval_decision {
-
+ my $cathow = @_>=6 ? pop(@_) : "UNKNOWN";
my $comment = pop( @_ );
my $decision = pop( @_ );
my $ShortDirectoryName = pop( @_ );
$message .= "comment $comment\n" if $comment;
&email_message( $message, $address );
-print STDERR "DECISION: $decision for $ShortDirectoryName sent to $address, for $newsgroup\n";
+ my $sanisubj= $Subject;
+ $sanisubj =~ s/.*\:\://;
+
+print STDERR "DECISION: $newsgroup | $ShortDirectoryName | $decision | $cathow | $sanisubj\n";
&rmdir_rf( &article_file_name( $ShortDirectoryName ) );
my $newsgroup = pop( @_ );
if( &name_is_in_list( $from, "bad.posters.list" ) ) {
- &process_approval_decision( $subject, $newsgroup, $dir, "reject abuse", "" );
+ &process_approval_decision( $subject, $newsgroup, $dir, "reject abuse", "", "auto bad poster" );
return;
}
if( &name_is_in_list( $real_subject, "bad.subjects.list" ) ) {
- &process_approval_decision( $subject, $newsgroup, $dir, "reject thread", "" );
+ &process_approval_decision( $subject, $newsgroup, $dir, "reject thread", "", "auto bad subject" );
return;
}
&process_approval_decision( $subject, $newsgroup, $dir, "reject charter",
"Your message has been autorejected because it appears to be off topic
based on our filtering criteria. Like everything, filters do not
- always work perfectly and you can always appeal this decision." );
+ always work perfectly and you can always appeal this decision.",
+ "auto bad word" );
return;
}
}
if( &name_is_in_list( $from, "good.posters.list" ) ) {
- &process_approval_decision( $subject, $newsgroup, $dir, "approve", "" );
+ &process_approval_decision( $subject, $newsgroup, $dir, "approve", "",
+ "auto good poster" );
return;
}
if( &name_is_in_list( $real_subject, "good.subjects.list" ) ) {
- &process_approval_decision( $subject, $newsgroup, $dir, "approve", "" );
+ &process_approval_decision( $subject, $newsgroup, $dir, "approve", "",
+ "auto good subject" );
return;
}
#
use POSIX;
+use CGI qw/escapeHTML/;
sub begin_html {
my $title = pop( @_ );
print "<FORM METHOD=$request_method action=$base_address>";
&html_print_credentials;
print "<INPUT NAME=action VALUE=moderator_admin TYPE=hidden>
- <INPUT TYPE=submit VALUE=\"Manage pass/grey/block-lists\">
+ <INPUT TYPE=submit VALUE=\"Management\">
</FORM>";
&end_html;
<INPUT NAME=password VALUE=\"$password\" TYPE=hidden>\n";
}
+# logs
+
+sub scanlogs ($$$) {
+ my ($forwards, $gotr, $callback) = @_;
+ my $dir= "$webstump_home/..";
+ opendir LOGSDIR, "$dir" or die "$dir $!";
+ my $num= sub {
+ local ($_) = @_;
+ return $forwards * (
+ m/^errs$/ ? -1 :
+ m/^errs\.(\d+)(?:\.gz$)$/ ? $1 :
+ undef
+ );
+ };
+ foreach my $leaf (
+ sort { $num->($a) <=> $num->($b) }
+ grep { defined $num->($_) }
+ readdir LOGSDIR
+ ) {
+ my $file= "$dir/$leaf";
+ if ($file =~ m/\.gz$/) {
+ open LOGFILE, "zcat $file |" or die "zcat $file $!";
+ } else {
+ open LOGFILE, "< $file" or die "$file $!";
+ }
+ while (<LOGFILE>) {
+ my $tgot= $callback->();
+ next unless $tgot;
+ $$gotr= $tgot if $tgot > $$gotr;
+ last if $tgot > 1;
+ }
+ $!=0; $?=0; close LOGFILE or die "$file $? $!";
+ last if $$gotr > 1;
+ }
+ closedir LOGSDIR or die "$dir $!";
+}
+
+sub html_search_logs {
+ &begin_html("Search logs for $request{'newsgroup'}");
+ my $reqnum;
+ my $forwards=1;
+ my $min= 9;
+ if ($request{'download_logs'}) {
+ print "<h2>Complete log download</h2>\n";
+ $min= 2;
+ } elsif ($request{'messagenum'} =~ m/^\s*(\d+)\s*$/) {
+ $reqnum= $1;
+ $forwards= -1;
+ $min= 1;
+ print "<h2>Log entry for single message $reqnum</h2>\n";
+ } else {
+ print "<h2>Log lookup - bad reference</h2>
+Please supply the numerical reference as found in the \"recent activity\"
+log or message headers. Reference numbers consist entirely of digits,
+and are often quoted in message headers in [square brackets].<p>
+ ";
+ &end_html;
+ return;
+ }
+ if ($mod_log_access < $min) {
+ print "Not permitted [$mod_log_access<$min]. Consult administrator.\n";
+ &end_html;
+ return;
+ }
+
+ my $sofar= 0;
+ &scanlogs($forwards, \$sofar, sub {
+ return 0 unless chomp;
+ return 0 unless m/^DECISION: /;
+ my @vals = split / \| /, $';
+ return 0 unless @vals >= 5;
+ my $subj= pop @vals;
+ my ($group,$dir,$act,$reason) = @vals;
+ return 0 unless $group eq $request{'newsgroup'};
+ return 0 unless $subj =~ m,/(\d+)$,;
+ my $treqnum= $1;
+ return 0 if defined($reqnum) and $treqnum ne $reqnum;
+ print "<table rules=all><tr><th>Reference<th>Disposal<th>Reason</tr>\n"
+ unless $sofar;
+ print "<tr>", (map { "<td>".escapeHTML($_) } $treqnum,$act,$reason);
+ print "</tr>\n";
+ return defined($reqnum) ? 2 : 1;
+ });
+ if ($sofar) {
+ print "</table>" if $sofar;
+ print "\n";
+ } else {
+ print "Reference not found.";
+ }
+ &end_html;
+}
+
# newsgroup admin page
sub html_newsgroup_management {
&begin_html( "Administer $request{'newsgroup'}" );
&link_to_help( "filter-lists", "filtering lists" );
+ print "</FORM><HR>";
+
+ if ($mod_log_access) {
+ print "<form>
+ Use this form to search logs of past moderation decisions:
+ <br>
+ <form method=$request_method action=$base_address>
+ <input name=action value=search_logs type=hidden>";
+
+ &html_print_credentials;
+
+ print "
+ Reference number: <input name=messagenum size=30>
+ <input type=submit value=\"Lookup\">";
+
+ print "
+ <input type=submit value=\"Download all logs\" name=\"download_logs\">"
+ if $mod_log_access >= 2;
+
+ print "</form><hr>\n";
+ }
+
print "
- </FORM><HR>
List of current moderators:<P>
if $thread_decision eq "watch";
# Subject, newsgroup, ShortDirectoryName, decision, comment
- &process_approval_decision( $Subject, $newsgroup, $file, $decision, $comment );
+ &process_approval_decision( $Subject, $newsgroup, $file, $decision, $comment, "moderator \U$request{'moderator'}" );
}
}
} elsif( $action eq "change_password" ) {
&authenticate( $newsgroup, $moderator, $password );
&html_change_password;
+ } elsif( $action eq "search_logs" ) {
+ &authenticate( $newsgroup, $moderator, $password );
+ &html_search_logs;
} elsif( $action eq "validate_change_password" ) {
&authenticate( $newsgroup, $moderator, $password );
&validate_change_password;
$webstump_home = $0;
$webstump_home =~ s/\/scripts\/webstump\.pl$//;
+my $logfile= "$webstump_home/../errs";
+open STDERR, ">> $logfile" or die "$logfile $!";
+
$webstump_home =~ /(^.*$)/;
$webstump_home = $1;
$message .= $line;
}
chomp;
- $f{Event}= "notify $'" if m/^X-Webstump-Event:\s*/i; #';
+ if (m/^X-Webstump-Event:\s*(?:\[(\d+)\])?\s*/i) { #';
+ $f{Event}= "notify $'";
+ $f{MessageNum}= $1 if defined $1;
+ }
last if m/^$/;
}
while (<STDIN>) {
if ($publish_rejections &&
$f{Event} =~ m/^notify reject /) {
- $f{CopyRef}= $f{MessageID};
+ $f{CopyRef}= $f{MessageNum} || $f{MessageID};
$f{CopyRef} =~ s/\W/ sprintf '-%02x', ord($&) /ge;
open I, ">$dir/public/nr-$f{CopyRef}.txt" or die $!;
print I $message or die $!;