[comp.sources.unix] v12i039: C News alpha release, Part14/14

rsalz@uunet.UU.NET (Rich Salz) (10/23/87)

Submitted-by: utzoo!henry (Henry Spencer)
Posting-number: Volume 12, Issue 39
Archive-name: cnews/part14

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 14 (of 14)."
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'rna/readnews.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rna/readnews.c'\"
else
echo shar: Extracting \"'rna/readnews.c'\" \(26200 characters\)
sed "s/^X//" >'rna/readnews.c' <<'END_OF_FILE'
X/*
X * readnews
X *
X *	Michael Rourke (UNSW) April 1984
X */
X
X#include "defs.h"
X
X#define ARTSEP "/"
X
Xchar postnews[]	 = POSTNEWS;
Xchar admsub[]	 = ADMSUB;
Xchar dfltsub[]	 = DFLTSUB;
Xchar *mailpath	 = MAIL;
X
X#define	MAXARGV	10		/* used in building argv[]s below */
X
X#ifndef NETID
Xchar systemid[DIRSIZ];
X#else
Xchar systemid[] = NETID;
X#endif
X
Xbool iflag;		/* -i ignore .newsrc */
Xbool lflag;		/* -l print headers only */
Xbool cflag;		/* -c check for news only */
Xbool pflag;		/* -p print everything selected */
Xchar **uflag;		/* -u messagid (unsubscribe from followups) */
Xint usize;		/* number of uflag entries */
Xbool Cflag;		/* -C verbose -c */
Xbool sflag;		/* -s print newsgroup subscription list */
Xbool splus;		/* -s+ */
Xbool slistall;		/* -s? */
Xbool sminus;		/* -s- */
Xchar *sarg;		/* arg to -s[+-] */
Xchar *nflag;		/* -n newsgroups */
Xextern char *rcgrps;	/* -n newsgroups from newsrc file */
Xbool n_on_cline;	/* nflag set on command line */
X
Xextern newsrc	*rc;		/* internal .newsrc */
X
Xactive *alist;		/* internal active list */
X
X#if MANGRPS
Xchar *mangrps;	/* mandatory subsciption list */
X#endif
X
X#if AUSAM
Xstruct pwent pe;		/* current user passwd struct */
Xchar sbuf[SSIZ];	/* passwd strings */
X#else
Xstruct passwd *pp;		/* current user passwd struct */
X#endif
Xlong now;		/* current time */
Xbool interrupt;		/* if interrupt hit */
Xchar *newsdir;		/* %news */
Xuid_t newsuid;		/* %news uid (not used) */
Xbool su;		/* if super user (not used) */
X
Xapplycom list(), check(), commands();
Xvoid *onintr();
Xbool ureject(), seen(), subs(), subsub();
X
X#if MANGRPS
Xchar *getmangrps();
X#endif
X
Xmain(argc, argv)
Xint argc;
Xchar *argv[];
X{
X	char buf[BUFSIZ], *p;
X
X	setbuf(stdout, buf);			/* TODO: remove this? */
X	if (options(--argc, ++argv, true)) {
X		(void) fprintf(stderr, "Usage: readnews [-n newsgroups] [-i] [-clpC] [-s[-+? [group]]] [-u messageid]\n");
X		exit(1);
X	}
X	now = time(&now);
X
X#if AUSAM
X	pe.pw_strings[LNAME] = NEWSROOT;
X	if (getpwuid(&pe, sbuf, sizeof(sbuf)) == PWERROR)
X		error("Password file error.");
X	newsdir = newstr(pe.pw_strings[DIRPATH]);
X	newsuid = pe.pw_limits.l_uid;
X#else
X	if ((pp = getpwnam(NEWSROOT)) == NULL)
X		error("Password file error.");
X	newsdir = newstr(pp->pw_dir);
X	newsuid = pp->pw_uid;
X#endif
X
X#if AUSAM
X#if MANGRPS
X	pe.pw_limits.l_uid = getuid();
X	if (getpwlog(&pe, NIL(char), 0) == PWERROR)	/* want pw_cmask */
X		error("Password file error.");
X#endif
X	pwclose();
X#else
X	pp = NIL(struct passwd );
X	endpwent();
X#endif
X
X#ifndef NETID
X	getaddr(G_SYSNAME, systemid);
X#endif
X
X	if (!iflag)
X		readnewsrc();
X
X	if (nflag)
X		convgrps(nflag);
X	else
X		nflag = dfltsub;
X	if (rcgrps)
X		convgrps(rcgrps);
X	if (!n_on_cline) {
X#if MANGRPS
X		int addsub();
X
X		if (mangrps = getmangrps(pe.pw_cmask))
X			applyng(mangrps, addsub, &nflag);
X#endif
X		if (!ngmatch(admsub, nflag))
X			nflag = newstr3(admsub, NGSEPS, nflag);
X	}
X	if ((int) sflag + (int) lflag + (int) cflag + (int) pflag > 1)
X		error("-clpsC flags are mutually exclusive.");
X	if (uflag)
X		qsort((char *) uflag, (unsigned) usize, sizeof(char *), strpcmp);
X
X	/* user has private mailer? */
X	if ((p = getenv("MAILER")) != NULL)
X		mailpath = newstr(p);
X
X	alist = readactive();
X
X	if (sflag) {
X		if (subs() && !iflag)
X			writenewsrc(alist);
X	} else if (lflag)
X		apply(alist, nflag, list, false);
X	else if (cflag)
X		apply(alist, nflag, check, false);
X	else {
X		if (!pflag) {
X			if (signal(SIGINT, SIG_IGN) != SIG_IGN)
X				(void) signal(SIGINT, onintr);
X			if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
X				(void) signal(SIGQUIT, onintr);
X		}
X		apply(alist, nflag, commands, true);
X		if (!iflag)
X			writenewsrc(alist);
X	}
X	exit(0);
X}
X
X#if MANGRPS
X/*
X * make a subscription list of all class groups the user belongs too
X * (mandatory subscription)
X */
Xchar *
Xgetmangrps(cmask)
Xchar *cmask;
X{
X	static char *weekday[] = { 
X		"mon", "tue", "wed", "thu", "fri" 	};
X	register char **classes;
X	register char *s, *end;
X	register char *grp;
X	register int i, size;
X	extern char **getclasses();
X
X	grp = NIL(char);
X	if ((classes = getclasses(cmask)) == NIL(char *))
X		error("Can't get classes.");
X	while (*classes) {
X		if (isdigit(**classes)) {
X			/*
X			 * trim string after numeric class
X			 * if it is a day of the week
X			 */
X			s = *classes;
X			while (isdigit(*s) || *s == '.')
X				s++;
X			if (*s) {
X				end = s;
X				while (isalpha(*end))
X					end++;
X				if (*end && end != s && end - s <= 3) {
X					size = end - s;
X					for (i = 0; i < 5; i++)
X						if (CMPN(s, weekday[i], size) == 0)
X							break;
X					if (i != 5)
X						*s = '\0';
X				}
X			}
X		}
X		grp = (grp? catstr2(grp, ",class.", *classes):
X			newstr2("class.", *classes));
X		classes++;
X	}
X	return grp;
X}
X
X/*
X * if newsgroup "ng" isn't subscribed to, add it to subscription list
X */
Xaddsub(ng, slist)
Xchar *ng;
Xchar **slist;
X{
X	if (!ngmatch(ng, *slist))
X		*slist = newstr3(ng, NGSEPS, *slist);
X}
X
X#endif
X
Xvoid *
Xonintr()
X{
X	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
X		(void) signal(SIGINT, onintr);
X	if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
X		(void) signal(SIGQUIT, onintr);
X	interrupt = true;
X}
X
X/*
X * process options
X * can be called from readnewsrc()
X */
Xoptions(argc, argv, cline)
Xint argc;
Xchar *argv[];
Xbool cline;
X{
X	register char c;
X
X	/* TODO: use getopt(3) */
X	while (argc > 0) {
X		if (argv[0][0] != '-')
X			break;
X		while (c = *(++(argv[0]))) {
X			switch (c) {
X			case 'n':
X				if (cline)
X					nflag = argv[1], n_on_cline = true;
X				else {
X					if (!n_on_cline)
X						nflag = (nflag?
X							catstr2(nflag, NGSEPS, argv[1]):
X							newstr(argv[1]));
X					rcgrps = (rcgrps?
X						catstr2(rcgrps, NGSEPS, argv[1]):
X						newstr(argv[1]));
X				}
X				argc--, argv++; 
X				break;
X			case 'u':
X				usize++;
X				uflag = (uflag? (char **)myrealloc((char *)uflag,
X						(int)sizeof(char *) * usize):
X					(char **)myalloc((int)sizeof(char *)));
X				uflag[usize - 1] = newstr(argv[1]);
X				argc--, argv++; 
X				break;
X			case 'i':
X				iflag = true; 
X				continue;
X			case 's':
X				sflag = true;
X				switch (argv[0][1]) {
X				case '\0':
X					continue;
X				case '+':
X					splus = true; 
X					break;
X				case '?':
X					slistall = true, ++(argv[0]); 
X					continue;
X				case '-':
X					sminus = true; 
X					break;
X				default:
X					argc = -1; 
X					break;
X				}
X				if (argc > 0) {
X					sarg = newstr(argv[1]);
X					argc--, argv++;
X				}
X				break;
X			case 'p':
X				pflag = true; 
X				continue;
X			case 'l':
X				lflag = true; 
X				continue;
X			case 'c':
X				cflag = true; 
X				continue;
X			case 'C':
X				cflag = Cflag = true; 
X				continue;
X			default:
X				argc = -1; 
X				break;
X			}
X			break;
X		}
X		argc--, argv++;
X	}
X	return argc != 0;
X}
X
X/*
X * subscription list handling
X * return true if newsrc is to be re-written
X */
Xbool
Xsubs()
X{
X	register newsrc	*np;
X	register active	*ap;
X	register char *tmp, *com;
X	register FILE *f;
X
X	if (slistall) {
X		(void) printf("Active newsgroups:\n");
X		(void) fflush(stdout);
X#ifdef	MC			/* gok. probably a local paginator */
X		com = newstr2("exec ", MC);
X		if ((f = popen(com, "w")) == NULL)
X			f = stdout;
X		free(com);
X#else
X		f = stdout;
X		com = 0;		/* for lint */
X		com = com;		/* for lint */
X#endif
X		for (ap = alist; ap; ap = ap->a_next)
X			(void) fprintf(f, "%s\n", ap->a_name);
X#ifdef	MC
X		if (f != stdout)
X			pclose(f);
X#endif
X		return false;
X	} else if (splus || sminus) {
X		if (strpbrk(sarg, BADGRPCHARS)) {
X			(void) printf("%s: Illegal char in newsgroup.\n", sarg);
X			return false;
X		}
X		if (ngmatch(sarg, nflag)) {
X			/*
X			 * normally we subscribe, check for an exclusion
X			 */
X			for (np = rc; np; np = np->n_next)
X				if (CMP(sarg, np->n_name) == 0)
X					break;
X			if (np) {
X				/*
X				 * altering subscribe flag is all
X				 * we need to change
X				 */
X				np->n_subscribe = splus;
X				return true;
X			}
X			if (sminus) {
X				/*
X				 * try deleting from sub list
X				 */
X				if (subsub(sarg, rcgrps))
X					return true;
X				/*
X				 * add specific exclusion
X				 */
X				rcgrps = newstr4(rcgrps, NGSEPS, NEGS, sarg);
X				return true;
X			}
X		} else if (splus) {
X			/*
X			 * we don't subscribe,
X			 * try deleting !sarg first
X			 */
X			tmp = newstr2(NEGS, sarg);
X			subsub(tmp, rcgrps);
X			if (!ngmatch(sarg, rcgrps))
X				/*
X				 * didn't work, so add explicit subscription
X				 */
X				rcgrps = rcgrps? newstr3(rcgrps, NGSEPS, sarg):
X					newstr(sarg);
X			return true;
X		}
X	} else {
X		(void) printf("Subscription list: %s", nflag);
X		for (np = rc; np; np = np->n_next)
X			if (!np->n_subscribe && ngmatch(np->n_name, nflag))
X				(void) printf(",!%s", np->n_name);
X		(void) printf("\n");
X	}
X	return false;
X}
X
X
X/*
X * try and delete group from subscription list
X * return true if successful
X */
Xbool
Xsubsub(grp, slist)
Xchar *grp;
Xchar *slist;
X{
X	register char *delim;
X
X	while (*slist) {
X		if (delim = strchr(slist, NGSEPCHAR))
X			*delim = '\0';
X		if (CMP(grp, slist) == 0) {
X			if (delim)
X				(void) strcpy(slist, delim + 1);
X			else if (slist[-1] = ',')
X				slist[-1] = '\0';
X			else
X				slist[0] = '\0';
X			return true;
X		}
X		if (delim)
X			*delim = NGSEPCHAR, slist = delim + 1;
X		else
X			break;
X	}
X	return false;
X}
X
X/*
X * list titles command (-l)
X */
Xapplycom
Xlist(ap, np)
Xactive *ap;
Xnewsrc *np;
X{
X	static active *lastap;
X	static bool first = true;
X	register char *fname;
X	register FILE *f;
X	header h;
X	ino_t ino;
X
X	np->n_last++;
X	fname = convg(newstr5(newsdir, "/", ap->a_name, ARTSEP,
X		itoa(np->n_last)));
X	ino = 0;
X	f = fopen(fname, "r");
X	free(fname);
X	if (!f || seen(f, &ino))
X		return next;
X	gethead(f, &h);
X	if (uflag && h.h_references && ureject(&h)) {
X		freehead(&h);
X		return next;
X	}
X	if (first) {
X		(void) printf("News articles:\n");
X		first = false;
X	}
X	if (lastap != ap)
X		(void) printf("  %s:\n", ap->a_name);
X	lastap = ap;
X	(void) printf("    %-4d %s\n", np->n_last, h.h_subject);
X	(void) fclose(f);
X	freehead(&h);
X	if (ino)
X		seen(NIL(FILE), &ino);
X	return next;
X}
X
X/*
X * check command (-c or -C)
X */
Xapplycom
Xcheck(ap, np)
Xactive *ap;
Xnewsrc *np;
X{
X	static bool done;
X	register int num;
X
X	np->n_last++;
X	if (Cflag) {
X		if (!done)
X			(void) printf("You have news:\n");
X		done = true;
X		num = ap->a_seq - np->n_last + 1;
X		(void) printf("\t%s %d article%s\n", ap->a_name, num, num > 1 ? "s" :
X		    "");
X		return nextgroup;
X	} else
X	 {
X		(void) printf("You have news.\n");
X		exit(0);
X		/* NOTREACHED */
X	}
X}
X
X
X/*
X * normal command handler (or pflag)
X * commands:
X *
X * \n 		print current article
X * + 		go to next article
X * q		quit
X * c		cancel
X * r		reply
X * m [person]	mail
X * f 		followup
X * p 		postnews
X * n [newsgrp]	next newsgroup
X * s [file]	save
X * u		unsubscribe from followup
X * U		unsubscribe from group
X * !stuff	shell escape
X * number or .	go to number
X * - 		back to previous article (toggle)
X * x		quick exit
X * h		long header info
X * H		full header
X *
X * inside r, f or p:
X *	.e	edit
X *	.i	interpolate
X *	. or EOT terminate message
X *	.!comd	shell escape
X */
Xapplycom
Xcommands(ap, np, last, pushed)
Xactive *ap;
Xnewsrc *np;
Xbool last;
Xbool pushed;
X{
X	static char errmess[] = "Incorrect command; Type `?' for help.\n";
X	static char form[]    = "%s: %s\n";
X
X	static char savedsys[BUFSIZ / 2];
X	static active	*lastap, *rlastap;
X	static newsrc	lastn;
X	static char number[20];
X	static active	*wantap;
X
X	register char *com, *arg;
X	register int c, i, size;
X	register FILE 	*f;
X	char *fname;
X	header		h;
X	newsrc		ntmp;
X	ino_t		ino;
X	bool printed, pheader, verbose, hadinterrupt;
X	applycom	nextact;
X
X	extern char t_from[], t_subject[], t_date[];
X	extern char t_newsgroups[], t_path[], t_sender[];
X	extern char t_replyto[], t_organization[];
X	extern char *strncpy();
X	extern active	*activep();
X
X
X	if (last) {
X		/*
X		 * give user one last chance to
X		 * see this article
X		 */
X		ap = rlastap;
X		np = &lastn;
X		wantap = NIL(active);
X		if (!ap || pflag)
X			return stop;
X	} else if (wantap)
X		/*
X		 * doing an "n newsgroup" command
X		 */
X		if (wantap != ap)
X			return nextgroup;
X		else
X			wantap = NIL(active);
X
X	fname = convg(newstr5(newsdir, "/", ap->a_name, ARTSEP,
X		itoa(np->n_last + 1)));
X	f = fopen(fname, "r");
X	ino = 0;
X	if (!f || !last && !pushed && seen(f, &ino)) {
X		if (pushed)
X			(void) printf("Article %d (%s) no longer exists.\n",
X				np->n_last + 1, ap->a_name);
X		else
X			np->n_last++;
X		if (f)
X			(void) fclose(f);
X		free(fname);
X		return next;
X	}
X
X	gethead(f, &h);
X	if (!pushed && uflag && h.h_references && ureject(&h)) {
X		/* unsubscribed followup */
X		freehead(&h);
X		np->n_last++;
X		(void) fclose(f);
X		free(fname);
X		return next;
X	}
X
X	(void) printf("\n");
X	interrupt = hadinterrupt = verbose = false;
X	if (last) {
X		(void) printf("No more articles.\n");
X		printed = pheader = true;
X	} else
X		printed = pheader = false;
X
X	while (1) {
X		if (lastap != ap) {
X			size = strlen(ap->a_name) + sizeof("Newsgroup");
X			for (i = 0; i < size; i++)
X				(void) putc('-', stdout);
X			(void) printf("\nNewsgroup %s\n", ap->a_name);
X			for (i = 0; i < size; i++)
X				(void) putc('-', stdout);
X			(void) printf("\n\n");
X		}
X		lastap = ap;
X		if (!pheader) {
X			(void) printf("Article %d of %d (%s)",
X				np->n_last + 1, ap->a_seq, ap->a_name);
X			if (h.h_lines != 0)
X				(void) printf(" (%s lines)", h.h_lines);
X			(void) printf("\n");
X			(void) printf(form, t_subject, h.h_subject);
X			(void) printf(form, t_from, h.h_from);
X			if (verbose || pflag) {
X				(void) printf(form, t_date, h.h_date);
X				(void) printf(form, t_newsgroups, h.h_newsgroups);
X				(void) printf(form, t_path, h.h_path);
X				if (h.h_sender)
X					(void) printf(form, t_sender, h.h_sender);
X				if (h.h_replyto)
X					(void) printf(form, t_replyto, h.h_replyto);
X				if (h.h_organisation)
X					(void) printf(form, t_organization, h.h_organisation);
X				verbose = false;
X			}
X			pheader = true;
X		}
X		if (!pushed && number[0])
X			/*
X			 * just returned from a number command
X			 * and have another to do
X			 */
X			com = number;
X		else if (pflag)
X			/*
X			 * just print it
X			 */
X			com = "";
X		else
X		 {
X			(void) printf("? ");
X			if (fflush(stdout) == EOF) {
X				(void) printf("\n? ");
X				(void) fflush(stdout);
X			}
X			interrupt = false;
X			if ((com = mgets()) == NIL(char)) {
X				if (interrupt)
X					if (!hadinterrupt) {
X						clearerr(stdin);
X						(void) printf("Interrupt\n");
X						hadinterrupt = true;
X						interrupt = false;
X						continue;
X					}
X					else
X						exit(1);
X				nextact = stop;
X				break;
X			}
X			hadinterrupt = false;
X		}
X		if (*com == '!') {
X			if (com[1] == '!') {
X				(void) printf("!%s\n", savedsys);
X				com = savedsys;
X			} else
X				com++;
X			(void) fflush(stdout);
X#ifdef F_SETFD
X			fcntl(fileno(f), F_SETFD, 1);	/* close on exec */
X#endif
X			system(com);
X			if (com != savedsys)
X				strncpy(savedsys, com, sizeof(savedsys) - 1);
X			(void) printf("!\n");
X			if (!printed)
X				pheader = false;
X			continue;
X		}
X		/*
X		 * check command syntax
X		 */
X		if (*com && !isdigit(*com) && com[1] && (!isspace(com[1]) ||
X		    strchr("nsm", *com) == NIL(char))) {
X			(void) printf(errmess);
X			continue;
X		}
X		if (c = *com) {
X			arg = com;
X			while (isspace(*++arg))
X				;
X		} else
X			arg = NIL(char);
X		switch (c) {
X		case 0:
X		case '.':
X			if (!printed || c == '.') {
X				if (pflag)
X					(void) printf("\n");
X				print(&h, f);
X				if (pflag) {
X					nextact = next;
X					break;
X				}
X				printed = true;
X				continue;
X			}
X		case 'n':			/* B compatible */
X		case '+':
X		case ';':
X			nextact = next;
X			break;
X		case '?':
X			help();
X			continue;
X		case 'c':
X			cancelarticle(&h);
X			continue;
X		case 'r':
X			reply(&h, fname);
X			continue;
X		case 'm':
X			if (!arg || !*arg)
X				(void) printf("Person argument missing.\n");
X			else
X				mail(&h, fname, arg);
X			continue;
X		case 'f':
X			followup(&h, fname);
X			continue;
X		case 'p':
X			pnews(fname);
X			continue;
X		case 'U':
X			if (ngmatch(np->n_name, ADMSUB)
X#if MANGRPS
X			 || ngmatch(np->n_name, mangrps))
X#else
X				)
X#endif
X				 {
X					(void) printf("Group \"%s\" can't be unsubscribed.\n",
X					     					 np->n_name);
X					continue;
X				}
X			np->n_subscribe = false;
X			nextact = nextgroup;
X			break;
X		case 'u':
X			unsubscribe(h.h_references);
X			nextact = next;
X			break;
X		case 'N':			/* B compatible */
X			if (!*arg) {
X				nextact = nextgroup;
X				break;
X			}
X			if ((wantap = activep(arg)) == NIL(active)) {
X				(void) printf("%s: non-existent newsgroup.\n", arg);
X				continue;
X			}
X			if (!ngmatch(arg, nflag)) {
X				(void) printf("%s: is not subscribed to!\n", arg);
X				wantap = NIL(active);
X				continue;
X			}
X			nextact = searchgroup;
X			break;
X		case 's':
X			save(&h, f, arg);
X			continue;
X		case 'q':
X			nextact = stop;
X			break;
X		case 'x':
X			exit(0);
X		case 'h':
X			verbose = true;
X			pheader = false;
X			continue;
X		case 'H':
X			puthead(&h, stdout, printing);
X			continue;
X		case '-':
X			if (pushed) {
X				nextact = next;
X				break;
X			}
X			if (!rlastap || !lastn.n_name) {
X				(void) printf("Can't go back!\n");
X				continue;
X			}
X			nextact = commands(rlastap, &lastn, false, true);
X			/*
X			 * number commands, after a "-" act on the
X			 * group of the "-" command
X			 */
X			while (number[0]) {
X				ntmp = lastn;
X				ntmp.n_last = atoi(number) - 1;
X				number[0] = '\0';
X				nextact = commands(rlastap, &ntmp, false, true);
X			}
X			if (nextact != next)
X				break;
X			(void) printf("\n");
X			pheader = false;
X			continue;
X		default:
X			if (isdigit(c)) {
X				i = c - '0';
X				while (isdigit(*arg))
X					i = i * 10 + *arg++ - '0';
X			}
X			if (!isdigit(c) || *arg != '\0') {
X				(void) printf(errmess);
X				continue;
X			}
X			number[0] = '\0';
X			if (i < ap->a_low || i > ap->a_seq) {
X				(void) printf("Articles in \"%s\" group range %d to %d.\n",
X				     					np->n_name, ap->a_low, ap->a_seq);
X				continue;
X			}
X			if (pushed) {
X				sprintf(number, "%d", i);
X				nextact = next;
X				break;
X			}
X			ntmp = *np;
X			ntmp.n_last = i - 1;
X			if ((nextact = commands(ap, &ntmp, false, true)) !=
X			    next)
X				break;
X			if (!number[0]) {
X				(void) printf("\n");
X				pheader = false;
X			}
X			continue;
X		}
X		break;
X	}
X	rlastap = ap;
X	lastn = *np;
X	if (!pushed && (nextact == next || printed)) {
X		np->n_last++;
X		if (ino)
X			seen(NIL(FILE), &ino);
X	}
X	freehead(&h);
X	(void) fclose(f);
X	free(fname);
X	return nextact;
X}
X
X
X/*
X * see if this is a followup we are ignoring
X */
Xbool
Xureject(hp)
Xregister header *hp;
X{
X	register bool found;
X	register char *rp, *ids, c;
X	char *key[1];
X
X	found = false;
X	rp = hp->h_references;
X	while (*rp && !found) {
X		if (ids = strpbrk(rp, " ,")) {
X			c = *ids;
X			*ids = '\0';
X		}
X		key[0] = rp;
X		found = (bool) (bsearch((char *) key, (char *) uflag, (unsigned) usize,
X		     sizeof(char *), strpcmp) != NIL(char));
X		if (ids)
X			*ids = c, rp = ids + 1;
X		else
X			break;
X		while (isspace(*rp) || *rp == ',')
X			rp++;
X	}
X	return found;
X}
X
X
X/*
X * see if the article has links, if so have we seen it?
X * close file if we return true
X *
X * called twice,
X *	first (with f set) to test (and possibly set *ino)
X *	again to put *ino in memory
X */
Xbool
Xseen(f, ino)
XFILE *f;
Xino_t *ino;
X{
X	static int num;
X	static ino_t	*ilist;
X	struct stat statb;
X	register int i;
X
X	if (f) {
X		if (fstat(fileno(f), &statb) != 0 || statb.st_nlink <= 1)
X			return false;
X		for (i = 0; i < num; i++)
X			if (ilist[i] == statb.st_ino) {
X				(void) fclose(f);
X				return true;
X			}
X		*ino = statb.st_ino;
X		return false;
X	} else if (*ino) {
X		num++;
X		ilist = (ino_t * ) (ilist ? myrealloc((char *) ilist, (int) sizeof(ino_t) *
X		    num) : myalloc((int) sizeof(ino_t)));
X		ilist[num - 1] = *ino;
X	}
X	return true;
X}
X
X
X/*
X * print out help file
X */
Xhelp()
X{
X	register FILE	*f;
X	register int c;
X	static char helppath[]	 = HELP;
X
X	if ((f = fopen(helppath, "r")) == NIL(FILE)) {
X		(void) printf("Can't open %s\n", helppath);
X		return;
X	}
X	while ((c = getc(f)) != EOF)
X		(void) putc(c, stdout);
X	(void) fclose(f);
X}
X
X/*
X * cancel an article.
X * inews does permission checking.
X */
Xcancelarticle(hp)
Xheader *hp;
X{
X	char *argv[MAXARGV];
X
X	argv[0] = strrchr(postnews, '/') + 1;
X	argv[1] = "-c";		/* TODO: no such option in C news */
X	argv[2] = newstr2("cancel ", hp->h_messageid);
X	argv[3] = "-n";
X	argv[4] = hp->h_newsgroups;
X	if (hp->h_distribution) {
X		argv[5] = "-d";
X		argv[6] = hp->h_distribution;
X		argv[7] = NIL(char);
X	} else
X		argv[5] = NIL(char);
X	run(postnews, argv, true);
X	free(argv[2]);
X}
X
X/*
X * reply to sender by mail
X */
X/* ARGSUSED fname */
Xreply(hp, fname)
Xheader *hp;
Xchar *fname;
X{
X	char *argv[MAXARGV];
X	register int argc;
X
X	argc = 0;
X	argv[argc++] = "mail";
X#ifdef UNSWMAIL
X	argv[argc++] = "-s";
X	if ((argv[argc++] = getsubject(hp)) == NIL(char))
X		return;
X	argv[argc++] = "-i";
X	argv[argc++] = fname;
X#endif
X
X	if ((argv[argc++] = getretaddr(hp)) == NIL(char)) {
X		(void) printf("Can't work out an address!\n");
X		return;
X	}
X
X	argv[argc++] = NIL(char);
X
X	run(mailpath, argv, false);
X
X	free(argv[argc - 2]);
X}
X
X
X/*
X * mail to person
X */
X/* ARGSUSED hp fname */
Xmail(hp, fname, person)
Xheader *hp;
Xchar *fname, *person;
X{
X	char *argv[MAXARGV];
X	register int argc;
X
X	argc = 0;
X	argv[argc++] = "mail";
X#ifdef UNSWMAIL
X	argv[argc++] = "-i";
X	argv[argc++] = fname;
X	argv[argc++] = "-s";
X	argv[argc++] = hp->h_subject;
X#endif
X	argv[argc++] = person;
X	argv[argc++] = NIL(char);
X
X	run(mailpath, argv, false);
X}
X
X
X/*
X * generate correct headers for a followup article
X * then call inews.
X */
Xfollowup(hp, fname)
Xheader *hp;
Xchar *fname;
X{
X	register int argc;
X	char *argv[10];
X
X	argc = 0;
X	argv[argc++] = strrchr(postnews, '/') + 1;
X	argv[argc++] = "-i";		/* TODO: what's this in B news? */
X	argv[argc++] = fname;
X	argv[argc++] = "-r";
X	if (hp->h_references && hp->h_messageid)
X		argv[argc++] = newstr3(hp->h_references, " ", hp->h_messageid);
X	else if (hp->h_messageid)
X		argv[argc++] = newstr(hp->h_messageid);
X	else
X		argc--;
X
X	argv[argc++] = "-s";
X	if ((argv[argc++] = getsubject(hp)) == NIL(char))
X		return;
X
X	argv[argc++] = "-n";
X	if (hp->h_followupto)
X		argv[argc++] = hp->h_followupto;
X	else
X		argv[argc++] = hp->h_newsgroups;
X	argv[argc++] = NIL(char);
X
X	run(postnews, argv, false);
X
X	if (argc == 10)
X		free(argv[4]);
X}
X
X/*
X * get correct "Subject: Re: .." line
X */
Xchar *
Xgetsubject(hp)
Xregister header *hp;
X{
X	register char *s;
X
X	if (!hp->h_subject) {
X		(void) printf("Subject: Re: ");
X		(void) fflush(stdout);
X		if ((s = mgets()) == NIL(char) || !*s) {
X			(void) printf("The Subject field is mandatory.\n");
X			return NIL(char);
X		}
X		return newstr2("Re: ", s);
X	} else if (CMPN(hp->h_subject, "Re: ", 4) != 0 && CMPN(hp->h_subject,
X	     "re: ", 4) != 0)
X		return newstr2("Re: ", hp->h_subject);
X	else
X		return hp->h_subject;
X}
X
X
X/*
X * run a command, optionally closing stdin
X */
Xrun(com, argv, closein)
Xchar *com;
Xchar *argv[];
Xbool closein;
X{
X	int pid, status, r;
X
X	switch (pid = fork()) {
X	default:
X		/* parent */
X		break;
X	case 0:
X		/* child */
X		if (closein)
X			close(fileno(stdin));
X		execvp(com, argv);
X		error("can't exec %s", com);
X		exit(1);
X
X	case -1:
X		error("can't fork");
X	}
X
X	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
X		(void) signal(SIGINT, SIG_IGN);
X	if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
X		(void) signal(SIGQUIT, SIG_IGN);
X
X	while ((r = wait(&status)) != pid && r != -1)
X		;
X
X	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
X		(void) signal(SIGINT, onintr);
X	if (signal(SIGQUIT, SIG_IGN) != SIG_IGN)
X		(void) signal(SIGQUIT, onintr);
X}
X
X/*
X * call postnews
X */
Xpnews(fname)
Xchar *fname;
X{
X	char *argv[MAXARGV];
X
X	argv[0] = strrchr(postnews, '/') + 1;
X	argv[1] = "-i";		/* TODO: what's this inews option? */
X	argv[2] = fname;
X	argv[3] = NIL(char);
X	run(postnews, argv, false);
X}
X
X/*
X * save an article
X */
Xsave(hp, f, s)
Xheader *hp;
XFILE *f;
Xchar *s;
X{
X	register long pos;
X	register int c;
X	register char *cp;
X	register FILE	*sf;
X	register char *aname;
X	long then;
X	extern char *getenv();
X
X	if (!*s) {
X		if ((aname = getenv("HOME")) == NIL(char)) {
X			(void) printf("No $HOME in environment.\n");
X			return;
X		}
X		s = aname = newstr3(aname, "/", ARTICLES);
X	} else
X		aname = NIL(char);
X	if ((sf = fopen(s, "a")) == NIL(FILE)) {
X		(void) fprintf(stderr, "readnews: can't open %s\n", s);
X		return;
X	}
X	if (aname)
X		free(aname);
X	pos = ftell(f);
X	rewind(f);
X	if (cp = strchr(hp->h_from, ' '))
X		*cp = '\0';
X	if (hp->h_date)
X		then = atot(hp->h_date);
X	else
X		then = 0L;
X	(void) fprintf(sf, "From %s %s", hp->h_from, ctime(then ? &then : &now));
X	if (cp)
X		*cp = ' ';
X	while ((c = getc(f)) != EOF)
X		(void) putc(c, sf);
X	(void) fclose(sf);
X	fseek(f, pos, 0);
X}
X
X
X/*
X * unsubscribe from all followup articles
X * on this topic
X */
Xunsubscribe(id)
Xchar *id;
X{
X	register char *s, c;
X
X	if (!id || !*id) {
X		(void) printf("no references! (warning)\n");
X		return;
X	}
X	while (*id) {
X		if (s = strpbrk(id, " ,")) {
X			c = *s;
X			*s = '\0';
X		}
X		usize++;
X		uflag = (uflag ? (char **) myrealloc((char *) uflag, (int) sizeof(char
X		    *) * usize) : (char **) myalloc((int) sizeof(char *)));
X		uflag[usize - 1] = newstr(id);
X		if (s)
X			*s = c, id = s + 1;
X		else
X			break;
X		while (isspace(*id) || *id == ',')
X			id++;
X	}
X	qsort((char *) uflag, (unsigned) usize, sizeof(char *), strpcmp);
X}
X
X
X/*
X * print an article, if it's long enough call page()
X */
Xprint(hp, f)
Xheader *hp;
XFILE *f;
X{
X	register int c;
X	register long pos;
X
X	pos = ftell(f);
X	if (!pflag && hp->h_lines && atoi(hp->h_lines) >= PAGESIZE - 4)
X		page(f);
X	else
X		while ((c = getc(f)) != EOF)
X			(void) putc(c, stdout);
X	fseek(f, pos, 0);
X}
X
X
X/*
X * copy article text to stdout, and break into pages
X */
Xpage(f)
XFILE *f;
X{
X	static char moremess[]	 = "<CR for more>";
X
X	register int c;
X	register unsigned lineno;
X	char lbuf[80];
X	struct sgttyb ttybuf;
X
X	gtty(fileno(stdin), &ttybuf);
X	if (ttybuf.sg_flags & ECHO) {
X		ttybuf.sg_flags &= ~ECHO;
X		stty(fileno(stdin), &ttybuf);
X		ttybuf.sg_flags |= ECHO;
X	}
X	lineno = 1;
X	while (!interrupt) {
X		while (lineno < PAGESIZE - 4 && !interrupt) {
X			while ((c = getc(f)) != EOF && c != '\n')
X				(void) putc(c, stdout);
X			if (c == EOF)
X				goto fastexit;
X			(void) putc('\n', stdout);
X			lineno++;
X		}
X		if (interrupt)
X			break;
X		(void) printf(moremess);
X		if (fflush(stdout) == EOF)
X			break;
X		(void) read(fileno(stdin), lbuf, sizeof(lbuf));	/* TODO: fix */
X		(void) printf("\r%*s\r", sizeof(moremess), " ");
X		lineno = 0;
X	}
X	if (lineno)
X		(void) putc('\n', stdout);
X	interrupt = false;
Xfastexit:
X	if (ttybuf.sg_flags & ECHO)
X		stty(fileno(stdin), &ttybuf);
X}
X
X/* VARARGS1 */
Xerror(s, a0, a1, a2, a3)
Xchar *s;
X{
X	(void) fprintf(stderr, "readnews: ");
X	(void) fprintf(stderr, s, a0, a1, a2, a3);
X	(void) fprintf(stderr, "\n");
X	exit(1);
X}
END_OF_FILE
if test 26200 -ne `wc -c <'rna/readnews.c'`; then
    echo shar: \"'rna/readnews.c'\" unpacked with wrong size!
