2.9BSD/usr/contrib/news/src/readnews.c

Compare this file to the similar file:
Show the results in this format:

/*
 * readnews - read news articles.
 */

static char	*SccsId = "@(#)readnews.c	2.10	4/23/83";

#include "rparams.h"

/*
 * readnews - article reading program
 */

#ifndef SYSBUF
char	SYSBUF[BUFSIZ];	/* to buffer std out */
#endif

#define OPTION	0	/* pick up an option string */
#define STRING	1	/* pick up a string of arguments */

/*
 *	Authors:
 *		Matt Glickman	ucbvax!glickman
 *		Mark Horton	cbosg!mark
 *		Stephen Daniels	duke!swd
 *		Tom Truscott	duke!trt
 */

main(argc, argv)
int	argc;
register char	**argv;
{
	register char	*ptr;	/* pointer to rest of buffer		*/
	char	*user, *home;
	struct passwd *pw;
	struct group *gp;
	int	i, optflag = FALSE, space = FALSE;
	struct utsname ubuf;
	char	*myrc;
#ifdef NOTIFY
	FILE		*nfd;		/* notify file descriptor */
#endif

	/* set up defaults and initialize. */
	pathinit();
	mode = UNKNOWN;
	header.title[0] = header.nbuf[0] = '\0';
	titlebuf[0] = coptbuf[0] = datebuf[0] = '\0';
	uname(&ubuf);
	strcpy(SYSNAME, ubuf.nodename);
	SYSNAME[SNLN] = '\0';

	savmask = umask(N_UMASK);	/* set up mask */
	uid = getuid();
	gid = getgid();
	duid = 0;
	dgid = 0;

#ifndef V6
#ifndef SHELL
	if ((SHELL = getenv("SHELL")) == NULL)
		SHELL = "/bin/sh";
#endif
#ifndef IHCC
	/*
	 * IHCC does not allow use of $LOGNAME to prevent forgery.
	 * Note that this shouldn't matter in readnews, since inews
	 * does all the actual posting of news.
	 */
	if ((user = getenv("USER")) == NULL)
		user = getenv("LOGNAME");
	if ((home = getenv("HOME")) == NULL)
		home = getenv("LOGDIR");
#endif
	if (user == NULL || home == NULL)
		getuser();
	else {
		strcpy(username, user);
		strcpy(header.path, username);
		strcpy(userhome, home);
	}

	getuser();
	if (!(MAILER = getenv("MAILER")))
		MAILER = "mail";	/* was /bin/mail */

#ifdef PAGE
	if (myrc = getenv("PAGER"))
		strcpy(PAGER, myrc);
	else
# ifdef IHCC
		sprintf(PAGER,"%s/bin/%s",logdir(HOME),PAGE);
# else
		strcpy(PAGER, PAGE);
# endif
#else
	strcpy(PAGER, "");
#endif

	if (ptr = getenv("NEWSOPTS"))
		strcpy(rcbuf, ptr);
	else
		*rcbuf = '\0';
	if (*rcbuf) {
		strcat(rcbuf, " \1");
		ptr = rcbuf;
		while (*++ptr)
			if (isspace(*ptr))
				*ptr = '\0';
		for (ptr = rcbuf; ; ptr++) {
			if (!*ptr)
				continue;
			if (*ptr == '\1')
				break;
			if (++line > LINES)
				xerror("Too many options.\n");
			if ((rcline[line] = malloc(strlen(ptr) + 1)) == NULL)
				xerror("Not enough memory.\n");
			argvrc[line] = rcline[line];
			strcpy(rcline[line], ptr);
			while (*ptr)
				ptr++;
		}
	}
#else
	getuser();
#endif
	myrc = getenv("NEWSRC");
	if (myrc == NULL) {
		myrc = NEWSRC;
		sprintf(newsrc, "%s/%s", userhome, myrc);
	} else {
		strcpy(newsrc, myrc);
	}
	if (access(newsrc, 0))
		newrc(newsrc);
	if ((rcfp = fopen(newsrc, "r")) != NULL) {
		rcreadok = FALSE;
		while (fgets(rcbuf, LBUFLEN, rcfp) != NULL) {
			if (!(space = isspace(*rcbuf)))
				optflag = FALSE;
			if (!strncmp(rcbuf, "options ", 8))
				optflag = TRUE;
			if (optflag) {
				strcat(rcbuf, "\1");
				if (space)
					ptr = rcbuf - 1;
				else
					ptr = &rcbuf[7];
				while (*++ptr)
					if (isspace(*ptr))
						*ptr = '\0';
				if (space)
					ptr = rcbuf;
				else
					ptr = &rcbuf[8];
				for (; ; ptr++) {
					if (!*ptr)
						continue;
					if (*ptr == '\1')
						break;
					if (++line > LINES)
						xerror("Too many options.\n");
					if ((rcline[line] = malloc(strlen(ptr) + 1)) == NULL)
						xerror("Not enough memory.\n");
					argvrc[line] = rcline[line];
					strcpy(rcline[line], ptr);
					while (*ptr)
						ptr++;
				}
			}
		}
		fclose(rcfp);
		rcreadok = TRUE;
	}
	if (line != -1) {
#ifdef DEBUG
		for (i = 0; i <= line; i++)
			fprintf(stderr, "options:  %s\n", rcline[i]);
#endif
		process(line + 2, argvrc);
		do {
#ifdef DEBUG
			fprintf(stderr, "Freeing %d\n", line);
#endif
			free(rcline[line]);
		} while (line--);
	}

	argv++;
	strcat(header.nbuf, ADMSUB);
	ngcat(header.nbuf);
	process(argc, argv);
	if (!nflag) {
		strcpy(header.nbuf, DFLTSUB);
		ngcat(header.nbuf);
		strcat(header.nbuf, ADMSUB);
		ngcat(header.nbuf);
	}
	if (*header.nbuf)
		lcase(header.nbuf);
	makehimask(header.nbuf, "junk");
	makehimask(header.nbuf, "control");
	makehimask(header.nbuf, "test");

	setbuf(stdout, SYSBUF);
	sigtrap = FALSE;	/* true if a signal has been caught */
	if (!pflag && !lflag && !eflag) {
		signal(SIGQUIT, SIG_IGN);
		signal(SIGHUP, onsig);
		signal(SIGINT, onsig);
		signal(SIGPIPE, onsig);
	}

	/*
	 * ALL of the command line has now been processed. (!)
	 */

	if (!*header.nbuf)
		ngcat(strcpy(header.nbuf, DFLTSUB));
	if (sflag) {
		ngdel(header.nbuf);
		printf("Subscription list:  %s\n", header.nbuf);
		xxit(0);
	}
	if (!xflag && (rcfp = xfopen(newsrc, "r"))) {
		while (!sigtrap && fgets(rcbuf, LBUFLEN, rcfp) != NULL) {
			if (!nstrip(rcbuf))
				xerror(".newsrc line too long");
			if (++line >= LINES)
				xerror("Too many .newsrc lines");
			if ((rcline[line] = malloc(strlen(rcbuf) + 1)) == NULL)
				xerror("Not enough memory");
			strcpy(rcline[line], rcbuf);
		}
		fclose(rcfp);
	}
	actfp = xfopen(ACTIVE, "r");

#ifdef DEBUG
	fprintf(stderr, "header.nbuf = %s\n", header.nbuf);
#endif
	switch (mode) {
	case UNKNOWN:
		readr();
		break;
#ifdef TMAIL
	case MAIL:
		Mail();
		break;
#endif
	}
	fflush(stdout);
	if (xflag || lflag || tflag)
		xxit(0);
	if (*groupdir && mode != MAIL)
		updaterc();
	writeoutrc();
	xxit(0);

	/* Camel, R.O.H. */
}

