sources-request@mirror.TMC.COM (11/07/86)
Submitted by: seismo!rick (Rick Adams) Mod.sources: Volume 7, Issue 55 Archive-name: 2.11news/Part06 # To extract, sh this file # news 2.11 source part 6 of 9 if test ! -d src then mkdir src fi echo x - src/header.c 1>&2 sed 's/.//' >src/header.c <<'*-*-END-of-src/header.c-*-*' -/* - * This software is Copyright (c) 1986 by Rick Adams. - * - * Permission is hereby granted to copy, reproduce, redistribute or - * otherwise use this software as long as: there is no monetary - * profit gained specifically from the use or reproduction or this - * software, it is not sold, rented, traded or otherwise marketed, and - * this copyright notice is included prominently in any copy - * made. - * - * The author make no claims as to the fitness or correctness of - * this software for any use whatsoever, and it is provided as is. - * Any use of this software is at the user's own risk. - * - * header.c - header functions plus some other goodies - */ - -#ifdef SCCSID -static char *SccsId = "@(#)header.c 2.43 10/23/86"; -#endif /* SCCSID */ - -#include <stdio.h> -#include "params.h" - -char *hfgets(); - -char *news_version = NEWS_VERSION; - -/* - * Read header from file fp into *hp. If wholething is FALSE, - * it's an incremental read, otherwise start from scratch. - * Return (FILE *) if header okay, else NULL. - */ -FILE * -hread(hp, fp, wholething) -register struct hbuf *hp; -FILE *fp; -int wholething; -{ - register int len; - register int i; -#ifdef OLD - char *p; -#endif /* OLD */ - - if (wholething) { - for(i=0;i<NUNREC;i++) - if (hp->unrec[i] != NULL) - free(hp->unrec[i]); - else - break; - bzero((char *)hp, sizeof (*hp)); - for (i=0;i<NUNREC;i++) - hp->unrec[i] = NULL; - } - - /* Check that it's a B news style header. */ - if (hfgets(bfr, PATHLEN, fp) != NULL && isalpha(bfr[0]) - && index(bfr, ':')) - if (frmread(fp, hp)) - goto strip; - - if (!nstrip(bfr+1)) - return NULL; - - /* It's not. Try A news (begins with PROTO). */ - if (bfr[0] != PROTO) - return NULL; -#ifndef OLD - logerr("Can not process A news format article without OLD defined"); -#else /* OLD */ - /* Read in an A news format article. */ - p = index(bfr+1, '.'); - if (p == NULL) { - (void) strcpy(hp->ident, bfr+1); - return NULL; - } - *p++ = '\0'; - (void) sprintf(hp->ident, "<%s@%s%s>", p, bfr+1, ".UUCP"); - - /* Newsgroup List */ - if (hfgets(hp->nbuf, BUFLEN, fp) == NULL || !nstrip(hp->nbuf)) - return NULL; - /* source path */ - if (hfgets(hp->path, PATHLEN, fp) == NULL || !nstrip(hp->path)) - return NULL; - /* date */ - if (hfgets(hp->subdate, DATELEN, fp) == NULL || !nstrip(hp->subdate)) - return NULL; - /* title */ - if (hfgets(hp->title, BUFLEN, fp) == NULL || !nstrip(hp->title)) - return NULL; -#endif /* OLD */ - -strip: /* strip off sys! from front of path. */ - if (strncmp(FULLSYSNAME, hp->path, (len = strlen(FULLSYSNAME))) == 0 - && index(NETCHRS, hp->path[len])) - (void) strcpy(hp->path, &(hp->path[len+1])); - lcase(hp->nbuf); - - /* Intuit the From: line if only a path was given. */ - if (wholething) { -#ifdef OLD - if (hp->from[0] == '\0') - intuitfrom(hp); - else -#endif /* OLD */ - fixfrom(hp); - } - - return fp; -} - - -/* - * Get header info from mail-format file. - * Return non-zero on success. - */ -#define FROM 1 -#define NEWSGROUP 2 -#define TITLE 3 -#define SUBMIT 4 -#define RECEIVE 5 -#define EXPIRE 6 -#define ARTICLEID 7 -#define MESSAGEID 8 -#define REPLYTO 9 -#define FOLLOWID 10 -#define CONTROL 11 -#define SENDER 12 -#define FOLLOWTO 13 -#define PATH 14 -#define POSTVERSION 15 -#define RELAYVERSION 16 -#define DISTRIBUTION 17 -#define ORGANIZATION 18 -#define NUMLINES 19 -#define KEYWORDS 20 -#define APPROVED 21 -#define NFID 22 -#define NFFROM 23 -#define XREF 24 -#define SUMMARY 25 -#define XPATH 26 -#define OTHER 99 - -char *malloc(); - -frmread(fp, hp) -register FILE *fp; -register struct hbuf *hp; -{ - int unreccnt = 0; - register int i; - long curpos; - - i = type(bfr); - do { - curpos = ftell(fp); - switch (i) { - case PATH: - getfield(hp->path, sizeof(hp->path)); - break; - case FROM: - getfield(hp->from, sizeof(hp->from)); - break; - case NEWSGROUP: - getfield(hp->nbuf, sizeof(hp->nbuf)); - break; - case TITLE: - getfield(hp->title, sizeof(hp->title)); - break; - case SUBMIT: - getfield(hp->subdate, sizeof(hp->subdate)); - break; - case EXPIRE: - getfield(hp->expdate, sizeof(hp->expdate)); - break; -#ifdef OLD - case ARTICLEID: - /* Believe Message-ID in preference to Article-ID */ - if (hp->ident[0] == '\0') { - register char *p; - char msgb[NAMELEN]; - getfield(msgb, sizeof msgb); - p = index(msgb, '.'); - if (p == NULL) { - (void) strcpy(hp->ident, msgb); - } else { - *p++ = '\0'; - (void) sprintf(hp->ident, "<%s@%s%s>", p, msgb, ".UUCP"); - } - } - break; -#endif /* OLD */ - case MESSAGEID: - getfield(hp->ident, sizeof(hp->ident)); - break; - case REPLYTO: - getfield(hp->replyto, sizeof(hp->replyto)); - break; - case FOLLOWID: - getfield(hp->followid, sizeof(hp->followid)); - break; - case SENDER: - getfield(hp->sender, sizeof(hp->sender)); - break; - case FOLLOWTO: - getfield(hp->followto, sizeof(hp->followto)); - break; - case CONTROL: - getfield(hp->ctlmsg, sizeof(hp->ctlmsg)); - break; - case DISTRIBUTION: - getfield(hp->distribution, sizeof(hp->distribution)); - break; - case ORGANIZATION: - getfield(hp->organization, sizeof(hp->organization)); - break; - case NUMLINES: - getfield(hp->numlines, sizeof(hp->numlines)); - hp->intnumlines = atoi(hp->numlines); - break; - case KEYWORDS: - getfield(hp->keywords, sizeof(hp->keywords)); - break; - case APPROVED: - getfield(hp->approved, sizeof(hp->approved)); - break; - case NFID: - getfield(hp->nf_id, sizeof(hp->nf_id)); - break; - case NFFROM: - getfield(hp->nf_from, sizeof(hp->nf_from)); - break; - /* discard these lines */ - case XREF: - case XPATH: - case RELAYVERSION: - case POSTVERSION: - case RECEIVE: - break; - case SUMMARY: - getfield(hp->summary, sizeof(hp->summary)); - break; - case OTHER: - if (unreccnt < NUNREC) { - if ((hp->unrec[unreccnt] = malloc((unsigned)(strlen(bfr) + 1))) != NULL ) { - (void) strcpy(hp->unrec[unreccnt], bfr); - (void) nstrip(hp->unrec[unreccnt]); - unreccnt++; - } else - xerror("frmread: out of memory"); - } - break; - } - } while ((i = type(hfgets(bfr, LBUFLEN, fp))) > 0); - - if (*bfr != '\n') - fseek(fp, curpos, 0); - if ((hp->from[0] || hp->path[0]) && hp->subdate[0] && hp->ident[0]) - return TRUE; - return FALSE; -} - -#ifdef OLD -/* - * There was no From: line in the message (because it was generated by - * an old news program). Guess what it should have been and create it. - */ -intuitfrom(hp) -register struct hbuf *hp; -{ - char *tp; - char *user, *host; - char *tailpath(), *rindex(); - char *at, *dot; - char pathbuf[PATHLEN]; - char fullname[BUFLEN]; - - tp = tailpath(hp); - user = rindex(tp, '!'); - if (user == NULL) - user = tp; - else - *user++ = '\0'; - - /* Check for an existing Internet address on the end. */ - at = index(user, '@'); - if (at) { - dot = index(at, '.'); - if (dot) { - (void) strcpy(hp->from, user); - return; - } - /* @ signs are illegal except for the biggie, so */ - *at = '%'; - } - - if (tp[0] == '.') - host = index(tp, '!') + 1; - else if (user == tp) - host = FULLSYSNAME; - else - host = tp; - - tp = index(host, '@'); - if (tp != NULL) - *tp = 0; - (void) sprintf(hp->from, "%s@%s%s", user, host, MYDOMAIN); - - skin(pathbuf, fullname, hp->path); /* remove RFC822-style comments */ - if (fullname[0] != '\0') { - strcat(hp->from, " ("); - (void) strcat(hp->from, fullname); - strcat(hp->from, ")"); - } - strcpy(hp->path, pathbuf); /* and stick it back in */ -} -#endif /* OLD */ - -/* - * Canonicalize the "From:" line into the form - * - * From: <mail-address> (full-name) - * - * RFC822 doesn't require the comment to be at the end of the string - * like that. - */ -fixfrom(hp) -register struct hbuf *hp; -{ - char frombuf[PATHLEN]; - char fullname[BUFLEN]; - - skin(frombuf, fullname, hp->from); /* remove RFC822-style comments */ - if (fullname[0] != '\0') { - strcat(frombuf, " ("); - strcat(frombuf, fullname); - strcat(frombuf, ")"); - } - strcpy(hp->from, frombuf); /* stick the canonicalized "from" back in */ -} - -skin(name, fullname, hfield) -char *name; -char *fullname; -char *hfield; -{ - register int c; - register char *cp, *cp2; - char *bufend; - int gotlt, parenlev, lastsp; - int seenfullname = FALSE; - - *fullname = '\0'; /* no full name yet */ - if (strpbrk(hfield, "(< ") == NULL) { /* include ',' ?? */ - strcpy(name, hfield); - return; - } - gotlt = 0; - parenlev = 0; - lastsp = 0; - bufend = name; - for (cp = hfield, cp2 = bufend; c = *cp++; ) { - switch (c) { - case '(': - /* - * Start of a "comment". - * Ignore it, or save it in "fullname" if we haven't - * seen a comment yet. - */ - parenlev++; - while ((c = *cp) != 0) { - cp++; - switch (c) { - case '\\': - if ((c = *cp) == 0) - goto outcm; - cp++; - break; - case '(': - parenlev++; - break; - case ')': - parenlev--; - if (parenlev == 0) - goto outcm; - break; - } - if (!seenfullname) - *fullname++ = c; - } - outcm: - parenlev = 0; - lastsp = 0; - if (!seenfullname) { - *fullname = '\0'; - seenfullname = TRUE; /* only extract first comment */ - } - break; - - case '"': - /* - * Start of a "quoted-string". - * Copy it in its entirety. - */ - while ((c = *cp) != 0) { - cp++; - switch (c) { - case '\\': - if ((c = *cp) == 0) - goto outqs; - cp++; - break; - case '"': - goto outqs; - } - *cp2++ = c; - } - outqs: - lastsp = 0; - break; - - case ' ': - if (cp[0] == 'a' && cp[1] == 't' && cp[2] == ' ') - cp += 3, *cp2++ = '@'; - else - if (cp[0] == '@' && cp[1] == ' ') - cp += 2, *cp2++ = '@'; - else - lastsp = 1; - break; - - case '<': - if (!seenfullname) { - *cp2 = '\0'; - strcpy(fullname, name); - seenfullname = TRUE; - } - cp2 = bufend; - gotlt++; - lastsp = 0; - break; - - case '>': - if (gotlt) { - gotlt = 0; - /* - * this doesn't seem reasonable, what about (,) - * or "," ?? - */ - while (*cp != ',' && *cp != 0) - cp++; - if (*cp == 0 ) - goto done; - *cp2++ = ','; - *cp2++ = ' '; - bufend = cp2; - break; - } - - /* Fall into . . . */ - - default: - if (lastsp) { - lastsp = 0; - *cp2++ = ' '; - } - *cp2++ = c; - break; - } - } -done: - *cp2 = 0; -} - - -#ifdef OLD -char * -oident(ident) -char *ident; -{ - char lbuf[BUFLEN]; - static char oidbuf[BUFLEN]; - register char *p, *q; - - (void) strcpy(lbuf, ident); - p = index(lbuf, '@'); - if (p == NULL) - return ident; - *p++ = '\0'; - q = index(p, '.'); - if (q == NULL) - q = index(p, '>'); - if (q) - *q++ = '\0'; - p[SNLN] = '\0'; - (void) sprintf(oidbuf, "%s.%s", p, lbuf+1); - return oidbuf; -} -#endif /* OLD */ - -/* - * Get the given field of a header (char * parm) from bfr, but only - * if there's something actually there (after the colon). Don't - * bother if we already have an entry for this field. - */ -getfield(hpfield, size) -char *hpfield; -int size; -{ - register char *ptr; - - if (hpfield[0]) - return; - for (ptr = index(bfr, ':'); isspace(*++ptr); ) - ; - if (*ptr != '\0') { - (void) strncpy(hpfield, ptr, size - 1); - (void) nstrip(hpfield); - } -} - - -#define its(type) (prefix(ptr, type)) -type(ptr) -register char *ptr; -{ - register char *colon, *space; - - if (ptr == NULL) - return FALSE; - if (its("From: ")) - if (index(ptr, '@') || !index(ptr, '!')) - return FROM; - else - return PATH; - if (its("Path: ")) - return PATH; - if (its("Newsgroups: ")) - return NEWSGROUP; - if (its("Subject: ")) - return TITLE; - if (its("Date: ")) - return SUBMIT; - if (its("Date-Received: ")) - return RECEIVE; -#ifdef OLD - if (its("Title: ")) - return TITLE; - if (its("Posted: ")) - return SUBMIT; - if (its("Received: ")) - return RECEIVE; -#endif /* OLD */ - if (its("Expires: ")) - return EXPIRE; - if (its("Article-I.D.: ")) - return ARTICLEID; - if (its("Message-ID: ")) - return MESSAGEID; - if (its("Reply-To: ")) - return REPLYTO; - if (its("References: ")) - return FOLLOWID; - if (its("Control: ")) - return CONTROL; - if (its("Sender: ")) - return SENDER; - if (its("Followup-To: ")) - return FOLLOWTO; - if (its("Posting-Version: ")) - return POSTVERSION; - if (its("Relay-Version: ")) - return RELAYVERSION; - if (its("Distribution: ")) - return DISTRIBUTION; - if (its("Organization: ")) - return ORGANIZATION; - if (its("Lines: ")) - return NUMLINES; - if (its("Summary: ")) - return SUMMARY; - if (its("Keywords: ")) - return KEYWORDS; - if (its("Approved: ")) - return APPROVED; - if (its("Nf-ID: ")) - return NFID; - if (its("Nf-From: ")) - return NFFROM; - if (its("Xref: ")) - return XREF; - if (its("Xpath: ")) - return XPATH; - if (!isalpha(*ptr)) - return FALSE; - colon = index(ptr, ':'); - space = index(ptr, ' '); - if (!colon || space && space < colon) - return FALSE; - return OTHER; -} - -/* - * Write header at 'hp' on stream 'fp' in B+ format. Include received date - * if wr is 1. Leave off sysname if wr is 2. - */ -ihwrite(hp, fp, wr) -register struct hbuf *hp; -register FILE *fp; -int wr; -{ - int iu; - time_t t; - time_t cgtdate(); - - /* - * We're being tricky with Path/From because of upward compatibility - * issues. The new version considers From and Path to be separate. - * The old one thinks they both mean "Path" but only believes the - * first one it sees, so will ignore the second. - */ - if (prefix(hp->path, FULLSYSNAME) && - index(NETCHRS, hp->path[strlen(FULLSYSNAME)])) - fprintf(fp, "Path: %s\n", hp->path); - else - fprintf(fp, "Path: %s!%s\n", FULLSYSNAME, hp->path); - if (hp->from[0]) - fprintf(fp, "From: %s\n", hp->from); - - fprintf(fp, "Newsgroups: %s\n", hp->nbuf); - fprintf(fp, "Subject: %s\n", hp->title); - if (*hp->summary) - fprintf(fp, "Summary: %s\n", hp->summary); - if (*hp->keywords) - fprintf(fp, "Keywords: %s\n", hp->keywords); - fprintf(fp, "Message-ID: %s\n", hp->ident); - t = cgtdate(hp->subdate); - fprintf(fp, "Date: %s\n", arpadate(&t)); -#ifdef OLD - fprintf(fp, "Article-I.D.: %s\n", oident(hp->ident)); - fprintf(fp, "Posted: %s", ctime(&t)); -#endif /* OLD */ - if (*hp->expdate) - fprintf(fp, "Expires: %s\n", hp->expdate); - if (*hp->followid) { - register char *dp, *cp; - - dp = cp = hp->followid; - while (*cp != '\0') - if (*cp == '<' && *(cp + 1) == '>') - cp += 2; - else - *dp++ = *cp++; - *dp = '\0'; - if (*hp->followid) - fprintf(fp, "References: %s\n", hp->followid); - } - if (*hp->ctlmsg) - fprintf(fp, "Control: %s\n", hp->ctlmsg); - if (*hp->sender) - fprintf(fp, "Sender: %s\n", hp->sender); - if (*hp->replyto) - fprintf(fp, "Reply-To: %s\n", hp->replyto); - if (*hp->followto) - fprintf(fp, "Followup-To: %s\n", hp->followto); - if (*hp->distribution) - fprintf(fp, "Distribution: %s\n", hp->distribution); - if (*hp->organization) - fprintf(fp, "Organization: %s\n", hp->organization); - if (*hp->numlines) - fprintf(fp, "Lines: %s\n", hp->numlines); - if (*hp->approved) - fprintf(fp, "Approved: %s\n", hp->approved); - if (*hp->nf_id) - fprintf(fp, "Nf-ID: %s\n", hp->nf_id); - if (*hp->nf_from) - fprintf(fp, "Nf-From: %s\n", hp->nf_from); -#ifdef DOXREFS - if ( wr ==1 && *hp->xref) - fprintf(fp, "Xref: %s\n", hp->xref); -#endif /* DOXREFS */ - for (iu = 0; iu < NUNREC; iu++) { - if (hp->unrec[iu]) - fprintf(fp, "%s\n", &hp->unrec[iu][0]); - } - putc('\n', fp); -} - - -#ifndef BSD4_2 -/* - * Set nc bytes, starting at cp, to zero. - */ -bzero(cp, nc) -register char *cp; -register int nc; -{ - if (nc > 0) - do { - *cp++ = 0; - } while (--nc); -} -#endif /* !BSD4_2 */ - -/* - * hfgets is like fgets, but deals with continuation lines. - * It also ensures that even if a line that is too long is - * received, the remainder of the line is thrown away - * instead of treated like a second line. - */ -char * -hfgets(buf, len, fp) -char *buf; -int len; -FILE *fp; -{ - register int c; - register int n = 0; - register char *cp; - - cp = buf; - while (n < len && (c = getc(fp)) != EOF) { - if (c == '\n') - break; - if (isprint(c) || c == '\b' || c == ' ' || c == '\t') { - *cp++ = c; - n++; - } - } - if (c == EOF && cp == buf) - return NULL; - *cp = '\0'; - - if (c != '\n') { - /* Line too long - part read didn't fit into a newline */ - while ((c = getc(fp)) != '\n' && c != EOF) - ; - } else if (cp == buf) { - /* Don't look for continuation of blank lines */ - *cp++ = '\n'; - *cp = '\0'; - return buf; - } - - while ((c = getc(fp)) == ' ' || c == '\t') { /* for each cont line */ - /* Continuation line. */ - if ((n += 2) < len) { - *cp++ = '\n'; - *cp++ = c; - } - while ((c = getc(fp)) != '\n' && c != EOF) - if ((isprint(c) || c == '\b' || c == ' ' || c == '\t') - && n++ < len) - *cp++ = c; - } - if (n >= len - 1) - cp = buf + len - 2; - *cp++ = '\n'; - *cp = '\0'; - if (c != EOF) - (void) ungetc(c, fp); /* push back first char of next header */ - return buf; -} *-*-END-of-src/header.c-*-* echo x - src/rfuncs.c 1>&2 sed 's/.//' >src/rfuncs.c <<'*-*-END-of-src/rfuncs.c-*-*' -/* - * This software is Copyright (c) 1986 by Rick Adams. - * - * Permission is hereby granted to copy, reproduce, redistribute or - * otherwise use this software as long as: there is no monetary - * profit gained specifically from the use or reproduction or this - * software, it is not sold, rented, traded or otherwise marketed, and - * this copyright notice is included prominently in any copy - * made. - * - * The author make no claims as to the fitness or correctness of - * this software for any use whatsoever, and it is provided as is. - * Any use of this software is at the user's own risk. - * - * rfuncs - functions for readnews. - */ - -#ifdef SCCSID -static char *SccsId = "@(#)rfuncs.c 2.31 10/23/86"; -#endif /* SCCSID */ - -/*LINTLIBRARY*/ - -#include "rparams.h" - -char lentab[LINES]; /* length of newsgroupname for each rcline */ -long nngsize; /* The next upcoming value of ngsize. */ -long nminartno; /* Smallest article number in this group */ -int BITMAPSIZE = 0; - -nextng() -{ - long curpos; -#ifdef DEBUG - fprintf(stderr, "nextng()\n"); -#endif - curpos = ftell(actfp); - -next: -#ifdef DEBUG - fprintf(stderr, "next:\n"); -#endif - if (actdirect == BACKWARD) { - if (back()) { - (void) fseek(actfp, curpos, 0); - return 1; - } - if (back()) { - (void) fseek(actfp, curpos, 0); - return 1; - } - } - if (fgets(afline, BUFLEN, actfp) == NULL) - return 1; - if (sscanf(afline, "%s %ld %ld", bfr, &nngsize, &nminartno) < 3) { - bfr[0] = '\0'; - nngsize = 0; - nminartno = 0; - } -#ifdef DEBUG - fprintf(stderr, "bfr = '%s'\n", bfr); -#endif - - if (!ngmatch(bfr, header.nbuf)) - goto next; - if (xflag) - readmode = SPEC; - else - readmode = NEXT; - if (selectng(bfr, TRUE, FALSE)) - goto next; - return 0; -} - - -selectng(name, fastcheck, resubscribe) -char *name; -{ - register char *ptr, punct = ','; - register int i; - register char *p; - register long cur; - long next = 0; - FILE *af; - long s, sm; - char buf[100], n[100]; - -#ifdef DEBUG - fprintf(stderr,"selectng: groupdir = %s\n", groupdir); -#endif /* DEBUG */ - if (*groupdir) - updaterc(); - last = 1; - if (strcmp(name, bfr)) { - af = xfopen(ACTIVE, "r"); - while (fgets(buf, sizeof buf, af) != NULL) { - if (sscanf(buf, "%s %ld %ld", n, &s, &sm) == 3 && - strcmp(n, name) == 0) { - ngsize = s; - minartno = sm; - break; - } - } - (void) fclose(af); - } else { - ngsize = nngsize; - minartno = nminartno; - } -#ifdef DEBUG - fprintf(stderr, "selectng(%s) sets ngsize to %ld, minartno to %ld\n", - name, ngsize, minartno); -#endif - (void) strcpy(groupdir, name); - if (!xflag) { - i = findrcline(name); - if (i >= 0) { - if (p = index(rcline[i], '!')) { - switch (resubscribe) { - case FALSE: - groupdir[0] = 0; - return 1; - case TRUE: - *p = ':'; - break; - case PERHAPS: - zapng = TRUE; - break; - } - } else - p = index(rcline[i], ':'); - if (!p) /* shouldn't happen */ - p = rcline[i]; - while (*++p == ' ') - ; - (void) sprintf(rcbuf, "%s%s%ld", rcline[i], - *p == '\0' ? " " : ",", ngsize+1); - } - else - (void) sprintf(rcbuf, "ng: %ld", ngsize+1); - } else - (void) sprintf(rcbuf, "ng: %ld", ngsize+1); -#ifdef DEBUG - fprintf(stderr, "rcbuf set to %s\n", rcbuf); -#endif /* DEBUG */ - - /* - * Fast check for common case: 1-### - */ - if (fastcheck) { - p = rcbuf; - while (*p != ' ') - p++; - while (*p == ' ') - p++; - if (*p++ == '1' && *p++ == '-') { - cur = 0; - while (isdigit(*p)) - cur = 10 * cur + *p++ - '0'; - if (*p == ',' && cur == ngsize) { -#ifdef DEBUG - fprintf(stderr, "Group: %s, all read\n", groupdir); -#endif - groupdir[0] = 0; - return 1; - } - if (cur > ngsize) { - /* - * Claim to have read articles - * which "active" believes have - * never existed - we believe "active" - */ - fprintf(stderr, - "%s %s...\r\n\t%s %ld to %ld\r\n", - "Warning: newsgroup", groupdir, - "last article claimed read reset from", - cur, ngsize); - } - } - } - -/* - * The key to understanding this piece of code is that a bit is set iff - * that article has NOT been read. Thus, we fill in the holes when - * commas are found (e.g. 1-20,30-35 will result in filling in the 21-29 - * holes), and so we assume the newsrc file is properly ordered, the way - * we write it out. - */ - if ((ngsize-minartno) > BITMAPSIZE) { - /* This should never happen */ - (void) xerror("Bitmap not large enough for newsgroup %s", groupdir); - } - - cur = 0; - bzero(bitmap, (int) (ngsize-minartno)/8+1); /* 8 bits per character */ - - /* Decode the .newsrc line indicating what we have read. */ - for (ptr = rcbuf; *ptr && *ptr != ':'; ptr++) - ; - while (*ptr) { - while (!isdigit(*ptr) && *ptr) - ptr++; - if (!*ptr) - break; - (void) sscanf(ptr, "%ld", &next); - if (punct == ',') { - while (++cur < next) { - set(cur); - } - } - cur = next; - while (!ispunct(*ptr) && *ptr) - ptr++; - punct = *ptr; - } - if (rflag) - bit = ngsize+1; - else - bit = minartno -1; - nextbit(); - ngrp = 1; - return 0; -} - -#ifdef TMAIL -catchterm() -{ - (void) unlink(infile); - (void) unlink(outfile); - xxit(0); -} - - -/* - * The -M (Mail) interface. This code is a reasonably simple model for - * writing other interfaces. We write out all relevant articles to - * a temp file, then invoke Mail with an option to have it tell us which - * articles it read. Finally we count those articles as really read. - */ -Mail() -{ - register FILE *fp = NULL, *ofp; - struct hbuf h; - register char *ptr, *fname; - int news = 0; - register int i; - - for(i=0;i<NUNREC;i++) - h.unrec[i] = NULL; - - ofp = xfopen(mktemp(outfile), "w"); - if (aflag && *datebuf) - if ((atime = cgtdate(datebuf)) == -1) - xerror("Cannot parse date string"); - while (!nextng()) - while (bit <= ngsize) { - (void) sprintf(filename, "%s/%ld", dirname(groupdir), bit); - if (access(filename, 4) - || ((fp = art_open (filename, "r")) == NULL) - || (hread(&h, fp, TRUE) == NULL) - || !aselect(&h, FALSE)) { -#ifdef DEBUG - fprintf(stderr, "Bad article '%s'\n", filename); -#endif - if (fp != NULL) { - (void) fclose(fp); - fp = NULL; - } - clear(bit); - nextbit(); - continue; - } - fname = ptr = index(h.from, '('); - if (fname) { - while (ptr && ptr[-1] == ' ') - ptr--; - if (ptr) - *ptr = 0; - fname++; - ptr = fname + strlen(fname) - 1; - if (*ptr == ')') - *ptr = 0; - } - h.subtime = cgtdate(h.subdate); - fprintf(ofp, "From %s %s", -#ifdef INTERNET - h.from[0] ? h.from : -#endif - h.path, ctime(&h.subtime)); - if (fname) - fprintf(ofp, "Full-Name: %s\n", fname); - fprintf(ofp, "Newsgroups: %s\n", h.nbuf); - fprintf(ofp, "Subject: %s\n", h.title); - fprintf(ofp, "Article-ID: %s/%ld\n\n", groupdir, bit); - tprint(fp, ofp, TRUE); - putc('\n', ofp); - news = TRUE; - (void) fclose(fp); - fp = NULL; - nextbit(); - } - updaterc(); - (void) fclose(ofp); - if (!news) { - fprintf(stderr, "No news.\n"); - (void) unlink(outfile); - return; - } - (void) signal(SIGHUP, catchterm); - (void) signal(SIGTERM, catchterm); - (void) sprintf(bfr, "%s -f %s -T %s", TMAIL, outfile, mktemp(infile)); - fwait(fsubr(ushell, bfr, (char *)NULL)); - ofp = xfopen(infile, "r"); - (void) fseek(actfp, 0L, 0); - while (fgets(afline, BUFLEN, actfp) != NULL) { - last = 0; - if (sscanf(afline, "%s %ld", bfr, &nngsize) < 2) { - bfr[0] = '\0'; - nngsize = 0; - } - if (!ngmatch(bfr, header.nbuf)) - continue; - *groupdir = 0; - if (selectng(bfr, TRUE, FALSE)) - continue; - (void) fseek(ofp, 0L, 0); - while (fgets(groupdir, BUFLEN, ofp) != NULL) { - (void) nstrip(groupdir); - ptr = index(groupdir, '/'); - *ptr = 0; - if (strcmp(bfr, groupdir)) - continue; - (void) sscanf(++ptr, "%ld", &last); - clear(last); - } - if (last) { - (void) strcpy(groupdir, bfr); - updaterc(); - } - } - (void) unlink(infile); - (void) unlink(outfile); -} -#endif - -updaterc() -{ - register long cur = 1, next = 1; - register int i; - register char *ptr; - char oldptr; - - sprintf(rcbuf, "%s%c ", groupdir, zapng ? '!' : ':'); - - zapng = FALSE; -again: - ptr = &rcbuf[strlen(rcbuf)]; - while (get(next) && next <= ngsize) - next++; - cur = next; - while (!(get(next)) && next <= ngsize) - next++; - if (cur == next) { - next = ngsize + 1; - goto skip; - } - if (ptr[-1] != ' ') - *ptr++ = ','; - if (cur + 1 == next) - (void) sprintf(ptr, "%ld", cur); - else - (void) sprintf(ptr, "%ld-%ld", cur, next - 1); -skip: - if ((long) next > ngsize) { - if (strpbrk(rcbuf, ":!") == NULL) /* bad line, huh?? */ - return; - ptr = index(rcbuf, ' '); - if (ptr == NULL) /* impossible */ - return; - ptr--; - oldptr = *ptr; - ptr[0] = ':'; - ptr[1] = '\0'; - i = findrcline(groupdir); - if (i >= 0) { - ptr[0] = oldptr; - ptr[1] = ' '; - rcline[i] = realloc(rcline[i], (unsigned)(strlen(rcbuf) + 1)); - if (rcline[i] == NULL) - xerror("Cannot realloc"); - (void) strcpy(rcline[i], rcbuf); -#ifdef DEBUG - fprintf(stderr," new rcline = %s\n", rcline[i]); -#endif /* DEBUG */ - return; - } - if (++line > LINES) - xerror("Too many newsgroups"); - ptr[0] = oldptr; - ptr[1] = ' '; - if ((rcline[line] = malloc((unsigned)(strlen(rcbuf) + 1))) == NULL) - xerror("Not enough memory"); - (void) strcpy(rcline[line], rcbuf); -#ifdef DEBUG - fprintf(stderr," new rcline2 = %s\n", rcline[line]); -#endif /* DEBUG */ - return; - } - cur = next; - goto again; -} - -newrc(rcname) -char *rcname; -{ - register FILE *fp; - - if (close(creat(rcname, 0666))) { - (void) sprintf(bfr, "Cannot create %s", newsrc); - xerror(bfr); - } - - sprintf(bfr, "%s/users", LIB); - if ((fp = fopen(bfr, "a")) != NULL) { - fprintf(fp, "%s\n", username); - (void) fclose(fp); - (void) chmod(bfr, 0666); - } -} - -nextbit() -{ -#ifdef DEBUG - fprintf(stderr,"nextbit() bit = %ld\n", bit); -#endif /* DEBUG */ - last = bit; - if (readmode == SPEC || xflag) { - if (rflag) - bit--; - else - bit++; - return; - } - if (rflag) - while (--bit, !get(bit) && bit > minartno) - ; - else - while (++bit, !get(bit) && bit <= ngsize) - ; -#ifdef DEBUG - fprintf(stderr,"nextng leaves bit as %ld\n", bit); -#endif /* DEBUG */ -} - -/* - * Return TRUE if the user has not ruled out this article. - */ -aselect(hp, insist) -register struct hbuf *hp; -int insist; -{ - if (insist) - return TRUE; - if (tflag && !titmat(hp, header.title)) - return FALSE; - if (aflag && cgtdate(hp->subdate) < atime) - return FALSE; - if (index(hp->nbuf, ',') && !rightgroup(hp)) - return FALSE; - if (fflag && (hp->followid[0] || prefix(hp->title, "Re:"))) - return FALSE; - return TRUE; -} - -/* - * Code to avoid showing multiple articles for news. - * Works even if you exit news. - * Returns nonzero if we should show this article. - */ -rightgroup(hp) -struct hbuf *hp; -{ - char ng[BUFLEN]; - register char *p, *g; - int i, flag; - - strcpy(ng, hp->nbuf); - g = ng; - flag = 1; - while (g != NULL) { - p = index(g, ','); - if (p != NULL) { - *p++ = '\0'; - while (*p == ' ') - p++; - } - if (strcmp(g, groupdir) == 0) - return flag; - if (ngmatch(g, header.nbuf) - && ((i = findrcline(g)) >= 0 - && index(rcline[i], '!') == NULL)) - flag = 0; - g = p; - } - /* we must be in "junk" or "control" */ - return TRUE; -} - -back() -{ - while (fseek(actfp, -2L, 1) != -1 && ftell(actfp) > 0L) { - if (getc(actfp) == '\n') - return 0; - } - if (ftell(actfp) == 0L) - return 0; - return 1; -} - -/* - * Trap interrupts. - */ -onsig(n) -int n; -{ - (void) signal(n, onsig); - SigTrap = n; - if (rcreadok < 2) { - fprintf(stderr, "Aborted early\n"); - xxit(0); - } -} - -/* - * finds the line in your .newsrc file (actually the in-core "rcline" - * copy of it) and returns the index into the array where it was found. - * -1 means it didn't find it. - * - * We play clever games here to make this faster. It's inherently - * quadratic - we spend lots of CPU time here because we search through - * the whole .newsrc for each line. The "prev" variable remembers where - * the last match was found; we start the search there and loop around - * to the beginning, in the hopes that the calls will be roughly in order. - */ -int -findrcline(name) -register char *name; -{ - register char * p; - register int i; - register int top; - register int len; - static int prev; - static int didthru; - - for ( ; didthru <= line; ++didthru) - if ((p = index(rcline[didthru], '!')) != 0 || - (p = index(rcline[didthru], ':')) != 0) { - lentab[didthru] = (int)(p - rcline[didthru]); - } - len = strlen(name); - top = line; - i = prev; -loop: - for ( ; i <= top; ++i) - if (lentab[i] == len && rcline[i] != NULL && - strncmp(name, rcline[i], len) == 0) - return prev = i; - if (i > line && line > prev - 1) { - i = 0; - top = prev - 1; - goto loop; - } - return -1; -} - -/* - * sortactive - make a local copy of the active file, sorted according - * to the user's preferences, according to his .newsrc file. - */ - -struct table_elt { - int rcindex; - long maxart, minart; - char yn; -}; - -#ifdef SORTACTIVE -static int -rcsort(a, b) -char *a, *b; -{ - return(((struct table_elt *)a)->rcindex - - ((struct table_elt *)b)->rcindex); -} - -static char *newactivename = "/tmp/newsaXXXXXX"; -#endif /* SORTACTIVE */ - -sortactive() -{ - register struct table_elt *tp; - register char *p; - register FILE *nfp, *afp; - char aline[BUFLEN], ngname[BUFLEN]; - struct table_elt table[LINES]; - int nlines = 0, i, delta, lastline; - -#ifdef SORTACTIVE - /* make a new sorted copy of ACTIVE */ - nfp = fopen(mktemp(newactivename), "w"); - (void) chmod(newactivename, 0600); - if (nfp == NULL) { - perror(newactivename); - return; - } - - /* look up all the lines in ACTIVE, finding their positions in .newsrc */ - p = ACTIVE; - ACTIVE = newactivename; - afp = xfopen(p, "r"); - tp = table; -#else /* !SORTACTIVE */ - afp = xfopen(ACTIVE, "r"); -#endif /* !SORTACTIVE */ - while (fgets(aline, sizeof aline, afp) != NULL) { - if (sscanf(aline,"%s %ld %ld %c", ngname, &tp->maxart, - &tp->minart, &tp->yn) != 4) - xerror("Active file corrupt"); - delta = tp->maxart - tp->minart; - if (delta >= BITMAPSIZE) - BITMAPSIZE = delta + 1; - if (Kflag && tp->maxart > 0 && ngmatch(ngname, header.nbuf)) { - int j; - - j = findrcline(ngname); - if (j >= 0 && index(rcline[j], '!') == NULL) { - char rbuf[BUFLEN]; - if (tp->maxart == 1) - sprintf(rbuf, "%s: 1", ngname); - else - sprintf(rbuf, "%s: 1-%ld", ngname, tp->maxart); - rcline[j] = realloc(rcline[j], - (unsigned)(strlen(rbuf)+1)); - if (rcline[j] == NULL) - xerror("Not enough memory"); - strcpy(rcline[j], rbuf); - } - } -#ifdef SORTACTIVE - tp->rcindex = findrcline(ngname); - if (tp->rcindex < 0) { - if (++line > LINES) - xerror("Too many newsgroups"); - strcat(ngname, ":"); - rcline[line] = malloc((unsigned)(strlen(ngname) + 1)); - if (rcline[line] == NULL) - xerror("Not enough memory"); - strcpy(rcline[line], ngname); - tp->rcindex = line; - } - tp++; -#endif /* SORTACTIVE */ - } - (void) fclose(afp); - BITMAPSIZE = 8 * ((BITMAPSIZE+7) / 8); - bitmap = malloc((unsigned)BITMAPSIZE/8); - if (bitmap == NULL) - xerror("Can't malloc bitmap"); - -#ifdef SORTACTIVE - /* sort by position in user's .newsrc file (new groups come up last) */ - nlines = tp - table; - qsort((char *)table, nlines, sizeof table[0], rcsort); - - tp = table; - lastline = tp->rcindex - 1; - /* copy active to newactive, in the new order */ - for (i = 0; i < nlines; i++) { - while (++lastline < tp->rcindex) { - if (strncmp(rcline[lastline], "options ", 8) == 0) { - fprintf(nfp, "%s\n", rcline[lastline]); - } else { - fprintf(stderr, "Duplicate .newsrc line or bad group %s\n", - rcline[lastline]); - lentab[lastline] = 0; - free(rcline[lastline]); - rcline[lastline] = NULL; - } - } - if (rcline[tp->rcindex] == NULL) - continue; - p = rcline[tp->rcindex]; - while (*p != ':' && *p != '!') - fputc(*p++, nfp); - (void) fprintf(nfp, " %ld %ld %c\n", tp->maxart, tp->minart, - tp->yn); - tp++; - } - (void) fclose(nfp); -#endif /* SORTACTIVE */ -} *-*-END-of-src/rfuncs.c-*-* echo x - src/makeactive.sh 1>&2 sed 's/.//' >src/makeactive.sh <<'*-*-END-of-src/makeactive.sh-*-*' -: "Create active file and newsgroup hierarchy for new machine" -: "Usage: sh makeactive.sh LIBDIR SPOOLDIR NEWSUSR NEWSGRP" -: '@(#)makeactive 1.22 10/29/86' -LIBDIR=$1 -SPOOLDIR=$2 -NEWSUSR=$3 -NEWSGRP=$4 -cat <<"E_O_F" > /tmp/$$groups -general Articles that should be read by everyone on your local system -net.ai Artificial intelligence discussions. -net.announce.arpa-internet Announcements from the Arpa world -net.arch Computer architecture. -net.audio High fidelity audio. -net.auto Automobiles, automotive products and laws. -net.auto.tech Technical aspects of automobiles, et. al. -net.aviation Aviation rules, means, and methods. -net.bicycle Bicycles, related products and laws. -net.books Books of all genres, shapes, and sizes. -net.bugs General bug reports and fixes. -net.bugs.2bsd Reports of UNIX* version 2BSD related bugs. -net.bugs.4bsd Reports of UNIX version 4BSD related bugs. -net.bugs.usg Reports of USG (System III, V, etc.) bugs. -net.bugs.uucp Reports of UUCP related bugs. -net.bugs.v7 Reports of UNIX V7 related bugs. -net.cog-eng Cognitive engineering. -net.comics The funnies, old and new. -net.cooks Food, cooking, cookbooks, and recipes. -net.cse Computer science education. -net.cycle Motorcycles and related products and laws. -net.database Database and data management issues and theory. -net.dcom Data communications hardware and software. -net.decus DEC* Users' Society newsgroup. -net.emacs EMACS editors of different flavors. -net.eunice The SRI Eunice system. -net.games Games and computer games. -net.games.board Discussion and hints on board games. -net.games.chess Chess & computer chess. -net.games.emp Discussion and hints about Empire. -net.games.frp Discussion about Fantasy Role Playing games. -net.games.go Discussion about Go. -net.games.hack Discussion, hints, etc. about the Hack game. -net.games.pbm Discussion about Play by Mail games. -net.games.rogue Discussion and hints about Rogue. -net.games.trivia Discussion about trivia. -net.games.video Discussion about video games. -net.garden Gardening, methods and results. -net.graphics Computer graphics, art, animation, image processing, -net.ham-radio Amateur Radio practices, contests, events, rules, etc. -net.ham-radio.packet Discussion about packet radio setups. -net.info-terms All sorts of terminals. -net.internat Discussion about international standards -net.jokes Jokes and the like. May be somewhat offensive. -net.jokes.d Discussions on the content of net.jokes articles -net.lan Local area network hardware and software. -net.lang Different computer languages. -net.lang.ada Discussion about Ada*. -net.lang.apl Discussion about APL. -net.lang.c Discussion about C. -net.lang.c++ The object-oriented C++ language. -net.lang.f77 Discussion about FORTRAN. -net.lang.forth Discussion about Forth. -net.lang.lisp Discussion about LISP. -net.lang.mod2 Discussion about Modula-2. -net.lang.pascal Discussion about Pascal. -net.lang.prolog Discussion about PROLOG. -net.lang.st80 Discussion about Smalltalk 80. -net.lsi Large scale integrated circuits. -net.mag Magazine summaries, tables of contents, etc. -net.mail Proposed new mail/network standards. -net.mail.headers Gatewayed from the ARPA header-people list. -net.micro Micro computers of all kinds. -net.micro.6809 Discussion about 6809's. -net.micro.68k Discussion about 68k's. -net.micro.apple Discussion about Apple micros. -net.micro.amiga Talk about the new Amiga micro. -net.micro.atari8 Discussion about 8 bit Atari micros. -net.micro.atari16 Discussion about 16 bit Atari micros. -net.micro.att Discussions about AT&T microcomputers -net.micro.cbm Discussion about Commodore micros. -net.micro.cpm Discussion about the CP/M operating system. -net.micro.hp Discussion about Hewlett/Packard's. -net.micro.mac Material about the Apple Macintosh & Lisa -net.micro.ns32k National Semiconductor 32000 series chips -net.micro.pc Discussion about IBM personal computers. -net.micro.ti Discussion about Texas Instruments. -net.micro.trs-80 Discussion about TRS-80's. -net.movies Reviews and discussions of movies. -net.music Music lovers' group. -net.music.classical Discussion about classical music. -net.music.folk Folks discussing folk music of various sorts -net.music.gdead A group for (Grateful) Dead-heads -net.music.makers For performers and their discussions. -net.music.synth Synthesizers and computer music -net.news Discussions of USENET itself. -net.news.adm Comments directed to news administrators. -net.news.b Discussion about B news software. -net.news.config Postings of system down times and interruptions. -net.news.group Discussions and lists of newsgroups -net.news.newsite Postings of new site announcements. -net.news.notes Notesfile software from the Univ. of Illinois. -net.news.sa Comments directed to system administrators. -net.news.stargate Discussion about satellite transmission of news. -net.periphs Peripheral devices. -net.pets Pets, pet care, and household animals in general. -net.poems For the posting of poems. -net.puzzle Puzzles, problems, and quizzes. -net.railroad Real and model train fans' newsgroup. -net.rec Recreational/participant sports. -net.rec.birds Hobbyists interested in bird watching. -net.rec.boat Hobbyists interested in boating. -net.rec.bridge Hobbyists interested in bridge. -net.rec.nude Hobbyists interested in naturist/nudist activities. -net.rec.photo Hobbyists interested in photography. -net.rec.scuba Hobbyists interested in SCUBA diving. -net.rec.ski Hobbyists interested in skiing. -net.rec.skydive Hobbyists interested in skydiving. -net.rec.wood Hobbyists interested in woodworking. -net.sf-lovers Science fiction lovers' newsgroup. -net.sources For the posting of software packages & documentation. -net.sources.bugs For bug fixes and features discussion -net.sources.d For any discussion on net.sources postings. -net.sources.games Postings of recreational software -net.sources.mac Software for the Apple Macintosh -net.sport Spectator sports. -net.sport.baseball Discussion about baseball. -net.sport.football Discussion about football. -net.sport.hockey Discussion about hockey. -net.sport.hoops Discussion about basketball. -net.startrek Star Trek, the TV show and the movies. -net.text Text processing. -net.travel Traveling all over the world. -net.tv The boob tube, its history, and past and current shows. -net.tv.drwho Discussion about Dr. Who. -net.tv.soaps Postings about soap operas. -net.unix UNIX neophytes group. -net.unix-wizards Discussions, bug reports, and fixes on and for UNIX. -net.usenix USENIX Association events and announcements. -net.veg Vegetarians. -net.video Video and video components. -net.wines Wines and spirits. -net.wobegon "A Prairie Home Companion" radio show discussion. -mod.announce General announcements of interest to all. (Moderated) -mod.announce.newusers Explanatory postings for new users. (Moderated) -mod.ai Discussions about Artificial Intelligence (Moderated) -mod.amiga Commodore Amiga micros -- info, uses, but no programs. (Moderated) -mod.amiga.binaries Encoded public domain programs in binary form. (Moderated) -mod.amiga.sources Public domain software in source code format. (Moderated) -mod.compilers Discussion about compiler construction, theory, etc. (Moderated) -mod.computers Discussion about various computers and related. (Moderated) -mod.computers.68k 68000-based systems. (Moderated) -mod.computers.apollo Apollo computer systems. (Moderated) -mod.computers.masscomp The Masscomp line of computers. (Moderated) -mod.computers.ibm-pc The IBM PC, PC-XT, and PC-AT. (Moderated) -mod.computers.laser-printers Laser printers, hardware and software. (Moderated) -mod.computers.pyramid Pyramid 90x computers. (Moderated) -mod.computers.ridge Ridge 32 computers and ROS. (Moderated) -mod.computers.sequent Sequent systems, (esp. Balance 8000). (Moderated) -mod.computers.sun Sun "workstation" computers (Moderated) -mod.computers.vax DEC's VAX* line of computers & VMS. (Moderated) -mod.computers.workstations Various workstation-type computers. (Moderated) -mod.conferences Calls for papers and conference announcements. (Moderated) -mod.comp-soc Discussion on the impact of technology on society. (Moderated) -mod.graphics Graphics software, hardware, theory, etc. (Moderated) -mod.human-nets Computer aided communications digest. (Moderated) -mod.legal Discussions of computers and the law. (Moderated) -mod.mac Apple Macintosh micros -- info, uses, but no programs. (Moderated) -mod.mac.binaries Encoded public domain programs in binary form. (Moderated) -mod.mac.sources Public domain software in source code format. (Moderated) -mod.mag Discussions on electronicly published "magazines" (Moderated) -mod.mag.otherrealms Edited science fiction and fantasy "magazine". (Moderated) -mod.map Various maps, including UUCP maps (Moderated) -mod.movies Reviews and discussion of movies (Moderated) -mod.music Reviews and discussion of things musical (Moderated) -mod.music.gaffa Progressive music discussions (e.g., Kate Bush). (Moderated) -mod.newprod Announcements of new products of interest to readers (Moderated) -mod.newslists Postings of news-related statistics and lists (Moderated) -mod.os Disussions about operating systems and related areas. (Moderated) -mod.os.os9 Discussions about the os9 operating system. (Moderated) -mod.os.unix Discussion of UNIX* features and bugs. (Moderated) -mod.philosophy Discussion of philosphical issues and concepts. (Moderated) -mod.philosophy.tech Technical philosophy: math, science, logic, etc (Moderated) -mod.politics Discussions on political problems, systems, solutions. (Moderated) -mod.politics.arms-d Arms discussion digest. (Moderated) -mod.protocols Various forms and types of FTP protocol discussions. (Moderated) -mod.protocols.appletalk Applebus hardware & software discussion. (Moderated) -mod.protocols.kermit Information about the Kermit package. (Moderated) -mod.protocols.tcp-ip TCP and IP network protocols. (Moderated) -mod.psi Discussion of paranormal abilities and experiences. (Moderated) -mod.rec Discussions on pastimes (not currently active) (Moderated) -mod.rec.guns Discussions about firearms (Moderated) -mod.recipes A "distributed cookbook" of screened recipes. (Moderated) -mod.religion Top-level group with no moderator (as of yet). (Moderated) -mod.religion.christian Discussions on Christianity and related topics. (Moderated) -mod.risks Risks to the public from computers & users. (Moderated) -mod.sources postings of public-domain sources. (Moderated) -mod.sources.doc Archived public-domain documentation. (Moderated) -mod.sources.games Postings of public-domain game sources (Moderated) -mod.std Discussion about various standards (Moderated) -mod.std.c Discussion about C language standards (Moderated) -mod.std.mumps Discussion for the X11.1 committee on Mumps (Moderated) -mod.std.unix Discussion for the P1003 committee on UNIX (Moderated) -mod.techreports Announcements and lists of technical reports. (Moderated) -mod.telecom Telecommunications digest. (Moderated) -mod.test Testing of moderated newsgroups -- no moderator (Moderated) -mod.vlsi Very large scale integrated circuits. (Moderated) -misc.consumers Consumer interests, product reviews, etc. -misc.consumers.house Discussion about owning and maintaining a house. -misc.forsale Items for sale. -misc.headlines Current interest: drug testing, terrorism, etc. -misc.invest Investments and the handling of money. -misc.jobs Job announcements, requests, etc. -misc.kids Children, their behavior and activities. -misc.legal Legalities and the ethics of law. -misc.misc Various discussions not fitting in any other group. -misc.taxes Tax laws and advice. -misc.test For testing of network software. Very boring. -misc.wanted Requests for things that are needed (NOT software). -sci.astro Astronomy discussions and information. -sci.bio Biology and related sciences. -sci.crypt Different methods of data en/decryption. -sci.electronics Circuits, theory, electrons and discussions. -sci.lang Natural languages, communication, etc. -sci.math Mathematical discussions and pursuits -sci.math.stat Statistics discussion. -sci.math.symbolic Symbolic algebra discussion. -sci.med Medicine and its related products and regulations. -sci.misc Short-lived discussions on subjects in the sciences. -sci.physics Physical laws, properties, etc. -sci.research Research methods, funding, ethics, and whatever. -sci.space Space, space programs, space related research, etc. -sci.space.shuttle The space shuttle and the STS program. -soc.college College, college activities, campus life, etc. -soc.culture.african Discussions about Africa & things African -soc.culture.celtic Group about Celtics (*not* basketball!) -soc.culture.greek Group about Greeks. -soc.culture.indian Group for discussion about India & things Indian -soc.culture.jewish Group for discussion about Jewish culture -soc.culture.misc Group for discussion about other cultures -soc.misc Socially-oriented topics not in other groups. -soc.motss Issues pertaining to homosexuality. -soc.roots Genealogical matters. -soc.singles Newsgroup for single people, their activities, etc. -soc.net-people Announcements, requests, etc. about people on the net. -soc.women Women's rights, discrimination, etc. -talk.abortion All sorts of discussions and arguments on abortion. -talk.bizarre The unusual, bizarre, curious, and often stupid. -talk.origins Evolution versus creationism (sometimes hot!). -talk.philosophy.misc Philosophical musings on all topics. -talk.politics.misc Political discussions and ravings of all kinds. -talk.politics.theory Theory of politics and political systems. -talk.religion.misc Religious, ethical, & moral implications. -talk.rumors For the posting of rumors. -E_O_F -: if active file is empty, create it -if test ! -s $LIBDIR/active -then - sed 's/[ ].*/ 00000 00001/' /tmp/$$groups > $LIBDIR/active - cat <<'E_O_F' >>$LIBDIR/active -control 00000 00001 -junk 00000 00001 -E_O_F - set - group 0 1 -else -: make sure it is in the new format - set - `sed 1q $LIBDIR/active` - case $# in - 4) ed - $LIBDIR/active << 'EOF' -g/^mod\./s/y$/m/ -w -q -EOF - ;; - 3) ;; - 2) ed - $LIBDIR/active << 'EOF' -1,$s/$/ 00001/ -w -q -EOF - echo - echo Active file updated to new format. - echo You must run expire immediately after this install - echo is done to properly update the tables.;; - *) echo Active file is in unrecognized format. Not upgraded.;; - esac -fi -if test $# -eq 3 -o $# -eq 2 -then - (sed '/^!net/!d -s/^!// -s!^!/! -s!$! /s/$/ n/! -' $LIBDIR/ngfile - echo '/ n$/!s/$/ y/') >/tmp/$$sed - mv $LIBDIR/active $LIBDIR/oactive - sed -f /tmp/$$sed $LIBDIR/oactive >$LIBDIR/active - chown $NEWSUSR $LIBDIR/active - chgrp $NEWSGRP $LIBDIR/active - chmod 644 $LIBDIR/active -fi -sort /tmp/$$groups | $LIBDIR/checkgroups | tee /tmp/checkgroups.out -echo the output of checkgroups has been copied into /tmp/checkgroups.out -rm -f /tmp/$$* *-*-END-of-src/makeactive.sh-*-* echo x - src/rfuncs2.c 1>&2 sed 's/.//' >src/rfuncs2.c <<'*-*-END-of-src/rfuncs2.c-*-*' -/* - * This software is Copyright 1986 by Rick Adams. - * - * Permission is hereby granted to copy, reproduce, redistribute or - * otherwise use this software as long as: there is no monetary - * profit gained specifically from the use or reproduction or this - * software, it is not sold, rented, traded or otherwise marketed, and - * this copyright notice is included prominently in any copy - * made. - * - * The author make no claims as to the fitness or correctness of - * this software for any use whatsoever, and it is provided as is. - * Any use of this software is at the user's own risk. - * - * rfuncs2 - more routines needed by readr. - */ - -#ifdef SCCSID -static char *SccsId = "@(#)rfuncs2.c 1.32 10/23/86"; -#endif /* SCCSID */ - -/*LINTLIBRARY*/ - -#include "rparams.h" - -static char lbuf[LBUFLEN]; - -FILE *popen(); - -/* - * Match title. - */ -titmat(h, titlist) -register struct hbuf *h; -register char *titlist; -{ - register char *p; - - while (*titlist != '\0') { - - if (strcmp(titlist, h->ident) == 0) - return TRUE; - for (p = h->title; *p != '\0'; p++) - if (prefix(p, titlist)) { - return TRUE; - } - while (*titlist++ != '\0') - ; - } - return FALSE; -} - - -/* - * Save the news item in the user's file. - * Allow files with first character as '|' to write article - * to program across a pipe. - */ - -#define PIPECHAR '|' - -save(file, to) -register char *file, *to; -{ - register FILE *ufp, *hfp; -#ifdef u370 - static struct hbuf hh; -#else /* !u370 */ - struct hbuf hh; -#endif /* !u370 */ - int isprogram = 0; - int isnew = 1; - register int i; - - for(i=0;i<NUNREC;i++) - hh.unrec[i] = NULL; - - if ((hfp = art_open(file, "r")) == NULL) { - fprintf(stderr, "Can't get article.\n"); - return; - } - if (hread(&hh, hfp, TRUE) == NULL) { - fprintf(stderr, "Article is garbled.\n"); - return; - } - ufp = fopen(to, "r"); - if (ufp != NULL) { - (void) fclose(ufp); - isnew = 0; - } - (void) setgid(gid); - (void) setuid(uid); - (void) umask(savmask); - - if (*to == PIPECHAR) { - if ((ufp = popen (&to[1], "w")) == NULL) { - fprintf(stderr,"Cannot execute %s\n", &to[1]); - return; - } - isprogram++; - } else if ((ufp = fopen(to, "a")) == NULL) { - fprintf(stderr,"Cannot append to %s.\n", to); - return; - } - /* - * V7MAIL code is here to conform to V7 mail format. - * If you need a different format to be able to - * use your local mail command (such as four ^A's - * on the end of articles) substitute it here. - */ -#ifdef MMDF - if (!isprogram) - fprintf(ufp, "\001\001\001\001\n"); /* MMDF message header */ -#endif /* MMDF */ -#ifdef V7MAIL - hh.subtime = cgtdate(hh.subdate); - fprintf(ufp, "From %s %s", replyname(&hh), ctime(&hh.subtime)); -#endif - hprint(&hh, ufp, 2); -#ifdef V7MAIL - tprint(hfp, ufp, TRUE); - putc('\n', ufp); /* force blank line at end (ugh) */ -#else - tprint(hfp, ufp, FALSE); -#endif - (void) fclose(hfp); -#ifdef MMDF - if (!isprogram) - fprintf(ufp, "\001\001\001\001\n"); /* MMDF message header */ -#endif /* MMDF */ - if (isprogram) - (void) pclose (ufp); - else - (void) fclose(ufp); - if (!isprogram) - printf("%s: %s\n", to, isnew ? "New file" : "Appended"); -} - - -/* - * Print out the rest of the article. - */ -tprint(ifp, ofp, checkfrom) -register FILE *ifp, *ofp; -int checkfrom; -{ - while ((fgets(bfr, sizeof bfr, ifp)) != NULL && !SigTrap) { - if (checkfrom && strncmp(bfr, "From ", 5) == 0) - putc('>', ofp); - (void) fputs(bfr, ofp); - } - if (SigTrap) - qfflush(ofp); - (void) fflush(ofp); - fprintf(ofp, (SigTrap ? "\n\n" : "\n")); - SigTrap = FALSE; -} - - -/* - * Print the file header. - */ -hprint(hp, ofp, verbose) -register struct hbuf *hp; -int verbose; -register FILE *ofp; -{ - register char *p1, *p2; - char fname[BUFLEN]; - char *tailpath(); - - fname[0] = '\0'; /* init name holder */ - - if (verbose == 2) { - lhwrite(hp, ofp); - return; - } - - if (lflag || eflag) { - char buf1[80], buf2[200]; - char *cp; - - (void) strcpy(bfr, groupdir); - for (cp=bfr; *cp; cp++) - if (*cp == '/') - *cp = '.'; - (void) sprintf(buf1, "%s/%ld", bfr, bit); - (void) sprintf(buf2, "%-20s %s", buf1, hp->title); - fprintf(ofp, "%.76s\n", buf2); - return; - } - - p1 = index(hp->from, '('); /* Find the sender's full name. */ - if (p1 == NULL && hp->path[0]) - p1 = index(hp->path, '('); - if (p1 != NULL) { - strcpy(fname, p1+1); - p2 = index(fname, ')'); - if (p2 != NULL) - *p2 = '\0'; - } - - fprintf(ofp, "Subject: %s\n", hp->title); - if (!hflag && hp->summary[0]) - fprintf(ofp, "Summary: %s\n", hp->summary); - if (!hflag && hp->keywords[0]) - fprintf(ofp, "Keywords: %s\n", hp->keywords); - if (verbose) { - fprintf(ofp, "From: %s\n", hp->from); - fprintf(ofp, "Path: %s\n", hp->path); - if (hp->organization[0]) - fprintf(ofp, "Organization: %s\n", hp->organization); - } - else { - if (p1 != NULL) - *--p1 = '\0'; /* bump over the '(' */ -#ifdef INTERNET - /* - * Prefer Path line if it's in internet format, or if we don't - * understand internet format here, or if there is no reply-to. - */ - fprintf(ofp, "From: %s", hp->from); -#else - fprintf(ofp, "Path: %s", tailpath(hp)); -#endif - if (fname[0] || hp->organization[0]) { - if (fname[0] == '\0') { - (void) strcpy(fname,hp->from); - p2 = index(fname,'@'); - if (p2) - *p2 = '\0'; - } - fprintf(ofp, " (%s", fname); - if (hp->organization[0] && !hflag) - fprintf(ofp, " @ %s", hp->organization); - fprintf(ofp, ")"); - } - fprintf(ofp, "\n"); - if (p1 != NULL) - *p1 = ' '; - } - - if (verbose) { - fprintf(ofp, "Newsgroups: %s\n", hp->nbuf); - fprintf(ofp, "Date: %s\n", hp->subdate); - if (hp->sender[0]) - fprintf(ofp, "Sender: %s\n", hp->sender); - if (hp->replyto[0]) - fprintf(ofp, "Reply-To: %s\n", hp->replyto); - if (hp->followto[0]) - fprintf(ofp, "Followup-To: %s\n", hp->followto); - } - else if (index(hp->nbuf, ',') || strcmp(groupdir, "junk") == 0) - fprintf(ofp, "Newsgroups: %s\n", hp->nbuf); - - if (pflag || ofp != stdout) - putc('\n', ofp); -} - - -/* - * If ofp != stdout, close it and run the script in coptbuf. - */ -cout(ofp) -FILE *ofp; -{ - register char *p, *q, *r; - - if (ofp == stdout || ofp == NULL) - return; - (void) fclose(ofp); - p = coptbuf; - q = lbuf; - while ((*q = *p++) != '\0') - if (*q++ == FMETA) { - q--; - r = outfile; - while ((*q++ = *r++) != '\0') - ; - q--; - } - fwait(fsubr(ushell, lbuf, (char *)NULL)); - (void) unlink(outfile); -} - - -cdump(ofp) -register FILE *ofp; -{ - if (ofp == stdout) - return; - fclose(ofp); - unlink(outfile); -} - - -/* - * Quiet 'flush'. - * Empty (without fflush()) the buffer for stream fp. - */ -/* ARGSUSED */ -qfflush(fp) -FILE *fp; -{ - /* Alas, stdio does not permit this */ -} - - -/* - * Count the number of remaining lines in file fp. - * Do not move the file pointer. - */ -linecnt(fp) -FILE *fp; -{ - long curpos; - register int nlines = 0; - register int c; - - if (fp == NULL) - return 0; - curpos = ftell(fp); - while ((c = getc(fp)) != EOF) - if (c == '\n') - nlines++; - (void) fseek(fp, curpos, 0); - return nlines; -} - - -/* - * Transmit file to system. - */ -transmit(sp, file) -register struct srec *sp; -char *file; -{ - register FILE *ifp, *ofp; - register int c, i; -#ifdef u370 - static struct hbuf hh; -#else /* !u370 */ - struct hbuf hh; -#endif /* !u370 */ - char TRANS[BUFLEN]; - -#ifdef DEBUG - fprintf(stderr, "xmit %s to %s using %s\n", file, sp->s_name, sp->s_xmit); -#endif - bzero((char *)&hh, sizeof hh); - ifp = xart_open(file, "r"); - if (hread(&hh, ifp, TRUE) == NULL) - return; - strcpy(TRANS, "/tmp/trXXXXXX"); - ofp = xfopen(mktemp(TRANS), "w"); - if (index(sp->s_flags, 'A') == NULL) - hwrite(&hh, ofp); - else { -#ifdef OLD - fprintf(ofp, "A%s\n%s\n%s!%s\n%s\n%s\n", oident(hh.ident), hh.nbuf, FULLSYSNAME, - hh.path, hh.subdate, hh.title); -#else /* !OLD */ - logerr("Must have OLD defined to use A flag for xmit"); - unlink(TRANS); - return; -#endif /* !OLD */ - } - while ((c = getc(ifp)) != EOF) - putc(c, ofp); - (void) fclose(ifp); - (void) fclose(ofp); - for (i=0;i<NUNREC;i++) - if (hh.unrec[i] != NULL) - free(hh.unrec[i]); - if (*sp->s_xmit == '\0' || strpbrk(sp->s_flags, "FUMH")) - (void) sprintf(bfr, DFTXMIT, sp->s_name, TRANS); - else - (void) sprintf(bfr, "(%s) < %s", sp->s_xmit, TRANS); -#ifdef DEBUG - fprintf(stderr, "%s\n", bfr); -#endif - (void) system(bfr); - (void) unlink(TRANS); -} - - -/* - * Cancel the article whose header is in hp, by posting a control message - * to cancel it. The scope of the control message depends on who would - * really be willing to cancel it. It is sent as far as it will do any good. - * notauthor is true iff the person posting this article is not the - * real author of the article being cancelled. - */ -cancel(ofp, hp, notauthor) -FILE *ofp; -struct hbuf *hp; -int notauthor; -{ - int pid; - - fflush(ofp); - pid = vfork(); - if (pid < 0) { - perror("readnews: cancel"); - return 0; - } - if (pid > 0) - return 0; - if (notauthor) - (void) sprintf(bfr, "%s/%s -c 'cancel %s' -n %s -d local < /dev/null", - LIB, "inews", hp->ident, hp->nbuf); - else { - if (hp->distribution[0] == '\0') - (void) sprintf(bfr, "%s/%s -c 'cancel %s' -n %s < /dev/null", - LIB, "inews", hp->ident, hp->nbuf); - else - (void) sprintf(bfr, "%s/%s -c 'cancel %s' -n %s -d %s < /dev/null", - LIB, "inews", hp->ident, hp->nbuf, hp->distribution); - } - execl("/bin/sh", "sh", "-c", bfr, (char *) 0); - perror(bfr); - for ( ; ; ) - exit(1); -} - - -dash(num, ofp) -register int num; -register FILE *ofp; -{ - register int i; - - for (i = 0; i < num; i++) - putc('-', ofp); - putc('\n', ofp); -} - - -help(ofp) -register FILE *ofp; -{ - register FILE *fp; - register int c; - char temp[BUFLEN]; - - if (cflag) { -oneline: - fprintf(ofp, "(n)ext re(p)rint (w)rite (q)uit (r)eply\ - (c)ancel -[n] +[n] (f)ollowup (N)ext (U)nsubscribe (v)ersion\n"); - return; - } - (void) sprintf(temp, "%s/%s", LIB, "help"); - if ((fp = fopen(temp, "r")) == NULL) { - fprintf(ofp, "No help file.\n"); - goto oneline; - } - while ((c = getc(fp)) != EOF && !SigTrap) - putc(c, ofp); - (void) fclose(fp); -} - - -pout(ofp) -FILE *ofp; -{ - register char *p, *q, *r; - - p = PAGER; - q = lbuf; - while ((*q = *p++) != '\0') - if (*q++ == FMETA) { - q--; - r = filename; - while ((*q++ = *r++) != '\0') - ; - q--; - } - fwait(fsubr(ushell, lbuf, (char *)NULL)); - fprintf(ofp, "\n"); -} - -/* - * Print a very brief version of the date in question. - */ -char * -briefdate(datestr) -char *datestr; -{ - time_t dt, now; - char *tmstr; - char *wkday, *monthdate, *timeofday; - static char rbuf[20]; - - dt = cgtdate(datestr); - tmstr = ctime(&dt); - - wkday = tmstr; tmstr[3] = '\0'; - monthdate = tmstr+4; tmstr[10] = '\0'; - timeofday = tmstr+11; tmstr[16] = '\0'; - - (void) time(&now); - if (now - dt < WEEKS) - (void) strcpy(rbuf, wkday); - else - (void) strcpy(rbuf, monthdate); - (void) strcat(rbuf, " "); - (void) strcat(rbuf, timeofday); - return rbuf; -} - -/* - * Return TRUE iff stdout is /dev/null. - */ -ignoring() -{ - struct stat ss, ns; - - if (fstat(1, &ss) < 0) - return FALSE; - if (stat("/dev/null", &ns) < 0) - return FALSE; - if (ss.st_dev == ns.st_dev && ss.st_rdev == ns.st_rdev) - return TRUE; - return FALSE; -} *-*-END-of-src/rfuncs2.c-*-* echo x - src/iextern.c 1>&2 sed 's/.//' >src/iextern.c <<'*-*-END-of-src/iextern.c-*-*' -/* - * iextern - external definitions for inews. - */ - -#ifdef SCCSID -static char *SccsId = "@(#)iextern.c 2.17 9/19/86"; -#endif /* SCCSID */ - -#include "iparams.h" - -int uid, gid; /* real user/group I.D. */ -int duid, dgid; /* effective user/group I.D. */ -int SigTrap; /* set if signal trapped */ -int savmask; /* old umask */ -int mode; /* mode of news program */ -struct hbuf header; /* general-use header structure */ -char bfr[LBUFLEN]; /* general-use scratch area */ -char nbuf[LBUFLEN]; /* local newsgroup buffer */ -char filename[BUFLEN]; /* general-use file name */ -char not_here[SBUFLEN]; /* name of system not to xmit to */ - -#ifndef ROOTID -int ROOTID; /* special users id # */ -#endif - -char *DFLTNG = "general"; /* default newsgroup */ -FILE *infp; /* input file-pointer */ -FILE *actfp; /* active newsgroups file pointer */ -int tty; /* set if infp is a tty */ -char *PARTIAL = "dead.article"; /* place to save partial news */ -char *SHELL = "/bin/sh"; /* shell for inews to use */ -int is_ctl; /* true for a control message */ -char is_mod[NAMELEN]; /* contains newsgroup if moderated */ *-*-END-of-src/iextern.c-*-* exit