fi
# end of 'rna/readnews.c'
fi
echo shar: End of archive 14 \(of 14\).
cp /dev/null ark14isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 14 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
if test -f 'rnews/print' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/print'\"
else
echo shar: Extracting \"'rnews/print'\" \(0 characters\)
sed "s/^X//" >'rnews/print' <<'END_OF_FILE'
END_OF_FILE
if test 0 -ne `wc -c <'rnews/print'`; then
    echo shar: \"'rnews/print'\" unpacked with wrong size!
fi
# end of 'rnews/print'
fi
if test -f 'rnews/printc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/printc'\"
else
echo shar: Extracting \"'rnews/printc'\" \(0 characters\)
sed "s/^X//" >'rnews/printc' <<'END_OF_FILE'
END_OF_FILE
if test 0 -ne `wc -c <'rnews/printc'`; then
    echo shar: \"'rnews/printc'\" unpacked with wrong size!
fi
# end of 'rnews/printc'
fi
if test -f 'rnews/printnonc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/printnonc'\"
else
echo shar: Extracting \"'rnews/printnonc'\" \(0 characters\)
sed "s/^X//" >'rnews/printnonc' <<'END_OF_FILE'
END_OF_FILE
if test 0 -ne `wc -c <'rnews/printnonc'`; then
    echo shar: \"'rnews/printnonc'\" unpacked with wrong size!
