[mod.sources] v07i051: 2.11 News Source, Part01/09

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

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

[  Again, notice the different between the Part# in the Subject line
   and the Part# in the Archive-name.  --r$  ]

# To extract, sh this file
#
#	news 2.11 source part 1 of 9
#
if test ! -d src
then
	mkdir src
fi
echo x - src/visual.c 1>&2
sed 's/.//' >src/visual.c <<'*-*-END-of-src/visual.c-*-*'
-/*
- * visual - visual news interface.
- * Kenneth Almquist
- */
-
-#ifdef SCCSID
-static char	*SccsId = "@(#)visual.c	1.32	10/23/86";
-#endif /* SCCSID */
-
-#include "rparams.h"
-#ifdef USG
-#include <sys/ioctl.h>
-#include <termio.h>
-#include <fcntl.h>
-#else /* !USG */
-#include <sgtty.h>
-#endif /* !USG */
-
-#include <errno.h>
-#if defined(BSD4_2) || defined(BSD4_1C)
-#include <sys/dir.h>
-#else
-#include "ndir.h"
-#endif
-#ifdef BSD4_2
-#ifndef sigmask
-#define sigmask(m) (1<<((m)-1))
-#endif /* !sigmask */
-#endif /* BSD4_2 */
-#ifdef MYDB
-#include "db.h"
-#endif /* MYDB */
-
-extern int errno;
-
-#ifdef SIGTSTP
-#include <setjmp.h>
-#endif /* SIGTSTP */
-
-#define ARTWLEN	(ROWS-2)/* number of lines used to display article */
-#define even(cols) ((cols&1) ? cols + 1 : cols)
-#ifdef STATTOP
-#define PRLINE	0	/* prompter line */
-#define SPLINE	1	/* secondary prompt line */
-#define ARTWIN	2	/* first line of article window */
-#define SECPRLEN 81	/* length of secondary prompter */
-#else
-#define PRLINE	(ROWS-1)/* prompter line */
-#define SPLINE	(ROWS-2)/* secondary prompt line */
-#define ARTWIN	0	/* first line of article window */
-#define SECPRLEN 100	/* length of secondary prompter */
-#endif
-
-#define PIPECHAR '|'	/* indicate save command should pipe to program */
-#define META	0200	/* meta character bit (as in emacs) */
-/* print (display) flags */
-#define HDRONLY	0001	/* print header only */
-#define NOPRT	0002	/* don't print at all */
-#define NEWART	0004	/* force article display to be regenerated */
-#define HELPMSG	0010	/* display currently contains help message */
-/* prun flags */
-#define CWAIT	0001	/* type "continue?" and wait for return */
-#define BKGRND	0002	/* run process in the background */
-/* values of curflag */
-#define CURP1	1	/* cursor after prompt */
-#define CURP2	2	/* cursor after secondary prompt */
-#define CURHOME	3	/* cursor at home position */
-/* flags for vsave routine */
-#define SVHEAD	01	/* write out article header */
-#define OVWRITE	02	/* overwrite the file if it already exists */
-/* other files */
-
-#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))
-
-/* terminal handler stuff */
-extern int _junked;
-#define clearok(xxx, flag) _junked = flag
-extern int COLS;
-extern int ROWS;
-extern int hasscroll;
-
-FILE *tmpfile();
-char *getmailname();
-#ifdef MYDB
-char *findparent();
-#endif /* MYDB */
-int onint();
-int onstop();
-int xxit();
-
-char *Progname = "vnews";		/* for xerror */
-
-/* variables shared between vnews routines */
-static char linebuf[LBUFLEN];		/* temporary workspace */
-static FILE *tfp;			/* temporary file */
-static char tfname[] = "/tmp/vnXXXXXX";	/* name of temp file */
-static long artbody;			/* offset of body into article */
-static int quitflg;			/* if set, then quit */
-static int erased;			/* current article has been erased */
-static int artlines;			/* # lines in article body */
-static int artread;			/* entire article has been read */
-static int hdrstart;			/* beginning of header */
-static int hdrend;			/* end of header */
-static int lastlin;			/* number of lines in tempfile */
-static int tflinno = 0;			/* next line in tempfile */
-static int maxlinno;			/* number of lines in file + folded */
-static char secpr[SECPRLEN];		/* secondary prompt */
-static char prompt[30];			/* prompter */
-static short prflags;			/* print flags (controls updscr) */
-static short curflag;			/* where to locate cursor */
-static int dlinno;			/* top line on screen */
-static char timestr[20];		/* current time */
-static int ismail;			/* true if user has mail */
-static char *mailf;			/* user's mail file */
-static int alflag;			/* set if unprocessed alarm signal */
-static int atend;			/* set if at end of article */
-static char cerase;			/* erase character */
-static char ckill;			/* kill character */
-static char cintr;			/* interrupt character */
-#ifdef TIOCGLTC
-static char cwerase;			/* word erase character */
-#endif /* TIOCGLTC */
-short ospeed;				/* terminal speed NOT STATIC */
-static int intflag;			/* set if interrupt received */
-
-#ifdef SIGTSTP
-static int reading;			/* to keep stupid BSD from restarting reads */
-jmp_buf intjmp, alrmjmp;
-#endif /* SIGTSTP */
-
-#ifdef MYDB
-static int hasdb;			/* true if article data base exists */
-#endif /* MYDB */
-
-#ifdef DIGPAGE
-static int endsuba;			/* end of sub-article in digest */
-#endif
-
-#ifdef MYDEBUG
-FILE *debugf;				/* file to write debugging info on */
-#endif
-
-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 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 char *tfilename;			/* temporary file name 		*/
-static char ofilename1[BUFLEN];		/* previous file name		*/
-static struct hbuf hbuf1, hbuf2; 	/* for minusing			*/
-static struct hbuf *h = &hbuf1,		/* current header		*/
-		*hold = &hbuf2,		/* previous header		*/
-		*hptr;			/* temporary			*/
-static char *ptr1, *ptr2, *ptr3;	/* for reply manipulation	*/
-static int  aabs = FALSE;		/* TRUE if we asked absolutely	*/
-static char *ed, tf[100];
-static long oobit;			/* last bit, really		*/
-static int dgest = 0;
-static FILE *fp;			/* current article to be printed*/
-
-readr()
-{
-
-#ifdef MYDEBUG
-	debugf = fopen("DEBUG", "w");
-	setbuf(debugf, (char *)NULL);
-#endif
-	if (aflag) {
-		if (*datebuf) {
-			if ((atime = cgtdate(datebuf)) == -1)
-				xerror("Cannot parse date string");
-		} else
-			atime = 0;
-	}
-
-	if (SigTrap)
-		xxit(1);
-	(void) mktemp(tfname);
-	(void) close(creat(tfname,0666));
-	if ((tfp = fopen(tfname, "w+")) == NULL)
-		xerror("Can't create temp file");
-	(void) unlink(tfname);
-	mailf = getmailname();
-#ifdef MYDB
-	if (opendb() >= 0) {
-		hasdb = 1;
-		fputs("Using article data base\n", stderr);	/*DEBUG*/
-		getng();
-	}
-#endif
-	ttysave();
-	(void) signal(SIGINT, onint);
-	(void) signal(SIGQUIT, xxit);
-	if (SigTrap)
-		xxit(1);
-	ttyraw();
-	timer();
-
-	/* loop reading articles. */
-	fp = NULL;
-	obit = -1;
-	nextng();
-	quitflg = 0;
-	while (quitflg == 0) {
-		if (getnextart(FALSE))
-			break;
-		(void) strcpy(goodone, filename);
-		if (SigTrap)
-			return;
-		vcmd();
-	}
-
-	if (!news) {
-		fprintf(stderr, "No news.\n");
-	}
-}
-
-/*
- * Read and execute a command.
- */
-vcmd() {
-	register c;
-	char *p;
-	long count;
-	int countset;
-
-	if (prflags & HDRONLY)
-		appfile(fp, lastlin + 1);
-	else
-		appfile(fp, dlinno + ARTWLEN + 1);
-
-#ifdef DIGPAGE
-	endsuba = findend(dlinno);
-	if (artlines > dlinno + ARTWLEN
-	 || endsuba > 0 && endsuba < artlines
-#else
-	if (artlines > dlinno + ARTWLEN
-#endif
-	 || (prflags & HDRONLY) && artlines > hdrend) {
-		atend = 0;
-		if (prflags&HDRONLY || maxlinno == 0)
-			(void) strcpy(prompt, "more? ");
-		else
-#ifdef DIGPAGE
-			(void) sprintf(prompt, "more(%d%%)? ",
-				((((endsuba > 0) ?
-				endsuba : (dlinno + ARTWLEN)) -
-				hdrend) * 100) / maxlinno);
-#else /* !DIGPAGE */
-			(void) sprintf(prompt, "more(%d%%)? ",
-				((dlinno + ARTWLEN - hdrend) * 100) / maxlinno);
-#endif /* !DIGPAGE */
-	} else {
-		atend = 1;
-		(void) strcpy(prompt, "next? ");
-		if (!erased)
-			clear(bit);		/* article read */
-	}
-	curflag = CURP1;
-	p = prompt + strlen(prompt);
-	countset = 0;
-	count = 0;
-	/*
-	 * Loop while accumulating a count, until an action character
-	 * is entered. Also handle "meta" here.
-	 *
-	 * Count is the current count. Countset=0 means no count
-	 * currently exists. Countset=1, count=0 is valid and means 
-	 * a count of 0 has been entered 
-	 */
-	for (;;) {
-		c = vgetc();
-		if (c == cerase || c == '\b' || c == '\177') {
-			if (countset == 0)
-				break;		/* Use as action char */
-			if (count < 10)
-				countset = 0;	/* Erase only char of count */
-			else
-				count /= 10L;	/* Erase 1 char of count */
-		} else {
-#ifdef TIOCGLTC
-			if (c == ckill || c == cwerase) {
-#else
-			if (c == ckill) {
-#endif
-				if (countset == 0)
-					break;
-				countset = 0;
-			} else if (c < '0' || c > '9')
-					break;
-				else {
-					countset = 1;
-					count = (count * 10) + (c - '0');
-				}
-		}
-		if (countset) {
-			(void) sprintf(p, "%ld", count);
-		} else {
-			*p = '\0';
-			count = 0;
-		}
-	}
-
-	if (c == '\033') {			/* escape */
-		(void) strcat(prompt, "M-");
-		c = vgetc();
-		if (c != cintr)
-			c |= META;
-	}
-	secpr[0] = '\0';
-	if (countset == 0)
-		count = 1;
-	docmd(c, count);
-	if (c != '?' && c != 'H')		/* UGGH */
-		prflags &=~ HELPMSG;
-	if (dlinno > hdrstart)
-		prflags &=~ HDRONLY;
-}
-
-
-/*
- * Process one command, which has already been typed in.
- */
-docmd(c, count)
-int c;
-long count;
-{
-	int i;
-	long nart, Hoffset;
-	char *findhist();
-
-	switch (c) {
-
-	/* Show more of current article, or advance to next article */
-	case '\n':
-	case ' ':
-#ifdef DIGPAGE
-	case 'm':
-#endif /* DIGPAGE */
-	case '\06':	/* Control-F for vi compat */
-		prflags &=~ NOPRT;
-		if (atend)
-			goto next;
-		else if (prflags & HDRONLY) {
-			prflags &=~ HDRONLY;
-			if (hasscroll)
-				dlinno = hdrstart;}
-#ifdef DIGPAGE
-		else if (endsuba > 0)
-			dlinno = endsuba;
-		else if (c == 'm') {
-			do {
-				if (lastlin >= maxlinno)
-					goto next;
-				else
-					appfile(fp, lastlin + 1);
-			} while(strncmp(linebuf, "------------------------", 24)
-				!= 0);
-			dlinno = endsuba = lastlin;
-		}
-#endif
-		else if ((appfile(fp, dlinno + 2 * ARTWLEN), artread)
-		 && hasscroll && artlines - dlinno <= ARTWLEN + 2)
-			dlinno = artlines - ARTWLEN;
-		else
-			dlinno += ARTWLEN * count;
-		break;
-
-	/* No.  Go on to next article. */
-	case '.':	/* useful if you have a keypad */
-next:	case 'n':
-		readmode = NEXT;
-		FCLOSE(fp);
-		clear(bit);
-		saveart;
-		nextbit();
-		break;
-
-
-	/* Back up count pages */
-	case '\b':	
-	case '\177':	
-		if (dlinno == 0)
-			goto backupone;
-		/* NO BREAK */
-	case META|'v':
-	case '\002':	/* Control-B */
-		dlinno -= ARTWLEN * count;
-		if (dlinno < 0)
-			dlinno = 0;
-		break;
-
-	/* forward half a page */
-	case '\004':	/* Control-D, as in vi */
-		if (!atend)
-			dlinno += ARTWLEN/2 * count;
-		break;
-
-	/* backward half a page */
-	case '\025':	/* Control-U */
-		dlinno -= ARTWLEN/2 * count;
-		if (dlinno < 0)
-			dlinno = 0;
-		break;
-
-	/* forward count lines */
-	case '\016':	/* Control-N */
-	case '\005':	/* Control-E */
-		dlinno += count;
-		break;
-
-	/* backwards count lines */
-	case '\020':	/* Control-P */
-	case '\031':	/* Control-Y */
-		dlinno -= count;
-		if (dlinno < 0)
-			dlinno = 0;
-		break;
-
-	/* Turn displaying of article back on */
-	case 'l':
-	case 'd':
-		prflags &=~ NOPRT;
-		break;
-
-	/* display header */
-	case 'h':
-		dlinno = hdrstart;
-		prflags |= HDRONLY;
-		prflags &=~ NOPRT;
-		break;
-
-	/*
-	 * Unsubscribe to the newsgroup and go on to next group
-	 */
-
-	case 'U':
-	case 'u':
-		strcat(prompt, "u");
-		c = vgetc();
-		if (c == 'g') {
-			obit = -1;
-			FCLOSE(fp);
-			zapng = TRUE;
-			saveart;
-			if (nextng()) {
-				if (actdirect == BACKWARD)
-					msg("Can't back up.");
-				else
-					quitflg = 1;	/* probably unnecessary */
-			}
-		} else {
-			if (c != cintr && c != ckill)
-				beep();
-				msg("Illegal command");
-		}
-		break;
-
-		/* Print the current version of news */
-	case 'v':
-		msg("News version: %s", news_version);
-		break;
-
-
-	/* Decrypt joke.  Always does rot 13 */
-	case 'D':
-		appfile(fp, 32767);
-		for (i = hdrend ; i < artlines ; i++) {
-			register char ch, *p;
-			tfget(linebuf, i);
-			for (p = linebuf ; (ch = *p) != '\0' ; p++) {
-				if (ch >= 'a' && ch <= 'z')
-					*p = (ch - 'a' + 13) % 26 + 'a';
-				else if (ch >= 'A' && ch <= 'Z')
-					*p = (ch - 'A' + 13) % 26 + 'A';
-			}
-			tfput(linebuf, i);
-		}
-		prflags |= NEWART;
-		prflags &=~ (HDRONLY|NOPRT);
-		break;
-
-		/* write out the article someplace */
-		/* w writes out without the header */
-	case 's':
-	case 'w': {
-		char *grn = groupdir;
-		int wflags;
-
-		msg("file: ");
-		curflag = CURP2;
-		while ((wflags = vgetc()) == ' ');
-		if (wflags == cintr) {
-			secpr[0] = '\0';
-			break;
-		}
-		if (wflags == '|') {
-			linebuf[0] = '|';
-			if (prget("| ", linebuf+1))
-				break;
-		} else {
-			pushback(wflags);
-			if (prget("file: ", linebuf))
-				break;
-		}
-		wflags = 0;
-		if (c == 's')
-			wflags |= SVHEAD;
-		if (count != 1)
-			wflags |= OVWRITE;
-		bptr = linebuf;
-		while( *bptr == ' ')
-			bptr++;	/* strip leading spaces */
-
-		if (*bptr != PIPECHAR && *bptr != '/') {
-			char	hetyped[BUFLEN];
-			char	*boxptr;
-			(void) strcpy(hetyped, bptr);
-			if (hetyped[0] == '~' && hetyped[1] == '/') {
-  				strcpy(hetyped, bptr+2);
-  				strcpy(bptr, userhome);
-			} else if (boxptr = getenv("NEWSBOX")) {
- 				if (index(boxptr, '%')) {
-					struct stat stbf;
- 					sprintf(bptr, boxptr, grn);
- 					if (stat(bptr,&stbf) < 0) {
- 						if (mkdir(bptr, 0777) < 0) {
-							msg("Cannot create directory %s", bptr);
-							break;
-						}
-					} else if ((stbf.st_mode&S_IFMT) !=  S_IFDIR) {
-						msg("%s not a directory", bptr);
-						break;
-					}
-				} else
-					strcpy(bptr, boxptr);
-  			 } else
-  				bptr[0] = '\0';
-
-			if (bptr[0])
-				(void) strcat(bptr, "/");
-			if (hetyped[0] != '\0')
-				(void) strcat(bptr, hetyped);
-			else
-				(void) strcat(bptr, "Articles");
-		}
-		vsave(bptr, wflags);
-		break;
-	}
-
-		/* back up  */
-	case '-':
-caseminus:
-		aabs = TRUE;
-		if (!*ofilename1) {
-			msg("Can't back up.");
-			break;
-		}
-		FCLOSE(fp);
-		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, FALSE, FALSE);
-			(void) strcpy(groupdir, ogroupdir);
-			(void) strcpy(ogroupdir, bfr);
-			ngrp = 1;
-			back();
-		}
-		bit = oobit;
-		oobit = obit;
-		obit = -1;
-		getnextart(TRUE);
-		break;
-
-		/* skip forwards */
-	case '+':
-	case '=':
-caseplus:	if (count == 0)
-			break;
-		saveart;
-		last = bit;
-		for (i = 0; i < count; i++) {
-			nextbit();
-			if ((bit > pngsize) || (rflag && bit < 1))
-				break;
-		}
-		FCLOSE(fp);
-		obit = -1;
-		break;
-
-	/* exit - time updated to that of most recently read article */
-	case 'q':
-		quitflg = 1;
-		break;
-
-	case 'x':
-		xxit(0);
-		break;
-
-	/* cancel the article. */
-	case 'c':
-		strcpy(prompt, "cancel [n]? ");
-		if (vgetc() != 'y') {
-			msg("Article not cancelled");
-			break;
-		}
-		cancel_command();
-		break;
-
-	/* escape to shell */
-	case '!': {
-		register char *p;
-		int flags;
-
-		p = linebuf;
-		if (prget("!", p))
-			break;
-		flags = CWAIT;
-		if (*p == '\0') {
-			(void) strcpy(linebuf, SHELL);
-			flags = 0;
-		}
-		while (*p) p++;
-		while (p > linebuf && p[-1] == ' ')
-			p--;
-		if (*--p == '&') {
-			*p = '\0';
-			flags = BKGRND;
-		} else if (*p == '|') {
-			*p = '\0';
-			(void) sprintf(bfr, "(%s)|mail '%s'", linebuf, username);
-			(void) strcpy(linebuf, bfr);
-			flags |= BKGRND;
-		} else {
-			prflags |= NOPRT;
-		}
-		shcmd(linebuf, flags);
-		break;
-	}
-
-	/* mail reply */
-	case 'r':
-		reply(FALSE);
-		break;
-
-	case 'R':
-		reply(TRUE);
-		break;
-
-	case META|'r':
-		direct_reply();
-		break;
-
-	/* next newsgroup */
-	case 'N':
-		FCLOSE(fp);
-		if (next_ng_command())
-			quitflg = 1;
-		break;
-
-	/*  mark the rest of the articles in this group as read */
-	case 'K':
-		saveart;
-		while (bit <= ngsize && bit >= minartno) {
-			clear(bit);
-			nextbit();
-		}
-		FCLOSE(fp);
-		break;
-
-	/* Print the full header */
-	case 'H':
-		if (fp == NULL) {
-			msg("No current article");
-			break;
-		}
-		move(ARTWIN, 0);
-		Hoffset = ftell(fp);
-		(void) fseek(fp, 0L, 0);
-		for (i = 0; i < ARTWLEN; i++) {
-			if (fgets(linebuf, COLS, fp) == NULL)
-				break;
-			if (linebuf[0] == '\n')
-				break;
-			linebuf[COLS] = '\0';
-			addstr(linebuf);
-		}
-		(void) fseek(fp, Hoffset, 0);
-		for(; i < ARTWLEN; i++)
-			addstr(linebuf);
-		prflags |= HELPMSG|NEWART;
-		break;
-	case 'b':	/* backup 1 article */
-backupone:
-		count = bit - 1;
-		/* NO BREAK */
-
-	case 'A':	/* specific number */
-		if (count > pngsize) {
-			msg("not that many articles");
-			break;
-		}
-		readmode = SPEC;
-		aabs = TRUE;
-		bit = count;
-		obit = -1;
-		FCLOSE(fp);
-		break;
-
-	/* display parent article */
-	case 'p':
-#ifdef MYDB
-		if (hasdb && (ptr3 = findparent(h->ident, &nart)) != NULL) {
-			msg("parent: %s/%ld", ptr3, nart);	/*DEBUG*/
-			updscr();				/*DEBUG*/
-			goto selectart;
-		}
-#endif
-		if (h->followid[0] == '\0') {
-			msg("no references line");
-			break;
-		}
-		ptr1 = h->followid + strlen(h->followid);
-		do {
-			ptr2 = ptr1;
-			if (*ptr2 == '\0')
-				ptr1 = rindex(h->followid, ' ');
-			else {
-				*ptr2 = '\0';
-				ptr1 = rindex(h->followid, ' ');
-				*ptr2 = ' ';
-			}
-		} while (ptr1 != NULL && --count > 0);
-		if (ptr1 == NULL)
-			ptr1 = h->followid;
-		else	++ptr1;
-		(void) strncpy(linebuf, ptr1, ptr2 - ptr1);
-		linebuf[ptr2 - ptr1] = '\0';
-		msg("%s", linebuf);
-		curflag = CURP2;
-		updscr();		/* may take this out later */
-		goto searchid;
-	/* specific message ID. */
-	case '<':
-		/* could improve this */
-		linebuf[0] = '<';
-		if (prget("<", linebuf+1))
-			break;
-searchid:	secpr[0] = '\0';
-		if (index(linebuf, '@') == NULL && index(linebuf, '>') == NULL) {
-			ptr1 = linebuf;
-			if (*ptr1 == '<')
-				ptr1++;
-			ptr2 = index(ptr1, '.');
-			if (ptr2 != NULL) {
-				*ptr2++ = '\0';
-				(void) sprintf(bfr, "<%s@%s.UUCP>", ptr2, ptr1);
-				(void) strcpy(linebuf, bfr);
-			}
-		}
-		if (index(linebuf, '>') == NULL)
-			(void) strcat(linebuf, ">");
-
-		ptr1 = findhist(linebuf);
-		if (ptr1 == NULL) {
-			msg("%s not found", linebuf);
-			break;
-		}
-		ptr2 = index(ptr1, '\t');
-		ptr3 = index(++ptr2, '\t');
-		ptr2 = index(++ptr3, ' ');
-		if (ptr2)
-			*ptr2 = '\0';
-		ptr2 = index(ptr3, '/');
-		if (!ptr2) {
-			if (strcmp(++ptr3, "cancelled") == 0)
-				msg("%s has been cancelled", linebuf);
-			else
-				msg("%s has expired", linebuf);
-			break;
-		}
-		*ptr2++ = '\0';
-		(void) sscanf(ptr2, "%ld", &nart);
-
-		/*
-		 * Go to a given article.  Ptr3 specifies the newsgroup
-		 * and nart specifies the article number.
-		 */
-#ifdef MYDB
-selectart:
-#endif /* MYDB */
-		aabs = TRUE;
-		FCLOSE(fp);
-		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();
-		}
-		bit = nart;
-		oobit = obit;
-		obit = -1;
-		getnextart(TRUE);
-		if (bit != nart || strcmp(groupdir, ptr3) != 0) {
-			msg("can't read %s/%ld", ptr3, nart);
-			goto caseminus;
-		}
-		rfq = 0;
-		break;
-
-	/* follow-up article */
-	case 'f':
-		if (strcmp(h->followto, "poster") == 0) {
-			reply(FALSE);
-			break;
-		}
-		(void) sprintf(bfr, "%s/%s %s", BIN, "postnews", goodone);
-		shcmd(bfr, CWAIT);
-		break;
-
-	/* erase - pretend we haven't seen this article. */
-	case 'e':
-		erased = 1;
-		set(bit);
-		goto caseplus;	/* skip this article for now */
-
-	case '#':
-		msg("Article %ld of %ld", rfq ? oobit : bit, pngsize);
-		break;
-
-		/* error */
-	case '?':
-		{
-			FILE *helpf;
-			(void) sprintf(linebuf, "%s/vnews.help", LIB);
-			if ((helpf = fopen(linebuf, "r")) == NULL) {
-				msg("Can't open help file");
-				break;
-			}
-			move(ARTWIN, 0);
-			while (fgets(linebuf, LBUFLEN, helpf) != NULL)
-				addstr(linebuf);
-			(void) fclose(helpf);
-			prflags |= HELPMSG|NEWART;
-		}
-		break;
-
-	default:
-		if (c != ckill && c != cintr && c != cerase) 
-#ifdef TIOCGLTC
-			if (c != cwerase)
-#endif
-			{
-				beep();
-				msg("Illegal command");
-			}
-		break;
-	}
-}
-
-cancel_command()
-{
-	int notauthor;
-
-	tfilename = filename;
-	(void) strcpy(rcbuf, h->path);
-	ptr1 = index(rcbuf, ' ');
-	if (ptr1)
-		*ptr1 = 0;
-	notauthor = strcmp(username, rcbuf);
-	if (uid != ROOTID && uid && notauthor) {
-		msg("Can't cancel what you didn't write.");
-		return;
-	}
-	if (!cancel(stderr, h, notauthor)) {
-		clear(bit);
-		saveart;
-		nextbit();
-		obit = -1;
-		fp = NULL;
-	}
-	FCLOSE(fp);
-}
-/*
- * Generate replies
- */
-
-reply(include)
-	int include;
-{
-	char *arg[4];
-	register FILE *rfp;
-	char subj[132];
-	register char *p;
-	char *replyname();
-	struct stat statb;
-	time_t creatm;
-
-	/* Put the user in the editor to create the body of the reply. */
-	ed = getenv("EDITOR");
-	if (ed == NULL || *ed == '\0')
-		ed = DFTEDITOR;
-	if (ed == NULL) {
-		msg("You don't have an editor");
-		return;
-	}
-
-	arg[0] = "/bin/sh";
-	arg[1] = "-c";
-
-	(void) strcpy(tf, tft);
-	(void) mktemp(tf);
-	(void) close(creat(tf,0600));
-	if ((rfp = fopen(tf, "w")) == NULL) {
-		msg("Can't create %s", tf) ;
-		return;
-	}
-	(void) strcpy(subj, h->title);
-	if (!prefix(subj, "Re:")){
-		(void) strcpy(bfr, subj);
-		(void) sprintf(subj, "Re: %s", bfr);
-	}
-
-	p = replyname(h);
-	fprintf(rfp, "To: %s\n", p);
-	fprintf(rfp, "Subject: %s\n", subj);
-	fprintf(rfp, "In-reply-to: your article %s\n", h->ident);
-#ifdef INTERNET
-	fprintf(rfp, "News-Path: %s\n", h->path);
-#endif /* INTERNET */
-	(void) sprintf(rcbuf, "%s -t < %s; rm -f %s", MAILPARSER, tf, tf);
-	putc('\n', rfp);
-	if (include) {
-		FILE *of;
-		char buf[BUFSIZ];
-
-		of = xart_open(goodone, "r");
-		while (fgets(buf, sizeof buf, of) != NULL)
-			if (buf[0] == '\n')
-				break;
-		while (fgets(buf, sizeof buf, of) != NULL)
-			fprintf(rfp, "> %s", buf);
-		fclose(of);
-		putc('\n', rfp);
-	}
-	fflush(rfp);
-	(void) fstat(fileno(rfp), &statb);
-	creatm = statb.st_mtime;
-	(void) fclose(rfp);
-
-	(void) sprintf(edcmdbuf, "exec %s %s", ed, tf);
-	arg[2] = edcmdbuf;
-	arg[3] = NULL;
-	if (prun(arg, 0) != 0) {
-		msg("Couldn't run editor");
-		(void) unlink(tf);
-		return;
-	}
-
-	if (access(tf, 4) || stat(tf, &statb)) {
-		msg("No input file - mail not sent");
-		(void) unlink(tf);
-		return;
-	}
-	if (statb.st_mtime == creatm || statb.st_size < 5) {
-		msg("File unchanged - no message posted");
-		(void) unlink(tf);
-		return;
-	}
-
-	arg[2] = rcbuf;
-	arg[3] = NULL;
-	prun(arg, BKGRND);
-	prflags |= NOPRT;
-}
-
-direct_reply()
-{
-	register char *p;
-	register char *q;
-	char *arg[4];
-	char address[PATHLEN];
-	extern char *replyname();
-	extern char *getenv();
-
-	arg[0] = "/bin/sh";
-	arg[1] = "-c";
-	p = replyname(h);
-	q = address;
-	while (*p != '\0') {
-		if (index("\"\\$", *p) != 0)
-			*q++ = '\\';
-		*q++ = *p++;
-	}
-	*q++ = '\0';
-	if ((MAILER = getenv("MAILER")) == NULL)
-		MAILER = "mail";
-	sprintf(rcbuf, MAILER, hptr->title);
-	sprintf(bfr, "%s %s", rcbuf, address);
-	arg[2] = bfr;
-	arg[3] = NULL;
-	if (prun(arg, 0) != 0) {
-		msg("Couldn't run mailer");
-		return;
-	}
-	prflags |= NOPRT;
-}
-
-next_ng_command()
-{
-	obit = -1;
-	if (prget("group? ", linebuf))
-		return FALSE;
-	bptr = linebuf;
-	if (!*bptr || *bptr == '-') {
-		if (*bptr)
-			actdirect = BACKWARD;
-		saveart;
-		if (nextng()) {
-			if (actdirect == BACKWARD)
-				msg("Can't back up.");
-			else
-				return TRUE;
-		}
-		return FALSE;
-	}
-	while (isspace(*bptr))
-		bptr++;
-	if (!validng(bptr)) {
-		msg("No such group.");
-		return FALSE;
-	}
-	saveart;
-	back();
-	selectng(bptr, TRUE, TRUE);
-	return 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;
-	long atol();
-
-	noaccess = 0;
-	if (minus)
-		goto nextart2;	/* Kludge for "-" command. */
-
-	if (bit == obit)	/* Return if still on same article as last time */
-		return 0;
-
-nextart:
-	if (news) {
-		curflag = CURHOME;
-		_amove(0, 0);
-		vflush();
-	}
-	dgest = 0;
-
-	/* If done with this newsgroup, find the next one. */
-	while (ngsize <= 0 || (!rflag && ((long) bit > ngsize)) || (rflag && bit < minartno)) {
-		if (nextng()) {
-			if (actdirect == BACKWARD) {
-				msg("Can't back up.");
-				actdirect = FORWARD;
-				continue;
-			}
-			else /* if (rfq++ || pflag || cflag) */
-				return 1;
-		}
-		if (rflag)
-			bit = ngsize + 1;
-		else
-			bit = -1;
-		noaccess = 2;
-	}
-
-	/* speed things up by not searching for article -1 */
-	if (bit < 0) {
-		bit = minartno - 1;
-		nextbit();
-		aabs = FALSE;
-		goto nextart;
-	}
-
-nextart2:
-	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 == SIGHUP)
-		return 1;
-	/* Decide if we want to show this article. */
-	if ((fp = art_open(filename, "r")) == NULL) {
-		/* 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)
-				msg("Can't open %s", dirname(groupdir));
-			goto nextart;
-		}
-		nextnum = rflag ? minartno - 1 : ngsize + 1;
-		while ((dir = readdir(dirp)) != NULL) {
-			if (!dir->d_ino)
-				continue;
-			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;
-		do {
-			clear(bit);
-			nextbit();
-		} while (rflag ? (nextnum < bit) : (nextnum > bit));
-		obit = -1;
-		aabs = FALSE;
-		goto nextart;
-	} else
-		noaccess = 0;
-
-	if (hread(h, fp, TRUE) == NULL || (!rfq && !aselect(h, aabs))) {
-badart:
-		FCLOSE(fp);
-		clear(bit);
-		obit = -1;
-		nextbit();
-		aabs = FALSE;
-		goto nextart;
-	}
-	aabs = FALSE;
-	actdirect = FORWARD;
-	news = TRUE;
-	artbody = ftell(fp);
-	fmthdr();
-	artlines = lastlin;
-	artread = 0;
-	prflags |= NEWART;
-	prflags &=~ NOPRT;
-	if (! cflag && hdrend < ARTWLEN && !cflag)
-		prflags |= HDRONLY;
-	dlinno = 0;
-	maxlinno = NLINES(h, fp);
-	erased = 0;
-
-	obit = bit;
-	return 0;
-}
-
-/*
- * Print out whatever the appropriate header is
- */
-fmthdr() {
-	char *briefdate();
-	static FILE *ngfd = NULL;
-	static int triedopen = 0;
-	char pbuf[BUFLEN], *printbuffer = groupdir;
-
-	lastlin = 0;
-	if (ngrp) {
-		pngsize = ngsize;
-		ngrp--;
-		if (!hflag) {
-			if (!triedopen) {
-				(void) sprintf(pbuf,"%s/newsgroups", LIB);
-				ngfd = fopen(pbuf, "r");
-				triedopen++;
-			}
-			if (ngfd != NULL) {
-				register char *p;
-				char ibuf[BUFLEN];
-				rewind(ngfd);
-				while (fgets(ibuf, BUFLEN, ngfd) != NULL) {
-					p = index(ibuf, '\t');
-					if (p)
-						*p++ = '\0';
-					if (strcmp(ibuf, groupdir) == 0) {
-						register char *q;
-						q = rindex(p, '\t');
-						if (q) {
-							p = q;
-							*p++ = '\0';
-						}
-						if (p) {
-							q = index(p, '\n');
-							if (q)
-								*q = '\0';
-							if (*--q == '.')
-								*q = '\0';
-						(void) sprintf(pbuf,"%s (%s)",
-							groupdir, p);
-							printbuffer = pbuf;
-						}
-						break;
-					}
-				}
-			}
-			(void) sprintf(linebuf, "Newsgroup %s", printbuffer);
-			tfappend(linebuf);
-		}
-	}
-	hdrstart = lastlin;
-	if (!hflag) {
-		(void) sprintf(linebuf, "Article %s %s",
-			h->ident, briefdate(h->subdate));
-		tfappend(linebuf);
-	}
-	xtabs(h);
-	vhprint(h, pflag ? 1 : 0);
-	(void) sprintf(linebuf, "(%d lines)", NLINES(h, fp)); tfappend(linebuf);
-	tfappend("");
-	hdrend = lastlin;
-}
-
-/*
- * Grow tabs into spaces in header fields, 'cause the rest of this
- * lax program drops turds all over tabs (so it does with \b's, but ..)
- */
-xtabs(p)
-register struct hbuf *p;
-{
-	xtabf(p->from, sizeof p->from);
-	xtabf(p->path, sizeof p->path);
-	xtabf(p->nbuf, sizeof p->nbuf);
-	xtabf(p->title, sizeof p->title);
-	xtabf(p->ident, sizeof p->ident);
-	xtabf(p->replyto, sizeof p->replyto);
-	xtabf(p->followid, sizeof p->followid);
-	xtabf(p->subdate, sizeof p->subdate);
-	xtabf(p->expdate, sizeof p->expdate);
-	xtabf(p->ctlmsg, sizeof p->ctlmsg);
-	xtabf(p->sender, sizeof p->sender);
-	xtabf(p->followto, sizeof p->followto);
-	xtabf(p->distribution, sizeof p->distribution);
-	xtabf(p->organization, sizeof p->organization);
-	xtabf(p->numlines, sizeof p->numlines);
-	xtabf(p->keywords, sizeof p->keywords);
-	xtabf(p->summary, sizeof p->summary);
-	xtabf(p->approved, sizeof p->approved);
-	xtabf(p->nf_id, sizeof p->nf_id);
-	xtabf(p->nf_from, sizeof p->nf_from);
-#ifdef DOXREFS
-	xtabf(p->xref, sizeof p->xref);
-#endif /* DOXREFS */
-}
-
-xtabf(s, size)
-char *s;
-int size;
-{
-	register char *p, *str;
-	register c, i;
-	char buf[LBUFLEN];
-
-	str = s;
-	if (index(str, '\t') == NULL)
-		return;
-	i = 0;
-	for (p = buf; c = *str++; i++) {
-		if (c == '\t') {
-			*p++ = ' ';
-			if ((i & 7) != 7)
-				str--;
-		} else if (c == '\n') {
-			i = -1;
-			*p++ = c;
-		} else
-			*p++ = c;
-	}
-	*p = '\0';
-	strncpy(s, buf, size - 1);
-}
-
-/*
- * Print the file header to the temp file.
- */
-vhprint(hp, verbose)
-register struct hbuf *hp;
-int	verbose;
-{
-	register char	*p1, *p2;
-	char	fname[BUFLEN];
-	char *tailpath();
-
-	fname[0] = '\0';		/* init name holder */
-
-	p1 = index(hp->from, '(');	/* Find the sender's full name. */
-	if (p1 == NULL && hp->path[0])
-		p1 = index(hp->path, '(');
-	if (p1 != NULL) {
-		(void) strcpy(fname, p1+1);
-		p2 = index(fname, ')');
-		if (p2 != NULL)
-			*p2 = '\0';
-	}
-
-	(void) sprintf(linebuf, "Subject: %s", hp->title);
-	tfappend(linebuf);
-	if (!hflag && hp->summary[0])
-		(void) sprintf(linebuf, "Summary: %s", hp->summary), tfappend(linebuf);
-	if (!hflag && hp->keywords[0])
-		(void) sprintf(linebuf, "Keywords: %s", hp->keywords), tfappend(linebuf);
-	if (verbose) {
-		(void) sprintf(linebuf, "From: %s", hp->from); tfappend(linebuf);
-		(void) sprintf(linebuf, "Path: %s", hp->path); tfappend(linebuf);
-		if (hp->organization[0]) {
-			(void) sprintf(linebuf, "Organization: %s", hp->organization);
-			tfappend(linebuf);
-		}
-	}
-	else {
-		if (p1 != NULL)
-			*--p1 = '\0';		/* bump over the '(' */
-#ifdef INTERNET
-		/*
-		 * Prefer Path line if it's in internet format, or if we don't
-		 * understand internet format here, or if there is no reply-to.
-		 */
-		(void) sprintf(linebuf, "From: %s", hp->from);
-#else
-		(void) sprintf(linebuf, "Path: %s", tailpath(hp));
-#endif
-		if (fname[0] || (hp->organization[0] && !hflag)) {
-			(void) strcat(linebuf, " (");
-			if (fname[0] == '\0') {
-				(void) strcpy(fname, hp->from);
-				p2 = index(fname,'@');
-				if (p2)
-					*p2 = '\0';
-			}
-			(void) strcat(linebuf, fname);
-			if (hp->organization[0] && !hflag) {
-				(void) strcat(linebuf, " @ ");
-				(void) strcat(linebuf, hp->organization);
-			}
-			(void) strcat(linebuf, ")");
-		}
-		tfappend(linebuf);
-		if (p1 != NULL)
-			*p1 = ' ';
-		if (hp->ctlmsg[0]) {
-			(void) sprintf(linebuf, "Control: %s", hp->ctlmsg);
-			tfappend(linebuf);
-		}
-	}
-
-	if (verbose) {
-		(void) sprintf(linebuf, "Newsgroups: %s", hp->nbuf); tfappend(linebuf);
-		(void) sprintf(linebuf, "Date: %s", hp->subdate); tfappend(linebuf);
-		if (hp->sender[0]) {
-			(void) sprintf(linebuf, "Sender: %s", hp->sender);
-			tfappend(linebuf);
-		}
-		if (hp->replyto[0]) {
-			(void) sprintf(linebuf, "Reply-To: %s", hp->replyto);
-			tfappend(linebuf);
-		}
-		if (hp->followto[0]) {
-			(void) sprintf(linebuf, "Followup-To: %s", hp->followto);
-			tfappend(linebuf);
-		}
-	}
-	else if (strcmp(hp->nbuf, groupdir) != 0) {
-		(void) sprintf(linebuf, "Newsgroups: %s", hp->nbuf);
-		tfappend(linebuf);
-		timer();
-	}
-}
-
-#ifdef MYDB
-
-char *
-findparent(id, num)
-char *id;
-long *num;
-{
-	struct artrec a;
-	char idbuf[BUFSIZE];
-	char *ngname();
-
-	strcpy(idbuf, id);
-	lcase(idbuf);
-
-	if (lookart(id, &a) == DNULL)
-		return NULL;
-	if (a.parent == DNULL)
-		return NULL;
-	readrec(a.parent, &a);
-	*num = a.groups[0].artno;
-	return ngname(a.groups[0].newsgroup);
-}
-
-#endif
-
-
-/*
- * Append file to temp file, handling control characters, folding lines, etc.
- * We don't grow the temp file to more than nlines so that a user won't have
- * to wait for 20 seconds to read in a monster file from net.sources.
- * What we really want is coroutines--any year now.
- */
-
-#define ULINE 0200
-static char *maxcol;
-
-appfile(iop, nlines)
-register FILE *iop;
-{
-	register int c;
-	register char *icol;	/* &linebuf[0] <= icol <= maxcol */
-
-	if (artread || artlines >= nlines || iop == NULL)
-		return;
-	maxcol = linebuf;
-	icol = linebuf;
-	while ((c = getc(iop)) != EOF) {
-		switch (c) {
-		case ' ':
-			if (icol == maxcol && icol < linebuf + LBUFLEN - 1) {
-				*icol++ = ' ';
-				maxcol = icol;
-			} else {
-				if (*icol == '_')
-					*icol++ = ULINE | ' ';
-				else
-					icol++;
-			}
-			break;
-		case '\t':
-			icol = (icol - linebuf &~ 07) + 8 + linebuf;
-			growline(icol);
-			break;
-		case '\b':
-			if (icol > linebuf) --icol;
-			break;
-		case '\n':
-			outline();
-			if (artlines >= nlines)
-				return;
-			icol = linebuf;
-			break;
-		case '\r':
-			icol = linebuf;
-			break;
-		case '\f':
-			outline(); outline(); outline();
-			if (artlines >= nlines)
-				return;
-			icol = linebuf;
-			break;
-		default:
-			if (c < ' ' || c > '~')
-				break;
-			else if (icol >= linebuf + LBUFLEN - 1)
-				icol++;
-			else if (icol == maxcol) {
-				*icol++ = c;
-				maxcol = icol; }
-			else if (c == '_')
-				*icol++ |= ULINE;
-			else if (*icol == '_')
-				*icol++ = (c | ULINE);
-			else	*icol++ = c;
-			break;
-		}
-	}
-	if (maxcol != linebuf)		/* file not terminated with newline */
-		outline();
-	artread++;
-}
-
-growline(col)
-char *col;
-{
-	while (maxcol < col && maxcol < linebuf + LBUFLEN - 1)
-		*maxcol++ = ' ';
-}
-
-outline()
-{
-	*maxcol = '\0';
-	if (strncmp(linebuf, ">From ", 6) == 0) {
-		register char *p;
-		for (p = linebuf ; (*p = p[1]) != '\0' ; p++);
-	}
-	tfappend(linebuf);
-	if (maxcol > linebuf)
-		artlines = lastlin;
-	maxcol = linebuf;
-}
-
-prget(prompter, buf)
-char *prompter, *buf;
-{
-	char *p, *q, *r;
-	int c, lastc;
-
-	curflag = CURP2;
-	r = buf;
-	lastc = '\0';
-	for (;;) {
-		*r = '\0';
-		p = secpr;
-		for (q = prompter ; *q ; q++)
-			*p++ = *q;
-		for (q = buf ; *q ; q++) {
-			if (p < &secpr[SECPRLEN-1] && *q >= ' ' && *p <= '~')
-				*p++ = *q;
-		}
-		*p = '\0';
-		c = vgetc();
-		if (c == '\n' || c == cintr) {
-			break;
-		}
-		if (c == cerase || c == '\b' || c == '\177') {
-			if (lastc == '\\')
-				r[-1] = c;
-			else if (r > buf)
-				r--;
-		} else if (c == ckill) {
-			if (lastc == '\\')
-				r[-1] = c;
-			else
-				r = buf;
-#ifdef TIOCGLTC
-		} else if (c == cwerase) {
-			if (lastc == '\\')
-				r[-1] = c;
-			else {
-				while (r > buf && (r[-1] == ' ' || r[-1] == '\t'))
-					r--;
-				while (r > buf && r[-1] != ' ' && r[-1] != '\t')
-					r--;
-			}
-#endif
-		} else {
-			*r++ = c;
-		}
-		lastc = c;
-	}
-	curflag = CURHOME;
-	secpr[0] = '\0';
-	return (c == cintr);
-}
-
-
-
-/*
- * Execute a shell command.
- */
-
-shcmd(cmd, flags)
-char *cmd;
-{
-	char *arg[4];
-
-	arg[0] = SHELL, arg[1] = "-c", arg[2] = cmd, arg[3] = NULL;
-	return prun(arg, flags);
-}
-
-
-prun(args, flags)
-char **args;
-{
-	int pid;
-	int i;
-	int (*savequit)();
-	char *env[100], **envp, **oenvp;
-	char a[BUFLEN + 2];
-	extern char **environ;
-	int pstatus, retval;
-
-	if (!(flags & BKGRND)) {
-		botscreen();
-		ttycooked();
-#ifdef SIGTSTP
-		(void) signal(SIGTSTP, SIG_DFL);
-		(void) signal(SIGTTIN, SIG_DFL);
-		(void) signal(SIGTTOU, SIG_DFL);
-#endif
-	}
-#ifdef BSD4_2
-	while ((pid = vfork()) == -1)
-#else /* !BSD4_2 */
-	/* 4.1 BSD (at least) can't handle this vfork with -ljobs */
-	while ((pid = fork()) == -1)
-#endif /* !BSD4_2 */
-		sleep(1);		/* must not clear alarm */
-	if (pid == 0) {
-		for (i = 3 ; i < 20 ; i++)
-			close(i);
-		if (flags & BKGRND) {
-			(void) signal(SIGINT, SIG_IGN);
-			(void) signal(SIGQUIT, SIG_IGN);
-#ifdef SIGTSTP
-			(void) signal(SIGTSTP, SIG_IGN);
-			(void) signal(SIGTTIN, SIG_IGN);
-			(void) signal(SIGTTOU, SIG_IGN);
-#endif
-			(void) close(0);
-			(void) close(1);
-			(void) open("/dev/null", 2);
-			(void) dup(0);
-		}
-		/* set $A */
-		(void) sprintf(a, "A=%s", filename);
-		oenvp = environ;
-		env[0] = a;
-		for (envp = env + 1 ; *oenvp != NULL && envp < env + 98 ; oenvp++)
-			if ((*oenvp)[0] != 'A' || (*oenvp)[1] != '=')
-				*envp++ = *oenvp;
-		*envp = NULL;
-
-		(void) umask(savmask);
-		execve(args[0], args, env);
-		perror(args[0]);
-		exit(20);
-	}
-	if (!(flags & BKGRND)) {
-		savequit = signal(SIGQUIT, SIG_IGN);
-		while ((i = wait(&pstatus)) != pid && (i != -1 || errno == EINTR))
-			;
-		if (i == -1)
-			retval = 1;
-		else
-			retval = pstatus;
-		if (flags & CWAIT) {
-			fprintf(stderr, "[Hit return to continue]");
-			while ((errno = 0, i = getchar()) != '\n'
-				&& (i != EOF || errno == EINTR));
-		}
-		(void) signal(SIGQUIT, savequit);
-		ttyraw();
-		clearok(curscr, 1);
-#ifdef SIGTSTP
-		(void) signal(SIGTSTP, onstop);
-		(void) signal(SIGTTIN, onstop);
-		(void) signal(SIGTTOU, onstop);
-#endif
-		return retval;
-	} else
-		return 0;
-}
-
-#ifdef DIGPAGE
-
-
-/*
- * Find end of current subarticle in digest.
- */
-
-findend(l)
-{
-	register int i, n;
-	register char *p;
-
-	for (i = l ; i < l + ARTWLEN && i < lastlin ; i++) {
-		tfget(linebuf, i);
-		for (p = linebuf ; *p == '-' ; p++)
-			;
-		n = (int)p - (int)linebuf;
-		if ( (n > 23 && n < 33) || (n > 65 && n < 79)) {
-			tfget(linebuf, ++i);
-			if (linebuf[0] == '\0')
-				return i + 1;
-		}
-	}
-	return 0;
-}
-
-#endif
-
-
-/*** Routines for handling temporary file ***/
-
-/*
- * Append to temp file.
- * Long lines are folded.
- */
-
-tfappend(tline)
-register char *tline;
-{
-	register char *nxtlin;
-
-	do {
-		nxtlin = index(tline, '\n');
-		if (nxtlin)
-			*nxtlin++ = '\0';
-
-		while (strlen(tline) > COLS) {
-			tfput(tline, lastlin++);
-			tline += COLS;
-			maxlinno++;
-		}
-		tfput(tline, lastlin++);
-	} while ((tline = nxtlin) != NULL);
-}
-
-
-tfput(tline, linno)
-char *tline;
-{
-	register char *p;
-	register FILE *rtfp;		/* try to make it a little faster */
-	register int i;
-
-	p = tline, i = even(COLS);
-	tfseek(linno, 1);
-	rtfp = tfp;
-	while (--i >= 0) {
-		if (*p)
-			putc(*p++, rtfp);
-		else
-			putc('\0', rtfp);
-	}
-	tflinno++;
-}
-
-
-tfget(tline, linno)
-char *tline;
-{
-	tfseek(linno, 0);
-	fread(tline, even(COLS), 1, tfp);
-	tline[COLS] = '\0';
-	tflinno++;
-}
-
-
-tfseek(linno, wrflag)
-{
-	static int lastwrflag = 1;
-
-	if (linno != tflinno || wrflag != lastwrflag) {
-		(void) fseek(tfp, (long)linno * even(COLS), 0);
-		tflinno = linno;
-		lastwrflag = wrflag;
-	}
-}
-
-/* VARARGS1 */
-msg(s, a1, a2, a3, a4)
-char *s;
-{
-	(void) sprintf(secpr, s, a1, a2, a3, a4);
-}
-
-
-/*
- * Update the display.
- * The display is entirely controlled by this routine,
- * which means that this routine may get pretty snarled.
- */
-
-static int savelinno = -1;		/* dlinno on last call to updscr */
-static int savepr;			/* prflags on last call */
-#ifdef TIOCGWINSZ
-static int UPDATING = 0, WINCH = 0;
-
-/*
- * called by winch() from virtterm.c -- resets state information back
- * to start-up state and forces a full redraw of the screen.  The
- * current article is rewound to the beginning because it's would
- * be very difficult to get the screen to return to the exact point
- * in the file that the user left off (I know, I tried).
- */
-winch_upd()
-{
-	if(UPDATING)	/* concurrency.  wow! */
-		WINCH++;
-	else if((WINCH == 0) && (savelinno >= 0)) {
-		int saveline = dlinno, saveflag = curflag;
-
-		/* reread the article */
-		FCLOSE(fp);
-		obit = -1;
-		getnextart(FALSE);
-		appfile(fp, dlinno + ARTWLEN + 1);
-
-		/* fix up the screen */
-		curflag = saveflag;
-		strcpy(prompt,"more? ");
-		clearok(curscr, 1);
-		updscr();
-	}
-}
-#endif /* TIOCGWINSZ */
-
-
-updscr()
-{
-	int count;
-	int i;
-
-#ifdef TIOCGWINSZ
-	UPDATING++;
-#endif /* TIOCGWINSZ */
-	if (checkin())
-		return;
-	if ((prflags & HELPMSG) == 0
-	 && (dlinno != savelinno || savepr != prflags)
-	 && quitflg == 0) {
-		if (dlinno != savelinno)
-			prflags &=~ NOPRT;
-		count = ARTWLEN;
-		if (prflags & NOPRT)
-			count = 0;
-		if ((prflags & HDRONLY) && count > hdrend)
-			count = hdrend - dlinno;
-#ifdef DIGPAGE
-		if (endsuba > 0 && count > endsuba - dlinno)
-			count = endsuba - dlinno;
-#endif
-		if ((prflags & NEWART) == 0)
-			ushift(ARTWIN, ARTWIN+ARTWLEN-1, dlinno - savelinno);
-		if (count > lastlin - dlinno)
-			count = lastlin - dlinno;
-		for (i = ARTWIN ; i < ARTWIN + ARTWLEN ; i++)
-			clrline(i);
-		for (i = 0 ; i < count ; i++) {
-			tfget(linebuf, dlinno + i);
-			mvaddstr(ARTWIN + i, 0, linebuf);
-		}
-		prflags &=~ NEWART;
-		savepr = prflags;
-		savelinno = dlinno;
-	}
-	clrline(SPLINE), clrline(PRLINE);
-#ifdef STATTOP
-	mvaddstr(PRLINE, 0, prompt);
-#else
-	if (strlen(secpr) <= COLS)
-		mvaddstr(PRLINE, 0, prompt);
-#endif
-	mvaddstr(PRLINE, 59, timestr);
-	mvaddstr(PRLINE, 17, groupdir);
-	addch(' '); addnum(bit); addch('/'); addnum(pngsize); addch(' ');
-	if (ismail)
-		mvaddstr(PRLINE, 75, ismail > 1? "MAIL" : "mail");
-	mvaddstr(SPLINE, 0, secpr);
-	if (curflag == CURP1)
-		move(PRLINE, strlen(prompt));
-	else if (curflag == CURHOME)
-		move(0, 0);
-	refresh();
-#ifdef TIOCGWINSZ
-	UPDATING=0;
-	if (WINCH) { /* window changed while updating screen */
-		WINCH = 0;
-		winch_upd();
-	}
-#endif /* TIOCGWINSZ */
-}
-
-addnum(n)
-register long n;
-{
-	if (n >= 10)
-		addnum(n / 10);
-	addch((char)(n % 10 + '0'));
-}
-
-/*
- * Called on alarm signal.
- * Simply sets flag, signal processed later.
- */
-
-onalarm()
-{
-#ifdef SIGTSTP
-	int dojump = reading;
-
-	reading = FALSE;
-	alflag++;
-	if (dojump)
-		longjmp(alrmjmp, 1);
-#else /* !SIGTSTP */
-	alflag++;
-#endif
-}
-
-/*
- * Process alarm signal (or start clock)
- */
-timer()
-{
-	time_t tod;
-	int hour;
-	int i;
-	struct tm *t;
-	struct stat statb;
-	struct tm *localtime();
-	static char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
-	static long oldmsize = 1000000L;
-	static int rccount = 10;
-	static time_t lastismail = 0;
-
-	alflag = 0;
-	(void) signal(SIGALRM, onalarm);
-	(void) time(&tod);
-	t = localtime(&tod);
-	i = 60 - t->tm_sec;
-	(void) alarm(i > 30? 30 : i);			/* reset alarm */
-	hour = t->tm_hour % 12;
-	if (hour == 0)  hour = 12;
-	(void) sprintf(timestr, "%.3s %d %d:%02d",
-		months + 3 * t->tm_mon, t->tm_mday, hour, t->tm_min);
-	if (mailf == NULL || stat(mailf, &statb) < 0) {
-		statb.st_size = 0;
-	}
-	if (statb.st_size > oldmsize) {
-		ismail = 2;
-		beep();
-	} else {
-		if (statb.st_size == 0)
-			ismail = 0;
-					/* force MAIL for at least 30 seconds */
-		else if (ismail > 1 && (lastismail+30) < tod)
-			ismail = 1;
-	}
-	oldmsize = statb.st_size;
-	lastismail = tod;
-	if (uflag && !xflag && --rccount < 0) {
-		writeoutrc();
-		if (secpr[0] == '\0')
-			(void) strcpy(secpr, ".newsrc updated");
-		rccount = 10;
-	}
-}
-
-char *
-getmailname()
-{
-	static char mailname[32];
-	register char *p;
-
-	if( (p = getenv("MAIL")) != NULL)
-		return p;
-#ifndef MMDF
-	if (username[0] == '\0' || strlen(username) > 15)
-		return NULL;
-#ifdef USG
-	(void) sprintf(mailname, "/usr/mail/%s", username);
-#else /* !USG */
-	(void) sprintf(mailname, "/usr/spool/mail/%s", username);
-#endif /* !USG */
-#else /* MMDF */
-	(void) sprintf(mailname, "%s/mailbox", userhome);
-#endif /* MMDF */
-	return mailname;
-}
-
-
-
-/*** Terminal I/O ***/
-
-#define INBUFSIZ 8
-
-char inbuf[INBUFSIZ];			/* input buffer */
-char outbuf[BUFSIZ];			/* output buffer */
-int innleft = 0;			/* # of chars in input buffer */
-int outnleft = BUFSIZ;			/* room left in output buffer */
-char *innext;				/* next input character */
-char *outnext = outbuf;			/* next space in output buffer */
-#ifdef USG
-int oflags;				/* fcntl flags (for nodelay read) */
-#endif
-
-/*
- * Input a character
- */
-
-vgetc()
-{
-	register c;
-#if defined(BSD4_2) || defined(BSD4_1C)
-	int readfds, exceptfds;
-#endif
-
-recurse:
-	if (--innleft >= 0) {
-		c = *innext++;
-	} else {
-		if (alflag)
-			timer();
-		updscr();	/* update the display */
-		for (;;) {
-			if (innleft > 0 || alflag)
-				goto recurse;
-			intflag = 0;
-#ifdef USG
-			if (oflags & O_NDELAY) {
-				oflags &=~ O_NDELAY;
-				fcntl(0, F_SETFL, oflags);
-			}
-#endif
-#ifdef SIGTSTP
-			if (setjmp(alrmjmp))
-				continue;
-			if (setjmp(intjmp))
-				return cintr;
-			reading = TRUE;
-#endif /* SIGTSTP */
-#if defined(BSD4_2) || defined(BSD4_1C)
-			/* Use a select because it can be interrupted. */
-			readfds = 1; exceptfds = 1;
-			select(1, &readfds, (int *)0, &exceptfds, (int *)0);
-			if (!(readfds & 1))
-				break;
-#endif
-			innleft = read(0, inbuf, INBUFSIZ);
-#ifdef SIGTSTP
-			reading = FALSE;
-#endif /* SIGTSTP */
-			if (innleft > 0)
-				break;
-			if (innleft == 0) {
-				quitflg++;
-				return cintr;
-			}
-			if (errno != EINTR)
-				abort();	/* "Can't happen" */
-			if (intflag) {
-				intflag--;
-				return cintr;
-			}
-		}
-		innext = inbuf + 1;
-		innleft--;
-		c = inbuf[0];
-	}
-#ifndef USG
-#ifndef CBREAK
-	c &= 0177;
-	if (c == '\034')	/* FS character */
-		xxit(0);
-#endif
-#endif
-	if (c == '\f') {
-		clearok(curscr, 1);
-		prflags &=~ NOPRT;
-		goto recurse;
-	}
-	if (c == '\r')
-		c = '\n';
-	return c;
-}
-
-
-/*
- * Push a character back onto the input stream.
- */
-
-pushback(c)
-{
-	if (innext <= inbuf)
-		abort();
-	*--innext = c;
-	innleft++;
-}
-
-/*
- * Check for terminal input
- */
-
-checkin()
-{
-#ifdef FIONREAD
-	int count;
-#endif
-#ifdef STATTOP
-	if (innleft > 0)
-#else
-	if (innleft > 0 || alflag)
-#endif
-		return 1;
-#if defined(USG) || defined(FIONREAD)
-	if (ospeed >= B9600)
-		return 0;
-	vflush();
-	if (ospeed <= B300)
-		ttyowait();
-#ifdef USG
-	if ((oflags & O_NDELAY) == 0) {
-		oflags |= O_NDELAY;
-		(void) fcntl(0, F_SETFL, oflags);
-	}
-	if ((innleft = read(0, inbuf, INBUFSIZ)) > 0) {
-		innext = inbuf;
-		return 1;
-	}
-#endif
-#ifdef FIONREAD
-	count = 0;			/* in case FIONREAD fails */
-	(void) ioctl(0, FIONREAD, (char *)&count);
-	if (count)
-		return 1;
-#endif
-#endif
-	return 0;
-}
-
-
-
-/*
- * flush terminal input queue.
- */
-
-clearin()
-{
-#ifdef USG
-	(void) ioctl(0, TCFLSH, (char *)0);
-#else
-#ifdef TIOCFLUSH
-	(void) ioctl(0, TIOCFLUSH, (char *)0);
-#else
-	struct sgttyb tty;
-	(void) ioctl(0, TIOCGETP, &tty);
-	(void) ioctl(0, TIOCSETP, &tty);
-#endif
-#endif
-	innleft = 0;
-}
-
-vputc(c)
-{
-	if (--outnleft < 0) {
-		vflush();
-		outnleft--;
-	}
-	*outnext++ = c;
-}
-
-/*
- * Flush the output buffer
- */
-
-vflush()
-{
-	register char *p;
-	register int i;
-#ifdef BSD4_2
-	int mask;
-#else
-	unsigned oalarm;
-#endif
-
-#ifdef BSD4_2
-	mask = sigblock(1 << (SIGALRM-1));
-#else
-	oalarm = alarm(0);
-#endif
-	for (p = outbuf ; p < outnext ; p += i) {
-		if ((i = write(1, p, outnext - p)) < 0) {
-			if (errno != EINTR)
-				abort();	/* "Can't happen" */
-			i = 0;
-		}
-	}
-	outnleft = BUFSIZ;
-	outnext = outbuf;
-#ifdef BSD4_2
-	sigsetmask(mask);
-#else
-	(void) alarm(oalarm);
-#endif
-}
-
-/*** terminal modes ***/
-
-#ifdef USG
-static struct termio oldtty, newtty;
-
-/*
- * Save tty modes
- */
-
-ttysave()
-{
-	if (ioctl(1, TCGETA, &oldtty) < 0)
-		xerror("Can't get tty modes");
-	newtty = oldtty;
-	newtty.c_iflag &=~ (INLCR|IGNCR|ICRNL);
-	newtty.c_oflag &=~ (OPOST);
-	newtty.c_lflag &=~ (ICANON|ECHO|ECHOE|ECHOK|ECHONL);
-	newtty.c_lflag |=  (NOFLSH);
-	newtty.c_cc[VMIN] = 1;
-	newtty.c_cc[VTIME] = 0;
-	cerase = oldtty.c_cc[VERASE];
-	ckill = oldtty.c_cc[VKILL];
-	cintr = oldtty.c_cc[VINTR];
-	ospeed = oldtty.c_cflag & CBAUD;
-	initterm();
-}
-
-
-/*
- * Set tty modes for visual processing
- */
-
-ttyraw()
-{
-	while (ioctl(1, TCSETAF, &newtty) < 0 && errno == EINTR)
-		;
-	rawterm();
-}
-
-ttyowait()
-{	/* wait for output queue to drain */
-	while (ioctl(1, TCSETAW, &newtty) < 0 && errno == EINTR)
-		;
-}
-
-/*
- * Restore tty modes
- */
-
-ttycooked()
-{
-	cookedterm();
-	vflush();
-	while (ioctl(1, TCSETAF, &oldtty) < 0 && errno == EINTR)
-		;
-	oflags &=~ O_NDELAY;
-	(void) fcntl(0, F_SETFL, oflags) ;
-}
-
-#else
-
-static struct sgttyb oldtty, newtty;
-#ifdef TIOCGLTC
-static struct ltchars oldltchars, newltchars;
-#endif
-
-/*
- * Save tty modes
- */
-
-ttysave()
-{
-#ifdef CBREAK
-	struct tchars tchars;	/* special characters, including interrupt */
-#endif
-#ifdef SIGTSTP
-	int getpgrp();
-#if defined(BSD4_2) || defined(BSD4_1C)
-	int tpgrp;
-#else /* BSD4_1 */
-	short tpgrp;
-#endif /* BSD4_1 */
-
-retry:
-#ifdef BSD4_2
-	(void) sigblock(sigmask(SIGTSTP)|sigmask(SIGTTIN)|sigmask(SIGTTOU));
-#else /* !BSD4_2 */
-	(void) signal(SIGTSTP, SIG_HOLD);
-	(void) signal(SIGTTIN, SIG_HOLD);
-	(void) signal(SIGTTOU, SIG_HOLD);
-#endif /* !BSD4_2 */
-	if (ioctl(2, TIOCGPGRP, (char *)&tpgrp) < 0)
-		goto nottty;
-	if (tpgrp != getpgrp(0)) { /* not in foreground */
-		(void) signal(SIGTTOU, SIG_DFL);
-#ifdef BSD4_2
-		(void) sigsetmask(sigblock(0) & ~sigmask(SIGTTOU));
-#endif /* BSD4_2 */
-		(void) kill(0, SIGTTOU);
-		/* job stops here waiting for SIGCONT */
-		goto retry;
-	}
-	(void) signal(SIGTTIN, SIG_DFL);
-	(void) signal(SIGTTOU, SIG_DFL);
-	(void) signal(SIGTSTP, SIG_DFL);
-#ifdef BSD4_2
-	(void) sigsetmask(sigblock(0) & ~(sigmask(SIGTSTP)|sigmask(SIGTTIN)|sigmask(SIGTTOU)));
-#endif /* BSD4_2 */
-#endif /* SIGTSTP */
-	if (ioctl(1, TIOCGETP, (char *)&oldtty) < 0)
-nottty:		xerror("Can't get tty modes");
-	newtty = oldtty;
-	newtty.sg_flags &=~ (CRMOD|ECHO|XTABS);
-#ifdef CBREAK
-	newtty.sg_flags |= CBREAK;
-	ioctl(1, TIOCGETC, (char *)&tchars);
-	cintr = tchars.t_intrc;
-#else /* !CBREAK */
-	newtty.sg_flags |= RAW;
-	cintr = '\0177';	/* forcibly this on V6 systems */
-#endif /* !CBREAK */
-	cerase = oldtty.sg_erase;
-	ckill = oldtty.sg_kill;
-	ospeed = oldtty.sg_ospeed;
-#ifdef	TIOCGLTC
-	if (ioctl(1, TIOCGLTC, (char *)&oldltchars) >= 0) {
-		newltchars = oldltchars;
-		newltchars.t_dsuspc = -1;
-		cwerase = oldltchars.t_werasc;
-	}
-#endif
-	initterm();
-#ifdef SIGTSTP
-	(void) signal(SIGTTIN, onstop);
-	(void) signal(SIGTTOU, onstop);
-	(void) signal(SIGTSTP, onstop);
-#endif /* SIGTSTP */
-}
-
-
-/*
- * Set tty modes for visual processing
- */
-
-ttyraw()
-{
-	while (ioctl(1, TIOCSETN, (char *)&newtty) < 0 && errno == EINTR)
-		;
-#ifdef TIOCGLTC
-	if (newltchars.t_dsuspc == '\377')
-	  while (ioctl(1, TIOCSLTC, (char *)&newltchars) < 0 && errno == EINTR)
-		;
-#endif
-	rawterm();
-}
-
-ttyowait()
-{	/* wait for output queue to drain */
-#ifdef TIOCDRAIN	/* This ioctl is a local mod on linus */
-	(void) ioctl(1, TIOCDRAIN, (char *)0);
-#endif
-}
-
-
-/*
- * Restore tty modes
- */
-
-ttycooked()
-{
-	cookedterm();
-	vflush();
-	while (ioctl(1, TIOCSETN, (char *)&oldtty) < 0 && errno == EINTR)
-		;
-#ifdef TIOCGLTC
-	if (newltchars.t_dsuspc == '\377')
-	  while (ioctl(1, TIOCSLTC, (char *)&oldltchars) < 0 && errno == EINTR)
-		;
-#endif
-}
-
-#endif
-
-
-
-/*** signal handlers ***/
-
-onint() {
-#ifdef SIGTSTP
-	int dojump = reading;
-
-	reading = FALSE;
-#endif /* SIGTSTP */
-	if (!news) {
-		ttycooked();
-		xxit(1);
-	}
-	(void) signal(SIGINT, onint);
-	clearin();			/* flush input queue */
-#ifdef SIGTSTP
-	if (dojump)
-		longjmp(intjmp, 1);
-#endif /* SIGTSTP */
-	intflag++;
-}
-
-#ifdef SIGTSTP
-onstop(signo)
-int signo;
-{
-	/* restore old terminal state */
-	botscreen();
-	vflush();
-	ttycooked();
-	(void) signal(signo, SIG_DFL);
-#ifdef BSD4_2
-	(void) sigblock(sigmask(SIGALRM)|sigmask(SIGINT));
-	(void) sigsetmask(sigblock(0) & ~sigmask(signo));
-#else /* BSD4_1 */
-	(void) alarm(0);
-#endif /* BSD4_1 */
-	(void) kill(0, signo);	/* stop here until continued */
-
-	(void) signal(signo, onstop);
-	/* restore our special terminal state */
-	ttyraw();
-#ifdef TIOCGWINSZ
-	winch();	/* get current window size and redraw screen */
-#endif 	/* TIOCGWINSZ */
-	clearok(curscr, 1);
-	updscr();
-#ifdef BSD4_2
-	(void) sigsetmask(sigblock(0) & ~(sigmask(SIGALRM)|sigmask(SIGINT)));
-#else /* BSD4_1 */
-	timer();
-#endif /* BSD4_1 */
-}
-#endif
-
-/*** stolen from rfuncs2.c and modified ***/
-
-vsave(to, flags)
-register char *to;
-{
-	register FILE *ufp;
-	int	isprogram = 0;
-	int	isnew = 1;
-	long	saveoff;
-	char	temp[20];
-	char	*fname;
-	char	prog[BUFLEN + 24];
-
-	saveoff = ftell(fp);
-	(void) fseek(fp, artbody, 0);
-	fname = to;
-	if (*to == PIPECHAR) {
-		if (strlen(to) > BUFLEN) {
-			msg("Command name too long");
-			goto out;
-		}
-		flags |= OVWRITE;
-		(void) strcpy(temp, "/tmp/vnXXXXXX");
-		(void) mktemp(temp);
-		fname = temp;
-		_amove(ROWS - 1, 0);
-		vflush();
-	}
-	if ((flags & OVWRITE) == 0) {
-		ufp = fopen(fname, "r");
-		if (ufp != NULL) {
-			(void) fclose(ufp);
-			isnew = 0;
-		}
-	}
-	(void) umask(savmask);
-
-	if (*to == PIPECHAR)
-		isprogram++;
-	if ((ufp = fopen(fname, (flags & OVWRITE) == 0? "a" : "w")) == NULL) {
-		msg("Cannot open %s", fname);
-		goto out;
-	}
-	/*
-	 * V7MAIL code is here to conform to V7 mail format.
-	 * If you need a different format to be able to
-	 * use your local mail command (such as four ^A's
-	 * on the end of articles) substitute it here.
-	 */
-	if (flags & SVHEAD) {
-#ifdef MMDF
-		if (!isprogram)
-			fprintf(ufp, "\001\001\001\001\n");
-#endif /* MMDF */
-#ifdef V7MAIL
-		h->subtime = cgtdate(h->subdate);
-		fprintf(ufp, "From %s %s", replyname(h), ctime(&h->subtime));
-#endif
-		hprint(h, ufp, 2);
-#ifdef V7MAIL
-		tprint(fp, ufp, TRUE);
-		putc('\n', ufp);	/* force blank line at end (ugh) */
-#else
-		tprint(fp, ufp, FALSE);
-#endif
-	} else {
-		tprint(fp, ufp, FALSE);
-	}
-
-	fclose(ufp);
-	if (isprogram) {
-		(void) sprintf(prog, "(%s)<%s", to + 1, fname);
-		shcmd(prog, CWAIT);
-		prflags |= NOPRT;
-	} else {
-		if ((flags & OVWRITE) == 0)
-			msg("file: %s %s", to, isnew ? "created" : "appended");
-		else
-			msg("file: %s written", to);
-	}
-
-out:
-	if (isprogram) {
-		(void) unlink(fname);
-	}
-	(void) umask(N_UMASK);
-	(void) fseek(fp, saveoff, 0);
-}
-
-xxit(status)
-int	status;
-{
-	(void) unlink(infile);
-	(void) unlink(outfile);
-#ifdef SORTACTIVE
-	if (strncmp(ACTIVE,"/tmp/", 5) == 0)
-		(void) unlink(ACTIVE);
-#endif /* SORTACTIVE */
-	if (ospeed) {	/* is == 0, we haven't been in raw mode yet */
-		botscreen();
-		vflush();
-		ttycooked();
-	}
-	exit(status);
-}
*-*-END-of-src/visual.c-*-*
echo x - src/recmail.c 1>&2
sed 's/.//' >src/recmail.c <<'*-*-END-of-src/recmail.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.
- *
- * recmail: read a mail message on stdin, grab all addresses in To and Cc
- * lines, and pass the full message to all addressees.  This is useful to
- * send the output of a recently edited mail message (with headers edited too).
- * It is similar to sendmail -t, but only assumes /bin/mail.
- * To use your own mailer, e. g. nmail, compile with -DMAILER=my_mailer.
- */
-
-#ifdef SCCSID
-static char	*SccsId = "@(#)recmail.c	1.15	10/23/86";
-#endif /* SCCSID */
-
-#include "params.h"
-
-#ifndef MAILER
-#define MAILER "/bin/mail"
-#endif
-char mailer[] = MAILER;
-
-#define MAXRECIPS 100
-char *recips[MAXRECIPS];
-int nrecips = 0;
-
-main()
-{
-	FILE *fd;
-	char *tmpf;
-	FILE *errfd;
-	char *errf;
-	char linebuf[1024];
-	int i, pid, wpid;
-	int exstat;
-	char *mypath;
-	int goodcnt, badcnt;
-	char *mktemp(), *getenv();
-
-	tmpf = mktemp("/tmp/rmXXXXXX");
-	(void) close(creat(tmpf,0666));
-	fd = fopen(tmpf, "w");
-	errf = mktemp("/tmp/rmXXXXXX");
-	(void) close(creat(errf,0666));
-	errfd = fopen(errf, "w");
-	fprintf(errfd, "Subject: Returned mail\n");
-	fprintf(errfd, "\n  ----- Transcript of session follows -----\n");
-	(void) fflush(errfd);
-	goodcnt = badcnt = 0;
-
-	while (fgets(linebuf, sizeof linebuf, stdin) != NULL) {
-	   	 if ((strncmp(linebuf, "Bcc: ", 5) == 0 ||
-		    strncmp(linebuf, "bcc: ", 5) == 0 ||
-		    strncmp(linebuf, "BCC: ", 5) == 0)) {
-		    if (linebuf[5] != '\n')
-			addrecips(linebuf+5);
-		    }
-		else if (fputs(linebuf, fd) == EOF)
-			goto werror;
-		if (linebuf[0] == '\n')
-			break;
-		if ((strncmp(linebuf, "To: ", 4) == 0 ||
-		    strncmp(linebuf, "to: ", 4) == 0 ||
-		    strncmp(linebuf, "TO: ", 4) == 0 ||
-		    strncmp(linebuf, "Cc: ", 4) == 0 ||
-		    strncmp(linebuf, "cc: ", 4) == 0 ||
-		    strncmp(linebuf, "CC: ", 4) == 0) &&
-		     linebuf[4] != '\n')
-			addrecips(linebuf+4);
-	}
-	if (!feof(stdin)) {
-		while (fgets(linebuf, sizeof linebuf, stdin) != NULL) {
-			if (fputs(linebuf, fd) == EOF) {
-werror:
-				printf("write error on temp file\n");
-				exit(2);
-			}
-		}
-	}
-	/*
-	 * Append the contents of the .signature file (if it exists) to
-	 * the end of the mail message
-	 */
-	{
-		char sigbuf[BUFSIZ];
-		register c;
-		register char *p = getenv("HOME");
-		FILE *infp;
-			
-		if (p) {
-			(void) sprintf(sigbuf, "%s/%s", p, ".signature");
-			if (infp = fopen(sigbuf, "r")) {
-				fprintf(fd,"---\n");
-				while ((c = getc(infp)) != EOF)
-					putc(c,fd);
-				(void) fclose(infp);
-			}
-		}
-	}
-	(void) fclose(fd);
-
-	/*
-	 * Force the path to only consider /bin and /usr/bin, since
-	 * that's the version of mail we want (not /usr/ucb/mail)
-	 */
-	if (mailer[0] != '/') {
-		register int e;
-		extern char **environ;
-		for (e = 0; environ[e] != NULL; ++e)
-			if (strncmp(environ[e], "PATH=", 5) == 0) {
-				environ[e] = "PATH=/bin:/usr/bin";
-				break;
-			}
-	}
-	mypath = getenv("PATH");
-	if (mypath)
-		strcpy(mypath, "/bin:/usr/bin");
-
-	/*
-	 * We send the copies out separately, because of a bug in
-	 * USG's /bin/mail which will generate ANOTHER To: line,
-	 * even though we already have one, if there are at least
-	 * two recipients.
-	 */
-	for (i=0; i<nrecips; i++) {
-		/*
-		 * mail recips[i] < tmpf
-		 */
-		pid = mailto(tmpf, errfd, recips[i]);
-		exstat = -1;
-		while ((wpid = wait(&exstat)) >= 0 && wpid != pid)
-			;
-		if (exstat == 0)
-			goodcnt++;
-		else
-			badcnt++;
-	}
-	if (badcnt) {
-		mailback(errfd, tmpf, errf);
-		(void) unlink(tmpf);
-		(void) unlink(errf);
-		exit(1);
-	} else if (goodcnt == 0) {
-		fprintf(errfd, "recmail: no 'To:' line\n");
-		mailback(errfd, tmpf, errf);
-		(void) unlink(tmpf);
-		(void) unlink(errf);
-		exit (1);
-	}
-	(void) unlink(tmpf);
-	(void) unlink(errf);
-	exit (0);
-}
-
-#define isok(c) (isprint(c) && (c) != ' ' && c != ',')
-addrecips(line)
-char *line;
-{
-	char *front, *back, *tail;
-	char *malloc();
-
-	tail = line + strlen(line);
-	for (front=line; front < tail; ) {
-		while (!isok(*front) && front < tail)
-			front++;
-		if (front >= tail)
-			break;	/* skip end of line garbage */
-		for (back=front; isok(*back); back++)
-			;
-		*back=0;
-		if (nrecips >= MAXRECIPS) {
-			printf("Too many destinations\n");
-			exit(2);
-		}
-		if ((recips[nrecips] = malloc(strlen(front) + 1)) == NULL) {
-			printf("Out of space\n");
-			exit(2);
-		}
-		(void) strcpy(recips[nrecips], front);
-		nrecips++;
-		front = back+1;
-	}
-}
-
-int
-mailto(tmpf, errfd, recip)
-char *tmpf;
-FILE *errfd;
-char *recip;
-{
-	register int pid;
-
-	/*
-	 * mail recips < tmpf
-	 */
-	while ((pid = vfork()) == -1) {
-		fprintf(stderr, "fork failed, waiting...\r\n");
-		sleep(60);
-	}
-	if (pid == 0) {
-		(void) close(0);
-		(void) open(tmpf, 0);
-		if (errfd != NULL) {
-			(void) close(1);
-			(void) dup(fileno(errfd));
-			(void) fclose(errfd);
-			(void) close(2);
-			(void) dup(1);
-		}
-		execlp(mailer, mailer, recip, (char *)0);
-		perror(mailer);
-		exit(1);
-	}
-	return pid;
-}
-
-mailback(errfd, tmpf, errf)
-register FILE *errfd;
-char *tmpf;
-char *errf;
-{
-	register FILE *fd;
-	register int c;
-	int exstat;
-	register int pid, wpid;
-	char *logn;
-	char *getlogin(), *getenv();
-	register struct passwd *pwd;
-
-	if ((fd = fopen(tmpf, "r")) != NULL) {
-		fprintf(errfd, "\n   ----- Unsent message follows -----\n");
-		while ((c = getc(fd)) != EOF)
-			putc(c, errfd);
-		(void) fclose(fd);
-	}
-	(void) fclose(errfd);
-	if ((logn = getlogin()) == NULL && (logn = getenv("USER")) == NULL) {
-		if ((pwd = getpwent(getuid())) == NULL)
-			return;
-		logn = pwd->pw_name;
-	}
-	pid = mailto(errf, (FILE *)NULL, logn);
-	while ((wpid = wait(&exstat)) >= 0 && wpid != pid)
-		;
-}
*-*-END-of-src/recmail.c-*-*
echo x - src/ftime.c 1>&2
sed 's/.//' >src/ftime.c <<'*-*-END-of-src/ftime.c-*-*'
-#ifdef SCCSID
-static char	*SccsId = "@(#)ftime.c	2.5	4/26/85";
-#endif /* SCSCID */
-
-#include <sys/types.h>
-struct timeb
-{
-	time_t	time;
-	unsigned short millitm;
-	short	timezone;
-	short	dstflag;
-};
-
-extern long timezone;
-extern int  daylight;
-
-ftime(tp)
-struct timeb *tp;
-{
-	long t;
-
-	time(&t);
-	tp->time = t;
-	tp->millitm = 0;
-	tp->timezone = timezone/60;
-	tp->dstflag = daylight;
-}
*-*-END-of-src/ftime.c-*-*
exit