[leafnode-list] Preventing crossposting to a local group?

Matthias Andree matthias.andree at gmx.de
Tue Dec 14 00:21:11 CET 2004


Lloyd Zusman schrieb am 2004-12-07:

> I fixed this problem by re-installing a newer version of leafnode:
> 
>   leafnode-2.0.0.alpha20041113a
> 
> I'm not sure why the other version didn't work.  But anyway,
> messages that I post to the local group are now indeed leaving the
> "in.coming" folder and going to their proper places in the newsgroup
> spool.
> 
> However, the filter rules that you suggested earlier are not
> working: crossposts are ending up in my local group, despite the
> rules.  See the message that I posted right before this one for more
> details.

Please let me know if the attached patch solves your problem. It applies
on top of 20041213a, the current release.

-- 
Matthias Andree
-------------- next part --------------
diff -Nur a/Makefile.am b/Makefile.am
--- a/Makefile.am	2004-12-04 04:08:43.000000000 +0100
+++ b/Makefile.am	2004-12-13 23:50:50.000000000 +0100
@@ -115,6 +115,7 @@
 	pcrewrap.h \
 	putaline.c \
 	queues.c \
+	readheaders.c \
 	redblack.c \
 	redblack.h \
 	sgetcwd.h \
diff -Nur a/Makefile.in b/Makefile.in
--- a/Makefile.in	2004-12-13 13:05:06.000000000 +0100
+++ b/Makefile.in	2004-12-13 23:50:55.000000000 +0100
@@ -98,10 +98,10 @@
 	msgid_hash.$(OBJEXT) msgid_sanitize.$(OBJEXT) \
 	mysetvbuf.$(OBJEXT) nfswrite.$(OBJEXT) nntputil.$(OBJEXT) \
 	parserange.$(OBJEXT) pcrewrap.$(OBJEXT) putaline.$(OBJEXT) \
-	queues.$(OBJEXT) redblack.$(OBJEXT) sgetcwd.$(OBJEXT) \
-	sort.$(OBJEXT) store.$(OBJEXT) strutil.$(OBJEXT) \
-	sync_dir.$(OBJEXT) sync_link.$(OBJEXT) tab2spc.$(OBJEXT) \
-	timeout_getaline.$(OBJEXT) touch.$(OBJEXT) \
+	queues.$(OBJEXT) readheaders.$(OBJEXT) redblack.$(OBJEXT) \
+	sgetcwd.$(OBJEXT) sort.$(OBJEXT) store.$(OBJEXT) \
+	strutil.$(OBJEXT) sync_dir.$(OBJEXT) sync_link.$(OBJEXT) \
+	tab2spc.$(OBJEXT) timeout_getaline.$(OBJEXT) touch.$(OBJEXT) \
 	ugid_gensure.$(OBJEXT) ugid_gget.$(OBJEXT) \
 	ugid_ggetbyuname.$(OBJEXT) ugid_gset.$(OBJEXT) \
 	ugid_uensure.$(OBJEXT) ugid_uget.$(OBJEXT) \
@@ -437,6 +437,7 @@
 	pcrewrap.h \
 	putaline.c \
 	queues.c \
+	readheaders.c \
 	redblack.c \
 	redblack.h \
 	sgetcwd.h \
@@ -798,6 +799,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/pcrewrap.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/putaline.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/queues.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/readheaders.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/redblack.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/rnews.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/sgetcwd.Po at am__quote@
diff -Nur a/NEWS b/NEWS
--- a/NEWS	2004-12-13 12:54:05.000000000 +0100
+++ b/NEWS	2004-12-14 00:11:00.000000000 +0100
@@ -2,6 +2,9 @@
 * Valgrind-2.1.X will interfere with writeactive, break fchmod. Use 2.0.
 * The code sometimes uses timeout_client where it should use a server timeout.
 |
+Changes since 20041213a:
+- Feature: when a fresh post matches a filter, reject the post.
+
 20041213a: Changes since 20041113a:
 - Bugfix: get rid of cosmetic bug "Groupinfo file damaged, ignoring line: 18"
 - Change: when complaining about damaged groupinfo file, print the line