fi
# end of 'rnews/printnonc'
fi
if test -f 'rnews/test/demo/batch.large' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/test/demo/batch.large'\"
else
echo shar: Extracting \"'rnews/test/demo/batch.large'\" \(0 characters\)
sed "s/^X//" >'rnews/test/demo/batch.large' <<'END_OF_FILE'
END_OF_FILE
if test 0 -ne `wc -c <'rnews/test/demo/batch.large'`; then
    echo shar: \"'rnews/test/demo/batch.large'\" unpacked with wrong size!
fi
# end of 'rnews/test/demo/batch.large'
fi
if test -f 'rnews/test/lib/errlog' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/test/lib/errlog'\"
else
echo shar: Extracting \"'rnews/test/lib/errlog'\" \(0 characters\)
sed "s/^X//" >'rnews/test/lib/errlog' <<'END_OF_FILE'
END_OF_FILE
if test 0 -ne `wc -c <'rnews/test/lib/errlog'`; then
    echo shar: \"'rnews/test/lib/errlog'\" unpacked with wrong size!
fi
# end of 'rnews/test/lib/errlog'
fi
if test -f 'rnews/test/lib/history' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/test/lib/history'\"
else
echo shar: Extracting \"'rnews/test/lib/history'\" \(0 characters\)
sed "s/^X//" >'rnews/test/lib/history' <<'END_OF_FILE'
END_OF_FILE
if test 0 -ne `wc -c <'rnews/test/lib/history'`; then
    echo shar: \"'rnews/test/lib/history'\" unpacked with wrong size!
