2.9BSD/usr/contrib/news/src/readnews.c
/*
* 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;
}