diff -Nur a/applyfilter.c b/applyfilter.c
--- a/applyfilter.c	2004-12-04 04:08:46.000000000 +0100
+++ b/applyfilter.c	2004-12-14 00:08:22.000000000 +0100
@@ -31,8 +31,6 @@
 #include <dmalloc.h>
 #endif
 
-#define MAXHEADERSIZE 2047
-
 extern char *optarg;
 extern int optind, opterr, optopt;
 
@@ -54,71 +52,6 @@
 	    sysconfdir);
 }
 
-/* read from fd into malloced buffer *bufp of size *size
- * up to delim or EOF.  Buffer is adjusted to fit input.
- * return pointer to match or end of file, NULL in case of error
- */
-static /*@null@*/ /*@dependent@*/ char *
-readtodelim(int fd, const char *name, /*@unique@*/ /*@observer@*/ const char *delim,
-    char **bufp, size_t *size)
-{
-    size_t dlen = strlen(delim) - 1;
-    size_t nread;
-    ssize_t res;
-    char *k;
-
-    nread = 0;
-    if (*size < 1 || *bufp == NULL)
-	*bufp = (char *)critmalloc((*size = MAXHEADERSIZE+1), "readtodelim");
-
-    /*@+loopexec@*/
-    for (;;) {
-	res = read(fd, *bufp + nread, *size - nread - 1);
-	if (res < 0) { /* read error/EINTR/whatever */
-	    printf("error reading %s: %s\n", name, strerror(errno));
-	    return NULL;
-	}
-
-	(*bufp)[nread + res] = '\0';
-	/* skip as much as possible */
-	k = strstr(nread > dlen ? *bufp + nread - dlen : *bufp, delim);
-
-	nread += res;
-	if ((size_t)res < *size-nread-1) { /* FIXME: can short reads happen? */
-	    return k != NULL ? k : *bufp + nread;
-	}
-
-	if (k != NULL) {
-	    return k;
-	}
-
-	/* must read more */
-	*bufp = (char *)critrealloc(*bufp, (*size)*=2, "readtodelim");
-    }
-    /*@=loopexec@*/
-}
-
-/* read article headers, cut off body
- * return 0 for success, -1 for error, -2 for article without body
- */
-static int
-readheaders(int fd, /*@unique@*/ const char *name, char **bufp, size_t *size)
-{
-    char *k = readtodelim(fd, name, "\n\n", bufp, size); /* XXX FIXME:
-							    cater for wire
-							    format */
-    if (k != NULL) {
-	if (*k == '\0')
-	    return -2;
-	else {
-	    k[1] = '\0'; /* keep last header line \n terminated */
-	    return 0;
-	}
-    } else {
-	return -1;
-    }
-}
-
 /* remove LF in LF+whitespace sequences, in place */
 static void unfold(char *p)
 {
@@ -172,7 +105,7 @@
 	int ret;
 
 	/* read and unfold headers */
-	ret = readheaders(fd, name, &l, &lsize);
+	ret = readheaders(fd, name, &l, &lsize, "\n\n");
 	if (ret != -1)
 	    unfold(l);
 
diff -Nur a/leafnode.h b/leafnode.h
--- a/leafnode.h	2004-12-04 04:09:15.000000000 +0100
+++ b/leafnode.h	2004-12-14 00:08:24.000000000 +0100
@@ -81,6 +81,9 @@
 /*@constant int BLOCKSIZE;@*/
 #define BLOCKSIZE 16384
 
+/*@constant int MAXHEADERSIZE;@*/
+#define MAXHEADERSIZE 16383
+
 /*@constant mode_t MKDIR_MODE;@*/
 #define MKDIR_MODE 0770
 
@@ -731,6 +734,12 @@
 #endif
 void d_stop_mid(const char *mid);
 
+/* readheaders.c */
+extern int
+readheaders(int fd, /*@unique@*/ const char *name, char **bufp, size_t *size,
+	const char *delim);
+
+
 #if 0
 #warning "WARNING: do not disable fsync in production use"
 #define fsync(a) (0)
diff -Nur a/nntpd.c b/nntpd.c
--- a/nntpd.c	2004-12-04 04:09:09.000000000 +0100
+++ b/nntpd.c	2004-12-14 00:08:52.000000000 +0100
@@ -1443,6 +1443,35 @@
 	    }
 	}
 
