static char *sccsid = "@(#)newsfuncs.c 1.1\t1/23/83"; /* * funcs - functions used by both inews and readnews. */ #include #include #include "structs.h" #include "newsgate.h" #include "bnews.h" extern char *SYSTEM; char bfr[WDLEN]; /* * Trap interrupts. */ onsig(n) int n; { /* * Most UNIX systems reset caught signals to SIG_DFL. * This bad design requires that the trap be set again here. * Unfortunately, if the signal recurs before the trap is set, * the program will die, possibly leaving the lock in place. */ signal(n, onsig); } /* * Append NGDELIM to string. */ ngcat(s) register char *s; { if (*s) { while (*s++); s -= 2; if (*s++ == NGDELIM) return; } *s++ = NGDELIM; *s = '\0'; } /* * News group matching. * * nglist is a list of newsgroups. * sublist is a list of subscriptions. * sublist may have "meta newsgroups" in it. * All fields are NGDELIM separated, * and there is an NGDELIM at the end of each argument. * * Currently implemented glitches: * sublist uses 'all' like shell uses '*', and '.' like shell '/'. * If subscription X matches Y, it also matches Y.anything. */ ngmatch(nglist, sublist) register char *nglist, *sublist; { register char *n, *s; register int rc; rc = FALSE; for (n = nglist; *n != '\0' && rc == FALSE;) { for (s = sublist; *s != '\0';) { if (*s != NEGCHAR) rc |= ptrncmp(s, n); else rc &= ~ptrncmp(s+1, n); while (*s++ != NGDELIM); } while (*n++ != NGDELIM); } return(rc); } /* * Compare two newsgroups for equality. * The first one may be a "meta" newsgroup. */ ptrncmp(ng1, ng2) register char *ng1, *ng2; { while (*ng1 != NGDELIM) { if (ng1[0]=='a' && ng1[1]=='l' && ng1[2]=='l') { ng1 += 3; while (*ng2 != NGDELIM && *ng2 != '.') if (ptrncmp(ng1, ng2++)) return(TRUE); return (ptrncmp(ng1, ng2)); } else if (*ng1++ != *ng2++) return(FALSE); } return (*ng2 == '.' || *ng2 == NGDELIM); } /* * Remove newsgroups in 'a' not subscribed to by 'b'. */ ngsquash(ap, bp) register char *ap, *bp; { register char *tp; char tbuf[WDLEN]; /* replace NGDELIM by '\0' in a */ for (tp = ap; *tp != '\0'; tp++) if (*tp == NGDELIM) *tp = '\0'; /* ap = building, tp = checking. */ tp = ap; while (*tp != '\0') { ngcat(strcpy(tbuf, tp)); if (ngmatch(tbuf, bp)) { while ((*ap++ = *tp++) != '\0') ; ap[-1] = NGDELIM; } else while (*tp++ != '\0'); } *ap = '\0'; } /* * Strip trailing newlines, blanks, and tabs from 's'. * Return TRUE if newline was found, else FALSE. */ nstrip(s) register char *s; { register char *p; register int rc; rc = FALSE; p = s; while (*p) if (*p++ == '\n') rc = TRUE; while (--p >= s && (*p == '\n' || *p == ' ' || *p == '\t')); *++p = '\0'; return(rc); } /* * Delete trailing NGDELIM. */ ngdel(s) register char *s; { if (*s++) { while (*s++); s -= 2; if (*s == NGDELIM) *s = '\0'; } } /* * Return the ptr in sp at which the character c appears; * NULL if not found * * These are the v7 index and rindex routines, stolen for portability. * (Some Unix systems call them strchr and strrchr, notably PWB 2.0 * and its derivitives such as Unix/TS 2.0, Unix 3.0, etc.) Others, * like v6, don't have them at all. */ char * index(sp, c) register char *sp, c; { do { if (*sp == c) return(sp); } while (*sp++); return(NULL); } /* * Return the ptr in sp at which the character c last * appears; NULL if not found */ char * rindex(sp, c) register char *sp, c; { register char *r; r = NULL; do { if (*sp == c) r = sp; } while (*sp++); return(r); } static FILE *sysfile; char *fldget(q, p) register char *q, *p; { while (*p && *p != ':') { if (*p == '\\' && p[1]==':') p++; *q++ = *p++; } *q = '\0'; return(p); } /* * Local open routine. */ FILE * xfopen(name, mode) register char *name, *mode; { register FILE *fp; if ((fp = fopen(name, mode)) == NULL) { sprintf(bfr, "Cannot open %s (%s)", name, mode); xerror(bfr); } return(fp); } time_t cgtdate(datestr) char *datestr; { time_t i; char junk[40],month[40],day[30],time[60],year[50]; if ((i = getdate(datestr, (struct timeb *) NULL)) >= 0) return i; sscanf(datestr, "%s %s %s %s %s", junk, month, day, time, year); sprintf(bfr, "%s %s, %s %s", month, day, year, time); return getdate(bfr, (struct timeb *) NULL); } lcase(s) register char *s; { register char *ptr; for (ptr = s; *ptr; ptr++) if (isupper(*ptr)) *ptr = tolower(*ptr); } ohwrite(hp, fp) register struct hbuf *hp; register FILE *fp; { ngdel(strcpy(bfr, hp->nbuf)); fprintf(fp, "A%s\n%s\n%s!%s\n%s\n%s\n", hp->ident, bfr, SYSTEM, hp->path, hp->subdate, hp->title); } static int hascaught = 0; static catchintr() { hascaught = 1; printf("\n"); fflush(stdout); } xerror(message) char *message; { printf("expire: %s.\n", message); fflush(stdout); exit(1); }