fi
# end of 'rnews/test/lib/history'
fi
if test -f 'rnews/test/lib/history.dir' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/test/lib/history.dir'\"
else
echo shar: Extracting \"'rnews/test/lib/history.dir'\" \(0 characters\)
sed "s/^X//" >'rnews/test/lib/history.dir' <<'END_OF_FILE'
END_OF_FILE
if test 0 -ne `wc -c <'rnews/test/lib/history.dir'`; then
    echo shar: \"'rnews/test/lib/history.dir'\" unpacked with wrong size!
fi
# end of 'rnews/test/lib/history.dir'
fi
if test -f 'rnews/test/lib/history.pag' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/test/lib/history.pag'\"
else
echo shar: Extracting \"'rnews/test/lib/history.pag'\" \(0 characters\)
sed "s/^X//" >'rnews/test/lib/history.pag' <<'END_OF_FILE'
END_OF_FILE
if test 0 -ne `wc -c <'rnews/test/lib/history.pag'`; then
    echo shar: \"'rnews/test/lib/history.pag'\" unpacked with wrong size!
fi
# end of 'rnews/test/lib/history.pag'
fi
if test -f 'rnews/test/lib/log' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/test/lib/log'\"
else
echo shar: Extracting \"'rnews/test/lib/log'\" \(0 characters\)
sed "s/^X//" >'rnews/test/lib/log' <<'END_OF_FILE'
END_OF_FILE
if test 0 -ne `wc -c <'rnews/test/lib/log'`; then
    echo shar: \"'rnews/test/lib/log'\" unpacked with wrong size!