+	if (filter) {
+	    char *t, *u = critstrdup(groups, "dopost");
+	    int fd;
+	    char *l;
+	    size_t lsize = MAXHEADERSIZE + 1;
+	    l = (char *)critmalloc(lsize, "Space for article");
+
+	    /* read header */
+	    fd = open(inname, O_RDONLY);
+	    if (fd < 0 || readheaders(fd, inname, &l, &lsize, "\r\n\r\n") < 0) {
+		nntpprintf("441 internal error.");
+		free(u);
+		log_unlink(inname, 0);
+		goto cleanup;
+	    }
+
+	    /* apply filter for all newsgroups found in turn */
+	    for (t = strtok(u, ", "); t; t = strtok(NULL, ", ")) {
+		struct filterlist *fi = selectfilter(t);
+		if (killfilter(fi, l)) {
+		    nntpprintf("441 Article rejected by filter.");
+		    log_unlink(inname, 0);
+		    free(u);
+		    goto cleanup;
+		}
+	    }
+	    free(u);
+	}
+
 	/* check if we can obtain the MID or if the article is duplicate */
 	switch(msgid_allocate(inname, mid)) {
 	    case 1:
@@ -2503,6 +2532,12 @@
     if (conffile)
 	free(conffile);
 
+    if (filterfile && !readfilter(filterfile)) {
+	ln_log_so(LNLOG_SERR, LNLOG_CTOP,
+		  "503 Server misconfiguration: cannot read filter file.");
+	exit(EXIT_FAILURE);
+    }
+
     if (!init_post())
 	init_failed(myname);
 
diff -Nur a/readheaders.c b/readheaders.c
--- a/readheaders.c	1970-01-01 01:00:00.000000000 +0100
+++ b/readheaders.c	2004-12-14 00:08:23.000000000 +0100
@@ -0,0 +1,69 @@
+#include "leafnode.h"
+#include "critmem.h"
+
+#define MAXHEADERSIZE 16383
+
+/* read from fd into malloced buffer *bufp of size *size
+ * up to delim or EOF.  Buffer is adjusted to fit input.
+ * return pointer to match or end of file, NULL in case of error
+ */
+/*@null@*/ /*@dependent@*/ static char *
+readtodelim(int fd, const char *name, /*@unique@*/ /*@observer@*/ const char *delim,
+    char **bufp, size_t *size)
+{
+    size_t dlen = strlen(delim) - 1;
+    size_t nread;
+    ssize_t res;
+    char *k;
+
+    nread = 0;
+    if (*size < 1 || *bufp == NULL)
+	*bufp = (char *)critmalloc((*size = MAXHEADERSIZE+1), "readtodelim");
+
+    /*@+loopexec@*/
+    for (;;) {
+	res = read(fd, *bufp + nread, *size - nread - 1);
+	if (res < 0) { /* read error/EINTR/whatever */
+	    printf("error reading %s: %s\n", name, strerror(errno));
+	    return NULL;
+	}
+
+	(*bufp)[nread + res] = '\0';
+	/* skip as much as possible */
+	k = strstr(nread > dlen ? *bufp + nread - dlen : *bufp, delim);
+
+	nread += res;
+	if ((size_t)res < *size-nread-1) { /* FIXME: can short reads happen? */
+	    return k != NULL ? k : *bufp + nread;
+	}
+
+	if (k != NULL) {
+	    return k;
+	}
+
+	/* must read more */
+	*bufp = (char *)critrealloc(*bufp, (*size)*=2, "readtodelim");
+    }
+    /*@=loopexec@*/
+}
+
+/* read article headers, cut off body
+ * return 0 for success, -1 for error, -2 for article without body
+ */
+int
+readheaders(int fd, /*@unique@*/ const char *name, char **bufp, size_t *size, const char *delim)
+{
+    char *k = readtodelim(fd, name, delim, bufp, size); /* XXX FIXME:
+							    cater for wire
+							    format */
+    if (k != NULL) {
+	if (*k == '\0')
+	    return -2;
+	else {
+	    k[1] = '\0'; /* keep last header line \n terminated */
+	    return 0;
+	}
+    } else {
+	return -1;
+    }
+}


More information about the leafnode-list mailing list