[PATCH 1/2] storage: Add "filtered" option, to store based on the filter's decision
Christoph Biedl
isc.cxzo at manchmal.in-ulm.de
Tue Jan 16 19:00:00 UTC 2024
---
doc/pod/storage.conf.pod | 8 ++++++++
frontends/cnfsstat.in | 35 +++++++++++++++++++++++------------
include/inn/storage.h | 1 +
innd/art.c | 5 +++--
storage/interface.c | 11 +++++++++++
storage/interface.h | 1 +
6 files changed, 47 insertions(+), 14 deletions(-)
diff --git a/doc/pod/storage.conf.pod b/doc/pod/storage.conf.pod
index 852bf589f..52c8cc2c8 100644
--- a/doc/pod/storage.conf.pod
+++ b/doc/pod/storage.conf.pod
@@ -137,6 +137,14 @@ wildmat as described above.) This is a boolean value; C<true>, C<yes>
and C<on> are usable to enable this key. The case of these values is
not significant. The default is false.
+=item I<filtered>: <bool>
+
+If this key is set to true, the article must have been rejected by the
+Perl/Python filter. This also requires that dontfilterrejected is set
+to true in F<inn.conf>. This is a boolean value; C<true>, C<yes> and
+C<on> are usable to enable this key. The case of these values is not
+significant. The default is false.
+
=back
If an article matches all of the constraints of an entry, it is stored
diff --git a/frontends/cnfsstat.in b/frontends/cnfsstat.in
index 667c24ccb..953f0c266 100644
--- a/frontends/cnfsstat.in
+++ b/frontends/cnfsstat.in
@@ -159,28 +159,29 @@ if ($lastconftime < $maxtime) {
my $logline;
my $header_printed = 0;
-my ($gr, $cl, $min, $max);
+my ($gr, $cl, $min, $max, $filtered);
if ($oclass) {
if ($class{$oclass}) {
if (!$header_printed) {
if ($stor{$oclass}) {
- ($gr, $cl, $min, $max) = split(/:/, $stor{$oclass});
+ ($gr, $cl, $min, $max, undef, $filtered) = split(/:/, $stor{$oclass});
} else {
- ($gr, $cl, $min, $max) = ('', $oclass, 0, 0);
+ ($gr, $cl, $min, $max, $filtered) = ('', $oclass, 0, 0, 0);
}
# Remove leading and trailing double quotes, if present.
+ my $filtered_s = $filtered ? ", filtered only" : "";
$gr =~ s/"?([^"]*)"?/$1/g;
if ($use_syslog) {
if ($min || $max) {
$logline = sprintf(
"Class %s for groups matching \"%s\" "
- . "article size min/max: %d/%d",
- $oclass, $gr, $min, $max,
+ . "article size min/max: %d/%d%s",
+ $oclass, $gr, $min, $max, $filtered_s,
);
} else {
$logline = sprintf(
- "Class %s for groups matching \"%s\"",
- $oclass, $gr,
+ "Class %s for groups matching \"%s\"%s",
+ $oclass, $gr, $filtered_s,
);
}
} else {
@@ -189,6 +190,9 @@ if ($oclass) {
if ($min || $max) {
print STDOUT ", article size min/max: $min/$max";
}
+ if ($filtered) {
+ print STDOUT ", filtered articles only";
+ }
print STDOUT "\n";
}
$header_printed = 1;
@@ -213,19 +217,20 @@ if ($oclass) {
} else { # Print all Classes
my %buffDone;
foreach my $c (@storsort) {
- ($gr, $cl, $min, $max) = split(/:/, $stor{$c});
+ ($gr, $cl, $min, $max, undef, $filtered) = split(/:/, $stor{$c});
+ my $filtered_s = $filtered ? ", filtered only" : "";
# Remove leading and trailing double quotes, if present.
$gr =~ s/"?([^"]*)"?/$1/g;
if ($use_syslog) {
if ($min || $max) {
$logline = sprintf(
"Class %s for groups matching \"%s\" "
- . "article size min/max: %d/%d",
- $c, $gr, $min, $max,
+ . "article size min/max: %d/%d%s",
+ $c, $gr, $min, $max, $filtered_s,
);
} else {
$logline
- = sprintf("Class %s for groups matching \"%s\"", $c, $gr);
+ = sprintf("Class %s for groups matching \"%s\"%s", $c, $gr, $filtered_s);
}
} else {
print STDOUT "Class $c";
@@ -233,6 +238,9 @@ if ($oclass) {
if ($min || $max) {
print STDOUT ", article size min/max: $min/$max";
}
+ if ($filtered) {
+ print STDOUT ", filtered articles only";
+ }
print STDOUT "\n";
}
@buffers = split(/,/, $class{$c});
@@ -357,10 +365,13 @@ sub read_storageconf {
$key{'SIZE'} .= ",0" unless $key{'SIZE'} =~ /,/;
$key{'SIZE'} =~ s/,/:/;
+ $key{'FILTERED'} =
+ defined $key{'FILTERED'} ?
+ $key{'FILTERED'} =~ /^(true|yes|on)$/ ? 1 : 0 : 0;
if (!defined $stor{ $key{'OPTIONS'} }) {
$stor{ $key{'OPTIONS'} } = "$key{'NEWSGROUPS'}:$key{'CLASS'}:"
- . "$key{'SIZE'}:$key{'OPTIONS'}";
+ . "$key{'SIZE'}:$key{'OPTIONS'}:$key{'FILTERED'}";
push(@storsort, $key{'OPTIONS'});
}
}
diff --git a/include/inn/storage.h b/include/inn/storage.h
index 56230792a..2cdb1625c 100644
--- a/include/inn/storage.h
+++ b/include/inn/storage.h
@@ -50,6 +50,7 @@ typedef struct {
void *private; /* A pointer to method specific data */
time_t arrived; /* The time when the article arrived */
time_t expires; /* The time when the article will be expired */
+ bool filtered; /* Article was marked by the filter */
char *groups; /* Where Newsgroups header field body starts */
int groupslen; /* Length of Newsgroups header field body */
TOKEN *token; /* A pointer to the article's TOKEN */
diff --git a/innd/art.c b/innd/art.c
index be51e7bf1..0ef1ac06b 100644
--- a/innd/art.c
+++ b/innd/art.c
@@ -435,7 +435,7 @@ ARTheaderpcmp(const void *p1, const void *p2)
/* Write an article using the storage api. Put it together in memory and
call out to the api. */
static TOKEN
-ARTstore(CHANNEL *cp)
+ARTstore(CHANNEL *cp, bool filtered)
{
struct buffer *Article = &cp->In;
ARTDATA *data = &cp->Data;
@@ -557,6 +557,7 @@ ARTstore(CHANNEL *cp)
arth.arrived = (time_t) 0;
arth.token = (TOKEN *) NULL;
arth.expires = data->Expires;
+ arth.filtered = filtered;
if (innconf->storeonxref) {
arth.groups = data->Replic;
arth.groupslen = data->ReplicLength;
@@ -2576,7 +2577,7 @@ ARTpost(CHANNEL *cp)
for (i = 0; (ngp = GroupPointers[i]) != NULL; i++)
ngp->PostCount = 0;
- token = ARTstore(cp);
+ token = ARTstore(cp, Filtered);
/* Change trailing '\r\n' to '\0\n' of all system header fields. */
for (i = 0; i < MAX_ARTHEADER; i++) {
if (HDR_FOUND(i)) {
diff --git a/storage/interface.c b/storage/interface.c
index 81e7a25b4..34c0ebaec 100644
--- a/storage/interface.c
+++ b/storage/interface.c
@@ -261,6 +261,7 @@ ParseTime(char *tmbuf)
#define SMexpire 14
#define SMoptions 15
#define SMexactmatch 16
+#define SMfiltered 17
static CONFTOKEN smtoks[] = {
{SMlbrace, (char *) "{" },
@@ -272,6 +273,7 @@ static CONFTOKEN smtoks[] = {
{SMexpire, (char *) "expires:" },
{SMoptions, (char *) "options:" },
{SMexactmatch, (char *) "exactmatch:"},
+ {SMfiltered, (char *) "filtered:" },
{0, NULL }
};
@@ -298,6 +300,7 @@ SMreadconfig(void)
char *options = 0;
int inbrace;
bool exactmatch = false;
+ bool filtered = false;
/* if innconf isn't already read in, do so. */
if (innconf == NULL) {
@@ -351,6 +354,7 @@ SMreadconfig(void)
minexpire = 0;
maxexpire = 0;
exactmatch = false;
+ filtered = false;
} else {
type = tok->type;
@@ -403,6 +407,11 @@ SMreadconfig(void)
|| strcasecmp(p, "on") == 0)
exactmatch = true;
break;
+ case SMfiltered:
+ if (strcasecmp(p, "true") == 0 || strcasecmp(p, "yes") == 0
+ || strcasecmp(p, "on") == 0)
+ filtered = true;
+ break;
default:
SMseterror(SMERR_CONFIG,
"Unknown keyword in method declaration");
@@ -448,6 +457,7 @@ SMreadconfig(void)
sub->minexpire = minexpire;
sub->maxexpire = maxexpire;
sub->exactmatch = exactmatch;
+ sub->filtered = filtered;
free(method);
method = 0;
@@ -643,6 +653,7 @@ SMgetsub(const ARTHANDLE article)
&& (!sub->maxsize || (article.len <= sub->maxsize))
&& (!sub->minexpire || article.expires >= sub->minexpire)
&& (!sub->maxexpire || (article.expires <= sub->maxexpire))
+ && (sub->filtered == article.filtered)
&& MatchGroups(article.groups, article.groupslen, sub->pattern,
sub->exactmatch)) {
if (InitMethod(typetoindex[sub->type]))
diff --git a/storage/interface.h b/storage/interface.h
index b3cc35ca6..c67d1eb1e 100644
--- a/storage/interface.h
+++ b/storage/interface.h
@@ -45,6 +45,7 @@ typedef struct __S_SUB__ {
method */
bool exactmatch; /* all newsgroups to which article belongs
should match the patterns */
+ bool filtered; /* article was marked by the filter */
struct __S_SUB__ *next;
} STORAGE_SUB;
--
2.39.2
More information about the inn-workers
mailing list