/*
 * Write out the .newsrc file.  We sort it into "active" file order,
 * for speed in future invocations, and to get rid of junk.
 */
writeoutrc()
{
	FILE *rcfp, *actfp;
	char afline[BUFLEN];
	register int i, c;
	register char *p;

	if (!rcreadok)
		return;
#ifdef VMS
	unlink(newsrc);
#endif

	rcfp = xfopen(newsrc, "w");
	actfp = xfopen(ACTIVE, "r");

	/* Write out options line, continuations, and comments. */
	for (i=0; ;i++) {
		c = rcline[i][0];
		if (c != 'o' && c != '#' && c != ' ' && c != '\t')
			break;
		if (c == 'o' && strncmp(rcline[i], "options", 7) != 0)
			break;
		fprintf(rcfp, "%s\n", rcline[i]);
	}

	/* For each newsgroup in active, find that newsrc line and write it out. */
	while (fgets(afline, sizeof afline, actfp)) {
		p = index(afline, ' ');
		if (p)
			*p = 0;
		i = findrcline(afline);
		if (i >= 0)
			fprintf(rcfp, "%s\n", rcline[i]);
	}
	fclose(rcfp);
	fclose(actfp);
}

/*
 * Forbid newsgroup ng, unless he asked for it in nbuf.
 */
makehimask(nbuf, ng)
char *nbuf, *ng;
{
	if (!findex(nbuf, ng)) {
		ngcat(nbuf);
		strcat(nbuf, "!");
		strcat(nbuf, ng);
		ngcat(nbuf);
	}
}

/*
 * Return true if the string searchfor is in string, but not if preceeded by !.
 */
findex(string, searchfor)
char *string, *searchfor;
{
	register char first;
	register char *p;

	first = *searchfor;
	for (p=index(string, first); p; p = index(p+1, first)) {
		if (p==string || (p>string && p[-1] != '!' && strncmp(p, searchfor, strlen(searchfor)) == 0))
			return TRUE;
	}
	return FALSE;
}