fi
# end of 'rnews/test/lib/log'
fi
if test -f 'rnews/test/lib/realrnews' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/test/lib/realrnews'\"
else
echo shar: Extracting \"'rnews/test/lib/realrnews'\" \(0 characters\)
sed "s/^X//" >'rnews/test/lib/realrnews' <<'END_OF_FILE'
END_OF_FILE
if test 0 -ne `wc -c <'rnews/test/lib/realrnews'`; then
    echo shar: \"'rnews/test/lib/realrnews'\" unpacked with wrong size!
fi
# end of 'rnews/test/lib/realrnews'
fi
if test -f 'rnews/test/time.rnews' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/test/time.rnews'\"
else
echo shar: Extracting \"'rnews/test/time.rnews'\" \(144 characters\)
sed "s/^X//" >'rnews/test/time.rnews' <<'END_OF_FILE'
X#! /bin/sh
XHERE=`pwd`
XPATH=$HERE/lib:/bin:/usr/bin; export PATH
Xtime realrnews -s $HERE/spool -l $HERE/lib <demo/batch.large $* # -d fhlmt # -p
END_OF_FILE
if test 144 -ne `wc -c <'rnews/test/time.rnews'`; then
    echo shar: \"'rnews/test/time.rnews'\" unpacked with wrong size!
