This inn 1.5.1 patch was converted from Clayton O'Neill's patch for inn1.4unoff4 found at http://thereisnocabal.news.erols.com/patches/xrefslave.diff It has been used successfully here for the past month. Bob Thrush rd@thrush.com diff -u art.c.orig art.c --- art.c.orig Tue Dec 17 09:40:40 1996 +++ art.c Fri Dec 20 13:22:16 1996 @@ -66,7 +66,6 @@ STATIC ARTOVERFIELD *ARTfields; - /* ** General newsgroup we care about, and what we put in the Path line. */ @@ -127,7 +126,7 @@ #define _alsocontrol 15 { "References", HTstd }, #define _references 16 - { "Xref", HTobs }, + { "Xref", HTsav }, #define _xref 17 { "Keywords", HTstd }, #define _keywords 18 @@ -578,7 +577,7 @@ } /* Install in header table; STRLEN("Xref: ") == 6. */ - HDR(_xref) = Xref.Data + 6; + strcpy(ARTheaders[_xref].Value, Xref.Data + 6); ARTheaders[_xref].Length = Xref.Used - 6; ARTheaders[_xref].Found = 1; @@ -738,6 +737,10 @@ return in; } + if (hp->Type == HTsav) { + *deltap = 0; + } + /* If body of header is all blanks, drop the header. */ for (p = colon + 1; ISWHITE(*p); p++) continue; @@ -1475,6 +1478,75 @@ /* +** Parse the data from the xref header and assign the numbers. +** This involves replacing the GroupPointers entries. +*/ +STATIC BOOL +ARTxrefslave() +{ + char *p; + char *q; + char *r; + char *name; + char *next; + NEWSGROUP *ngp; + int i; + + if (!ARTheaders[_xref].Found) + return FALSE; + if ((name = strchr(HDR(_xref), ' ')) == NULL) + return FALSE; + + p = &Xref.Data[Xref.Used]; + name++; /* Point at first article ref */ + for (i = 0; *name; name = next) { + /* Mark end of this entry and where next one starts. */ + if ((next = strchr(name, ' ')) != NULL) + *next++ = '\0'; + else + next = ""; + + /* Split into news.group/# from news.group:# */ + if ((q = strchr(name, ':')) == NULL) { + syslog(L_ERROR, "%s bad_format %s", LogName, name); + continue; + } + *q = '\0'; + if ((ngp = NGfind(name)) == NULL) { + syslog(L_ERROR, "%s bad_newsgroup %s", LogName, name); + continue; + } + ngp->Filenum = atol(q + 1); + + /* Update active file if we got a new high-water mark. */ + if (ngp->Last < ngp->Filenum) { + ngp->Last = ngp->Filenum; + if (!FormatLong(ngp->LastString, (long)ngp->Last, + ngp->Lastwidth)) { + syslog(L_ERROR, "%s cant update_active %s", + LogName, ngp->Name); + continue; + } + } + + /* Mark that this group gets the article. */ + ngp->PostCount++; + GroupPointers[i++] = ngp; + + /* Append to the global Xref buffer */ + *q = ':'; + *p++ = ' '; + p += strlen(strcpy(p, name)); + } + /* Update global Xref */ + Xref.Used = p - Xref.Data; + Xref.Data[Xref.Used++] = '\n'; + Xref.Data[Xref.Used] = '\0'; + return TRUE; +} + + +/* ** Parse the data from the xreplic command and assign the numbers. ** This involves replacing the GroupPointers entries. */ @@ -2107,9 +2179,17 @@ } } *ngptr = NULL; - j++; - if (Replic) + if (Replic) { j = Replic->Used + 1; + } else if(XrefSlave) { + /* Don't count the length of our feed's news name */ + char *q; + p=HDR(_xref); + q=strchr(p, ' ') + 1; + j = ARTheaders[_xref].Length - (q - p) + 1; + } else { + j++; + } /* Make sure the Xref buffer has room. */ Xref.Used = Xrefbase; @@ -2129,10 +2209,28 @@ } /* Assign article numbers, fill in Xref buffer. */ + if (XrefSlave == TRUE) { + if (ARTxrefslave() == FALSE) { + if (HDR(_xref)) { + (void)sprintf(buff, "%d Invalid Xref header \"%s\"", + NNTP_REJECTIT_VAL, + MaxLength(HDR(_xref), HDR(_xref))); + } else { + (void)sprintf(buff, "%d No Xref header", + NNTP_REJECTIT_VAL); + } + ARTlog(&Data, ART_REJECT, buff); + if (distributions) + DISPOSE(distributions); + ARTreject(buff, article); + return buff; + } + } else { if (Replic == NULL) ARTassignnumbers(); else ARTreplic(Replic); + } /* Optimize how we place the article on the disk. */ ARTsortfordisk(); diff -u art.h.orig art.h --- art.h.orig Tue Dec 17 09:40:40 1996 +++ art.h Fri Dec 20 13:16:01 1996 @@ -9,7 +9,8 @@ typedef enum _ARTHEADERTYPE { HTreq, /* Drop article if this is missing */ HTobs, /* Delete this header if found */ - HTstd /* Standard optional header */ + HTstd, /* Standard optional header */ + HTsav /* Save header, but delete from article */ } ARTHEADERTYPE; /* diff -u innd.c.orig innd.c --- innd.c.orig Tue Dec 17 09:40:40 1996 +++ innd.c Fri Dec 20 13:16:01 1996 @@ -638,13 +638,16 @@ /* Parse JCL. */ CCcopyargv(av); - while ((i = getopt(ac, av, "ac:Cdfi:l:Lm:o:n:p:rsS:t:uH:T:X:")) != EOF) + while ((i = getopt(ac, av, "abc:Cdfi:l:Lm:o:n:p:rsS:t:uH:T:X:")) != EOF) switch (i) { default: Usage(); /* NOTREACHED */ case 'a': AnyIncoming = TRUE; + break; + case 'b': + XrefSlave = TRUE; break; case 'c': Cutoff = atoi(optarg) * 24 * 60 * 60; diff -u innd.h.orig innd.h --- innd.h.orig Tue Dec 17 09:40:40 1996 +++ innd.h Fri Dec 20 13:16:02 1996 @@ -388,6 +388,7 @@ extern BOOL NNRPTracing; extern BOOL StreamingOff; extern BOOL Tracing; +EXTERN BOOL XrefSlave; EXTERN BUFFER Path; EXTERN BUFFER Xref; EXTERN char *ModeReason; /* NNTP reject message */ diff -u nc.c.orig nc.c --- nc.c.orig Tue Dec 17 09:40:40 1996 +++ nc.c Fri Dec 20 13:16:02 1996 @@ -232,7 +232,7 @@ return; case OMrunning: wp = &NCwip[cp->fd]; - response = ARTpost(cp, AmSlave ? &wp->Replic : NULL, wp->MessageID); + response = ARTpost(cp, (AmSlave && !XrefSlave) ? &wp->Replic : NULL, wp->MessageID); if (atoi(response) == NNTP_TOOKIT_VAL) { cp->Received++; if (cp->Sendid.Size > 3) { /* We be streaming */ @@ -571,7 +571,7 @@ register char *p; WIP *who; - if (AmSlave) { + if (AmSlave && !XrefSlave) { NCwritetext(cp, NCbadcommand); return; } @@ -615,7 +615,7 @@ register char *p; WIP *wp; - if (AmSlave) { + if (AmSlave && !XrefSlave) { NCwritetext(cp, NCbadcommand); return; } @@ -1462,7 +1462,7 @@ int msglen; WIP *who; - if (AmSlave) { + if (AmSlave && !XrefSlave) { NCwritetext(cp, NCbadcommand); return; }