[PATCH 2/2] storage: Add "path" option, to store based on the path the article went

Christoph Biedl isc.cxzo at manchmal.in-ulm.de
Tue Jan 16 19:00:00 UTC 2024


---
 doc/pod/storage.conf.pod | 15 +++++++++++++++
 include/inn/storage.h    |  2 ++
 innd/art.c               |  2 ++
 storage/interface.c      | 35 +++++++++++++++++++++++++++++++++++
 storage/interface.h      |  5 +++++
 5 files changed, 59 insertions(+)

diff --git a/doc/pod/storage.conf.pod b/doc/pod/storage.conf.pod
index 52c8cc2c8..16dca3099 100644
--- a/doc/pod/storage.conf.pod
+++ b/doc/pod/storage.conf.pod
@@ -145,6 +145,21 @@ 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.
 
+=item I<path>: <wildmat>
+
+What articles by the path are stored using this storage method.
+<wildmat> is a I<uwildmat> pattern which is matched against the path an
+article has passed, or was posted at.  Poison wildmat expressions
+(expressions starting with C<@>) are allowed and can be used to exclude
+certain path patterns.  The <wildmat> pattern is matched in order.
+
+A typical use case might be to store articles from a spammy site in
+a small buffer to avoid overall retenition suffers:
+
+    Path: "*!spam-site.example.com!not-for-mail"
+
+The default is to match all articles.
+
 =back
 
 If an article matches all of the constraints of an entry, it is stored
diff --git a/include/inn/storage.h b/include/inn/storage.h
index 2cdb1625c..d6db1d345 100644
--- a/include/inn/storage.h
+++ b/include/inn/storage.h
@@ -53,6 +53,8 @@ typedef struct {
     bool filtered;            /* Article was marked by the filter */
     char *groups;             /* Where Newsgroups header field body starts */
     int groupslen;            /* Length of Newsgroups header field body */
+    char *path;               /* Where Path header field body starts */
+    int pathlen;              /* Length of Path header field body */
     TOKEN *token;             /* A pointer to the article's TOKEN */
 } ARTHANDLE;
 
diff --git a/innd/art.c b/innd/art.c
index 0ef1ac06b..ffb1951b9 100644
--- a/innd/art.c
+++ b/innd/art.c
@@ -565,6 +565,8 @@ ARTstore(CHANNEL *cp, bool filtered)
         arth.groups = HDR(HDR__NEWSGROUPS);
         arth.groupslen = HDR_LEN(HDR__NEWSGROUPS);
     }
+    arth.path = HDR(HDR__PATH);
+    arth.pathlen = HDR_LEN(HDR__PATH);
 
     SMerrno = SMERR_NOERROR;
     result = SMstore(arth);
diff --git a/storage/interface.c b/storage/interface.c
index 34c0ebaec..41eae78aa 100644
--- a/storage/interface.c
+++ b/storage/interface.c
@@ -262,6 +262,7 @@ ParseTime(char *tmbuf)
 #define SMoptions    15
 #define SMexactmatch 16
 #define SMfiltered   17
+#define SMpath       18
 
 static CONFTOKEN smtoks[] = {
     {SMlbrace,     (char *) "{"          },
@@ -274,6 +275,7 @@ static CONFTOKEN smtoks[] = {
     {SMoptions,    (char *) "options:"   },
     {SMexactmatch, (char *) "exactmatch:"},
     {SMfiltered,   (char *) "filtered:"  },
+    {SMpath,       (char *) "path:"  },
     {0,            NULL                  }
 };
 
@@ -301,6 +303,7 @@ SMreadconfig(void)
     int inbrace;
     bool exactmatch = false;
     bool filtered = false;
+    char *path_pattern = NULL;
 
     /* if innconf isn't already read in, do so. */
     if (innconf == NULL) {
@@ -355,6 +358,7 @@ SMreadconfig(void)
             maxexpire = 0;
             exactmatch = false;
             filtered = false;
+            path_pattern = NULL;
 
         } else {
             type = tok->type;
@@ -412,6 +416,15 @@ SMreadconfig(void)
                         || strcasecmp(p, "on") == 0)
                         filtered = true;
                     break;
+                case SMpath:
+                    if (path_pattern)
+                        free(path_pattern);
+                    path_pattern = xstrdup(tok->name);
+                    /* Transform ! to | */
+                    for (char *p = path_pattern; *p; p++)
+                        if (*p == '!')
+                            *p = '|';
+                    break;
                 default:
                     SMseterror(SMERR_CONFIG,
                                "Unknown keyword in method declaration");
@@ -458,6 +471,7 @@ SMreadconfig(void)
             sub->maxexpire = maxexpire;
             sub->exactmatch = exactmatch;
             sub->filtered = filtered;
+            sub->path_pattern = path_pattern;
 
             free(method);
             method = 0;
@@ -632,6 +646,24 @@ MatchGroups(const char *g, int len, const char *pattern, bool exactmatch)
     return wanted;
 }
 
+static bool
+MatchPath(const char *p, int len, const char *pattern)
+{
+    char *path, *q;
+    int i, lastwhite;
+    enum uwildmat matched;
+
+    path = xmalloc(len + 1);
+    strncpy(path, p, len);
+    path[len] = '\0';
+    for (q = path; *q; q++)
+        if (*q == '!')
+            *q = '|';
+    matched = uwildmat_poison(path, pattern);
+    free(path);
+    return matched;
+}
+
 STORAGE_SUB *
 SMgetsub(const ARTHANDLE article)
 {
@@ -654,6 +686,9 @@ SMgetsub(const ARTHANDLE article)
             && (!sub->minexpire || article.expires >= sub->minexpire)
             && (!sub->maxexpire || (article.expires <= sub->maxexpire))
             && (sub->filtered == article.filtered)
+            && (
+                sub->path_pattern == NULL ||
+                MatchPath(article.path, article.pathlen, sub->path_pattern))
             && 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 c67d1eb1e..6e3be1933 100644
--- a/storage/interface.h
+++ b/storage/interface.h
@@ -46,6 +46,11 @@ typedef struct __S_SUB__ {
     bool exactmatch;  /* all newsgroups to which article belongs
                          should match the patterns */
     bool filtered;    /* article was marked by the filter */
+    char *path_pattern;
+                      /* Wildmat pattern to check against the
+                         path to determine if the article
+                         should go to this method. NULL if any path
+                         should match. */
     struct __S_SUB__ *next;
 } STORAGE_SUB;
 
-- 
2.39.2



More information about the inn-workers mailing list