[news.software.b] C news patch to deal with bogus distributions

pst@ack.Stanford.EDU (Paul Traina) (10/22/90)

Here are my patches for C news to deal with the bogus distribution problem.
I find the entire thing distasteful, as I don't like fixing other peoples
problems in local code,  but since the universe is a screwed place to begin
with...

The whole problem becomes simple if you ask yourself, "when is the
distribution line actually necessary?"

_My_ answer is:
The distribution line is only necessary when one wants to further limit
the distribution of an article, when "newsgroup" granularity is not enough.

What is a "bogus" distribution line?

One that can't do anything useful, since the distribution line would not cut
the distributon of a group in the "real" USENET world (in other words, when
dealing with the old B news convolutions, rather than a strict interpretation
of the RFC).

examples of bogus distribution lines:

	Newsgroups: rec.autos
	Distribution: rec

	Newsgroups: rec.autos,comp.lsi
	Distribution: rec,comp

	Newsgroup: ba.judges.bork.bork.bork
	Distribution: ba

examples of useful distribution lines:

	Newsgroups: alt.sex
	Distribution: ba

	Newsgroups: alt.sex,ba.singles
	Distribution: ba

	Newsgroups: clari.news.hot.iraq
	Distribution: na

	Newsgroups: misc.forsale
	Distribution: nj,ny

This code should never over-restrict an article,  rather it will open up
distribution in a quasi-B-news compatible way.  The entire effect is to say:

	If the distribution line isn't useful, just ignore the damn thing
	and rely on newsgroup checking to see which machines should get
	the article.

Implementation:  I added a general routine to "ngmatch.c" called ngallmatch
which performs an "AND" pattern match to complement ngmatch()'s "OR" pattern
match.  Then I reversed the actual call arguments from the cannonical sequence
when it's used in oktransmit() so that "Distribution:" is a pattern and 
"Newsgroups:" is a string to match against the pattern.  This ass-backwards
approach will declare a distribution "useless" if all newsgroups are covered
in the distribution pattern.

Warnings:  I just wrote this,  but ran it through a test jig with all the
	cases I could think of and it seems to work fine.  If it breaks, it
	will break in the "flood" rather than "starve" direction;  but be
	warned that I have not thought about this enough to "prove"
	the code.

Patches (may need some fuzz as I have other patches in transmit.c):

*** transmit.c.save	Sun Oct 21 21:54:22 1990
--- transmit.c	Sun Oct 21 22:36:38 1990
***************
*** 102,108 ****
  	    exclude != NULL && STREQ(exclude, site) || hostin(site, path) ||
  	    sys->sy_excl != NULL && anyhostin(sys->sy_excl, path) ||
  	    !ngmatch(sys->sy_ngs, art->h.h_ngs) ||
! 	    !ngmatch(sys->sy_distr, art->h.h_distr))
  		result = NO;
  	else if (flags&(FLG_MOD|FLG_UNMOD)) {	/* u, m flag selection */
  		if ((flags&(FLG_MOD|FLG_UNMOD)) != (FLG_MOD|FLG_UNMOD))
--- 102,109 ----
  	    exclude != NULL && STREQ(exclude, site) || hostin(site, path) ||
  	    sys->sy_excl != NULL && anyhostin(sys->sy_excl, path) ||
  	    !ngmatch(sys->sy_ngs, art->h.h_ngs) ||
! 	    (!ngallmatch(art->h.h_distr, art->h.h_ngs) && /* ignore dumb dist */
! 		!ngmatch(sys->sy_distr, art->h.h_distr)))
  		result = NO;
  	else if (flags&(FLG_MOD|FLG_UNMOD)) {	/* u, m flag selection */
  		if ((flags&(FLG_MOD|FLG_UNMOD)) != (FLG_MOD|FLG_UNMOD))


*** ngmatch.c.sav	Wed Sep  5 21:43:53 1990
--- ngmatch.c	Sun Oct 21 22:32:06 1990
***************
*** 52,57 ****
--- 52,83 ----
  }
  
  boolean
+ ngallmatch(ngpat, ngs)
+ char *ngpat, *ngs;
+ {
+ 	register char *ngp;			/* point at current group */
+ 	register char *ngcomma;
+ 	register char *rngpat = ngpat;
+ 
+ 	if (debug)
+ 		(void) fprintf(stderr, "ngmatch(`%s', `%s')\n", rngpat, ngs);
+ 	for (ngp = ngs; ngp != NULL; ngp = ngcomma) {
+ 		register boolean match;
+ 
+ 		STRCHR(ngp, NGSEP, ngcomma);
+ 		if (ngcomma != NULL)
+ 			*ngcomma = '\0';	/* will be restored below */
+ 		match = mpatsmatch(rngpat, ngp); /* try 1 group, n-patterns */
+ 		if (ngcomma != NULL)
+ 			*ngcomma++ = NGSEP;	/* point after the comma */
+ 		if (!match)
+ 			return NO;
+ 	}
+ 	return YES;			/* pattern matched all groups */
+ }
+ 
+ 
+ boolean
  ngmatch(ngpat, ngs)
  char *ngpat, *ngs;
  {