[mod.sources] v07i054: 2.11 News Source, Part05/09

sources-request@mirror.UUCP (11/06/86)

Submitted by: seismo!rick (Rick Adams)
Mod.sources: Volume 7, Issue 54
Archive-name: 2.11news/Part15

# To extract, sh this file
#
#	news 2.11 source part 5 of 9
#
if test ! -d src
then
	mkdir src
fi
echo x - src/expire.c 1>&2
sed 's/.//' >src/expire.c <<'*-*-END-of-src/expire.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.
- *
- * expire - expire daemon runs around and nails all articles that
- *		 have expired.
- */
-
-#ifdef SCCSID
-static char	*SccsId = "@(#)expire.c	2.47	10/23/86";
-#endif /* SCCSID */
-
-#include "params.h"
-#include <errno.h>
-#if defined(BSD4_2) || defined(BSD4_1C)
-# include <sys/dir.h>
-# include <sys/file.h>
-#else
-# include "ndir.h"
-# ifdef LOCKF
-# include <unistd.h>
-# endif /* LOCKF */
-#endif
-
-char *Progname = "expire";	/* used by xerror to identify failing program */
-
-/*	Number of array entries to allocate at a time.	*/
-#define SPACE_INCREMENT	1000
-
-struct expdata {
-	char *e_name;
-	long e_min, e_max;
-	time_t	e_droptime, e_expiretime;
-	char e_ignorexp;
-	char e_doarchive;
-	char e_doexpire;
-};
-
-extern int	errno;
-char	NARTFILE[BUFLEN], OARTFILE[BUFLEN];
-char	PAGFILE[BUFLEN], DIRFILE[BUFLEN];
-char	NACTIVE[BUFLEN], OACTIVE[BUFLEN];
-char	recdate[BUFLEN];
-long	rectime, exptime;
-extern char *OLDNEWS;
-int	verbose = 0;
-int	ignorexp = 0;
-int	doarchive = 0;
-int	nohistory = 0;
-int	dorebuild = 0;
-int	usepost = 0;
-int	frflag = 0;
-int	updateactive = 0;
-char	baduser[BUFLEN];
-extern 	char filename[], nbuf[];
-
-struct timeb Now;
-
-/*
- * This code uses realloc to get more of the multhist array.
- */
-struct multhist {
-	char	*mh_ident;
-	char	*mh_file;
-} *multhist;
-unsigned int mh_size;
-char *calloc();
-char *realloc();
-struct tm *gmtime();
-
-typedef struct {
-	char *dptr;
-	int dsize;
-} datum;
-
-long	expincr;
-long	dropincr;
-long	atol();
-time_t	cgtdate(), time();
-FILE *popen();
-struct passwd *pw;
-struct group *gp;
-char	arpat[LBUFLEN];
-int	arpatlen = 0;
-char	ngpat[LBUFLEN];
-int	ngpatlen = 0;
-char	afline[BUFLEN];
-char	grpsleft[BUFLEN];
-struct hbuf h;
-int	ExpireLock;
-
-main(argc, argv)
-int	argc;
-char	**argv;
-{
-	register char	*p1, *p2, *p3;
-	register time_t newtime, today;
-	register FILE *fp = NULL;
-	FILE	*ohfd, *nhfd;
-	DIR	*ngdirp = NULL;
-	static struct direct *ngdir;
-	char fn[BUFLEN];
-	int i, LockFd;
-#ifndef DBM
-	char *ptr, chr;
-	FILE *subfd[10];
-	char *histfile();
-#endif /* !DBM */
-
-	pathinit();
-	(void) umask(N_UMASK);
-
-	/*
-	 * Try to run as NEWSUSR/NEWSGRP
-	 */
-	if ((pw = getpwnam(NEWSUSR)) == NULL)
-		xerror("Cannot get NEWSUSR pw entry");
-
-	uid = pw->pw_uid;
-	if ((gp = getgrnam(NEWSGRP)) == NULL)
-		xerror("Cannot get NEWSGRP gr entry");
-	gid = gp->gr_gid;
-	(void) setgid(gid);
-	(void) setuid(uid);
-
-	expincr = DFLTEXP;
-	dropincr = HISTEXP;
-	ngpat[0] = ',';
-	arpat[0] = ',';
-	while (argc > 1) {
-		switch (argv[1][1]) {
-		case 'v':
-			if (isdigit(argv[1][2]))
-				verbose = argv[1][2] - '0';
-			else if (argc > 2 && argv[2][0] != '-') {
-
-				argv++;
-				argc--;
-				verbose = atoi(argv[1]);
-			} else
-				verbose = 1;
-			if (verbose < 3)
-				setbuf(stdout, (char *)NULL);
-			break;
-		case 'e':	/* Use this as default expiration time */
-			if (argc > 2 && argv[2][0] != '-') {
-				argv++;
-				argc--;
-				expincr = atol(argv[1]) * DAYS;
-			} else if (isdigit(argv[1][2]))
-				expincr = atol(&argv[1][2]) * DAYS;
-			break;
-		case 'E':	/* Use this as default forget time */
-			if (argc > 2 && argv[2][0] != '-') {
-				argv++;
-				argc--;
-				dropincr = atol(argv[1]) * DAYS;
-			} else if (isdigit(argv[1][2]))
-				dropincr = atol(&argv[1][2]) * DAYS;
-			break;
-		case 'I':	/* Ignore any existing expiration date */
-			ignorexp = 2;
-			break;
-		case 'i':	/* Ignore any existing expiration date */
-			ignorexp = 1;
-			break;
-		case 'n':
-			if (argc > 2) {
-				argv++;
-				argc--;
-				while (argc > 1 && argv[1][0] != '-') {
-					int argvlen;
-					argvlen = strlen(argv[1]);
-					if (ngpatlen + argvlen + 2 > sizeof (ngpat)) {
-						xerror("Too many groups specified for -n\n");
-					}
-					if (ngpat[ngpatlen] == '\0') {
-						ngpat[ngpatlen++] = ',';
-						ngpat[ngpatlen] = '\0';
-					}
-					strcpy(&ngpat[ngpatlen], argv[1]);
-					ngpatlen += argvlen;
-					argv++;
-					argc--;
-				}
-				argv--;
-				argc++;
-			}
-			break;
-		case 'a':	/* archive expired articles */
-			if (access(OLDNEWS,0) < 0){
-				perror(OLDNEWS);
-				xerror("No archiving possible\n");
-			}
-			doarchive++;
-			if (argc > 2) {
-				argv++;
-				argc--;
-				while (argc > 1 && argv[1][0] != '-') {
-					int argvlen;
-					argvlen = strlen(argv[1]);
-					if (arpatlen + argvlen + 2 > sizeof (arpat)) {
-						xerror("Too many groups specified for -a\n");
-					}
-					if (arpat[arpatlen] == '\0') {
-						arpat[arpatlen++] = ',';
-						arpat[arpatlen] = '\0';
-					}
-					strcpy(&arpat[arpatlen], argv[1]);
-					arpatlen += argvlen;
-					argv++;
-					argc--;
-				}
-				argv--;
-				argc++;
-			}
-			break;
-		case 'h':	/* ignore history */
-			nohistory++;
-			break;
-		case 'r':	/* rebuild history file */
-			dorebuild++;
-			nohistory++;
-			break;
-		case 'p':
-			usepost++;
-			break;
-		case 'f':
-			frflag++;
-			if (argc > 2) {
-				strcpy(baduser, argv[2]);
-				argv++;
-				argc--;
-			}
-			break;
-		case 'u':
-			updateactive++;
-			break;
-		default:
-			printf("Usage: expire [ -v [level] ] [-e days ] [-i] [-a] [-r] [-h] [-p] [-u] [-f username] [-n newsgroups]\n");
-			xxit(1);
-		}
-		argc--;
-		argv++;
-	}
-	if (dropincr < expincr) {
-		dropincr = HISTEXP;
-		fprintf(stderr, "History expiration time < article expiration time. Default used.\n");
-	}
-	if (ngpat[0] == ',')
-		(void) strcpy(ngpat, "all,");
-	if (arpat[0] == ',')
-		(void) strcpy(arpat, "all,");
-	(void) ftime(&Now);
-	today = Now.time;
-	if (chdir(SPOOL))
-		xerror("Cannot chdir %s", SPOOL);
-
-	if (verbose) {
-		printf("expire: nohistory %d, rebuild %d, doarchive %d\n",
-			nohistory, dorebuild, doarchive);
-		printf("newsgroups: %s\n",ngpat);
-		if (doarchive)
-			printf("archiving: %s\n",arpat);
-	}
-
-	(void) sprintf(OARTFILE, "%s/%s", LIB, "ohistory");
-	(void) sprintf(NARTFILE, "%s/%s", LIB, "nhistory");
-
-	(void) sprintf(OACTIVE, "%s/%s", LIB, "oactive");
-	(void) sprintf(NACTIVE, "%s/%s", LIB, "nactive");
-
-	if (updateactive)
-		goto doupdateactive;
-
-#ifdef DBM
-	if (!dorebuild) {
-		(void) sprintf(PAGFILE, "%s/%s", LIB, "nhistory.pag");
-		(void) sprintf(DIRFILE, "%s/%s", LIB, "nhistory.dir");
-		(void) close(creat(PAGFILE, 0666));
-		(void) close(creat(DIRFILE, 0666));
- 		initdbm(NARTFILE);
-	}
-#endif
-
-	if (nohistory) {
-		ohfd = xfopen(ACTIVE, "r");
-		if (dorebuild) {
-			/* Allocate initial space for multiple newsgroup (for an
-			   article) array */
-			multhist = (struct multhist *)calloc (SPACE_INCREMENT,
-					sizeof (struct multhist));
-			mh_size = SPACE_INCREMENT;
-
-			(void) sprintf(afline, "exec sort -t\t +1.6 -2 +1 >%s", NARTFILE);
-			if ((nhfd = popen(afline, "w")) == NULL)
-				xerror("Cannot exec %s", afline);
-		} else
-			nhfd = xfopen("/dev/null", "w");
-	} else {
-		ohfd = xfopen(ARTFILE, "r");
-		nhfd = xfopen(NARTFILE, "w");
-	}
-
-	/* set up exclusive locking so inews doesn't run while expire does */
-#if defined(BSD4_2) || defined(LOCKF)
-	LockFd = open(ACTIVE, 2);
-#ifdef	LOCKF
-	(void) lockf(LockFd, F_LOCK, 0);
-#else	/* BSD4_2 */
-	(void) flock(LockFd, LOCK_EX);
-#endif	/* BSd4_2 */
-#else	/* !BSD4_2 && !LOCKF */
-	i = 0;
-	sprintf(afline,"%s.lock", ACTIVE);
-	while (LINK(ACTIVE, afline) < 0 && errno == EEXIST) {
-		if (i++ > 5)
-			xerror("Can't get lock for expire");
-		sleep(i*2);
-	}
-		
-#endif	/* !BSD4_2  && !LOCKF */
-
-	for(i=0;i<NUNREC;i++)
-		h.unrec[i] = NULL;
-
-	while (TRUE) {
-		fp = NULL;
-		if (nohistory) {
-			recdate[0] = '\0';
-			do {
-				if (ngdir == NULL) {
-					if ( ngdirp != NULL )
-						closedir(ngdirp);
-					if (fgets(afline, BUFLEN, ohfd) == NULL)
-						goto out;
-					(void) strcpy(nbuf, afline);
-					p1 = index(nbuf, ' ');
-					if (p1 == NULL)
-						p1 = index(nbuf, '\n');
-					if (p1 != NULL)
-						*p1 = NULL;
-					if (!ngmatch(nbuf, ngpat))
-						continue;
-
-					/* Change a group name from
-					   a.b.c to a/b/c */
-					for (p1=nbuf; *p1; p1++)
-						if (*p1 == '.')
-							*p1 = '/';
-
-					if ((ngdirp = opendir(nbuf)) == NULL)
-						continue;
-
-				}
-				ngdir = readdir(ngdirp);
-			/*	Continue looking if not an article.	*/
-			} while (ngdir == NULL || !islegal(fn,nbuf,ngdir->d_name));
-
-			p2 = fn;
-			if (verbose > 2)
-				printf("article: %s\n", fn);
-			strcpy(filename, dirname(fn));
-			fp = access(filename, 04) ? NULL : art_open(filename, "r");
-		} else {
-			char dc;
-			if (fgets(afline, BUFLEN, ohfd) == NULL)
-				break;
-			if (verbose > 2)
-				printf("article: %s", afline);
-			p1 = index(afline, '\t');
-			if (!p1)
-				continue;
-			*p1 = '\0';
-			(void) strcpy(h.ident, afline);
-			*p1 = '\t';
-			p2 = index(p1 + 1, '\t');
-			if (!p2)
-				continue;
-			*p2 = '\0';
-			(void) strcpy(recdate, p1+1);
-			rectime = cgtdate(recdate);
-			*p2++ = '\t';
-			(void) strcpy(nbuf, p2);
-			p3 = index(nbuf, '/');
-			if (p3) {
-				register char *p4;
-
-				p4 = index(p3, '\n');
-				if (p4) {
-					while (p4[-1] == ' ')
-						p4--;
-					*p4 = '\0';
-				}
-
-				/*
-				 * convert list of newsgroups from
-				 *	ng1/num ng2/num ...
-				 * to
-				 *	ng1,ng2,...
-				 */
-				p4 = p3;
-				do {
-					*p3++ = NGDELIM;
-					while (*p4 != '\0' && *p4 != ' ')
-						p4++;
-					if (*p4++ == '\0') {
-						*--p3 = '\0';
-						break;
-					}
-					while (*p3 = *p4++) {
-						if (*p3 == '/')
-							break;
-						else
-							p3++;
-					}
-				} while (*p3);
-			} else {
-				/*
-				 * Nothing after the 2nd tab.  This happens
-				 * when there's no message left in the spool
-				 * directory, only the memory of it in the
-				 * history file. Use date in the history file
-				 * to decide if we should keep this article.
-				 */
-				grpsleft[0] = '\0';
-				goto checkdate;
-			}
-			if (!ngmatch(nbuf, ngpat) ||
-			     ((rectime+expincr > today) && !dorebuild &&
-			         !frflag && !usepost && recdate[0] != ' '))
-				goto keephist;
-			if (!dorebuild && !frflag && !usepost &&
-				recdate[0] != ' ') {
-				grpsleft[0] = '\0';
-				goto nailit; /* just expire it */
-			}
-
-			/*
-			 * Look for the file--possibly several times,
-			 * if it was posted to several news groups.
-			 */
-			dc = ' ';
-			p3 = p2;
-			while (dc != '\n') {
-				p1 = index(p3, ' ');
-				if (p1) {
-					dc = ' ';
-					*p1 = '\0';
-				} else {
-					p1 = index(p3, '\n');
-					if (p1 && p1 > p3) {
-						dc = '\n';
-						*p1 = '\0';
-					} else {
-						fp = NULL;
-						break;
-					}
-				}
-				strcpy(filename, dirname(p3));
-				if (access(filename, 4) == 0 &&
-					((fp=art_open(filename, "r")) != NULL))
-						break;
-				p3 = p1 + 1;
-			}
-			if (p1)
-				*p1 = dc;
-		}
-
-		if (fp == NULL) {
-			/*
-			 * this probably means that the article has been
-			 * cancelled.  Lets assume that, and make an
-			 * entry in the history file to that effect.
-			 */
-			if (verbose)
-				perror(filename);
-			strcpy(p2, "cancelled\n");
-			grpsleft[0] = '\0';
-			goto checkdate;
-		}
-		for(i=0; i<NUNREC; i++)
-			if (h.unrec[i] != NULL)
-				free(h.unrec[i]);
-			else
-				break;
-		if (!hread(&h, fp, TRUE)) {
-			printf("Garbled article %s.\n", filename);
-			(void) fclose(fp);
-			/*
-			 * Usually means disk ran out of space.
-			 * Drop this article from our history file
-			 * completely, so we have a chance of picking
-			 * it up again from another feed ..
-			 */
-			goto nailit;
-		}
-		if (nohistory) {
-			if (recdate[0] == '\0') {
-				struct stat statb;
-				if (fstat(fileno(fp), &statb) < 0)
-					rectime = cgtdate(h.subdate);
-				else
-					rectime = statb.st_mtime;
-			} else
-				rectime = cgtdate(recdate);
-		}
-		if (dorebuild) {
-			register char	*cp, *lastslash;
-			register struct multhist *mhp;
-
-			/*
-			 * Format of filename until now was /SPOOL/a/b/c/4
-			 * and this code changes it to a.b.c/4 (the correct
-			 * kind of entry in the history file.)
-			 *
-			 * This can't be a strcpy because the addresses overlap
-			 * and some machines can't handle that.
-			 */
-			p1 = filename;
-			cp = p1 + strlen(SPOOL);
-			while (*++cp) {
-				if (*cp == '/') {
-					lastslash = p1;
-					*p1++ = '.';
-				} else
-					*p1++ = *cp;
-			}
-			*p1 = '\0';
-			*lastslash = '/';
-
-			if ((cp = index(h.nbuf, NGDELIM)) == NULL) {
-				struct tm *tm;
-saveit:
-				tm = gmtime(&rectime);
-				if (fprintf(nhfd,
-#ifdef USG
-				     "%s\t%s%2.2d/%2.2d/%d %2.2d:%2.2d\t%s\n",
-#else /* !USG */
-				     "%s\t%s%02d/%02d/%d %02d:%02d\t%s\n",
-#endif /* !USG */
-					h.ident, h.expdate[0] ? " " : "",
-					tm->tm_mon+1, tm->tm_mday, tm->tm_year,
-					tm->tm_hour, tm->tm_min, filename)
-					== EOF)
-						xerror("History write failed");
-				(void) fclose(fp);
-				continue;
-			}
-			for (mhp = multhist; mhp < multhist+mh_size && mhp->mh_ident != NULL; mhp++) {
-				if (mhp->mh_file == NULL)
-					continue;
-				if (strcmp(mhp->mh_ident, h.ident))
-					continue;
-				(void) strcat(filename, " ");
-				(void) strcat(filename, mhp->mh_file);
-				free(mhp->mh_file);
-				mhp->mh_file = NULL;
-				/*
-				 * if we have all the links, write to hist now
-				 */
-				if (chrcnt(filename, ' ') == chrcnt(cp,NGDELIM))
-					goto saveit;
-				break;
-			}
-
-			/*
-			 * Here is where we realloc the multhist space rather
-			 * than the old way of static allocation.  It's
-			 * really trivial.  We just clear out the space
-			 * in case it was reused.  The old static array was
-			 * guaranteed to be cleared since it was cleared when
-			 * the process started.
-			 */
-			if (mhp >= multhist + mh_size) {
-				multhist = (struct multhist *)
-					realloc ((char *)multhist,
-					  sizeof (struct multhist) *
-					  (SPACE_INCREMENT + mh_size));
-				if (multhist == NULL)
-					xerror("Too many articles with multiple newsgroups");
-				for (mhp = multhist + mh_size;
-				  mhp < multhist+mh_size+SPACE_INCREMENT;
-					mhp++) {
-					mhp->mh_ident = NULL;
-					mhp->mh_file = NULL;
-				}
-				mhp = multhist + mh_size;
-				mh_size += SPACE_INCREMENT;
-			}
-
-			if (mhp->mh_ident == NULL) {
-				mhp->mh_ident = malloc(strlen(h.ident)+1);
-				(void) strcpy(mhp->mh_ident, h.ident);
-			}
-			cp = malloc(strlen(filename) + 1);
-			if (cp == NULL)
-				xerror("Out of memory");
-			(void) strcpy(cp, filename);
-			mhp->mh_file = cp;
-			(void) fclose(fp);
-			continue;
-		}
-
-		(void) fclose(fp);
-
-		if (h.expdate[0]) {
-			Now.time = rectime;
-			exptime = cgtdate(h.expdate);
-		}
-		newtime = (usepost ? cgtdate(h.subdate) : rectime) + expincr;
-		if (!h.expdate[0] || ignorexp == 2 ||
-		    (ignorexp == 1 && newtime < exptime))
-			exptime = newtime;
-		if (frflag ? strcmp(baduser,h.from)==0 : today >= exptime) {
-nailit:
-#ifdef DEBUG
-			printf("cancel %s\n", filename);
-#else /* !DEBUG */
-			if (verbose)
-				printf("cancel %s\n", h.ident);
-			ulall(p2, &h);
-			(void) sprintf(p2, "%s\n", grpsleft);
-			if (verbose > 2 && grpsleft[0])
-				printf("Some good in %s\n", h.ident);
-#endif /* !DEBUG */
-		} else {
-			if (verbose > 2)
-				printf("Good article %s\n", h.ident);
-			grpsleft[0] = '!';
-		}
-
-checkdate:
-		if (grpsleft[0] == '\0' && today >= rectime + dropincr) {
-			if (verbose > 3)
-				printf("Drop history of %s - %s\n",
-				    h.ident, recdate);
-		} else {
-			long hpos;
-keephist:
-			hpos = ftell(nhfd);
-
-			if (verbose > 3)
-				printf("Retain history of %s - %s\n",
-				    h.ident, recdate);
-			if (fputs(afline, nhfd) == EOF)
-				xerror("history write failed");
-#ifdef DBM
-			if (!dorebuild)
-				remember(h.ident, hpos);
-#endif /* DBM */
-		}
-	}
-out:
-	if (dorebuild) {
-		register struct multhist *mhp;
-		struct tm *tm;
-		for (mhp = multhist; mhp < multhist+mh_size && mhp->mh_ident != NULL; mhp++)
-			if (mhp->mh_file != NULL) {
-				if (verbose)
-					printf("Article: %s [%s] Cannot find all links\n", mhp->mh_ident, mhp->mh_file);
-				(void) sprintf(filename,"%s/%s",SPOOL,mhp->mh_file);
-				for (p1 = filename; *p1 != ' ' && *p1 != '\0'; p1++)
-					if (*p1 == '.')
-						*p1 = '/';
-				*p1 = '\0';
-				if ((fp = art_open(filename, "r")) == NULL) {
-					if (verbose)
-						printf("Can't open %s.\n", filename);
-					continue;
-				}
-				if (!hread(&h, fp, TRUE)) {
-					printf("Garbled article %s.\n", filename);
-					(void) fclose(fp);
-					continue;
-				} else {
-					struct stat statb;
-					if (fstat(fileno(fp), &statb) < 0)
-						rectime = cgtdate(h.subdate);
-					else
-						rectime = statb.st_mtime;
-				}
-				tm = gmtime(&rectime);
-				if (
-#ifdef USG
-					fprintf(nhfd,"%s\t%s%2.2d/%2.2d/%d %2.2d:%2.2d\t%s\n",
-#else /* !USG */
-					fprintf(nhfd,"%s\t%s%02d/%02d/%d %02d:%02d\t%s\n",
-#endif /* !USG */
-					h.ident, h.expdate[0] ? " " : "",
-					tm->tm_mon+1, tm->tm_mday, tm->tm_year,
-					tm->tm_hour, tm->tm_min, mhp->mh_file)
-					== EOF )
-						xerror("History write failed");
-				(void) fclose(fp);
-				continue;
-			}
-		(void) pclose(nhfd);
-		free ((char *)multhist);
-	} else
-		if (fclose(nhfd))
-			xerror("History write failed, %s", errmsg(errno));
-
-	if (dorebuild || !nohistory) {
-		(void) rename(ARTFILE, OARTFILE);
-		(void) rename(NARTFILE, ARTFILE);
-#ifdef DBM
-		if (dorebuild)
-			rebuilddbm( );
-		else {
-			char tempname[BUFLEN];
-			(void) sprintf(tempname,"%s.pag", ARTFILE);
-			(void) strcat(NARTFILE, ".pag");
-			(void) rename(NARTFILE, tempname);
-			(void) sprintf(tempname,"%s.dir", ARTFILE);
-			(void) strcpy(rindex(NARTFILE, '.'), ".dir");
-			(void) rename(NARTFILE, tempname);
-		}
-#endif
-	}
-#ifndef DBM
-	/* rebuild history subfiles */
-	for (i = 0; i < 10; i++) {
-		(void) sprintf(fn, "%s.d/%c", ARTFILE, i + '0');
-		close(creat(fn, 0644));
-		subfd[i] = xfopen(fn, "w+");
-	}
-	ohfd = xfopen(ARTFILE, "r");
-	while (fgets(fn, BUFLEN, ohfd) != NULL) {
-		ptr = histfile(fn);
-		chr = *(ptr + strlen(ptr) - 1);
-		if (isdigit(chr))
-			i = chr - '0';
-		else
-			i = 0;
-		fputs(fn, subfd[i]);
-	}
-	(void) fclose(ohfd);
-	for (i = 0; i < 10; i++)
-		if (ferror(subfd[i]) || fclose(subfd[i]))
-			xerror("History subfile write");
-#endif /* !DBM */
-
-doupdateactive:
-	ohfd = xfopen(ACTIVE, "r");
-	nhfd = xfopen(NACTIVE, "w");
-	do {
-		long n;
-		long maxart, minart;
-		char cansub;
-		int gdsize, hassubs;
-		struct stat stbuf;
-
-		if (fgets(afline, BUFLEN, ohfd) == NULL)
-			continue;
-		if (sscanf(afline,"%s %ld %ld %c",nbuf,&maxart, &minart,
-		    &cansub) < 4)
-			xerror("Active file corrupt");
-		if (!ngmatch(nbuf, ngpat)) {
-			if (fputs(afline, nhfd) == EOF)
-				xerror("active file write failed");
-			continue;
-		}
-		minart = 99999L;
-		/* Change a group name from a.b.c to a/b/c */
-		for (p1=nbuf; *p1; p1++)
-			if (*p1 == '.')
-				*p1 = '/';
-
-		hassubs = stat(nbuf, &stbuf) != 0 || stbuf.st_nlink != 2;
-		gdsize = strlen(nbuf);
-		if ((ngdirp = opendir(nbuf)) != NULL) {
-			while (ngdir = readdir(ngdirp)) {
-				nbuf[gdsize] = '/';
-				(void) strcpy(&nbuf[gdsize+1], ngdir->d_name);
-				/* We have to do a stat because of micro.6809 */
-				if (hassubs && (stat(nbuf, &stbuf) < 0 ||
-					!(stbuf.st_mode&S_IFREG)) )
-					continue;
-				n = atol(ngdir->d_name);
-				if (n > 0 && n < minart)
-					minart = n;
-				if (n > 0 && n > maxart)
-					maxart = n;
-			}
-			closedir(ngdirp);
-		}
-		afline[gdsize] = '\0';
-		if (minart > maxart)
-			minart = maxart;
-		if (fprintf(nhfd,"%s %05ld %05ld %c\n", afline, maxart,
-			minart, cansub) == EOF)
-			xerror("Active file write failed");
-	} while (!feof(ohfd));
-	if (fclose(nhfd))
-		xerror("Active file write failed, %s", errmsg(errno));
-	(void) fclose(ohfd); /* unlocking inews as a side effect */
-#ifndef BSD4_2
-	sprintf(bfr, "%s.lock", ACTIVE);
-	(void) UNLINK(bfr);
-#endif	/* !BSD4_2 */
-
-	(void) rename(ACTIVE, OACTIVE);
-	(void) rename(NACTIVE, ACTIVE);
-
-	execl(RNEWS, "rnews", "-U", (char *)NULL);
-	perror(RNEWS);
-	xxit(1);
-}
-
-/* Unlink (using unwound tail recursion) all the articles in 'artlist'. */
-ulall(artlist, hp)
-char	*artlist;
-struct hbuf *hp;
-{
-	register char	*p, *q;
-	int	last = 0;
-	char	newname[BUFLEN];
-	time_t	timep[2];
-	char *fn;
-
-	grpsleft[0] = '\0';
-	do {
-		if (verbose > 2)
-			printf("ulall '%s', '%s'\n", artlist, hp->subdate);
-		if (nohistory) {
-			last = 1;
-		} else {
-			while (*artlist == ' ' || *artlist == '\n' || *artlist == ',')
-				artlist++;
-			if (*artlist == '\0')
-				return;
-			p = index(artlist, ' ');
-			if (p == NULL) {
-				last = 1;
-				p = index(artlist, '\n');
-			}
-			if (p == NULL) {
-				last = 1;
-				fn = dirname(artlist);
-				if (UNLINK(fn) < 0 && errno != ENOENT)
-					perror(fn);
-				return;
-			}
-			if (p)
-				*p = 0;
-		}
-		strcpy(newname, artlist);
-		q = index(newname,'/');
-		if (q) {
-			*q++ = NGDELIM;
-			*q = '\0';
-		} else {
-			q = index(newname, '\0');
-			if (q == artlist)		/* null -> the end */
-				return;
-			/* should be impossible to get here */
-		}
-		fn = dirname(artlist);
-		if (ngmatch(newname, ngpat)) {
-			if (doarchive){
-				if (ngmatch(newname, arpat)) {
-					q = fn + strlen(SPOOL) + 1;
-					(void) sprintf(newname, "%s/%s", OLDNEWS, q);
-					if (verbose)
-						printf("link %s to %s\n", fn, newname);
-					if (LINK(fn, newname) == -1) {
-						if (mkparents(newname) == 0)
-							if (LINK(fn, newname) == -1)
-								fcopy(fn, newname);
-					}
-					timep[0] = timep[1] = cgtdate(hp->subdate);
-					(void) utime(newname, timep);
-				}
-			}
-			if (verbose)
-				printf("unlink %s\n", fn);
-			if (UNLINK(fn) < 0 && errno != ENOENT)
-				perror(fn);
-		} else {
-			if (verbose > 3)
-				printf("retain %s (%s)\n", hp->ident, fn);
-			strcat(grpsleft, artlist);
-			strcat(grpsleft, " ");
-		}
-		artlist = p + 1;
-	} while (!last);
-}
-
-fcopy(fn, newname)
-char *fn, *newname;
-{
-	int f1, f2;
-	int r;
-	char buf[BUFSIZ];
-	f1 = open(fn, 0);
-	if (f1 < 0)
-		return -1;
-	f2 = open(newname, 1);
-	if (f2 < 0) {
-		if (errno == ENOENT) {
-			f2 = creat(newname,0644);
-			if (f2 < 0) {
-				close(f1);
-				return -1;
-			}
-		} else {
-			close(f1);
-			return -1;
-		}
-	}
-	while((r=read(f1, buf, BUFSIZ)) > 0)
-		write(f2, buf, r);
-	(void) close(f1);
-	(void) close(f2);
-	return 0;
-}
-
-/* 
- * Count instances of c in s
- */
-chrcnt(s, c)
-register char *s;
-register c;
-{
-	register n = 0;
-	register cc;
-
-	while (cc = *s++)
-		if (cc == c)
-			n++;
-	return n;
-}
-
-/*
- * If any parent directories of this dir don't exist, create them.
- */
-mkparents(fullname)
-char *fullname;
-{
-	char buf[200];
-	register char *p;
-	int rc;
-
-	(void) strcpy(buf, fullname);
-	p = rindex(buf, '/');
-	if (p)
-		*p = '\0';
-	if (access(buf, 0) == 0)
-		return 0;
-	mkparents(buf);
-	if ((rc = mkdir(buf, 0755)) < 0)
-		perror("mkdir failed");
-	if (verbose)
-		printf("mkdir %s, rc %d\n", buf, rc);
-
-	return rc;
-}
-
-
-/*	Make sure this file is a legal article. */
-islegal(fullname, path, name)
-register char *fullname;
-register char *path;
-register char *name;
-{
-	struct stat buffer;
-
-	(void) sprintf(fullname, "%s/%s", path, name);
-
-	/* make sure the article is numeric. */
-	while (*name != '\0')
-		if (!isascii(*name) || !isdigit(*name))
-			return 0;
-		else
-			name++;
-
-	/*  Now make sure we don't have a group like net.micro.432,
-	 *  which is numeric but not a regular file -- i.e., check
-	 *  for being a regular file.
-	 */
-	if ((stat(fullname, &buffer) == 0) &&
-		((buffer.st_mode & S_IFMT) == S_IFREG)) {
-		/* Now that we found a legal group in a/b/c/4
-		   notation, switch it to a.b.c/4 notation.  */
-		for (name = fullname; name != NULL && *name != '\0'; name++)
-			if (*name == '/' && name != rindex (name, '/'))
-				*name = '.';
-
-			return 1;
-	}
-	return 0;
-}
-
-#ifdef DBM
-/*
- * This is taken mostly intact from ../cvt/cvt.hist.c and is used at the
- * end by the options that make a new history file.
- * Routine to convert history file to dbm file.  The old 3 field
- * history file is still kept there, because we need it for expire
- * and for a human readable copy.  But we keep a dbm hashed copy
- * around by message ID so we can answer the yes/no question "have
- * we already seen this message".  The content is the ftell offset
- * into the real history file when we get the article - you can't
- * really do much with this because the file gets compacted.
- */
-
-FILE *fd;
-
-char namebuf[BUFSIZ];
-char lb[BUFSIZ];
-
-rebuilddbm()
-{
-	register char *p;
-	long fpos;
-
-	(void) umask(0);
-	(void) sprintf(namebuf, "%s.dir", ARTFILE);
-	(void) close(creat(namebuf, 0666));
-	(void) sprintf(namebuf, "%s.pag", ARTFILE);
-	(void) close(creat(namebuf, 0666));
-	(void) sprintf(namebuf, "%s", ARTFILE);
-
-	fd = fopen(namebuf, "r");
-	if (fd == NULL) {
-		perror(namebuf);
-		xxit(2);
-	}
-
-	initdbm(namebuf);
-	while (fpos=ftell(fd), fgets(lb, BUFSIZ, fd) != NULL) {
-		p = index(lb, '\t');
-		if (p)
-			*p = 0;
-		remember(lb, fpos);
-	}
-}
-
-remember(article, fileoff)
-register char *article;
-long fileoff;
-{
-	datum	lhs, rhs;
-
-	lcase(article);
-	lhs.dptr = article;
-	lhs.dsize = strlen(article) + 1;
-	rhs.dptr = (char *) &fileoff;
-	rhs.dsize = sizeof fileoff;
-
-	if (verbose > 5)
-		printf("remember: %s @ %ld\n", article, fileoff);
-	if (store(lhs, rhs) < 0)
-		xerror("dbm store failed");
-}
-#endif /* DBM */
-
-xxit(i)
-{
-	sprintf(bfr,"%s.lock", ACTIVE);
-	(void) UNLINK(bfr);
-	exit(i);
-}
*-*-END-of-src/expire.c-*-*
echo x - src/readr.c 1>&2
sed 's/.//' >src/readr.c <<'*-*-END-of-src/readr.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.
- *
- * readr - /bin/mail and msgs interface and associated functions.
- */
-
-#ifdef SCCSID
-static char	*SccsId = "@(#)readr.c	2.58	10/23/86";
-#endif /* SCCSID */
-
-#include "rparams.h"
-#if defined(BSD4_2) || defined(BSD4_1C)
-#include <sys/dir.h>
-#else
-#include "ndir.h"
-#endif /* !BSD4_2 && !BSD4_1C */
-#include <setjmp.h>
-#include <errno.h>
-
-extern int errno;
-
-char *Progname = "readnews";	/* used by xerror to identify failing program */
-
-static char	lbuf[BUFLEN*2];
-long atol();
-
-#define	saveart	oobit = bit;strcpy(ofilename1, filename);strcpy(ogroupdir, groupdir);hptr = h;h = hold;hold = hptr;ongsize = pngsize
-#define NLINES(h, fp) (h->numlines[0] ? h->intnumlines : (h->intnumlines=linecnt(fp),sprintf(h->numlines, "%d", h->intnumlines), h->intnumlines))
-
-char *tft = "/tmp/folXXXXXX";
-
-/*
- * These were made static for u370 with its buggy cc.
- * I judged it better to have one copy with no ifdefs than
- * to conditionally compile them as automatic variables
- * in readr (which they originally were).  Performance
- * considerations might warrant moving some of the simple
- * things into register variables, but I don't know what
- * breaks the u370 cc.
- */
-static char goodone[BUFLEN];		/* last decent article		*/
-static char ogroupdir[BUFLEN];		/* last groupdir		*/
-static char address[PATHLEN];		/* for reply copy		*/
-static char edcmdbuf[128];
-static int rfq = 0;			/* for last article		*/
-static long ongsize;			/* Previous ngsize		*/
-static long pngsize;			/* Printing ngsize		*/
-static char *bptr;			/* temp pointer.		*/
-static struct srec srec;		/* srec for sys file entries	*/
-static char *tfilename;			/* temporary file name 		*/
-static char ofilename1[BUFLEN];		/* previous file name		*/
-static struct hbuf hbuf1, hbuf2,	/* for minusing			*/
-		*h = &hbuf1,		/* current header		*/
-		*hold = &hbuf2,		/* previous header		*/
-		*hptr;			/* temporary 			*/
-static char *ptr1, *ptr2, *ptr3;	/* for reply manipulation	*/
-static int  abs = FALSE;		/* TRUE if we asked absolutely	*/
-static char tf[100];
-static long oobit;			/* last bit, really		*/
-static int dgest = 0;
-static FILE *ofp;			/* Current output file to terminal*/
-static FILE *fp;			/* current article to be printed*/
-static int holdup;			/* 1 iff should stop before hdr */
-static int ignorenews;			/* 1 iff readnews -p > /dev/null*/
-static time_t timelastsaved;		/* time newsrc last written out */
-static jmp_buf sigjmpbuf;		/* for signal processing */
-static int canlongjmp;			/* TRUE if setjmp on sigjmp valid */
-
-int catchcont();
-readr()
-{
-	register char *m = getenv("MORE");
-	register char *m2, cc;
-
-	/*
-	 * Turn of more's 'l' option, so \f kludge will work.
-	 * This is really revolting!
-	 */
-	if (m2 = m) {
-		while (cc = *m++)
-			if (cc != 'l')
-				*m2++ = cc;
-		*m2 = '\0';
-	}
-
-#ifdef DEBUG
-	fprintf(stderr, "readr()\n");
-#endif
-	if (aflag) {
-		if (*datebuf) {
-			if ((atime = cgtdate(datebuf)) == -1)
-				xerror("Cannot parse date string");
-		} else
-			atime = 0;
-	}
-
-	if (pflag && ignoring())
-		ignorenews = TRUE;
-
-	if (xflag)
-		uflag = 0;
-	if (uflag)
-		(void) time(&timelastsaved);
-
-	ofp = stdout;
-	if (cflag && coptbuf[0] != '\0') {
-		(void) umask(022);
-		(void) mktemp(outfile);	/* get "unique" file name */
-		(void) close(creat(outfile,0666));
-		ofp = xfopen(outfile, "w");
-		(void) umask(N_UMASK);
-		cflag = FALSE;
-		pflag = TRUE;
-	}
-
-	/* loop reading articles. */
-	fp = NULL;
-	obit = -1;
-	nextng();
-	for ( ;; ) {
-		if (getnextart(FALSE))
-			break;
-#ifdef DEBUG
-		fprintf(stderr,"after getnextart, fp %x, pos %ld, bit %ld, group '%s', filename '%s'\n",
-			fp, ftell(fp), bit, groupdir, filename);
-#endif
-		(void) strcpy(goodone, filename);
-		if (pflag || lflag || eflag) {
-			/* This code should be gotten rid of */
-			if (SigTrap) {
-				qfflush(ofp);
-				fprintf(ofp, "\n");
-				cdump(ofp);
-				xxit(0); /* kludge! drop when qfflush works */
-				return;
-			}
-			clear(bit);
-			nextbit();
-			FCLOSE(fp);
-			continue;
-		}
-		for ( ;; ) {
-			char *pp;
-			int nlines;
-			int (*ointr)();
-#ifdef	SIGCONT
-			int (*ocont)();
-#endif
-			(void) setjmp(sigjmpbuf);
-			canlongjmp = TRUE;
-
-			SigTrap = FALSE;
-			if (!cflag) {
-				if (rfq)
-					(void) sprintf(bfr, "Last article.  [qfr] ");
-				else {
-					nlines = NLINES(h, fp);
-					if (nlines <= 0) {
-						(void) sprintf(bfr, "(0 lines) Next? [nqfr] ");
-						FCLOSE(fp);
-					} else {
-						(void) sprintf(bfr, "(%d lines) More? [ynq] ", nlines);
-					}
-				}
-			} else
-				(void) sprintf(bfr, "? ");
-			fprintf(ofp, "%s", bfr);
-			(void) fflush(ofp);
-			bptr = lbuf;
-			ointr = signal(SIGINT, catchcont);
-#ifdef SIGCONT
-			ocont = signal(SIGCONT, catchcont);
-#endif
-			pp = fgets(bptr, BUFLEN, stdin);
-			canlongjmp = FALSE;
-			(void) signal(SIGINT, ointr);
-#ifdef SIGCONT
-			(void) signal(SIGCONT, ocont);
-#endif
-			if (pp != NULL)
-				break;
-			if (!SigTrap)
-				return;
-#ifdef SIGCONT
-			if (SigTrap != SIGCONT)
-#endif
-				fprintf(ofp, "\n");
-		}
-		(void) nstrip(bptr);
-		while (*bptr == ' ' || *bptr == '\t')
-			bptr++;
-		if (command())
-			break;
-	}
-
-	if (!pflag && !news) {
-		fprintf(stderr, "No news.\n");
-	}
-	cout(ofp);
-}
-
-#define EOL() if (*bptr != '\0') { fprintf(ofp, "? for commands.\n"); return FALSE; }
-/*
- * Process one command, which has already been typed in.
- */
-command()
-{
-	char *findhist();
-	long i;
-
-	switch (*bptr++) {
-
-	/* No.  Go on to next article. */
-	case 'n':
-		EOL();
-		readmode = NEXT;
-		if (!cflag)
-			FCLOSE(fp);
-		fprintf(ofp, "\n");
-		clear(bit);
-		saveart;
-		nextbit();
-		break;
-
-	/* Undigestify the article. */
-	case 'd':
-		dgest = 1;
-		/* fall through */
-
-	/* yes: print this article, go on. */
-	case 'y':
-		EOL();
-		/* fall through. */
-
-	/* The user hit return.  Default is 'y' unless rfq, then it's 'q'. */
-	case '\0':
-		if (!bptr[-1] && rfq)
-			return TRUE;
-		readmode = NEXT;
-		showtail(fp);
-		clear(bit);
-		saveart;
-		nextbit();
-		break;
-
-	/*
-	 * Unsubscribe to the newsgroup and go on to next group
-	 */
-	case 'u':
-		fprintf(ofp, "To unsubscribe, use 'U'\n");
-		break;
-
-	case 'U':
-		fprintf(ofp, "Unsubscribing to newsgroup: %s\n", groupdir);
-		obit = -1;
-		FCLOSE(fp);
-		if (cflag)
-			clear(bit);
-		else
-			putc('\n', ofp);
-		rfq = 0;
-		zapng = TRUE;
-		saveart;
-		if (nextng()) {
-			if (actdirect == BACKWARD)
-				fprintf(ofp, "Can't back up.\n");
-			else
-				return TRUE;
-		}
-		break;
-
-		/* Print the current version of news */
-	case 'v':
-		fprintf(ofp, "News version: %s\n", news_version);
-		break;
-
-		/* reprint the article */
-	case 'p':
-		EOL();
-		if (!cflag)
-			goto minus;
-		readmode = NEXT;
-		if (!cflag) {
-			FCLOSE(fp);
-			bit = last;
-			putc('\n', ofp);
-		}
-		obit = -1;
-		break;
-
-		/* decrypt joke */
-	case 'D':
-		caesar_command();
-		readmode = NEXT;
-		clear(bit);
-		saveart;
-		nextbit();
-		break;
-
-		/* write out the article someplace */
-	case 's':
-	case 'w':
-		{
-		char *grn = groupdir;
-		tfilename = filename;
-		if (*bptr == '-') {
-			bptr++;
-			grn = ogroupdir;
-			if (*ofilename1)
-				tfilename = ofilename1;
-		}
-		if (*bptr != '\0' && *bptr != ' ') {
-			fprintf(ofp, "Bad file name.\n");
-			break;
-		}
-		while (*bptr == ' ')
-			bptr++;
-		if (*bptr != '|' && *bptr != '/') {
-			char	hetyped[BUFLEN];
-			char	*boxptr;
-			struct	stat stbf;
-  			(void) strcpy(hetyped, bptr);
-			if (hetyped[0] == '~' && hetyped[1] == '/') {
-  				strcpy(hetyped, bptr+2);
-  				strcpy(bptr, userhome);
-			} else if (boxptr = getenv("NEWSBOX")) {
- 				if (index(boxptr, '%')) {
- 					sprintf(bptr, boxptr, grn);
- 				    	if (stat(bptr, &stbf) < 0) {
-						if (mkdir(bptr, 0777) < 0) {
-							fprintf(ofp, "Cannot create directory %s", bptr);
-							break;
-						}
-					} else if ((stbf.st_mode & S_IFMT) != S_IFDIR) {
-						fprintf(ofp, "%s is not a directory", bptr);
-						break;
-					}
-				} else
-				    strcpy(bptr, boxptr);
-			} else
-				(void) strcpy(bptr, ".");
-			(void) strcat(bptr, "/");
-			if (hetyped[0] != '\0')
-				(void) strcat(bptr, hetyped);
-			else
-				(void) strcat(bptr, "Articles");
-		}
-		fwait(fsubr(save, tfilename, bptr));
-		}
-		break;
-
-		/* back up  */
-	case '-':
-minus:
-		rfq = 0;
-		abs = TRUE;
-		if (!*ofilename1) {
-			fprintf(ofp, "Can't back up.\n");
-			break;
-		}
-		if (cflag)
-			clear(bit);
-		else {
-			FCLOSE(fp);
-			putc('\n', ofp);
-		}
-		hptr = h;
-		h = hold;
-		hold = hptr;
-		(void) strcpy(bfr, filename);
-		(void) strcpy(filename, ofilename1);
-		(void) strcpy(ofilename1, bfr);
-		obit = bit;
-		if (strcmp(groupdir, ogroupdir)) {
-			(void) strcpy(bfr, groupdir);
-			selectng(ogroupdir, TRUE, FALSE);
-			(void) strcpy(groupdir, ogroupdir);
-			(void) strcpy(ogroupdir, bfr);
-			ngrp = 1;
-			back();
-		}
-		bit = oobit;
-		oobit = obit;
-		obit = -1;
-		(void) getnextart(TRUE);
-		return FALSE;
-
-		/* skip forwards */
-	case '+':
-caseplus:
-		if (*bptr == '\0')
-			(void) strcat(bptr, "1");
-		rfq = 0;
-		if (cflag)
-			clear(bit);
-		saveart;
-		last = bit;
-		for (i = 0; i < atol(bptr); i++) {
-			nextbit();
-			if ((bit > pngsize) || (rflag && bit < 1))
-				break;
-		}
-		if (!cflag) {
-			putc('\n', ofp);
-			FCLOSE(fp);
-		}
-		obit = -1;
-		break;
-
-	/* exit - time updated to that of most recently read article */
-	case 'q':
-		EOL();
-		return TRUE;
-
-	/* exit - no time update. */
-	case 'x':
-		EOL();
-		xxit(0);
-
-	/* cancel the article. */
-	case 'c':
-		(void) cancel_command();
-		break;
-
-	/* escape to shell */
-	case '!':
-		fwait(fsubr(ushell, bptr, (char *)NULL));
-		fprintf(ofp, "\n");
-		hdr();
-		break;
-
-	/* mail reply */
-	case 'r':
-		(void) reply_command();
-		break;
-
-	/* send to some system */
-	case 'X':
-		xmit_command();
-		break;
-	/* mark the rest of the articles in this group as read */
-	case 'K':
-		saveart;
-		while (bit <= pngsize && bit >= minartno) {
-			clear(bit);
-			nextbit();
-		}
-		FCLOSE(fp);
-		break;
-
-	/* next newsgroup */
-	case 'P':
-		*bptr = '-';
-	case 'N':
-		FCLOSE(fp);
-		if (next_ng_command())
-			return TRUE;
-		break;
-
-	case 'b':	/* back up 1 article */
-		i = bit - 1;
-		goto tryartnum;
-	case '0':	/* specific no. */
-	case '1':
-	case '2':
-	case '3':
-	case '4':
-	case '5':
-	case '6':
-	case '7':
-	case '8':
-	case '9':
-		(void) sscanf(--bptr, "%ld", &i);
-		if (i == 0) {
-			fprintf(ofp, "Bad article no.\n");
-			break;
-		}
-		if (i > pngsize) {
-			fprintf(ofp, "Not that many articles.\n");
-			break;
-		}
-tryartnum:
-		readmode = SPEC;
-		abs = TRUE;
-		bit = i;
-		obit = -1;
-		if (!cflag) {
-			putc('\n', ofp);
-			FCLOSE(fp);
-		}
-		rfq = 0;
-		break;
-
-	/* specific message ID. */
-	case '<':
-		ptr1 = findhist(--bptr);
-		if (ptr1 == NULL) {
-			fprintf(ofp, "No such article: %s.\n", bptr);
-			break;
-		}
-		ptr2 = index(ptr1, '\t');
-		ptr3 = index(++ptr2, '\t');
-		ptr2 = index(++ptr3, ' ');
-		if (ptr2)
-			*ptr2 = '\0';
-		ptr2 = index(ptr3, '/');
-		if (!ptr2) {
-			*ptr3 = '\0';
-			if (strcmp(++ptr3, "cancelled") == 0) {
-				fprintf(ofp, "Article %s has been cancelled.\n",
-					bptr);
-				break;
-			}
-			fprintf(ofp, "Article %s (dated %s) has expired.\n",
-				bptr, index(ptr1, '\t')+1);
-			break;
-		}
-		*ptr2++ = '\0';
-		abs = TRUE;
-		if (cflag)
-			clear(bit);
-		else {
-			FCLOSE(fp);
-			putc('\n', ofp);
-		}
-		saveart;
-		(void) strcpy(ogroupdir, ptr3);
-		if (strcmp(groupdir, ogroupdir)) {
-			(void) strcpy(bfr, groupdir);
-			selectng(ogroupdir, TRUE, PERHAPS);
-			(void) strcpy(groupdir, ogroupdir);
-			(void) strcpy(ogroupdir, bfr);
-			ngrp = 1;
-			back();
-		}
-		(void) sscanf(ptr2, "%ld", &bit);
-		oobit = obit;
-		obit = -1;
-		i = bit;
-		(void) getnextart(TRUE);
-		if (bit != i || strcmp(groupdir, ptr3) != 0) {
-			(void) fprintf(ofp, "Can't read %s/%ld.\n", ptr3, i);
-			goto minus;
-		}
-		rfq = 0;
-		break;
-
-	/* follow-up article */
-	case 'f':
-		if (strcmp(h->followto, "poster") == 0) {
-			(void) reply_command();
-			break;
-		}
-
-		if (*bptr == '-')
-			tfilename = ofilename1;
-		else
-			tfilename = filename;
-		(void) sprintf(bfr,"%s/%s %s", BIN, "postnews", tfilename);
-		(void) system(bfr);
-		break;
-
-	/* erase - pretend we haven't seen this article. */
-	case 'e':
-		if (rfq || *bptr == '-') {
-			if (strcmp(groupdir, ogroupdir)) {
-				i = bit;
-				(void) strcpy(bfr, groupdir);
-				selectng(ogroupdir, FALSE, PERHAPS);
-				set(oobit);
-				fprintf(ofp,"Holding article %ld newsgroup %s\n", oobit, ogroupdir),
-				(void) strcpy(groupdir, ogroupdir);
-				selectng(bfr, FALSE, FALSE);
-				bit = i;
-			} else {
-				fprintf(ofp,"Holding article %ld\n", oobit);
-				set(oobit);
-			}
-		} else {
-			fprintf(ofp,"Holding article %ld\n", bit);
-			set(bit);
-			goto caseplus;	/* skip this article for now */
-		}
-		break;
-
-	case 'H':
-	case 'h':
-		if (!hflag)
-			dash(8, ofp);
-		if (*bptr == '-') {
-			if (oobit > 0)
-				fprintf(ofp, "Article %ld:\n", oobit);
-			hprint(hold, ofp, 1 + (bptr[-1]=='H'));
-		} else {
-			fprintf(ofp, "Article %ld of %ld: %s\n",
-				rfq ? oobit : bit, pngsize, h->ident);
-			hprint(h, ofp, 1 + (bptr[-1]=='H'));
-		}
-		if (!hflag)
-			dash(8, ofp);
-		break;
-
-	case '#':
-		fprintf(ofp, "Article %ld of %ld: newsgroup %s\n",
-			rfq ? oobit : bit, pngsize, rfq ? ogroupdir : groupdir);
-		break;
-
-		/* error */
-	case '?':
-		help(ofp);
-		break;
-	default:
-		fprintf(ofp, "? for commands.\n");
-		break;
-	}
-
-	return FALSE;
-}
-
-cancel_command()
-{
-	int notauthor;
-	tfilename = filename;
-	hptr = h;
-	if (*bptr == '-') {
-		if (*ofilename1) {
-			tfilename = ofilename1;
-			hptr = hold;
-		}
-		bptr++;
-	}
-	EOL();
-	readmode = SPEC;
-	(void) strcpy(rcbuf, hptr->path);
-	ptr1 = index(rcbuf, ' ');
-	if (ptr1)
-		*ptr1 = 0;
-	notauthor = strcmp(username, rcbuf);
-	if (uid != ROOTID && uid && notauthor) {
-		fprintf(ofp, "Can't cancel what you didn't write.\n");
-		return FALSE;
-	}
-	if (!cancel(ofp, hptr, notauthor) && hptr == h) {
-		clear(bit);
-		saveart;
-		nextbit();
-		obit = -1;
-		if (!cflag)
-			putc('\n', ofp);
-		FCLOSE(fp);
-	}
-	return TRUE;
-}
-
-reply_command()
-{
-	register char	*pathptr;
-	int edit = 1;
-	char *ed, *fbp;
-	int idlen;
-	FILE *tfp;
-	char *replyname();
-	char subj[BUFLEN];
-	char folbuf[BUFLEN];
-	struct stat statb;
-	long creatm;
-
-	hptr = h;
-	while (*bptr && index("d-", *bptr)) {
-		switch (*bptr) {
-		/* Followup the previous article. */
-		case '-':
-			hptr = hold;
-			break;
-
-		/* Don't edit the headers */
-		case 'd':
-			edit = 0;
-			break;
-		}
-		bptr++;
-	}
-	EOL();
-	ptr1 = index(MAILPARSER, ' ');
-	if (ptr1)
-		*ptr1 = '\0';
-	if (edit && access(MAILPARSER, 1)) {
-#ifdef IHCC
-		fprintf(stderr, "Can't edit headers, 'recmail' missing.\n");
-#else
-		fprintf(stderr, "Can't edit headers without %s\n", MAILPARSER);
-#endif
-		edit = 0;
-	}
-	if (ptr1)
-		*ptr1 = ' ';
-
-	*rcbuf = '\0';
-	pathptr = replyname(hptr);;
-	for (ptr1 = address, ptr2 = pathptr; *ptr2; ptr1++, ptr2++) {
-		if (index("\"\\$", *ptr2))
-			*ptr1++ = '\\';
-		*ptr1 = *ptr2;
-	}
-	*ptr1 = '\0';
-
-	folbuf[0] = '\0';		/* References */
-	if (hptr->followid[0]) {
-		fbp = hptr->followid;
-		idlen = strlen(hptr->ident);
-
-		/*
-		 * If the references line is too long, truncate it.
-		 * The "3" is for the comma, the space, and the '\0' at
-		 * the end of the string.
-		 */
-		while (fbp && strlen(fbp) + idlen > BUFLEN - 3)
-			fbp = index(fbp + 1, '<');
-		if (fbp != NULL) {
-			(void) strcpy(folbuf, fbp);
-			(void) strcat(folbuf, ", ");
-		}
-	}
-	(void) strcat(folbuf, hptr->ident);
-
-	(void) strcpy(subj, hptr->title);	/* Subject */
-	while (isspace(*bptr))
-		bptr++;
-	if (*bptr != '\0')
-		(void) strcpy(subj, bptr);
-	if (!prefix(subj, "Re:")){
-		(void) strcpy(bfr, subj);
-		(void) sprintf(subj, "Re: %s", bfr);
-	}
-	if (!edit) {
-		fprintf(ofp, "To: %s\n", pathptr);
-		ed = index(MAILER, '%');
-		if (ed && ed[1] == 's')
-			fprintf(ofp, "Subject: %s\n", subj);
-		(void) fflush(ofp);
-	}
-
-	/* Put the user in the editor to create the body of the followup. */
-	if (edit) {
-		int oumask;
-
-		(void) strcpy(tf, tft);
-		(void) mktemp(tf);
-
-		ed = getenv("EDITOR");
-		if (ed == NULL)
-			ed = DFTEDITOR;
-
-		oumask = umask(077);
-		if ((tfp = fopen(tf, "w")) == NULL) {
-			perror(tf);
-			creatm = 0L;
-		} else {
-			fprintf(tfp, "To: %s\n", pathptr);
-			fprintf(tfp, "Subject: %s\n", subj);
-#ifdef INTERNET
-			fprintf(tfp, "News-Path: %s\n", hptr->path);
-#endif /* INTERNET */
-			fprintf(tfp, "References: %s\n\n", folbuf);
-			fstat(fileno(tfp), &statb);
-			creatm = statb.st_mtime;
-			(void) fclose(tfp);
-		}
-		(void) umask(oumask);
-
-		(void) sprintf(edcmdbuf, "%s %s", ed, tf);
-		(void) system(edcmdbuf);
-		(void) strcpy(rcbuf, MAILPARSER);
-		(void) strcat(rcbuf, " -t");
-		(void) strcat(rcbuf, " < ");
-		(void) strcat(rcbuf, tf);
-		if (access(tf, 4) || stat(tf, &statb)) {
-			fprintf(stderr, "Reply not sent: no input file.\n");
-			return FALSE;
-		}
-		if (statb.st_mtime == creatm) {
-			fprintf(stderr, "Reply not sent: cancelled.\n");
-			(void) unlink(tf);
-			return FALSE;
-		}
-		fprintf(ofp,"Sending reply.\n");
-		(void) fflush(stdout);
-		if (vfork() == 0) {
-			(void) system(rcbuf);
-			(void) unlink(tf);
-			_exit(0);
-		}
-	} else {
-		(void) sprintf(rcbuf, MAILER, hptr->title);
-		(void) sprintf(bfr, "%s %s", rcbuf, address);
-		(void) system(bfr);
-	}
-	hdr();
-	return TRUE;
-}
-
-xmit_command()
-{
-	tfilename = filename;
-	if (*bptr == '-') {
-		if (*ofilename1)
-			tfilename = ofilename1;
-		bptr++;
-	}
-	if (*bptr != '\0' && *bptr != ' ') {
-		fprintf(ofp, "Bad system name.\n");
-		return;
-	}
-	while (*bptr == ' ')
-		bptr++;
-	if (*bptr == '\0') {
-		fprintf(ofp, "Missing system name.\n");
-		return;
-	}
-	if (s_find(&srec, bptr) == NULL) {
-		fprintf(ofp, "%s not in SYSFILE\n", bptr);
-		return;
-	}
-	(void) transmit(&srec, tfilename);
-}
-
-next_ng_command()
-{
-	obit = -1;
-	if (!*bptr || *bptr == '-') {
-		if (cflag)
-			clear(bit);
-		else
-			putc('\n', ofp);
-		if (*bptr)
-			actdirect = BACKWARD;
-		rfq = 0;
-		saveart;
-		if (nextng()) {
-			if (actdirect == BACKWARD)
-				fprintf(ofp, "Can't back up.\n");
-			else
-				return TRUE;
-		}
-		return FALSE;
-	}
-	while (isspace(*bptr))
-		bptr++;
-	if (!validng(bptr)) {
-		fprintf(ofp, "No such group.\n");
-		return FALSE;
-	}
-	if (cflag)
-		clear(bit);
-	else
-		putc('\n', ofp);
-	readmode = SPEC;
-	rfq = 0;
-	saveart;
-	back();
-	selectng(bptr, TRUE, TRUE);
-	return FALSE;
-}
-
-caesar_command()
-{
-	char	temp[BUFLEN];
-	FILE	*pfp, *popen();
-
-	fprintf(stderr, "Caesar decoding:\n");
-	(void) sprintf(temp, "%s/%s", LIB, "caesar");
-	if (*bptr) {
-		(void) strcat(temp, " ");
-		(void) strcat(temp, bptr);
-	}
-	if (NLINES(h, fp) > LNCNT && *PAGER) {
-		(void) strcat(temp, " | ");
-		(void) strcat(temp, PAGER);
-	}
-	pfp = popen(temp, "w");
-	tprint(fp, pfp, FALSE);
-	FCLOSE(fp);
-	(void) pclose(pfp);
-}
-
-/*
- * Show the user the tail, if any, of the message on file
- * descriptor fd, and close fd.  The digester is considered,
- * and the pager is used if appropriate.
- */
-showtail(fd)
-FILE *fd;
-{
-	if (fd == NULL)
-		return;
-
-	if (dgest) {
-		digest(fd, ofp, h);
-	} else if (!lflag && !pflag && !eflag) {
-		pprint(fd);
-	}
-	(void) fclose(fd);
-}
-
-/*
- * Print out the rest of the article through the pager.
- */
-pprint(fd)
-FILE *fd;
-{
-#ifdef PAGE
-	/* Filter the tail of long messages through PAGER. */
-	if (NLINES(h, fd) > LNCNT && *PAGER) {
-		if (!index(PAGER, FMETA)) {
-			FILE *pfp, *popen();
-
-			pfp = popen(PAGER, "w");
-			if (pfp == NULL)
-				pfp = ofp;
-			/*
-			 * What follows is an attempt to prevent the
-			 * next message from scrolling part of this
-			 * message off the top of the screen before
-			 * the poor luser can read it.
-			 */
-			tprint(fd, pfp, FALSE);
-			putc('\f', pfp);
-			putc('\n', pfp);
-			putc(' ', pfp);
-			(void) pclose(pfp);
-		}
-		else
-			pout(ofp);
-		holdup = TRUE;
-	}
-	else
-#endif
-		tprint(fd, ofp, FALSE);
-}
-
-/*
- * Find the next article we want to consider, if we're done with
- * the last one, and show the header.
- */
-getnextart(minus)
-int minus;
-{
- 	int noaccess;
- 	register DIR *dirp;
- 	register struct direct *dir;
- 	long nextnum, tnum;
-
- 	noaccess = 0;
-
-	if (minus)
-		goto nextart2;	/* Kludge for "-" command. */
-
-	if (bit == obit)	/* Return if still on same article as last time */
-		return 0;
-
-	SigTrap = FALSE;
-
-nextart:
-#ifdef DEBUG
-	fprintf(stderr,"nextart:\n");
-#endif /* DEBUG */
-	dgest = 0;
-
-	if (bit < minartno && !rflag)
-		bit = minartno;
-
-	/* If done with this newsgroup, find the next one. */
-	while (ngsize <= 0 || (!rflag && ((long) bit > ngsize)) || (rflag && bit < minartno)) {
-		if (nextng()) {
-			if (actdirect == BACKWARD) {
-				fprintf(ofp, "Can't back up.\n");
-				actdirect = FORWARD;
-				continue;
-			} else
-				if (rfq++ || pflag || cflag)
-					return 1;
-			break;
-		}
-		if (rflag)
-			bit = ngsize + 1;
-		else
-			bit = minartno - 1;
-		if (uflag && !xflag) {
-			time_t now;
-			(void) time(&now);
-			if (now - timelastsaved > 5*60 /* 5 minutes */) {
-				if (!xflag)
-					fprintf(stderr,"[Saving .newsrc]\n");
-				writeoutrc();
-				timelastsaved = now;
-			}
-		}
-		noaccess = 0;
-	}
-
-nextart2:
-#ifdef DEBUG
-	fprintf(stderr, "article: %s/%ld\n", groupdir, bit);
-#endif
-	if (rcreadok)
-		rcreadok = 2;	/* have seen >= 1 article */
-	(void) sprintf(filename, "%s/%ld", dirname(groupdir), bit);
-	if (rfq && goodone[0])
-		strcpy(filename, goodone);
-	if (SigTrap) {
-		if (SigTrap == SIGHUP)
-			return 1;
-		if (!rcreadok)
-			xxit(0);
-		fprintf(ofp, "Abort (n)?  ");
-		(void) fflush(ofp);
-		(void) gets(bfr);
-		if (*bfr == 'y' || *bfr == 'Y')
-			xxit(0);
-		SigTrap = FALSE;
-	}
-#ifdef DEBUG
-	fprintf(stderr, "filename = '%s'\n", filename);
-#endif
-	/* Decide if we want to show this article. */
- 	if (bit <= 0 || (fp = art_open(filename, "r")) == NULL) {
-		/* don't show the header if the article was specifically
-		 * requested and it isn't there
-		 */
-		if (lbuf[0] == '<') {
-			lbuf[0] = '\0';
-			bit = -1;
-			return 1;
-		}
- 		/* since there can be holes in legal article numbers, */
- 		/* we wait till we hit 5 consecutive bad articles */
- 		/* before we haul off and scan the directory */
- 		if (++noaccess < 5)
- 			goto badart;
-		noaccess = 0;
- 		dirp = opendir(dirname(groupdir));
- 		if (dirp == NULL) {
-			if (errno != EACCES)
-				fprintf(stderr,"Can't open %s\n", dirname(groupdir));
- 			goto badart;
- 		}
- 		nextnum = rflag ? minartno - 1 : ngsize + 1;
- 		while ((dir = readdir(dirp)) != NULL) {
- 			tnum = atol(dir->d_name);
- 			if (tnum <= 0)
- 				continue;
- 			if (rflag ? (tnum > nextnum && tnum < bit)
- 				  : (tnum < nextnum && tnum > bit))
- 				nextnum = tnum;
- 		}
- 		closedir(dirp);
- 		if (rflag ? (nextnum >= bit) : (nextnum <= bit))
- 			goto badart;
-#ifdef DEBUG
-		fprintf(stderr,"nextnum = %ld\n",nextnum);
-#endif /* DEBUG */
- 		do {
- 			clear(bit);
- 			nextbit();
- 		} while (rflag ? (nextnum < bit) : (nextnum > bit));
- 		obit = -1;
- 		abs = FALSE;
-		if (ignorenews) /* ignored news is still news */
-			news = TRUE;
- 		goto nextart;
- 	} else
- 		noaccess = 0;
-
- 	if (ignorenews || hread(h, fp, TRUE) == NULL
-		|| (!rfq && !aselect(h, abs))) {
-		if (ignorenews)
-			news = TRUE;
- badart:
-#ifdef DEBUG
-		fprintf(stderr, "Bad article '%s'\n", filename);
-#endif
-		FCLOSE(fp);
-		clear(bit);
-		obit = -1;
-		nextbit();
-		abs = FALSE;
-		goto nextart;
-	}
-	abs = FALSE;
-	actdirect = FORWARD;
-	news = TRUE;
-	hdr();
-	if (pflag)
-		tprint(fp, ofp, FALSE);
-	else if (cflag && !lflag && !eflag) {
-		(void) fflush(ofp);
-		pprint(fp);
-	}
-	if (cflag || lflag || eflag || pflag) {
-		SigTrap = FALSE;
-		FCLOSE(fp);
-	}
-	obit = bit;
-	return 0;
-}
-
-/*
- * Print out whatever the appropriate header is
- */
-hdr()
-{
-	char *briefdate();
-
-	if (rfq)
-		return;
-
-	if (lflag || eflag) {
-		hprint(h, ofp, 0);
-		return;
-	}
-
-	/* Print out a header */
-	if (ngrp) {
-		pngsize = ngsize;
-		ngrp--;
-		nghprint(groupdir);
-	}
-	if (!hflag)
-		fprintf(ofp, "Article %ld of %ld, %s.\n",
-			bit, pngsize, briefdate(h->subdate));
-	hprint(h, ofp, pflag ? 1 : 0);
-}
-
-nghprint(title)
-char *title;
-{
-	char *tstr = "Newsgroup ";
-	int l = strlen(title) + strlen(tstr);
-
-	fprintf(ofp, "\n");
-	if (!hflag) {
-		dash(l, ofp);
-		fprintf(ofp, "%s%s\n", tstr, title);
-		dash(l, ofp);
-	} else {
-		fprintf(ofp, "%s%s, ", tstr, title);
-		if (bit == pngsize)
-			fprintf(ofp, "%ld\n", pngsize);
-		else
-			fprintf(ofp, "%ld-%ld\n", bit, pngsize);
-	}
-	fprintf(ofp, "\n");
-}
-
-/*
- * Routine to catch a continue signal.
- */
-catchcont(sig)
-int sig;
-{
-	(void) signal(sig, catchcont);
-	SigTrap = sig;
-	(void) fflush(ofp);
-#ifdef SIGCONT
-	if (fp && sig == SIGCONT)
-		hdr();
-	if (sig != SIGCONT)
-#endif /* SIGCONT */
-		putc('\n', ofp);
-	if (canlongjmp)
-		longjmp(sigjmpbuf,1);
-}
-
-xxit(status)
-int	status;
-{
-	(void) unlink(infile);
-	(void) unlink(outfile);
-#ifdef SORTACTIVE
-	if (strncmp(ACTIVE,"/tmp/", 5) == 0)
-		(void) unlink(ACTIVE);
-#endif /* SORTACTIVE */
-	exit(status);
-}
*-*-END-of-src/readr.c-*-*
echo x - src/pathinit.c 1>&2
sed 's/.//' >src/pathinit.c <<'*-*-END-of-src/pathinit.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.
- *
- * This function initializes all the strings used for the various
- * filenames.  They cannot be compiled into the program, since that
- * would be non-portable.  With this convention, the netnews sub-system
- * can be owned by any non-privileged user.  It is also possible
- * to work when the administration randomly moves users from one
- * filesystem to another.  The convention is that a particular user
- * (HOME, see Makefile) is searched for in /etc/passwd and all files
- * are presumed relative to there.  This method also allows one copy
- * of the object code to be used on ANY machine.  (this code runs
- * un-modified on 50+ machines at IH!!)
- *
- * The disadvantage to using this method is that all netnews programs
- * (inews, readnews, rnews, checknews) must first search /etc/passwd
- * before they can start up.  This can cause significant overhead if
- * you have a big password file.
- *
- * Some games are played with ifdefs to get four .o files out of this
- * one source file.  INEW is defined for inews, READ for readnews,
- * CHKN for checknews, and EXP for expire.
- */
-
-#ifdef SCCSID
-static char	*SccsId = "@(#)pathinit.c	1.18	10/23/86";
-#endif /* SCCSID */
-
-#if defined(INEW) || defined(EXP)
-#include	"iparams.h"
-#endif /* INEW || EXP */
-
-#ifdef READ
-#include	"rparams.h"
-#endif /* READ */
-
-#if defined(CHKN)
-#include "params.h"
-#endif /* CHKN */
-
-
-char *FULLSYSNAME, *SPOOL, *LIB, *BIN, *ACTIVE, *SUBFILE, *ARTFILE,
-	*username, *userhome;
-
-#ifdef INEW
-char *LOCKFILE, *SEQFILE, *ARTICLE, *INFILE, *TELLME;
-
-int c_cancel(), c_newgroup(), c_ihave(), c_sendme(), c_rmgroup(),
-    c_sendsys(), c_senduuname(), c_version(), c_checkgroups(), c_unimp();
-
-struct msgtype msgtype[] = {
-	"cancel", NULL, c_cancel,
-	"newgroup", NULL, c_newgroup,
-	"ihave", NULL, c_ihave,
-	"sendme", NULL, c_sendme,
-	"sendbad", NULL, c_sendme,
-	"rmgroup", NULL, c_rmgroup,
-	"sendsys", NULL, c_sendsys,
-	"senduuname", NULL, c_senduuname,
-	"version", NULL, c_version,
-	"checkgroups", NULL, c_checkgroups,
-	"delsub", NULL, c_unimp,
-	NULL, NULL, NULL
-};
-#endif /* INEW */
-
-#if defined(INEW) || defined(READ)
-char *ALIASES;
-#endif /* INEW || READ */
-
-#ifdef EXP
-char *OLDNEWS;
-#endif /* EXP */
-
-#ifdef READ
-char *MAILPARSER;
-#endif /* READ */
-
-#ifdef HIDDENNET
-char *LOCALSYSNAME;
-#endif /* HIDDENNET */
-
-
-struct passwd *getpwnam();
-char *rindex();
-
-#define Sprintf(where,fmt,arg)	(void) sprintf(bfr,fmt,arg); where = AllocCpy(bfr)
-
-char *
-AllocCpy(cp)
-register char *cp;
-{
-	register char *mp;
-	char *malloc();
-
-	mp = malloc((unsigned)strlen(cp) + 1);
-
-	if (mp == NULL)
-		xerror("malloc failed on %s", cp);
-
-	(void) strcpy(mp, cp);
-	return mp;
-}
-
-pathinit()
-{
-#if defined(INEW) && defined(NOTIFY)
-	FILE *nfd;		/* notify file descriptor */
-	char *p;
-#endif /* INEW && NOTIFY */
-#ifndef ROOTID
-	struct passwd	*pw;	/* struct for pw lookup	*/
-#endif /* !ROOTID */
-#ifdef EXP
-	char *p;
-#endif /* EXP */
-#ifndef CHKN
-	struct utsname ubuf;
-
-	uname(&ubuf);
-#ifdef HIDDENNET
-	FULLSYSNAME = AllocCpy(HIDDENNET);
-	LOCALSYSNAME = AllocCpy(ubuf.nodename);
-#else /* !HIDDENNET */
-	FULLSYSNAME = AllocCpy(ubuf.nodename);
-#endif /* !HIDDENNET */
-#endif /* !CHKN */
-
-#ifdef HOME
-	/* Relative to the home directory of user HOME */
-	(void) sprintf(bfr, "%s/%s", logdir(HOME), SPOOLDIR);
-	SPOOL = AllocCpy(bfr);
-	(void) sprintf(bfr, "%s/%s", logdir(HOME), LIBDIR);
-	LIB = AllocCpy(bfr);
-#else /* !HOME */
-	/* Fixed paths defined in Makefile */
-	SPOOL = AllocCpy(SPOOLDIR);
-	LIB = AllocCpy(LIBDIR);
-#endif /* !HOME */
-
-#ifdef IHCC
-	(void) sprintf(bfr, "%s/%s", logdir(HOME), BINDIR);
-	BIN = AllocCpy(bfr);
-#else /* !IHCC */
-	Sprintf(BIN, "%s", BINDIR);
-#endif /* !IHCC */
-
-	Sprintf(ACTIVE, "%s/active", LIB);
-
-#ifdef EXP
-	(void) strcpy(bfr, SPOOL);
-	p = rindex(bfr, '/');
-	if (p) {
-		strcpy(++p, "oldnews");
-		OLDNEWS = AllocCpy(bfr);
-	} else
-		OLDNEWS = AllocCpy("oldnews");
-#endif /* EXP */
-
-#ifndef CHKN
-	Sprintf(SUBFILE, "%s/sys", LIB);
-	Sprintf(ARTFILE, "%s/history", LIB);
-# endif /* !CHKN */
-
-# ifdef READ
-#ifdef SENDMAIL
-	Sprintf(MAILPARSER, "%s -oi -oem", SENDMAIL);
-#else /* !SENDMAIL */
-	Sprintf(MAILPARSER, "%s/recmail", LIB);
-#endif /* !SENDMAIL */
-# endif /* READ */
-
-# if defined(READ) || defined(INEW)
-	Sprintf(ALIASES, "%s/aliases", LIB);
-# endif /* READ || INEW */
-# ifdef INEW
-	Sprintf(LOCKFILE, "%s/LOCK", LIB);
-	Sprintf(SEQFILE, "%s/seq", LIB);
-	Sprintf(ARTICLE, "%s/.arXXXXXX", SPOOL);
-	Sprintf(INFILE, "%s/.inXXXXXX", SPOOL);
-/*
- * The person notified by the netnews sub-system.  Again, no name is
- * compiled in, but instead the information is taken from a file.
- * If the file does not exist, a "default" person will get the mail.
- * If the file exists, but is empty, nobody will get the mail.  This
- * may seem backwards, but is a better fail-safe.
- */
-# ifdef NOTIFY
-	parse_notify();
-# endif /* NOTIFY */
-
-/*
- * Since the netnews owner's id number is different on different
- * systems, we'll extract it from the /etc/passwd file.  If no entry,
- * default to root.  This id number seems to only be used to control who
- * can input certain control messages or cancel any message.  Note that
- * entry is the name from the "notify" file as found above if possible.
- * Defining ROOTID in defs.h hardwires in a number and avoids
- * another search of /etc/passwd.
- */
-# ifndef ROOTID
-	if ((pw = getpwnam(TELLME)) != NULL)
-		ROOTID =  pw->pw_uid;
-	else if ((pw = getpwnam(HOME)) != NULL)
-		ROOTID =  pw->pw_uid;
-	else
-		ROOTID = 0;		/* nobody left, let only root */
-# endif /* !ROOTID */
-#endif /* INEW */
-}
-
-#ifdef INEW
-#ifdef NOTIFY
-/*
- * Attempt to parse the LIB/notify file into the global structure msgtype[].
- */
-parse_notify()
-{
-	FILE *nfd;
-	int valid = 0, done = 0;
-	register struct msgtype *mp;
-	char mtype[BUFLEN], addr[BUFLEN];
-
-	(void) sprintf(bfr, "%s/notify", LIB);
-#ifndef ROOTID
-	TELLME = AllocCpy(NOTIFY);	
-#endif /* !ROOTID */
-	if ( (nfd = fopen(bfr, "r")) == NULL) {
-		/* 
-		 * Set defaults to NOTIFY
-		 */
-#ifdef debug
-		log("parse_notify: %s/notify not found", LIB);
-#endif /* debug */
-		(void)setmsg("all", NOTIFY);
-		return;
-	}
-	do  {
-		mtype[0] = addr[0] = 0;
-		switch( get_notify(nfd, mtype, addr) ) {
-		case 0:
-			continue;
-		case 1:
-			valid += setmsg(mtype, "");
-			break;
-		case 2:
-			valid += setmsg(mtype, addr);
-			break;
-		case -1:
-			if( !valid ) {
-#ifdef debug
-				log("parse_notify: no valid entries found.");
-#endif /* debug */
-				setmsg("all", ""); /* send mail to no one */
-			}
-			done = 1;
-		}
-	} while( !done );
-
-	/*
-	 * point to zero length string for all entries we haven't touched
-	 */
-	for(mp=msgtype; mp->m_name; mp++)
-		if(mp->m_who_to == 0)
-			mp->m_who_to = "";
-}
-
-setmsg(what, to)
-char *what, *to;
-{
-	register struct msgtype *mp;
-#ifdef debug
-	log("setmsg: what='%s', to='%s'", what, to);
-#endif /* debug */
-	/*
-	 * Special case for "all"
-	 */
-	if(strcmp(what, "all") == 0) {
-		for(mp=msgtype; mp->m_name; mp++) {
-			mp->m_who_to = AllocCpy(to);
-#ifdef debug
-			log("setmsg: '%s'='%s'", mp->m_name, mp->m_who_to);
-#endif /* debug */
-		}
-		return 1;
-	}
-
-	for(mp=msgtype; mp->m_name; mp++)
-		if(strcmp(mp->m_name, what) == 0) {
-			mp->m_who_to = AllocCpy(to);
-#ifdef debug
-			log("setmsg: '%s'='%s'", mp->m_name, mp->m_who_to);
-#endif /* debug */
-			return 1;
-		}
-	return 0;
-}
-
-static
-get_notify(fp, s, t)
-FILE *fp;
-register char *s, *t;
-{
-	register char *cp;
-	char buf[BUFSIZ];
-
-	if( cp=fgets(buf, sizeof(buf), fp ) ) {
-		if( *cp == '\n' ) 
-			return 0;
-		while(*cp && *cp != ' ' && *cp != '\t' && *cp != '\n')
-			*s++ = *cp++;
-		*s = '\0';	/* terminate first string */
-
-		while(*cp && (*cp == ' ' || *cp == '\t' || *cp == '\n') )
-			cp++;	/* look for start of second */
-		if( !*cp || *cp == '\n' )
-			return 1; 	/* no second string */
-		
-		while( *cp && *cp != '\n' )
-			*t++ = *cp++;
-		*t = '\0';
-		return 2;
-	} else
-		return -1;
-}
-#endif /* NOTIFY */
-#endif /* INEW */
*-*-END-of-src/pathinit.c-*-*
echo x - src/localize.sample 1>&2
sed 's/.//' >src/localize.sample <<'*-*-END-of-src/localize.sample-*-*'
-rm -f Makefile
-cp Makefile.dst Makefile
-chmod u+w Makefile
-ed Makefile  <<'EOF'
-/^UUXFLAGS/s/-r -z/-r -z -n -gd/
-g/^#V7 /s///
-g/^#BSD4_3 /s///
-g/^#BSD4_1 /d
-g/^#USG /d
-/^LIBDIR/s;/usr/lib/news;/usr/new/lib/news;
-/^BINDIR/s;/usr/bin;/usr/new;
-w
-q
-EOF
-rm -f defs.h
-cp defs.dist defs.h
-chmod u+w defs.h
-ed - defs.h <<'EOF'
-/ROOTID/s/10/352/
-/N_UMASK/s/000/002/
-/DFTXMIT/s/-z/-z -gd/
-/UXMIT/s/-z/-z -gd/
-/NONEWGROUPS/s;/\* ;;
-/INTERNET/s;/\* ;;
-/MYDOMAIN/s;.UUCP;.CSS.GOV;
-/GHNAME/s;/\* ;;
-/DOXREFS/s;/\* ;;
-/BSD4_2/s;/\* ;;
-/ALWAYSALIAS/s;/\* ;;
-/SENDMAIL/s;/\* ;;
-/HIDDENNET/s;frooz;seismo;
-s;/\* ;;
-/MYORG/s/Frobozz Inc., St. Louis/Center for Seismic Studies, Arlington, VA/
-/ORGDISTRIB/s;/\* ;;
-/ORGDISTRIB/s;froozum;css;
-w
-q
-EOF
*-*-END-of-src/localize.sample-*-*
exit