fi
# end of 'rnews/test/time.rnews'
fi
if test -f 'rnews/vers/bsd42/clsexec.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/vers/bsd42/clsexec.c'\"
else
echo shar: Extracting \"'rnews/vers/bsd42/clsexec.c'\" \(158 characters\)
sed "s/^X//" >'rnews/vers/bsd42/clsexec.c' <<'END_OF_FILE'
X/*
X * set close on exec (on Berklix)
X */
X
X#include <stdio.h>
X#include <sgtty.h>
X
Xfclsexec(fp)
XFILE *fp;
X{
X	(void) ioctl(fileno(fp), FIOCLEX, (char *)NULL);
X}
END_OF_FILE
if test 158 -ne `wc -c <'rnews/vers/bsd42/clsexec.c'`; then
    echo shar: \"'rnews/vers/bsd42/clsexec.c'\" unpacked with wrong size!
fi
# end of 'rnews/vers/bsd42/clsexec.c'
fi
if test -f 'rnews/vers/bsd42/fcntl.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/vers/bsd42/fcntl.h'\"
else
echo shar: Extracting \"'rnews/vers/bsd42/fcntl.h'\" \(47 characters\)
sed "s/^X//" >'rnews/vers/bsd42/fcntl.h' <<'END_OF_FILE'
X#include <sys/file.h>		/* 4.2's O_EXCL defn */
END_OF_FILE
if test 47 -ne `wc -c <'rnews/vers/bsd42/fcntl.h'`; then
    echo shar: \"'rnews/vers/bsd42/fcntl.h'\" unpacked with wrong size!
