This is a merger of the Panix poison patch with Odd Einar's patch to prevent
articles rejected due to exclusion patterns in hosts.nntp from being entered
into history even with REMEMBER_TRASH set to DO.  The original Panix poison
patch is available under <URL:http://www.panix.com/gizmo/>.

This patch was built relative to INN 1.7.2-insync-1.1d.  It allows @
patterns in hosts.nntp and allows one to use hosts.nntp patterns to exclude
posts in certain hierarchies from certain hosts without losing those posts
if other sites that you do allow to feed those hierarchies offer them to
you.

				-- Russ Allbery (rra@stanford.edu)

============================================================================

--- innd/art.c.orig	Tue Dec 16 21:33:16 1997
+++ innd/art.c	Sun Jan  4 17:40:15 1998
@@ -1747,6 +1747,7 @@
     ARTDATA		Data;
     BOOL		Approved;
     BOOL		Accepted;
+    BOOL		DontRemember;
     BOOL		LikeNewgroup;
     BOOL		ToGroup;
     BOOL		GroupMissing;
@@ -1760,6 +1761,7 @@
     char		ControlWord[SMBUF];
     int			ControlHeader;
     int			oerrno;
+    int 		canpost;
 #if defined(DO_PERL)
     char		*perlrc;
 #endif /* DO_PERL */
@@ -2004,8 +2006,20 @@
     ngptr = GroupPointers;
     j = 0;
     for (GroupMissing = Accepted = FALSE; (p = *groups) != NULL; groups++) {
-	if (!RCcanpost(cp, p))
+        canpost = RCcanpost(cp, p);
+	if (!canpost) {
+	    DontRemember = TRUE;
 	    continue;
+	}
+	else if (canpost < 0) {
+	    (void)sprintf(buff, "%d Won't accept posts in \"%s\"",
+	        NNTP_REJECTIT_VAL, p);
+	    ARTlog(&Data, ART_REJECT, buff);
+	    if (distributions)
+		DISPOSE(distributions);
+	    ARTreject(buff, article);
+	    return buff;
+	}
 	if ((ngp = NGfind(p)) == NULL) {
 	    GroupMissing = TRUE;
 	    if (LikeNewgroup && Approved) {
@@ -2113,7 +2127,7 @@
 	    ARTlog(&Data, ART_REJECT, buff);
 #if	defined(DONT_WANT_TRASH)
 #if	defined(DO_REMEMBER_TRASH)
-	    if (Mode == OMrunning && !HISwrite(&Data, ""))
+	    if (!DontRemember && Mode == OMrunning && !HISwrite(&Data, ""))
 		syslog(L_ERROR, "%s cant write history %s %m",
                        LogName, Data.MessageID);
 #endif	/* defined(DO_REMEMBER_TRASH) */
@@ -2129,7 +2143,7 @@
 	     * you explicitly excluded in your active file. */
 	    if (!GroupMissing) {
 #if	defined(DO_REMEMBER_TRASH)
-                if (Mode == OMrunning && !HISwrite(&Data, ""))
+                if (!DontRemember && Mode == OMrunning && !HISwrite(&Data, ""))
                     syslog(L_ERROR, "%s cant write history %s %m",
                            LogName, Data.MessageID);
 #endif	/* defined(DO_REMEMBER_TRASH) */
--- innd/innd.h.orig	Fri Dec 12 09:26:10 1997
+++ innd/innd.h	Sun Jan  4 17:36:12 1998
@@ -539,7 +539,7 @@
 
 extern BOOL		RCnolimit();
 extern BOOL		RCauthorized();
-extern BOOL		RCcanpost();
+extern int		RCcanpost();
 extern char		*RChostname();
 extern int		RCismaster();
 extern void		RCclose();
--- innd/rc.c.orig	Mon Dec  8 15:48:50 1997
+++ innd/rc.c	Sun Jan  4 17:36:12 1998
@@ -586,14 +586,14 @@
 /*
 **  Is the remote site allowed to post to this group?
 */
-BOOL
+int
 RCcanpost(cp, group)
     register CHANNEL	*cp;
     register char	*group;
 {
     register REMOTEHOST	*rp;
-    register BOOL	match;
-    register BOOL	subvalue;
+    register char	match;
+    register char	subvalue;
     register char	**argv;
     register char	*pat;
     register int	i;
@@ -604,16 +604,20 @@
 	    continue;
 	if (rp->Patterns == NULL)
 	    break;
-	for (match = TRUE, argv = rp->Patterns; (pat = *argv++) != NULL; ) {
-	    subvalue = *pat != SUB_NEGATE;
-	    if (!subvalue)
+	for (match = 0, argv = rp->Patterns; (pat = *argv++) != NULL; ) {
+	    subvalue = (*pat != SUB_NEGATE) && (*pat != SUB_POISON) ?
+	      0 : *pat;
+	    if (subvalue)
 		pat++;
-	    if ((match != subvalue) && wildmat(group, pat))
+	    if ((match != subvalue) && wildmat(group, pat)) {
+		if (subvalue == SUB_POISON)
+		    return -1;
 		match = subvalue;
+	    }
 	}
-	return match;
+	return !match;
     }
-    return TRUE;
+    return 1;
 }
 
 
