Path: utzoo!utstat!news-server.csri.toronto.edu!clyde.concordia.ca!uunet!tut.cis.ohio-state.edu!ucbvax!agate!shelby!morrow.stanford.edu!news From: pst@ack.Stanford.EDU (Paul Traina) Newsgroups: news.software.b Subject: C news patch to deal with bogus distributions Message-ID: <1990Oct22.061147.25624@morrow.stanford.edu> Date: 22 Oct 90 06:11:47 GMT Sender: news@morrow.stanford.edu (UNIX News Service) Organization: Big Ed's Gas Farm, Twin Peaks, Washington Lines: 126 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; {