fi
# end of 'rnews/vers/bsd42/fcntl.h'
fi
if test -f 'rnews/vers/bsd42/memcpy.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/vers/bsd42/memcpy.c'\"
else
echo shar: Extracting \"'rnews/vers/bsd42/memcpy.c'\" \(84 characters\)
sed "s/^X//" >'rnews/vers/bsd42/memcpy.c' <<'END_OF_FILE'
Xmemcpy(to, from, length)
Xchar *to, *from;
Xint length;
X{
X	bcopy(from, to, length);
X}
END_OF_FILE
if test 84 -ne `wc -c <'rnews/vers/bsd42/memcpy.c'`; then
    echo shar: \"'rnews/vers/bsd42/memcpy.c'\" unpacked with wrong size!
fi
# end of 'rnews/vers/bsd42/memcpy.c'
fi
if test -f 'rnews/vers/usg/clsexec.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/vers/usg/clsexec.c'\"
else
echo shar: Extracting \"'rnews/vers/usg/clsexec.c'\" \(145 characters\)
sed "s/^X//" >'rnews/vers/usg/clsexec.c' <<'END_OF_FILE'
X/*
X * set close on exec (on Uglix)
X */
X
X#include <stdio.h>
X#include <fcntl.h>
X
Xfclsexec(fp)
XFILE *fp;
X{
X	(void) fcntl(fileno(fp), F_SETFD, 1);
X}
END_OF_FILE
if test 145 -ne `wc -c <'rnews/vers/usg/clsexec.c'`; then
    echo shar: \"'rnews/vers/usg/clsexec.c'\" unpacked with wrong size!
fi
# end of 'rnews/vers/usg/clsexec.c'
fi
if test -f 'rnews/vers/usg/ftime.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/vers/usg/ftime.c'\"
else
echo shar: Extracting \"'rnews/vers/usg/ftime.c'\" \(251 characters\)
sed "s/^X//" >'rnews/vers/usg/ftime.c' <<'END_OF_FILE'
X/*
X * Uglix ftime simulation
X */
X
X#include <sys/types.h>
X#include <sys/timeb.h>		/* HACK */
X
Xftime(tp)
Xstruct timeb *tp;
X{
X	time_t time();
X
X	tp->time = time(&tp->time);
X	tp->millitm = 0;
X	tp->timezone = 5*60;	/* HACK */
X	tp->dstflag = 1;	/* HACK */
X}
END_OF_FILE
if test 251 -ne `wc -c <'rnews/vers/usg/ftime.c'`; then
    echo shar: \"'rnews/vers/usg/ftime.c'\" unpacked with wrong size!
