sources-request@mirror.TMC.COM (11/07/86)
Submitted by: seismo!rick (Rick Adams) Mod.sources: Volume 7, Issue 56 Archive-name: 2.11news/Part07 # To extract, sh this file # news 2.11 source part 7 of 9 if test ! -d src then mkdir src fi echo x - src/funcs2.c 1>&2 sed 's/.//' >src/funcs2.c <<'*-*-END-of-src/funcs2.c-*-*' -/* - * This software is Copyright (c) 1985 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. - * - * - * funcs2 - functions used by both inews and readnews. - */ - -#ifdef SCCSID -static char *SccsId = "@(#)funcs2.c 1.16 10/23/86"; -#endif /* SCCSID */ - -#include "params.h" - -#ifdef SunIII -#ifndef INTERNET -#define INTERNET -#endif /* !INTERNET */ -#endif /* SunIII */ - -/*LINTLIBRARY*/ - -/* - * Get user name and home directory. - */ -getuser() -{ - static int flag = TRUE; - register struct passwd *p; - - if (flag) { - if ((p = getpwuid(uid)) == NULL) - xerror("Cannot get user's name"); - if ( username == NULL || username[0] == 0) - username = AllocCpy(p->pw_name); - userhome = AllocCpy(p->pw_dir); - flag = FALSE; - } - (void) strcpy(header.path, username); -} - -static FILE *sysfile; - -char *fldget(); - -static int sfline; - -/* - * Open SUBFILE. - */ -s_openr() -{ - sysfile = xfopen(SUBFILE, "r"); - sfline = 0; -} - -/* - * Read SUBFILE. - */ -s_read(sp) -register struct srec *sp; -{ - register char *p; - register int c; - char *e; - int chop_spaces = 0; -again: - p = bfr; - /* - * Read the SUBFILE (/usr/lib/news/sys) from the current - * position to the first unescaped newline. If a newline is - * escaped with a backslash (\) continue reading but throw away - * the backslash and newline; read the next line skipping spaces - * and tabs until the first non-space/tab character, then start - * looking for a newline again. Skipping the leading - * spaces/tabs after a escaped newline keeps the news groups - * together. If a line begins with a newline, just skip it. - */ - for (e=p+LBUFLEN; p < e && (c=getc(sysfile)) != EOF; p++) { - *p = c; - if (c == '\n') { - sfline++; - if (p == bfr || p[-1] != '\\') { - p[1] = '\0'; - break; - } else { - chop_spaces++; - p -= 2; - } - } else if (chop_spaces) { - if (c == '\t' || c == ' ') - p--; - else - chop_spaces = 0; - } - } - if (c == EOF) { - return FALSE; - } - p = bfr; - while (*p == ' ' || *p == '\t') /* skip leading white space */ - p++; - if (*p == '\n') - goto again; /* skip newlines */ - if (!nstrip(p)) - xerror("SUBFILE (%s) line %d too long.", SUBFILE, sfline); - if (*p == '#') - goto again; - sp->s_xmit[0] = '\0'; - sp->s_flags[0] = '\0'; - sp->s_nosend = (char *)0; - - p = fldget(sp->s_name, p); - if (*p++ == '\0') - xerror("Bad SUBFILE (%s) line %d.", SUBFILE, sfline); -/* - * A sys file line reading "ME" means the name of the local system. - */ - if (strcmp(sp->s_name, "ME") == 0) - (void) strcpy(sp->s_name, FULLSYSNAME); - e = index(sp->s_name, '/'); - if (e) { - *e++ = '\0'; - sp->s_nosend = e; - } - p = fldget(sp->s_nbuf, p); - lcase(sp->s_nbuf); - if (*p++ == '\0') - return TRUE; - - p = fldget(sp->s_flags, p); - if (*p++ == '\0') - return TRUE; - - (void) fldget(sp->s_xmit, p); - return TRUE; -} - -char * -fldget(q, p) -register char *q, *p; -{ - while (*p && *p != ':') { - if (*p == '\\' && p[1]==':') - p++; - *q++ = *p++; - } - *q = '\0'; - return p; -} - -/* - * Find the SUBFILE record for a system. - */ -s_find(sp, system) -register struct srec *sp; -char *system; -{ - s_openr(); - while (s_read(sp)) - if (strncmp(system, sp->s_name, SNLN) == 0) { - s_close(); - return TRUE; - } - s_close(); - return FALSE; -} - -/* - * Close sysfile. - */ -s_close() -{ - (void) fclose(sysfile); -} - -extern struct timeb Now; - -time_t -cgtdate(datestr) -char *datestr; -{ - char junk[40],month[40],day[30],tod[60],year[50]; - static time_t lasttime; - static char lastdatestr[BUFLEN] = ""; - - if ( lastdatestr[0] && strcmp(datestr, lastdatestr) == 0) - return lasttime; - lasttime = getdate(datestr, &Now); - if (lasttime < 0 && - sscanf(datestr, "%s %s %s %s %s", junk, month, day, tod, year) == 5) { - (void) sprintf(bfr, "%s %s, %s %s", month, day, year, tod); - lasttime = getdate(bfr, &Now); - } - strncpy(lastdatestr, datestr, BUFLEN); - return lasttime; -} - -lcase(s) -register char *s; -{ - register char *ptr; - - for (ptr = s; *ptr; ptr++) - if (isupper(*ptr)) - *ptr = tolower(*ptr); -} - -/* - * Return a compact representation of the person who posted the given - * message. A sender or internet name will be used, otherwise - * the last part of the path is used preceded by an optional ".." - */ -char * -tailpath(hp) -struct hbuf *hp; -{ - char *p, *r; - static char resultbuf[BUFLEN]; - char pathbuf[PATHLEN]; - char *malloc(); - - /* - * This only happens for articles posted by old news software - * in non-internet format. - */ - resultbuf[0] = '\0'; - (void) strncpy(pathbuf, hp->path, PATHLEN); - p = index(pathbuf, ' '); - if (p) - *p = '\0'; /* Chop off trailing " (name)" */ - r = rindex(pathbuf, '!'); - if (r == 0) { - r = pathbuf; - } else { - while (r > pathbuf && *--r != '!') - ; - if (r > pathbuf) { - r++; - (void) strcpy(resultbuf, "..!"); - } - } - (void) strcat(resultbuf, r); - return resultbuf; -} - -/* - * arpadate is like ctime(3) except that the time is returned in - * an acceptable ARPANET time format instead of ctime format. - */ -char * -arpadate(longtime) -time_t *longtime; -{ - register char *p, *q, *ud; - register int i; - static char b[40]; - extern struct tm *gmtime(); - extern char *asctime(); - - /* Get current time. This will be used resolve the timezone. */ - ud = asctime(gmtime(longtime)); - - /* Crack the UNIX date line in a singularly unoriginal way. */ - q = b; - -#ifdef notdef -/* until every site installs the fix to getdate.y, the day - of the week can cause time warps */ - p = &ud[0]; /* Mon */ - *q++ = *p++; - *q++ = *p++; - *q++ = *p++; - *q++ = ','; *q++ = ' '; -#endif - - p = &ud[8]; /* 16 */ - if (*p == ' ') - p++; - else - *q++ = *p++; - *q++ = *p++; *q++ = ' '; - - p = &ud[4]; /* Sep */ - *q++ = *p++; *q++ = *p++; *q++ = *p++; *q++ = ' '; - - p = &ud[22]; /* 1979 */ - *q++ = *p++; *q++ = *p++; *q++ = ' '; - - p = &ud[11]; /* 01:03:52 */ - for (i = 8; i > 0; i--) - *q++ = *p++; - - *q++ = ' '; - *q++ = 'G'; /* GMT */ - *q++ = 'M'; - *q++ = 'T'; - *q = '\0'; - - return b; -} - -char * -replyname(hptr) -struct hbuf *hptr; -{ - register char *ptr; - static char tbuf[PATHLEN]; - - ptr = hptr->path; - if (prefix(ptr, FULLSYSNAME) && - index(NETCHRS, ptr[strlen(FULLSYSNAME)])) - ptr = index(ptr, '!') + 1; -#ifdef INTERNET - if (hptr->from[0]) - ptr = hptr->from; - if (hptr->replyto[0]) - ptr = hptr->replyto; -#endif - (void) strcpy(tbuf, ptr); - ptr = index(tbuf, '('); - if (ptr) { - while (ptr[-1] == ' ') - ptr--; - *ptr = 0; - } -#ifdef SunIII - if (ptr = rindex(tbuf, '.')) { - if (prefix(++ptr, "OZ")) { - /* some people only allow it in lower case ... */ - strcpy(ptr, "oz"); - return tbuf; - } - if (prefix(ptr, "UUCP") || prefix(ptr, "ARPA") || - prefix(ptr, "DEC") || prefix(ptr, "CSNET")) { - strcat(tbuf, "@munnari.oz"); /* via sun to munnari */ - return tbuf; - } - } - /* - * must(?) have come from a uucp site, lets look see if path passes - * through munnari, and if so delete the fake uucp path after that. - */ - for (ptr = tbuf ;; ptr++) { - if (prefix(ptr, "munnari!")) { - strcpy(tbuf, ptr+8); - break; - } - ptr = index(ptr, '!'); - if (ptr == (char *)0) - break; - } - /* - * now, just send the address we have left to munnari, and - * hope that something sensible will be done with it there. - * (This works in more cases than you'd think ...) - */ - strcat(tbuf, "@munnari.oz"); -#else /* !SunIII */ -#ifndef INTERNET - /* - * Play games stripping off multiple berknet - * addresses (a!b!c:d:e => a!b!d:e) here. - */ - for (ptr=tbuf; *ptr; ptr++) { - register char *ptr2; - - if (index(NETCHRS, *ptr) && *ptr == ':' && - (ptr2=index(ptr+1, ':'))) - (void) strcpy(ptr, ptr2); - } -#else /* INTERNET */ - { - char mbuf[BUFLEN], modadd[BUFLEN]; - FILE *mfd; - /* Let's find a path to the backbone */ - sprintf(mbuf, "%s/mailpaths", LIBDIR); - mfd = xfopen(mbuf, "r"); - do { - if (fgets(mbuf, sizeof mbuf, mfd) == NULL) - xerror("Can't find internet in %s/mailpaths", - LIBDIR); - } while (!prefix(mbuf, "internet")); - if (sscanf(mbuf, "%*s %s", modadd) != 1) - xerror("backbone address corrupted"); - (void) fclose(mfd); - (void)strcpy(mbuf, tbuf); - /* If we are lucky, there is no ! or @ in the forward address */ - if (strpbrk(modadd, "!@") == NULL) { - sprintf(tbuf, modadd, mbuf); - } else { - char *cp = index(mbuf, '@'); - if (index(modadd, '@') == NULL && cp) { - /* we have to rearrange the address so no @ are in it */ - char atbuf[BUFLEN]; - *cp++ = '\0'; - sprintf(atbuf, "%s!%s", cp, mbuf); - sprintf(tbuf, modadd, atbuf); - } else if (cp) { - /* some days you don't get lucky. presume the % hack */ - *cp = '%'; - sprintf(tbuf, modadd, mbuf); - } - } - } -#endif /* INTERNET */ -#endif /* !SunIII */ - return tbuf; -} - -#ifdef DBM -typedef struct { - char *dptr; - int dsize; -} datum; -#endif /* DBM */ - -/* - * Given an article ID, find the line in the history file that mentions it. - * Return the text of the line, or NULL if not found. A pointer to a - * static area is returned. - */ -char * -findhist(artid) -char *artid; -{ - static char lbuf[256]; - char oidbuf[BUFSIZ]; - FILE *hfp; - register char *p; -#ifdef DBM - datum lhs, rhs; - datum fetch(); - long fpos; /* We have to use an explicit variable to insure alignment */ -#else /* !DBM */ - char *histfile(); -#endif /* !DBM */ - - /* Try to understand old artid's as well. Assume .UUCP domain. */ - if (artid[0] != '<') { - p = index(artid, '.'); - if (p) - *p++ = '\0'; - (void) sprintf(oidbuf, "<%s@%s.UUCP>", p, artid); - if (p) - *--p = '.'; - } else - (void) strcpy(oidbuf, artid); - lcase(oidbuf); -#ifdef DBM - initdbm(ARTFILE); - lhs.dptr = oidbuf; - lhs.dsize = strlen(lhs.dptr) + 1; - rhs = fetch(lhs); - if (rhs.dptr == NULL) - return NULL; - hfp = xfopen(ARTFILE, "r"); - /* The bcopy is NECESSARY to insure alignment on some machines */ - bcopy(rhs.dptr, (char *)&fpos, sizeof (long)); - fseek(hfp, fpos, 0); -#else /* !DBM */ - hfp = xfopen(histfile(oidbuf), "r"); -#endif /* !DBM */ - while (fgets(lbuf, BUFLEN, hfp) != NULL) { - p = index(lbuf, '\t'); - if (p == NULL) - p = index(lbuf, '\n'); - *p = 0; - if (strcmp(lbuf, artid) == 0 || strcmp(lbuf, oidbuf) == 0) { - (void) fclose(hfp); - *p = '\t'; - *(lbuf + strlen(lbuf) - 1) = 0; /* zap the \n */ - return lbuf; - } -#ifdef DBM - break; -#endif /* DBM */ - } - (void) fclose(hfp); - return NULL; -} - -/* - * Hunt up the article "artid", and return the newsgroup/artnum - * where it can be found. - */ -char * -findfname(artid) -char *artid; -{ - char *line, *p, *q; - char *findhist(); - static char fname[BUFLEN]; - - line = findhist(artid); - if (line) { - /* Look for it stored as an article, where it should be */ - p = index(line, '\t'); - p = index(p+1, '\t'); - p++; - if (*p) { - q = index(p, ' '); - if (q) - *q = 0; - (void) strcpy(fname, p); - return fname; - } - } - return NULL; -} - -/* - * Hunt up the article "artid", fopen it for read, and return a - * file descriptor to it. We look everywhere we can think of. - */ -FILE * -hfopen(artid) -char *artid; -{ - char *p; - char *findhist(); - FILE *rv = NULL; - char fname[BUFLEN]; - - p = findfname(artid); - if (p) { - (void) strcpy(fname, dirname(p)); - rv = fopen(fname, "r"); /* NOT xfopen! */ - if (rv == NULL) - xerror("Cannot hfopen article %s", artid); - } - return rv; -} - -#ifdef DBM -/* -** Avoid problems of multiple dbminit calls. -*/ -initdbm(name) -char *name; -{ - static int called = 0; - - if (called != 0) - return; - called = 1; - (void) dbminit(name); -} -#endif - -#ifndef BSD4_2 -/* - * move n bytes from a to b - */ -bcopy(a, b, n) -register char *a, *b; -register n; -{ - while (--n >= 0) - *b++ = *a++; -} -#endif - -#if !defined(BSD4_2) && !defined(BSD4_1C) -rename(from,to) -register char *from, *to; -{ - (void) unlink(to); - if (link(from, to) < 0) - return -1; - - (void) unlink(from); - return 0; -} -#endif /* !BSD4_2 && ! BSD4_1C */ - -#ifndef DBM -/* -** Generate the appropriate history subfile name -*/ -char * -histfile(hline) -char *hline; -{ - char *p; - char chr; /* least significant digit of article number */ - static char subfile[BUFLEN]; - - p = strchr(hline, '@'); - if (p != NULL && p > hline) - chr = *(p - 1); - else - chr = '0'; - if (!isdigit(chr)) - chr = '0'; - sprintf(subfile, "%s.d/%c", ARTFILE, chr); - if (access(subfile, 04) < 0) - return(ARTFILE); - return(subfile); -} -#endif /* !DBM */ - -#ifdef VMS -/* - * These functions open an article with one level of indirection, - * to support symbolic links. xart_open exits if the open fails. - */ -FILE * -xart_open (filename,mode) -char *filename,*mode; -{ - FILE *fp = art_open (filename, mode); - extern int errno; - if (fp == NULL) - xerror("Cannot open article %s (%s): %s\n", - filename, mode, errmsg(errno)); - return fp; -} - -FILE * -art_open (filename,mode) -char *filename,*mode; -{ - char linkfile[BUFSIZ]; - FILE *fp; - - if ((fp = fopen (filename, mode)) == NULL) - return NULL; - if (fgets (linkfile, BUFSIZ, fp) == NULL || linkfile[0] != '/') { - rewind (fp); - return fp; - } -/* Chase the symbolic link. */ - (void) fclose (fp); - if ((fp = fopen (linkfile, mode)) == NULL) -/* Clean up dangling link, if we have the power. Ignore error if we don't. */ - (void) unlink (filename); - return fp; -} -#endif /* VMS */ *-*-END-of-src/funcs2.c-*-* echo x - src/getdate.y 1>&2 sed 's/.//' >src/getdate.y <<'*-*-END-of-src/getdate.y-*-*' -%token ID MONTH DAY MERIDIAN NUMBER UNIT MUNIT SUNIT ZONE DAYZONE AGO -%{ - /* Steven M. Bellovin (unc!smb) */ - /* Dept. of Computer Science */ - /* University of North Carolina at Chapel Hill */ - /* @(#)getdate.y 2.13 9/16/86 */ - -#include <sys/types.h> -#ifdef USG -struct timeb -{ - time_t time; - unsigned short millitm; - short timezone; - short dstflag; -}; -#else -#include <sys/timeb.h> -#endif -#include <ctype.h> - -#include "defs.h" -#if defined(BSD4_2) || defined (BSD4_1C) -#include <sys/time.h> -#else sane -#include <time.h> -#endif sane - -#define NULL 0 -#define daysec (24L*60L*60L) - static int timeflag, zoneflag, dateflag, dayflag, relflag; - static time_t relsec, relmonth; - static int hh, mm, ss, merid, daylight; - static int dayord, dayreq; - static int month, day, year; - static int ourzone; -#define AM 1 -#define PM 2 -#define DAYLIGHT 1 -#define STANDARD 2 -#define MAYBE 3 -%} - -%% -timedate: /* empty */ - | timedate item; - -item: tspec = - {timeflag++;} - | zone = - {zoneflag++;} - | dtspec = - {dateflag++;} - | dyspec = - {dayflag++;} - | rspec = - {relflag++;} - | nspec; - -nspec: NUMBER = - {if (timeflag && dateflag && !relflag) year = $1; - else {timeflag++;hh = $1/100;mm = $1%100;ss = 0;merid = 24;}}; - -tspec: NUMBER MERIDIAN = - {hh = $1; mm = 0; ss = 0; merid = $2;} - | NUMBER ':' NUMBER = - {hh = $1; mm = $3; merid = 24;} - | NUMBER ':' NUMBER MERIDIAN = - {hh = $1; mm = $3; merid = $4;} - | NUMBER ':' NUMBER NUMBER = - {hh = $1; mm = $3; merid = 24; - daylight = STANDARD; ourzone = $4%100 + 60*$4/100;} - | NUMBER ':' NUMBER ':' NUMBER = - {hh = $1; mm = $3; ss = $5; merid = 24;} - | NUMBER ':' NUMBER ':' NUMBER MERIDIAN = - {hh = $1; mm = $3; ss = $5; merid = $6;} - | NUMBER ':' NUMBER ':' NUMBER NUMBER = - {hh = $1; mm = $3; ss = $5; merid = 24; - daylight = STANDARD; ourzone = $6%100 + 60*$6/100;}; - -zone: ZONE = - {ourzone = $1; daylight = STANDARD;} - | DAYZONE = - {ourzone = $1; daylight = DAYLIGHT;}; - -dyspec: DAY = - {dayord = 1; dayreq = $1;} - | DAY ',' = - {dayord = 1; dayreq = $1;} - | NUMBER DAY = - {dayord = $1; dayreq = $2;}; - -dtspec: NUMBER '/' NUMBER = - {month = $1; day = $3;} - | NUMBER '/' NUMBER '/' NUMBER = - {month = $1; day = $3; year = $5;} - | MONTH NUMBER = - {month = $1; day = $2;} - | MONTH NUMBER ',' NUMBER = - {month = $1; day = $2; year = $4;} - | NUMBER MONTH = - {month = $2; day = $1;} - | NUMBER MONTH NUMBER = - {month = $2; day = $1; year = $3;}; - - -rspec: NUMBER UNIT = - {relsec += 60L * $1 * $2;} - | NUMBER MUNIT = - {relmonth += $1 * $2;} - | NUMBER SUNIT = - {relsec += $1;} - | UNIT = - {relsec += 60L * $1;} - | MUNIT = - {relmonth += $1;} - | SUNIT = - {relsec++;} - | rspec AGO = - {relsec = -relsec; relmonth = -relmonth;}; -%% - -static int mdays[12] = - {31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; -#define epoch 1970 - -extern struct tm *localtime(); -time_t dateconv(mm, dd, yy, h, m, s, mer, zone, dayflag) -int mm, dd, yy, h, m, s, mer, zone, dayflag; -{ - time_t tod, jdate; - register int i; - time_t timeconv(); - - if (yy < 0) yy = -yy; - if (yy < 100) yy += 1900; - mdays[1] = 28 + (yy%4 == 0 && (yy%100 != 0 || yy%400 == 0)); - if (yy < epoch || yy > 1999 || mm < 1 || mm > 12 || - dd < 1 || dd > mdays[--mm]) return (-1); - jdate = dd-1; - for (i=0; i<mm; i++) jdate += mdays[i]; - for (i = epoch; i < yy; i++) jdate += 365 + (i%4 == 0); - jdate *= daysec; - jdate += zone * 60L; - if ((tod = timeconv(h, m, s, mer)) < 0) return (-1); - jdate += tod; - if (dayflag==DAYLIGHT || (dayflag==MAYBE&&localtime(&jdate)->tm_isdst)) - jdate += -1*60*60; - return (jdate); -} - -time_t dayconv(ord, day, now) int ord, day; time_t now; -{ - register struct tm *loctime; - time_t tod; - time_t daylcorr(); - - tod = now; - loctime = localtime(&tod); - tod += daysec * ((day - loctime->tm_wday + 7) % 7); - tod += 7*daysec*(ord<=0?ord:ord-1); - return daylcorr(tod, now); -} - -time_t timeconv(hh, mm, ss, mer) register int hh, mm, ss, mer; -{ - if (mm < 0 || mm > 59 || ss < 0 || ss > 59) return (-1); - switch (mer) { - case AM: if (hh < 1 || hh > 12) return(-1); - return (60L * ((hh%12)*60L + mm)+ss); - case PM: if (hh < 1 || hh > 12) return(-1); - return (60L * ((hh%12 +12)*60L + mm)+ss); - case 24: if (hh < 0 || hh > 23) return (-1); - return (60L * (hh*60L + mm)+ss); - default: return (-1); - } -} -time_t monthadd(sdate, relmonth) time_t sdate, relmonth; -{ - struct tm *ltime; - time_t dateconv(); - time_t daylcorr(); - int mm, yy; - - if (relmonth == 0) return 0; - ltime = localtime(&sdate); - mm = 12*ltime->tm_year + ltime->tm_mon + relmonth; - yy = mm/12; - mm = mm%12 + 1; - return daylcorr(dateconv(mm, ltime->tm_mday, yy, ltime->tm_hour, - ltime->tm_min, ltime->tm_sec, 24, ourzone, MAYBE), sdate); -} - -time_t daylcorr(future, now) time_t future, now; -{ - int fdayl, nowdayl; - - nowdayl = (localtime(&now)->tm_hour+1) % 24; - fdayl = (localtime(&future)->tm_hour+1) % 24; - return (future-now) + 60L*60L*(nowdayl-fdayl); -} - -static char *lptr; - -yylex() -{ - extern int yylval; - int sign; - register char c; - register char *p; - char idbuf[20]; - int pcnt; - - for (;;) { - while (isspace(*lptr)) lptr++; - - if (isdigit(c = *lptr) || c == '-' || c == '+') { - if (c== '-' || c == '+') { - if (c=='-') sign = -1; - else sign = 1; - if (!isdigit(*++lptr)) { - /* yylval = sign; return (NUMBER); */ - return yylex(); /* skip the '-' sign */ - } - } else sign = 1; - yylval = 0; - while (isdigit(c = *lptr++)) yylval = 10*yylval + c - '0'; - yylval *= sign; - lptr--; - return (NUMBER); - - } else if (isalpha(c)) { - p = idbuf; - while (isalpha(c = *lptr++) || c=='.') - *p++ = c; - *p = '\0'; - lptr--; - return (lookup(idbuf)); - } - - else if (c == '(') { - pcnt = 0; - do { - c = *lptr++; - if (c == '\0') return(c); - else if (c == '(') pcnt++; - else if (c == ')') pcnt--; - } while (pcnt > 0); - } - - else return (*lptr++); - } -} - -struct table { - char *name; - int type, value; -}; - -struct table mdtab[] = { - {"January", MONTH, 1}, - {"February", MONTH, 2}, - {"March", MONTH, 3}, - {"April", MONTH, 4}, - {"May", MONTH, 5}, - {"June", MONTH, 6}, - {"July", MONTH, 7}, - {"August", MONTH, 8}, - {"September", MONTH, 9}, - {"Sept", MONTH, 9}, - {"October", MONTH, 10}, - {"November", MONTH, 11}, - {"December", MONTH, 12}, - - {"Sunday", DAY, 0}, - {"Monday", DAY, 1}, - {"Tuesday", DAY, 2}, - {"Tues", DAY, 2}, - {"Wednesday", DAY, 3}, - {"Wednes", DAY, 3}, - {"Thursday", DAY, 4}, - {"Thur", DAY, 4}, - {"Thurs", DAY, 4}, - {"Friday", DAY, 5}, - {"Saturday", DAY, 6}, - {0, 0, 0}}; - -#define HRS *60 -#define HALFHR 30 -struct table mztab[] = { - {"a.m.", MERIDIAN, AM}, - {"am", MERIDIAN, AM}, - {"p.m.", MERIDIAN, PM}, - {"pm", MERIDIAN, PM}, - {"nst", ZONE, 3 HRS + HALFHR}, /* Newfoundland */ - {"n.s.t.", ZONE, 3 HRS + HALFHR}, - {"ast", ZONE, 4 HRS}, /* Atlantic */ - {"a.s.t.", ZONE, 4 HRS}, - {"adt", DAYZONE, 4 HRS}, - {"a.d.t.", DAYZONE, 4 HRS}, - {"est", ZONE, 5 HRS}, /* Eastern */ - {"e.s.t.", ZONE, 5 HRS}, - {"edt", DAYZONE, 5 HRS}, - {"e.d.t.", DAYZONE, 5 HRS}, - {"cst", ZONE, 6 HRS}, /* Central */ - {"c.s.t.", ZONE, 6 HRS}, - {"cdt", DAYZONE, 6 HRS}, - {"c.d.t.", DAYZONE, 6 HRS}, - {"mst", ZONE, 7 HRS}, /* Mountain */ - {"m.s.t.", ZONE, 7 HRS}, - {"mdt", DAYZONE, 7 HRS}, - {"m.d.t.", DAYZONE, 7 HRS}, - {"pst", ZONE, 8 HRS}, /* Pacific */ - {"p.s.t.", ZONE, 8 HRS}, - {"pdt", DAYZONE, 8 HRS}, - {"p.d.t.", DAYZONE, 8 HRS}, - {"yst", ZONE, 9 HRS}, /* Yukon */ - {"y.s.t.", ZONE, 9 HRS}, - {"ydt", DAYZONE, 9 HRS}, - {"y.d.t.", DAYZONE, 9 HRS}, - {"hst", ZONE, 10 HRS}, /* Hawaii */ - {"h.s.t.", ZONE, 10 HRS}, - {"hdt", DAYZONE, 10 HRS}, - {"h.d.t.", DAYZONE, 10 HRS}, - - {"gmt", ZONE, 0 HRS}, - {"g.m.t.", ZONE, 0 HRS}, - {"bst", DAYZONE, 0 HRS}, /* British Summer Time */ - {"b.s.t.", DAYZONE, 0 HRS}, - {"eet", ZONE, 0 HRS}, /* European Eastern Time */ - {"e.e.t.", ZONE, 0 HRS}, - {"eest", DAYZONE, 0 HRS}, /* European Eastern Summer Time */ - {"e.e.s.t.", DAYZONE, 0 HRS}, - {"met", ZONE, -1 HRS}, /* Middle European Time */ - {"m.e.t.", ZONE, -1 HRS}, - {"mest", DAYZONE, -1 HRS}, /* Middle European Summer Time */ - {"m.e.s.t.", DAYZONE, -1 HRS}, - {"wet", ZONE, -2 HRS }, /* Western European Time */ - {"w.e.t.", ZONE, -2 HRS }, - {"west", DAYZONE, -2 HRS}, /* Western European Summer Time */ - {"w.e.s.t.", DAYZONE, -2 HRS}, - - {"jst", ZONE, -9 HRS}, /* Japan Standard Time */ - {"j.s.t.", ZONE, -9 HRS}, /* Japan Standard Time */ - /* No daylight savings time */ - - {"aest", ZONE, -10 HRS}, /* Australian Eastern Time */ - {"a.e.s.t.", ZONE, -10 HRS}, - {"aesst", DAYZONE, -10 HRS}, /* Australian Eastern Summer Time */ - {"a.e.s.s.t.", DAYZONE, -10 HRS}, - {"acst", ZONE, -(9 HRS + HALFHR)}, /* Australian Central Time */ - {"a.c.s.t.", ZONE, -(9 HRS + HALFHR)}, - {"acsst", DAYZONE, -(9 HRS + HALFHR)}, /* Australian Central Summer */ - {"a.c.s.s.t.", DAYZONE, -(9 HRS + HALFHR)}, - {"awst", ZONE, -8 HRS}, /* Australian Western Time */ - {"a.w.s.t.", ZONE, -8 HRS}, /* (no daylight time there, I'm told */ - {0, 0, 0}}; - -struct table unittb[] = { - {"year", MUNIT, 12}, - {"month", MUNIT, 1}, - {"fortnight", UNIT, 14*24*60}, - {"week", UNIT, 7*24*60}, - {"day", UNIT, 1*24*60}, - {"hour", UNIT, 60}, - {"minute", UNIT, 1}, - {"min", UNIT, 1}, - {"second", SUNIT, 1}, - {"sec", SUNIT, 1}, - {0, 0, 0}}; - -struct table othertb[] = { - {"tomorrow", UNIT, 1*24*60}, - {"yesterday", UNIT, -1*24*60}, - {"today", UNIT, 0}, - {"now", UNIT, 0}, - {"last", NUMBER, -1}, - {"this", UNIT, 0}, - {"next", NUMBER, 2}, - {"first", NUMBER, 1}, - /* {"second", NUMBER, 2}, */ - {"third", NUMBER, 3}, - {"fourth", NUMBER, 4}, - {"fifth", NUMBER, 5}, - {"sixth", NUMBER, 6}, - {"seventh", NUMBER, 7}, - {"eigth", NUMBER, 8}, - {"ninth", NUMBER, 9}, - {"tenth", NUMBER, 10}, - {"eleventh", NUMBER, 11}, - {"twelfth", NUMBER, 12}, - {"ago", AGO, 1}, - {0, 0, 0}}; - -struct table milzone[] = { - {"a", ZONE, 1 HRS}, - {"b", ZONE, 2 HRS}, - {"c", ZONE, 3 HRS}, - {"d", ZONE, 4 HRS}, - {"e", ZONE, 5 HRS}, - {"f", ZONE, 6 HRS}, - {"g", ZONE, 7 HRS}, - {"h", ZONE, 8 HRS}, - {"i", ZONE, 9 HRS}, - {"k", ZONE, 10 HRS}, - {"l", ZONE, 11 HRS}, - {"m", ZONE, 12 HRS}, - {"n", ZONE, -1 HRS}, - {"o", ZONE, -2 HRS}, - {"p", ZONE, -3 HRS}, - {"q", ZONE, -4 HRS}, - {"r", ZONE, -5 HRS}, - {"s", ZONE, -6 HRS}, - {"t", ZONE, -7 HRS}, - {"u", ZONE, -8 HRS}, - {"v", ZONE, -9 HRS}, - {"w", ZONE, -10 HRS}, - {"x", ZONE, -11 HRS}, - {"y", ZONE, -12 HRS}, - {"z", ZONE, 0 HRS}, - {0, 0, 0}}; - -lookup(id) char *id; -{ -#define gotit (yylval=i->value, i->type) -#define getid for(j=idvar, k=id; *j++ = *k++; ) - - char idvar[20]; - register char *j, *k; - register struct table *i; - int abbrev; - - getid; - if (strlen(idvar) == 3) abbrev = 1; - else if (strlen(idvar) == 4 && idvar[3] == '.') { - abbrev = 1; - idvar[3] = '\0'; - } - else abbrev = 0; - - if (islower(*idvar)) *idvar = toupper(*idvar); - - for (i = mdtab; i->name; i++) { - k = idvar; - for (j = i->name; *j++ == *k++;) { - if (abbrev && j==i->name+3) return gotit; - if (j[-1] == 0) return gotit; - } - } - - getid; - for (i = mztab; i->name; i++) - if (strcmp(i->name, idvar) == 0) return gotit; - - for (j = idvar; *j; j++) - if (isupper(*j)) *j = tolower(*j); - for (i=mztab; i->name; i++) - if (strcmp(i->name, idvar) == 0) return gotit; - - getid; - for (i=unittb; i->name; i++) - if (strcmp(i->name, idvar) == 0) return gotit; - - if (idvar[strlen(idvar)-1] == 's') - idvar[strlen(idvar)-1] = '\0'; - for (i=unittb; i->name; i++) - if (strcmp(i->name, idvar) == 0) return gotit; - - getid; - for (i = othertb; i->name; i++) - if (strcmp(i->name, idvar) == 0) return gotit; - - getid; - if (strlen(idvar) == 1 && isalpha(*idvar)) { - if (isupper(*idvar)) *idvar = tolower(*idvar); - for (i = milzone; i->name; i++) - if (strcmp(i->name, idvar) == 0) return gotit; - } - - return(ID); -} - -time_t getdate(p, now) char *p; struct timeb *now; -{ -#define mcheck(f) if (f>1) err++ - time_t monthadd(); - int err; - struct tm *lt; - struct timeb ftz; - - time_t sdate, tod; - - lptr = p; - if (now == ((struct timeb *) NULL)) { - now = &ftz; - ftime(&ftz); - } - lt = localtime(&now->time); - year = lt->tm_year; - month = lt->tm_mon+1; - day = lt->tm_mday; - relsec = 0; relmonth = 0; - timeflag=zoneflag=dateflag=dayflag=relflag=0; - ourzone = now->timezone; - daylight = MAYBE; - hh = mm = ss = 0; - merid = 24; - - if (err = yyparse()) return (-1); - - mcheck(timeflag); - mcheck(zoneflag); - mcheck(dateflag); - mcheck(dayflag); - - if (err) return (-1); - if (dateflag || timeflag || dayflag) { - sdate = dateconv(month,day,year,hh,mm,ss,merid,ourzone,daylight); - if (sdate < 0) return -1; - } - else { - sdate = now->time; - if (relflag == 0) - sdate -= (lt->tm_sec + lt->tm_min*60 + - lt->tm_hour*(60L*60L)); - } - - sdate += relsec; - sdate += monthadd(sdate, relmonth); - - if (dayflag && !dateflag) { - tod = dayconv(dayord, dayreq, sdate); - sdate += tod; - } - - return sdate; -} - -yyerror(s) char *s; -{} *-*-END-of-src/getdate.y-*-* echo x - src/funcs.c 1>&2 sed 's/.//' >src/funcs.c <<'*-*-END-of-src/funcs.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. - * - * funcs - functions used by many programs - */ - -#ifdef SCCSID -static char *SccsId = "@(#)funcs.c 2.33 10/23/86"; -#endif /* SCCSID */ - -/*LINTLIBRARY*/ - -#include "params.h" -#include <errno.h> -#if defined(USG) || defined(BSD4_2) || defined(BSD4_1C) -#include <fcntl.h> -#endif /* !v7 */ - -extern char *Progname; - -/* - * 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 = rc || ptrncmp(s, n); - else - rc = rc && !ptrncmp(s+1, n); - while (*s++ != NGDELIM && *s != '\0') - ; - } - while (*n++ != NGDELIM && *n != '\0') - ; - } - 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 && *ng1 != '\0') { - if (ng1[0]=='a' && ng1[1]=='l' && ng1[2]=='l') { - ng1 += 3; - while (*ng2 != NGDELIM && *ng2 != '.' && *ng2 != '\0') - if (ptrncmp(ng1, ng2++)) - return(TRUE); - return ptrncmp(ng1, ng2); - } else if (*ng1++ != *ng2++) - return FALSE; - } - return *ng2 == '.' || *ng2 == NGDELIM || *ng2 == '\0'; -} - -/* - * Exec the shell. - * This version resets uid, gid, and umask. - * Called with fsubr(ushell, s, NULL) - */ -/* ARGSUSED */ -ushell(s, dummy) -char *s, *dummy; -{ - (void) umask(savmask); - (void) setgid(gid); - (void) setuid(uid); - xshell(s); -} - -/* - * Exec the shell. - */ - -#ifdef lint -char **environ; -#else /* !lint */ -extern char **environ; -#endif /* !lint */ - -xshell(s) -char *s; -{ - char *env[100], **envp; - char a[BUFLEN + 2]; - extern char filename[]; - /* set $A */ - (void) sprintf(a, "A=%s", filename); - env[0] = a; - for (envp = env + 1 ; *environ != NULL && envp < env + 98 ; environ++) - if ((*environ)[0] != 'A' || (*environ)[1] != '=') - *envp++ = *environ; - *envp = NULL; - - execle(SHELL, SHELL, "-c", s, (char *)0, env); - xerror("No shell!"); -} - -/* - * Fork and call a subroutine with two args. - * Return pid without waiting. - */ -fsubr(f, s1, s2) -int (*f)(); -char *s1, *s2; -{ - register int pid; - - /* this may NOT be a vfork */ - while ((pid = fork()) == -1) - sleep((unsigned)1); - if (pid == 0) { - (*f)(s1, s2); - exit(0); - } - return pid; -} - -/* - * Wait on a child process. - */ -fwait(pid) -register int pid; -{ - register int w; - int status; - int (*onhup)(), (*onint)(); - - onint = signal(SIGINT, SIG_IGN); - onhup = signal(SIGHUP, SIG_IGN); - while ((w = wait(&status)) != pid && w != -1) - ; - if (w == -1) - status = -1; - (void) signal(SIGINT, onint); - (void) signal(SIGHUP, onhup); - return status; -} - -/* - * 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; -} - -/* - * Local open routine. - */ -FILE * -xfopen(name, fmode) -register char *name, *fmode; -{ - register FILE *fp; - char *fname; - extern int errno; - - if ((fp = fopen(name, fmode)) == NULL) { -#ifdef IHCC - /* - * IHCC users only see the "filename" that was in trouble, - * not the whole path. (for security!) - */ - fname = rindex(name, '/') + 1; -#else - fname = name; -#endif - xerror("Cannot open %s (%s): %s", fname, fmode, errmsg(errno)); - } - /* kludge for setuid not being honored for root */ - if ((uid == 0) && (duid != 0) && ((*fmode == 'a') || (*fmode == 'w'))) - (void) chown(name, duid, dgid); - return fp; -} - -char * -errmsg(code) -int code; -{ - extern int sys_nerr; - extern char *sys_errlist[]; - static char ebuf[6+5+1]; - - if (code > sys_nerr) { - (void) sprintf(ebuf, "Error %d", code); - return ebuf; - } else - return sys_errlist[code]; -} - -prefix(full, pref) -register char *full, *pref; -{ - register char fc, pc; - - while ((pc = *pref++) != '\0') { - fc = *full++; - if (isupper(fc)) - fc = tolower(fc); - if (isupper(pc)) - pc = tolower(pc); - if (fc != pc) - return FALSE; - } - return TRUE; -} - -char * -dirname(ngname) -char *ngname; -{ - static char rbuf[BUFLEN]; - register char *p; - - (void) sprintf(rbuf, "%s/%s", SPOOL, ngname); - - for (p=rbuf+strlen(SPOOL); *p; p++) - if (*p == '.') - *p = '/'; - return rbuf; -} - -/* - * Return TRUE iff ngname is a valid newsgroup name - */ -validng(ngname) -char *ngname; -{ - register FILE *fp; - register char *p, *q; - char abuf[BUFLEN]; - - fp = xfopen(ACTIVE, "r"); - while(fgets(abuf, BUFLEN, fp) != NULL) { - p = abuf; - q = ngname; - while (*p++ == *q++) - ; - if (*--q == '\0' && *--p == ' ') { - (void) fclose(fp); - return TRUE; - } - } - (void) fclose(fp); - return FALSE; -} - -/* VARARGS1 */ -xerror(message, arg1, arg2, arg3) -char *message; -long arg1, arg2, arg3; -{ - char buffer[LBUFLEN]; - - fflush(stdout); - (void) sprintf(buffer, message, arg1, arg2, arg3); - logerr(buffer); - xxit(1); -} - -/* VARARGS1 */ -log(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9) -char *fmt; -long a1, a2, a3, a4, a5, a6, a7, a8, a9; -{ - _dolog(0, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9); -} - -/* VARARGS1 */ -logerr(fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9) -char *fmt; -long a1, a2, a3, a4, a5, a6, a7, a8, a9; -{ - _dolog(1, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9); -} - -char *lfsuffix[] = { - "log", - "errlog", - 0 -}; - -/* - * Log the given message, with printf strings and parameters allowed, - * on the log file, if it can be written. The date and an attempt at - * figuring out the remote system name are also logged. - */ -/* VARARGS1 */ -_dolog(which, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9) -char *fmt; -long a1, a2, a3, a4, a5, a6, a7, a8, a9; -{ - FILE *logfile; - register char *p, *logtime; - int i; - char logfname[BUFLEN]; /* the log file */ - char rmtsys[BUFLEN]; - char msg[LBUFLEN]; - time_t t; - - (void) strcpy(rmtsys, header.path); - p = index(rmtsys, '!'); - if (p == NULL) - p = index(rmtsys, ':'); - if (p) - *p = 0; - else { - p = rindex(rmtsys, '@'); - if (p) - (void) strcpy(rmtsys, p+1); - else - (void) strcpy(rmtsys, "local"); - } - - (void) time(&t); - logtime = ctime(&t); - logtime[16] = 0; - logtime += 4; - - - (void) sprintf(msg, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9); - - if (which) - fprintf(stderr,"%s: %s\n", Progname, msg); - - for (i=0; i<=which;i++) { - (void) sprintf(logfname, "%s/%s", LIB, lfsuffix[i]); - - if (access(logfname, 0) == 0 && (logfile = fopen(logfname, "a")) != NULL) { -#if defined(USG) || defined(BSD4_2) || defined(BSD4_1C) - int flags; - flags = fcntl(fileno(logfile), F_GETFL, 0); - (void) fcntl(fileno(logfile), F_SETFL, flags|O_APPEND); -#else /* v7 */ - (void) lseek(fileno(logfile), 0L, 2); -#endif /* v7 */ - if (i) - fprintf(logfile, "%s\t%s\t%s: %s\n", logtime, - header.ident[0] ? header.ident : username, Progname, msg); - else - fprintf(logfile, "%s\t%s\t%s\n", logtime, - rmtsys, msg); - (void) fclose(logfile); - } - } -} -#ifdef VMS - -/* - * vmslink allows simulation of file linking under VMS. - */ -vmslink(infile,outfile) -char *infile, *outfile; -{ - FILE *fp; - - if (access(outfile,0) == 0) { - errno = EEXIST; - return -1; - } - - fp = fopen(outfile, "w"); - if (fp == NULL) { - errno = EACCES; - return -1; - } - - (void) fprintf(fp, "%s", infile); - (void) fclose(fp); - - return 0; -} - -/* - * vmsdelete deletes all revisions of a file. It attempts to - * appear as unlink(2) under conventional Unix in other respects. - */ -vmsdelete(file) -char *file; -{ - int i; - - i = unlink(file); - if (i != 0) - return i; - - i = errno; - while (unlink(file) == 0) - ; - errno = i; - - return 0; -} - -/* - * Convert a Unix file to a VMS fixed record format file by - * executing the 'unixtovms' command. - */ -unixtovms(file) -char *file; -{ - char buf[BUFLEN]; - sprintf(buf, "exec /etc/unixtovms %s", file); - return system(buf); -} - -/* - * Convert a VMS fixed record format file to a Unix file by - * executing the 'vmstounix' command. - */ -vmstounix(file) -char *file; -{ - char buf[BUFLEN]; - sprintf(buf,"exec /etc/vmstounix %s", file); - return system(buf); -} -#endif /* VMS */ - -#if !defined(BSD4_2) && !defined(BSD4_1C) -/* - * make a directory. Also make sure that the directory is owned - * by the right userid - */ -mkdir(path, perm) -char *path; -int perm; -{ - int pid, status; - - if (pid=vfork()) { - status = fwait(pid); -#if defined(USG) && !defined(CHEAP) - if (pid=vfork()) - (void) fwait(pid); - else { - setgid(gid); - setuid(uid); - if (chown(path, duid, dgid) == 0) - (void) chmod(path, perm&(~N_UMASK)); - _exit(0); - } -#endif /* USG && !CHEAP */ - } else { - (void) setgid(dgid); - if (setuid(duid) < 0) - (void) umask(0); - else - (void) umask(perm&N_UMASK); - (void) execlp("mkdir", "mkdir", path, (char *)NULL); - perror(path); - _exit(1); - } - return status; -} -#endif /* !BSD4_2 && ! BSD4_1C */ -#ifndef USG -char * -strpbrk(str, chars) -register char *str, *chars; -{ - register char *cp; - - do { - cp = chars - 1; - while (*++cp) { - if (*str == *cp) - return str; - } - } while (*str++); - return NULL; -} -#endif /* !USG */ - -#ifdef FASCIST -/* - * This routine checks to see if the posting user is allowed to - * post to the given newsgroup. If the username is not in the file - * $LIBDIR/authorized then the default in the symbol FASCIST is used. - * - * Format of the call: - * fascist(user, newgroups) - * - * Returns: - * FALSE, if authorized - * TRUE, if not - * - * Format of the file "authorized" is: - * user:allowed groups - * - * Example: - * root:net.all,mod.all - * naughty_person:junk,net.politics - * operator:!net.all,general,test,mod.unix - * - * An open environment could have FASCIST set to "all" - * and then individual entries could be made in the authorized file - * to prevent certain individuals from posting to such a wide - * area. - * - * Note that a distribution of "all" does NOT mean to allow postings - * only to local groups -- "all" includes "all.all". - * Use "all,!all.all" to get this behavior - * - * Eugene Spafford spaf@gatech May 22, 1985 - */ - -fascist(user, newsgroups) -register char *user, *newsgroups; -{ - FILE *facfd; - char facuser[BUFLEN], facgroups[BUFLEN], factemp[BUFLEN]; - register char *facptr; - - /* First, open the necessary file...$LIBDIR/authorized and see if there - * is an entry for this user - */ - - (void) strncpy(facgroups, FASCIST, BUFLEN); - sprintf(factemp, "%s/%s", LIBDIR, "authorized"); - facfd = fopen(factemp, "r"); - - if (facfd != NULL) { /* If no such file, we go with the global default */ - while (fscanf(facfd, "%[^:]:%s\n", facuser, factemp) != EOF) - if (strncmp(facuser, user, BUFLEN) == 0) { - (void) strcat(facgroups, ","); - (void) strcat(facgroups, factemp); - break; - } - fclose (facfd); - } -#ifdef DEBUG - fprintf(stderr, "facgroups = %s\n", facgroups); - fprintf(stderr, "newsgroups = %s\n", newsgroups); -#endif DEBUG - - /* We step through the newsgroups being posted to and check each against - * the restriction list. *ALL* posted groups must match the restriction - * list or we don't allow the posting. - */ - - while (*newsgroups != '\0') { - facptr = factemp; - while (*newsgroups != '\0' && *newsgroups != NGDELIM) - *facptr++ = *newsgroups++; - *facptr = '\0'; - if (*newsgroups == NGDELIM) - newsgroups++; - -#ifdef DEBUG - fprintf(stderr, "Checking newsgroup '%s'\n", factemp); -#endif - - if (ngmatch(factemp, facgroups) == FALSE) - return TRUE; - } - - /* must be okay -- return */ -#ifdef DEBUG - fprintf (stderr, "Newsgroups approved for this poster.\n"); -#endif DEBUG - return FALSE; -} -#endif FASCIST *-*-END-of-src/funcs.c-*-* echo x - src/checknews.c 1>&2 sed 's/.//' >src/checknews.c <<'*-*-END-of-src/checknews.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. - * - * checknews - news checking program - */ - -#ifdef SCCSID -static char *SccsId = "@(#)checknews.c 2.25 5/27/86"; -#endif /* SCCSID */ - -char *Progname = "checknews"; /* used by xerror */ - -#include "params.h" - -char bfr[LBUFLEN]; /* general-use scratch area */ -char optbuf[BUFLEN]; /* NEWSOPTS buffer */ -int line = -1, y, e, n, q; -int verbose; /* For debugging. */ -int nflag; /* for spec. newsgroup */ -char narggrp[BUFLEN]; /* spec newsgroup */ -FILE *rcfp, *actfp; -char newsrc[BUFLEN],*rcline[LINES],rcbuf[LBUFLEN],*argvrc[LINES]; -struct hbuf header; -char coptbuf[BUFLEN],datebuf[BUFLEN]; -int mode = 1; -#ifndef SHELL -char *SHELL; -#endif - -main(argc, argv) -int argc; -register char **argv; -{ - register char *ptr; /* pointer to rest of buffer */ - char *user, *home; - struct passwd *pw; - struct group *gp; - int sflag = 0, optflag = FALSE, space = FALSE; - int i; - - y = 0; - n = 0; - e = 0; - q = 0; - nflag = 0; - pathinit(); - if (--argc > 0) { - for (argv++; **argv; ++*argv) { - switch(**argv) { - case 'y': - y++; - break; - case 'q': - q++; - break; - case 'v': - verbose++; - break; - case 'n': - n++; - break; - case 'N': - nflag++; - strcpy(narggrp,argv[1]); - strcat(narggrp,","); - break; - case 'e': - case 'f': - e++; - break; - } - } - } - if (!n && !e && !y && !q) - y++; - if (nflag) - argv++; - -#ifndef V6 - if ((user = getenv("USER")) == NULL) - user = getenv("LOGNAME"); - if ((home = getenv("HOME")) == NULL) - home = getenv("LOGDIR"); - if (user == NULL || home == NULL) - getuser(); - else { - username = AllocCpy(user); - userhome = AllocCpy(home); - } - if (ptr = getenv("NEWSOPTS")) - strcpy(rcbuf, ptr); - else - *rcbuf = '\0'; - if (*rcbuf) { - strcat(rcbuf, " \1"); - ptr = rcbuf; - while (*++ptr) - if (isspace(*ptr)) - *ptr = '\0'; - for (ptr = rcbuf;; ptr++) { - if (!*ptr) - continue; - if (*ptr == '\1') - break; - if (++line > LINES) - xerror("Too many options."); - if ((rcline[line] = malloc(strlen(ptr) + 1)) == NULL) - xerror("Not enough memory."); - argvrc[line] = rcline[line]; - strcpy(rcline[line], ptr); - while (*ptr) - ptr++; - } - } -#else - getuser(); -#endif - ptr = getenv("NEWSRC"); - if (ptr == NULL) - sprintf(newsrc, "%s/%s", userhome, NEWSRC); - else - strcpy(newsrc, ptr); - if ((rcfp = fopen(newsrc, "r")) != NULL) { - while (fgets(rcbuf, LBUFLEN, rcfp) != NULL) { - if (!(space = isspace(*rcbuf))) - optflag = FALSE; - if (!strncmp(rcbuf, "options ", 8)) - optflag = TRUE; - if (optflag) { - strcat(rcbuf, "\1"); - if (space) - ptr = rcbuf - 1; - else - ptr = &rcbuf[7]; - while (*++ptr) - if (isspace(*ptr)) - *ptr = '\0'; - if (space) - ptr = rcbuf; - else - ptr = &rcbuf[8]; - for (;; ptr++) { - if (!*ptr) - continue; - if (*ptr == '\1') - break; - if (++line > LINES) - xerror("Too many options."); - if ((rcline[line] = malloc(strlen(ptr) + 1)) == NULL) - xerror("Not enough memory."); - argvrc[line] = rcline[line]; - strcpy(rcline[line], ptr); - while (*ptr) - ptr++; - } - } - } - fclose(rcfp); - } - header.nbuf[0] = 0; - if (line != -1) { -#ifdef DEBUG - for (i = 0; i <= line; i++) - fprintf(stderr, "options: %s\n", rcline[i]); -#endif - process(line+2, argvrc); - do { -#ifdef DEBUG - fprintf(stderr, "Freeing %d\n", line); -#endif - free(rcline[line]); - } while (line--); - } - - if (!*header.nbuf) { - strcpy(header.nbuf, DFLTSUB); - ngcat(header.nbuf); - } - strcat(header.nbuf, ADMSUB); - ngcat(header.nbuf); - if (*header.nbuf) - lcase(header.nbuf); - makehimask(header.nbuf, "junk"); - makehimask(header.nbuf, "control"); - makehimask(header.nbuf, "test"); - if (access(newsrc, 0)) { - if (verbose > 1) - printf("No newsrc\n"); - yep(argv); - } - if ((rcfp = fopen(newsrc, "r")) == NULL) - xerror("Cannot open .newsrc file"); - while (fgets(rcbuf, LBUFLEN, rcfp) != NULL) { - if (!nstrip(rcbuf)) - xerror(".newsrc line too long"); - if (++line >= LINES) - xerror("Too many .newsrc lines"); - if ((rcline[line] = malloc(strlen(rcbuf)+1)) == NULL) - xerror("Not enough memory"); - strcpy(rcline[line], rcbuf); - } - if ((actfp = fopen(ACTIVE, "r")) == NULL) - xerror("Cannot open active newsgroups file"); - -#ifdef DEBUG - fprintf(stderr, "header.nbuf = %s\n", header.nbuf); -#endif - nchk(argv); - exit(0); -} - -nchk(argv) -char **argv; -{ - register int i; - register char *ptr; - long l; - long narts; - char saveptr; - int isnews = 0; - char aline[BUFLEN]; - -#ifdef DEBUG - fprintf(stderr, "nchk()\n"); -#endif - while (fgets(aline, sizeof aline, actfp) != NULL) { - sscanf(aline, "%s %ld", bfr, &narts); -#ifdef DEBUG - fprintf(stderr, "bfr = '%s'\n", bfr); -#endif - ngcat(bfr); - if (!ngmatch(bfr, nflag ? narggrp : header.nbuf)) - continue; - ngdel(bfr); - i = findrcline(bfr); - if (i < 0) { - if (verbose>1) - printf("No newsrc line for newsgroup %s\n", bfr); - strcpy(rcbuf, " 0"); - } else - strcpy(rcbuf, rcline[i]); - ptr = rcbuf; - - if (index(rcbuf, '!') != NULL) - continue; - if (index(rcbuf, ',') != NULL) { - if (verbose > 1) - printf("Comma in %s newsrc line\n", bfr); - else { - isnews++; - continue; - } - } - while (*ptr) - ptr++; - while (!isdigit(*--ptr) && *ptr != ':' && ptr >= rcbuf) - ; - if (*ptr == ':') - continue; - if (ptr < rcbuf) { - if (verbose > 1) - printf("Ran off beginning of %s newsrc line.\n", bfr); - yep(argv); - } - while (isdigit(*--ptr)) - ; - sscanf(++ptr, "%ld", &l); - if (narts > l) { - if (verbose) { - printf("News: %s ...\n", bfr); - if (verbose < 2) - y = 0; - } - yep(argv); - } -contin:; - } - if (isnews) - yep(argv); - if (n) - printf("No news is good news.\n"); -} - -yep(argv) -char **argv; -{ - if (y) { - if (verbose) - printf("There is probably news"); - else - printf("There is news"); - if (nflag) { - narggrp[strlen(narggrp)-1] = '.'; - printf(" in %s\n",narggrp); - } - else - printf(".\n"); - } - if (e) { -#ifdef V6 - execv("/usr/bin/readnews", argv); -#else - execvp("readnews", argv); -#endif - perror("Cannot exec readnews."); - } - if (q) - exit(1); - else - exit(0); -} - -xerror(message, arg1, arg2) -char *message; -int arg1, arg2; -{ - char buffer[128]; - - sprintf(buffer, message, arg1, arg2); - fprintf(stderr, "checknews: %s.\n", buffer); - exit(1); -} - -/* - * 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); -} - -/* - * Get user name and home directory. - */ -getuser() -{ - static int flag = TRUE; - register struct passwd *p; - - if (flag) { - if ((p = getpwuid(getuid())) == NULL) - xerror("Cannot get user's name"); - if (username == NULL || *username == '\0') - username = AllocCpy(p->pw_name); - userhome = AllocCpy(p->pw_dir); - flag = FALSE; - } -} - -/* - * 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'; - } -} - -lcase(s) -register char *s; -{ - register char *ptr; - - for (ptr = s; *ptr; ptr++) - if (isupper(*ptr)) - *ptr = tolower(*ptr); -} - -/* - * 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) -char *name; -{ - register char *p, *ptr; - register int cur; - register int i; - register int top; - static int prev = 0; - - top = line; i = prev; -loop: - for (; i <= top; i++) { - for (p = name, ptr = rcline[i]; (cur = *p++); ) { - if (cur != *ptr++) - goto contin2; - } - if (*ptr != ':' && *ptr != '!') - continue; - prev = i; - return i; -contin2: - ; - } - if (i > line && line > prev-1) { - i = 0; - top = prev-1; - goto loop; - } - return -1; -} - -/* - * Forbid newsgroup ng, unless he asked for it in nbuf. - */ -makehimask(nbuf, ng) -char *nbuf, *ng; -{ - if (!findex(nbuf, ng)) { - ngcat(nbuf); - strcat(nbuf, "!"); - strcat(nbuf, ng); - ngcat(nbuf); - } -} - -/* - * Return true if the string searchfor is in string, but not if preceded by !. - */ -findex(string, searchfor) -char *string, *searchfor; -{ - register char first; - register char *p; - - first = *searchfor; - for (p=index(string, first); p; p = index(p+1, first)) { - if (p>string && p[-1] != '!' && strncmp(p, searchfor, strlen(searchfor)) == 0) - return TRUE; - } - return FALSE; -} - -xxit(i) -{ - exit(i); -} *-*-END-of-src/checknews.c-*-* echo x - src/recnews.c 1>&2 sed 's/.//' >src/recnews.c <<'*-*-END-of-src/recnews.c-*-*' -/* - * recnews [to newsgroup] [from user] - * - * Process a news article which has been mailed to some group like msgs. - * Such articles are in normal mail format and have never seen the insides - * of netnews. If the "to newsgroup" is included, the article is posted - * to this newsgroup instead of trying to intuit it from the headers. - * If the "from user" is included, the return address is forged to look - * like that user instead of what getuid or a from line says. - * - * It is recommended that you always include the to newsgroup, since the - * intuition code is flakey and out of date. The from user is probably - * appropriate for arpanet mailing lists being funnelled at ucbvax but - * not otherwise. Sample lines in /usr/lib/aliases (if you run delivermail): - * worldnews: "|/usr/lib/news/recnews net.general" - * Allows you to mail to worldnews rather than using inews. - * Intended for humans to mail to. - * post-unix-wizards: "|/usr/lib/news/recnews fa.unix-wizards unix-wizards" - * Causes mail to post-unix-wizards to be fed into fa.unix-wizards - * and the return address forged as unix-wizards on the local - * machine. post-unix-wizards (on the local machine) should - * be part of the master mailing list somewhere (on a different - * machine.) - * - * Recnews is primarily useful in remote places on the usenet which collect - * mail from mailing lists and funnel them into the network. It is also - * useful if you like to send mail to some user instead of invoking - * inews -t .. -n .. when you want to submit an article. (Many mailers give - * you nice facilities like editing the message.) It is not, however, - * essential to use recnews to be able to join usenet. - * - * WARNING: recnews disables the "recording" check - it has to because - * by the time inews is run, it's in the background and too late to - * ask permission. If you depend heavily on recordings you probably - * should not allow recnews (and thus the mail interface) to be used. -* - * 1) We leave the from line alone. Just escape the double quotes, but let the - * mailer do the rest. - * 2) We give precedence to "From:" over "From " or ">From " in determining - * who the article is really from. - * Modifications by rad@tek - */ - -#ifdef SCCSID -static char *SccsId = "@(#)recnews.c 2.13 10/23/86"; -#endif /* SCCSID */ - -#include "defs.h" - -#include <stdio.h> -#include <ctype.h> - -/* - * Note: we assume there are 2 kinds of hosts using recnews: - * Those that have delivermail (and hence this program will never - * have to deal with more than one message at a time) and those on the arpanet - * that do not (and hence all messages end with a sentinel). It is - * supposed that regular v7 type systems without delivermail or some - * other automatic forwarding device will just use rnews. We do - * not attempt to tell where a message ends on all systems due to the - * different conventions in effect. (This COULD be fixed, I suppose.) - */ - -/* - * Kinds of lines in a message. - */ -#define FROM 001 /* From line */ -#define SUBJ 002 /* Subject */ -#define TO 003 /* To (newgroup based on this) */ -#define BLANK 004 /* blank line */ -#define EOM 005 /* End of message (4 ctrl A's) */ -#define HEADER 006 /* any unrecognized header */ -#define TEXT 007 /* anything unrecognized */ -#define INCLUSIVE 010 /* newsgroup is already in header */ - -/* - * Possible states program can be in. - */ -#define SKIPPING 0100 /* In header of message */ -#define READING 0200 /* In body of message */ - -#define BFSZ 250 - -#define EOT '\004' - -char from[BFSZ]; /* mailing address for replies */ -char sender[BFSZ]; /* mailing address of author, if different */ -char to[BFSZ]; /* Destination of mail (msgs, etc) */ -char subject[BFSZ]; /* subject of message */ -char newsgroup[BFSZ]; /* newsgroups of message */ -int fromset; /* from passed on command line */ -char cmdbuf[BFSZ]; /* command to popen */ - -extern char *strcat(), *strcpy(); -extern FILE *popen(); -char *any(); - -main(argc, argv) -int argc; -char **argv; -{ - char buf[BFSZ], inews[BFSZ]; - register char *p, *q; - register FILE *pipe = NULL; - register int state; - - /* build inews command */ -#ifdef IHCC - sprintf(inews, "%s/%s/%s", logdir(HOME), LIBDIR, "inews"); -#else - sprintf(inews, "%s/%s", LIBDIR, "inews"); -#endif - - if (argc > 1) - strcpy(to, argv[1]); - if (argc > 2) - strcpy(from, argv[2]); - - /* - * Flag that we know who message is from to avoid trying to - * decipher the From line. - */ - if (argc > 2 && (argv[2][0] != '\0')) - fromset++; - -#ifdef debug - printf("argv[0] is <%s>, argv[1] is <%s>, argv[2] is <%s>\n", - argv[0], argv[1], argv[2]); -#endif - state = SKIPPING; - while (fgets(buf, BFSZ, stdin) != NULL) { - if (state == READING) { - fputs(buf,pipe); - continue; - } - switch (type(buf)) { - - case FROM: - frombreak(buf, from); - break; - - case SUBJ: - p = any(buf, " \t"); - if (p == NULL) - p = buf + 8; - q = subject; - while (*++p) { - if (*p == '"') - *q++ = '\\'; - *q++ = *p; - } - q[-1] = '\0'; - break; - - case TO: - if (to[0]) - break; /* already have one */ - p = any(buf, " \t"); - if (p == NULL) - p = buf + 3; - q = to; - while (*++p) { - if (*p == '"') - *q++ = '\\'; - *q++ = *p; - } - q[-1] = '\0'; - break; - - case INCLUSIVE: - sprintf(cmdbuf,"exec %s -p", inews); - pipe = popen(cmdbuf,"w"); - if (pipe == NULL){ - perror("recnews: open failed"); - exit(1); - } - state = READING; - fputs(buf,pipe); - break; - - /* - * Kludge to compensate for messages without real headers - */ - case HEADER: - break; - - case BLANK: - state = READING; - strcpy(newsgroup, to); - sprintf(cmdbuf, "exec %s -t \"%s\" -n \"%s\" -f \"%s\"", - inews, *subject ? subject : "(none)", - newsgroup, from); -#ifdef debug - pipe = stdout; - printf("BLANK: %s\n", cmdbuf); -#else - pipe = popen(cmdbuf, "w"); - if (pipe == NULL) { - perror("recnews: popen failed"); - exit(1); - } -#endif - if (sender[0]) { - fputs(sender, pipe); - putc('\n', pipe); - } - break; - - case TEXT: - strcpy(newsgroup, to); - state = READING; - if (subject[0] == 0) { - strcpy(subject, buf); - if (subject[strlen(subject)-1] == '\n') - subject[strlen(subject)-1] = '\0'; - } - sprintf(cmdbuf, "exec \"%s\" -t \"%s\" -n \"%s\" -f \"%s\"", - inews, subject, newsgroup, from); -#ifdef debug - pipe = stdout; - printf("TEXT: %s\n", cmdbuf); -#else - pipe = popen(cmdbuf, "w"); - if (pipe == NULL) { - perror("pipe failed"); - exit(1); - } -#endif - if (sender[0]){ - fputs(sender, pipe); - putc('\n',pipe); - } - break; - } - } - exit(0); -} - -type(p) -register char *p; -{ - char *firstbl; - static char lasthdr = 1; /* prev line was a header */ - - if ((*p == ' ' || *p == '\t') && lasthdr) - return HEADER; /* continuation line */ - firstbl = any(p, " \t"); - while (*p == ' ' || *p == '?' || *p == '\t') - ++p; - - if (*p == '\n' || *p == 0) - return BLANK; - if (strncmp(p, ">From", 5) == 0 || strncmp(p, "From", 4) == 0) - return FROM; - if (strncmp(p, "Subj", 4)==0 || strncmp(p, "Re:", 3)==0 || - strncmp(p, "re:", 3)==0) - return SUBJ; - if (strncmp(p, "To", 2)==0) - return TO; - if (strncmp(p, "\1\1\1\1", 4)==0) - return EOM; - if (firstbl && firstbl[-1] == ':' && isalpha(*p)) - return HEADER; - lasthdr = 0; - return TEXT; -} - -/* - * Figure out who a message is from. - */ -frombreak(buf, fbuf) -register char *buf, *fbuf; -{ - register char *p, *q; - - if (fbuf[0] && fromset) { /* we already know who it's from */ - if (sender[0] == 0 || buf[4] == ':') { -#ifdef debug - printf("sender set to: %s", buf); -#endif - strcpy(sender, buf); - } - return; - } - /* - * Leave fancy Froms alone - this parsing is done by mail - * Just quote the double quotes to prevent interpetation - * by the shell. - * rad@tek - */ - p = any(buf, " \t"); - if (p==NULL) - p = buf + 4; - q = fbuf; - while (*++p) { - if (*p == '"') - *q++ = '\\'; - *q++ = *p; - } - q[-1] = '\0'; - if ((p=(char *)index(fbuf,'\n')) != NULL) - *p = '\0'; - if (buf[4] == ':') - fromset++; -} - -/* - * Return the ptr in sp at which a character in sq appears; - * NULL if not found - * - */ -char * -any(sp, sq) -char *sp, *sq; -{ - register c1, c2; - register char *q; - - while (c1 = *sp++) { - q = sq; - while (c2 = *q++) - if (c1 == c2) - return(--sp); - } - return(NULL); -} *-*-END-of-src/recnews.c-*-* echo x - src/rextern.c 1>&2 sed 's/.//' >src/rextern.c <<'*-*-END-of-src/rextern.c-*-*' -/* - * rextern - external definitions for readnews - */ - -#ifdef SCCSID -static char *SccsId = "@(#)rextern.c 2.15 4/16/85"; -#endif /* SCCSID */ - -/*LINTLIBRARY*/ - -#include "rparams.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 */ - -#ifndef ROOTID -int ROOTID; /* special users id # */ -#endif - -char *outfile = "/tmp/M1XXXXXX"; /* output file for -M and -c */ -char *infile = "/tmp/M2XXXXXX"; /* -T output from Mail */ -int ngrp, line = -1; - -char filename[BUFLEN], coptbuf[BUFLEN], datebuf[BUFLEN]; -char afline[BUFLEN]; -FILE *rcfp, *actfp; -time_t atime; -char newsrc[BUFLEN], groupdir[BUFLEN], *rcline[LINES], rcbuf[LBUFLEN]; -char *bitmap, *argvrc[LINES]; -long bit, obit, last; -int readmode = NEXT; -int news = 0; /* Was there any news to read */ -int actdirect = FORWARD; /* read direction in ACTIVE file */ -int rcreadok = FALSE; /* NEWSRC has been read OK */ -int zapng = FALSE; /* ! out this newsgroup on next updaterc */ -long ngsize; /* max article # in this newsgroup */ -long minartno; /* min article # in this newsgroup */ - -#ifndef SHELL -char *SHELL; -#endif - -#ifndef MAILER -char *MAILER; -#endif - -char *PAGER = ""; *-*-END-of-src/rextern.c-*-* exit