fi
# end of 'rnews/vers/usg/ftime.c'
fi
if test -f 'rnews/vers/v7/clsexec.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/vers/v7/clsexec.c'\"
else
echo shar: Extracting \"'rnews/vers/v7/clsexec.c'\" \(165 characters\)
sed "s/^X//" >'rnews/vers/v7/clsexec.c' <<'END_OF_FILE'
X/*
X * set close on exec (on Unix)
X */
X
X#include <stdio.h>
X#include <sgtty.h>
X
Xfclsexec(fp)
XFILE *fp;
X{
X	(void) ioctl(fileno(fp), FIOCLEX, (struct sgttyb *)NULL);
X}
X
END_OF_FILE
if test 165 -ne `wc -c <'rnews/vers/v7/clsexec.c'`; then
    echo shar: \"'rnews/vers/v7/clsexec.c'\" unpacked with wrong size!
fi
# end of 'rnews/vers/v7/clsexec.c'
fi
if test -f 'rnews/vers/v7/fcntl.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/vers/v7/fcntl.h'\"
else
echo shar: Extracting \"'rnews/vers/v7/fcntl.h'\" \(0 characters\)
sed "s/^X//" >'rnews/vers/v7/fcntl.h' <<'END_OF_FILE'
END_OF_FILE
if test 0 -ne `wc -c <'rnews/vers/v7/fcntl.h'`; then
    echo shar: \"'rnews/vers/v7/fcntl.h'\" unpacked with wrong size!
fi
# end of 'rnews/vers/v7/fcntl.h'
fi
if test -f 'rnews/vers/v8/README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/vers/v8/README'\"
else
echo shar: Extracting \"'rnews/vers/v8/README'\" \(85 characters\)
sed "s/^X//" >'rnews/vers/v8/README' <<'END_OF_FILE'
XThough it is undocumented, V8 contains an Uglix uname(3) emulation
Xin the C library.
END_OF_FILE
if test 85 -ne `wc -c <'rnews/vers/v8/README'`; then
    echo shar: \"'rnews/vers/v8/README'\" unpacked with wrong size!
fi
# end of 'rnews/vers/v8/README'
fi
if test -f 'rnews/zeropad.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'rnews/zeropad.c'\"
else
echo shar: Extracting \"'rnews/zeropad.c'\" \(84 characters\)
sed "s/^X//" >'rnews/zeropad.c' <<'END_OF_FILE'
X/*
X * zero-padding printf format(s) (non-broken)
X */
X
Xchar ldzeropad[] = "%0*.*ld";
END_OF_FILE
if test 84 -ne `wc -c <'rnews/zeropad.c'`; then
    echo shar: \"'rnews/zeropad.c'\" unpacked with wrong size!
fi
# end of 'rnews/zeropad.c'
fi
if test -f 'batch/batchmunch' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'batch/batchmunch'\"
else
echo shar: Extracting \"'batch/batchmunch'\" \(566 characters\)
sed "s/^X//" >'batch/batchmunch' <<'END_OF_FILE'
X# Alter batch as appropriate for transmission.  Usually this means doing
X# data compression.  We explicitly use "-b 12" here because (1) it is the
X# lowest common denominator for news-capable machines, and (2) higher levels
X# of -b are much more expensive in time and memory and seldom yield much
X# denser output.
X#
X# Just 'cat' will do if straight pass-through is desired.
X#
X# The 'echo' is for compatibility with the stupid 2.11 compressed format.
X# The 'exec' cuts down the number of processes active for this simple case.
X
Xecho '#! cunbatch'
Xexec compress -b 12
END_OF_FILE
if test 566 -ne `wc -c <'batch/batchmunch'`; then
    echo shar: \"'batch/batchmunch'\" unpacked with wrong size!
fi
# end of 'batch/batchmunch'
fi
if test -f 'batch/roomfor' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'batch/roomfor'\"
else
echo shar: Extracting \"'batch/roomfor'\" \(649 characters\)
sed "s/^X//" >'batch/roomfor' <<'END_OF_FILE'
X# About how many batches of $1 bytes will fit in the available spool space
X# without cramping things too badly?
X#
X# You'll have to change this -- your blocksize, minimum-free-desired amount,
X# and df output format will probably differ, and your spool area may be on
X# a different filesystem.
X
XPATH=/bin:/usr/bin ; export PATH
X
Xmin=15000			# Want to keep this many df blocks free.
Xblock=512			# Size of df block in bytes.
Xavail=`df /dev/usr | awk '{print $2}'`		# How much free in spool?
X
Xawk "END {
X	nb = int(($avail - $min) * $block / $1)
X	if (nb <= 0)
X		print 0
X	else if (nb > 50)	# Arbitrary upper bound.
X		print 50
X	else
X		print nb
X}" /dev/null
END_OF_FILE
if test 649 -ne `wc -c <'batch/roomfor'`; then
    echo shar: \"'batch/roomfor'\" unpacked with wrong size!
fi
# end of 'batch/roomfor'
fi
if test -f 'expire/histslash.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'expire/histslash.c'\"
else
echo shar: Extracting \"'expire/histslash.c'\" \(655 characters\)
sed "s/^X//" >'expire/histslash.c' <<'END_OF_FILE'
X/*
X * Convert slashed filenames to dotted group/article names in a history
X * file, for use in mkhistory.  Input comes only from stdin.
X */
X#include <stdio.h>
X#include <assert.h>
X
Xchar *progname = "histslash";
X
Xmain()
X{
X	char buf[BUFSIZ];
X	register char *scan;
X	register char *last;
X	extern char *strchr();
X
X	while (fgets(buf, BUFSIZ, stdin) != NULL) {
X		scan = strchr(buf, '\t');
X		scan = strchr(scan+1, '\t');
X		scan++;
X		last = NULL;
X		while (*scan != '\0') {
X			if (*scan == '/') {
X				*scan = '.';
X				last = scan;
X			}
X			if (*scan == ' ' || *scan == '\n') {
X				assert(last != NULL);
X				*last = '/';
X			}
X			scan++;
X		}
X		fputs(buf, stdout);
X	}
X}
END_OF_FILE
if test 655 -ne `wc -c <'expire/histslash.c'`; then
    echo shar: \"'expire/histslash.c'\" unpacked with wrong size!
fi
# end of 'expire/histslash.c'
fi
##  End of shell archive.
exit 0