BSD 4_2 release
[unix-history] / usr / src / new / new / news / src / readr.c
/*
* readr - /bin/mail and msgs interface and associated functions.
*/
static char *SccsId = "@(#)readr.c 2.26 5/3/83";
#include "rparams.h"
static char lbuf[BUFLEN*2];
#define saveart oobit = bit;strcpy(ofilename1, filename);strcpy(ogroupdir, groupdir);hbufcp(&hbuf1, &h);ongsize = pngsize
#define NLINES(h, fp) (h.numlines[0] ? h.intnumlines : (h.intnumlines=linecnt(fp),sprintf(h.numlines, "%d", h.intnumlines), h.intnumlines))
char *tft = "/tmp/folXXXXXX";
static int hascaught = 0;
static catchintr()
{
hascaught = 1;
printf("\n");
fflush(stdout);
}
/*
* 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 warrent moving some of the simple
* things into register variables, but I don't know what
* breaks the u370 cc.
*/
static char goodone[BUFLEN]; /* last decent article */
static char ogroupdir[BUFLEN]; /* last groupdir */
static char address[PATHLEN]; /* for reply copy */
static char edcmdbuf[128];
static char folbuf[160];
static int rfq = 0; /* for last article */
static long ongsize; /* Previous ngsize */
static long pngsize; /* Printing ngsize */
static char *bptr; /* temp pointer. */
static struct srec srec; /* srec for sys file entries */
static char *tfilename; /* temporary file name */
static char ofilename1[BUFLEN]; /* previous file name */
static struct hbuf hbuf1, hbuf2, *hptr; /* for minusing */
static char *ptr1, *ptr2, *ptr3; /* for reply manipulation */
static int news = 0;
static int abs = FALSE; /* TRUE if we asked absolutely */
static char *ed, tf[100];
static struct hbuf h; /* ditto. */
static int i;
static int oobit; /* last bit, really */
static char *oldsig;
static int dgest = 0;
static FILE *ofp; /* Current output file to terminal*/
static FILE *fp; /* current article to be printed*/
static int holdup; /* 1 iff should stop before hdr */
static int ignorenews; /* 1 iff readnews -p > /dev/null*/
static long timelastsaved; /* time newsrc last written out */
int catchcont();
\f
readr()
{
#ifdef DEBUG
fprintf(stderr, "readr()\n");
#endif
if (aflag) {
if (*datebuf) {
if ((atime = cgtdate(datebuf)) == -1)
xerror("Cannot parse date string");
} else
atime = 0L;
}
if (pflag && ignoring())
ignorenews = TRUE;
if (xflag)
uflag = 0;
if (uflag)
time(&timelastsaved);
ofp = stdout;
if (cflag && coptbuf[0] != '\0') {
umask(022);
mktemp(outfile); /* get "unique" file name */
ofp = xfopen(outfile, "w");
umask(N_UMASK);
cflag = FALSE;
pflag = TRUE;
}
/* loop reading articles. */
fp = NULL;
obit = -1;
nextng();
for ( ;; ) {
if (getnextart(FALSE))
break;
#ifdef DEBUG
printf("after getnextart, fp %x, pos %d, bit %d, group '%s', filename '%s'\n",
fp, ftell(fp), bit, groupdir, filename);
#endif
strcpy(goodone, filename);
if (pflag || lflag || eflag) {
/* This code should be gotten rid of */
if (sigtrap) {
qfflush(ofp);
fprintf(ofp, "\n");
cdump(ofp);
_exit(0); /* kludge! drop when qfflush works */
return;
}
clear(bit);
nextbit();
if (fp) {
fclose(fp);
fp = NULL;
}
continue;
}
for ( ;; ) {
char *pp;
#ifdef SIGCONT
int (*ocont)();
#endif
sigtrap = FALSE;
if (!cflag) {
if (rfq)
fprintf(ofp, "Last article. [qfr] ");
else
fprintf(ofp, "(%d lines) More? [ynq] ", NLINES(h, fp));
} else
fprintf(ofp, "? ");
fflush(ofp);
bptr = lbuf;
#ifdef SIGCONT
ocont = signal(SIGCONT, catchcont);
#endif
pp = fgets(bptr, BUFLEN, stdin);
#ifdef SIGCONT
signal(SIGCONT, ocont);
#endif
if (pp != NULL)
break;
if (!sigtrap)
return;
#ifdef SIGCONT
if (sigtrap != SIGCONT)
#endif
fprintf(ofp, "\n");
}
nstrip(bptr);
while (*bptr == ' ' || *bptr == '\t')
bptr++;
i = command();
if (i)
break;
}
if (!news)
fprintf(stderr, "No news.\n");
cout(ofp);
}
\f
#define EOL() if (*bptr != '\0') { fprintf(ofp, "? for commands.\n"); return FALSE; }
/*
* Process one command, which has already been typed in.
*/
command()
{
char *findhist();
switch (i = *bptr++) {
/* No. Go on to next article. */
case 'n':
EOL();
itsbeenseen(h.ident);
readmode = NEXT;
if (!cflag) {
fclose(fp);
fp = NULL;
}
fprintf(ofp, "\n");
clear(bit);
saveart;
nextbit();
break;
/* Undigestify the article. */
case 'd':
dgest = 1;
/* fall through */
/* yes: print this article, go on. */
case 'y':
EOL();
/* fall through. */
/* The user hit return. Default is 'y' unless rfq, then it's 'q'. */
case '\0':
if (!bptr[-1] && rfq)
return;
readmode = NEXT;
showtail(fp);
clear(bit);
saveart;
nextbit();
break;
/*
* Unsubscribe to the newsgroup and go on to next group
*/
case 'u':
fprintf(ofp, "To unsubscribe, use 'U'\n");
break;
case 'U':
fprintf(ofp, "Unsubscribing to newsgroup: %s\n", groupdir);
obit = -1;
if (fp != NULL) {
fclose(fp);
fp = NULL;
}
if (cflag)
clear(bit);
else
putc('\n', ofp);
rfq = 0;
zapng = TRUE;
saveart;
if (nextng()) {
if (actdirect == BACKWARD)
fprintf(ofp, "Can't back up.\n");
else
return TRUE;
}
break;
/* Print the current version of news */
case 'v':
fprintf(ofp, "News version: %s\n", news_version);
break;
/* reprint the article */
case 'p':
EOL();
if (!cflag)
goto minus;
readmode = NEXT;
if (!cflag) {
fclose(fp);
fp = NULL;
bit = last;
putc('\n', ofp);
}
obit = -1;
break;
/* decrypt joke */
case 'D':
caesar_command();
readmode = NEXT;
clear(bit);
saveart;
nextbit();
break;
/* write out the article someplace */
case 's':
case 'w':
{
char *grn = groupdir;
tfilename = filename;
if (*bptr == '-') {
bptr++;
grn = ogroupdir;
if (*ofilename1)
tfilename = ofilename1;
}
if (*bptr != '\0' && *bptr != ' ') {
fprintf(ofp, "Bad file name.\n");
break;
}
while (*bptr == ' ')
bptr++;
if (*bptr != '|' && *bptr != '/') {
char hetyped[BUFLEN];
char *boxptr;
strcpy(hetyped, bptr);
if (boxptr = getenv("NEWSBOX"))
if (index(boxptr, '%'))
sprintf(bptr, boxptr, grn);
else
strcpy(bptr, boxptr);
else if (hetyped[0] == '~' && hetyped[1] == '/') {
strcpy(hetyped, bptr+2);
strcpy(bptr, userhome);
} else
strcpy(bptr, ".");
strcat(bptr, "/");
if (hetyped[0] != '\0')
strcat(bptr, hetyped);
else
strcat(bptr, "Articles");
}
fwait(fsubr(save, tfilename, bptr));
}
break;
/* back up */
case '-':
minus:
rfq = 0;
abs = TRUE;
if (!*ofilename1) {
fprintf(ofp, "Can't back up.\n");
break;
}
if (cflag)
clear(bit);
else {
fclose(fp);
fp = NULL;
putc('\n', ofp);
}
hbufcp(&hbuf2, &h);
hbufcp(&h, &hbuf1);
hbufcp(&hbuf1, &hbuf2);
strcpy(bfr, filename);
strcpy(filename, ofilename1);
strcpy(ofilename1, bfr);
obit = bit;
if (strcmp(groupdir, ogroupdir)) {
strcpy(bfr, groupdir);
selectng(ogroupdir);
strcpy(groupdir, ogroupdir);
strcpy(ogroupdir, bfr);
ngrp = 1;
back();
}
bit = oobit;
oobit = obit;
obit = -1;
getnextart(TRUE);
return FALSE;
/* skip forwards */
case '+':
caseplus:
if (*bptr == '\0')
strcat(bptr, "1");
rfq = 0;
if (cflag)
clear(bit);
saveart;
last = bit;
for (i = 0; i < atoi(bptr); i++) {
nextbit();
if ((bit > pngsize) || (rflag && bit < 1))
break;
}
if (!cflag) {
putc('\n', ofp);
fclose(fp);
fp = NULL;
}
obit = -1;
break;
/* exit - time updated to that of most recently read article */
case 'q':
EOL();
return TRUE;
/* exit - no time update. */
case 'x':
EOL();
xxit(0);
/* cancel the article. */
case 'c':
cancel_command();
break;
/* escape to shell */
case '!':
fwait(fsubr(ushell, bptr, (char *)NULL));
fprintf(ofp, "\n");
hdr();
break;
/* mail reply */
case 'r':
reply_command();
break;
/* send to some system */
case 'X':
xmit_command();
break;
/* next newsgroup */
case 'P':
*bptr = '-';
case 'N':
if (fp != NULL) {
fclose(fp);
fp = NULL;
}
if (next_ng_command())
return TRUE;
break;
/* specific no. */
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
sscanf(--bptr, "%d", &i);
if (i == 0) {
fprintf(ofp, "Bad article no.\n");
break;
}
if (i > pngsize) {
fprintf(ofp, "Not that many articles.\n");
break;
}
readmode = SPEC;
abs = TRUE;
bit = i;
obit = -1;
if (!cflag) {
putc('\n', ofp);
fclose(fp);
fp = NULL;
}
rfq = 0;
break;
/* specific message ID. */
case '<':
ptr1 = findhist(--bptr);
if (ptr1 == NULL) {
fprintf(ofp, "No such article: %s.\n", bptr);
break;
}
ptr2 = index(ptr1, '\t');
ptr3 = index(++ptr2, '\t');
ptr2 = index(++ptr3, ' ');
if (ptr2)
*ptr2 = '\0';
ptr2 = index(ptr3, '/');
*ptr2++ = '\0';
abs = TRUE;
if (cflag)
clear(bit);
else {
fclose(fp);
fp = NULL;
putc('\n', ofp);
}
hbufcp(&hbuf1, &h);
saveart;
strcpy(ogroupdir, ptr3);
if (strcmp(groupdir, ogroupdir)) {
strcpy(bfr, groupdir);
selectng(ogroupdir);
strcpy(groupdir, ogroupdir);
strcpy(ogroupdir, bfr);
back();
}
sscanf(ptr2, "%d", &bit);
oobit = obit;
obit = -1;
getnextart(TRUE);
rfq = 0;
break;
/* follow-up article */
case 'f':
followup_command();
break;
/* erase - pretend we haven't seen this article. */
case 'e':
if (rfq || *bptr == '-') {
if (strcmp(groupdir, ogroupdir)) {
i = bit;
strcpy(bfr, groupdir);
selectng(ogroupdir);
set(oobit);
printf("Holding article %d newsgroup %s\n", oobit, ogroupdir),
strcpy(groupdir, ogroupdir);
selectng(bfr);
bit = i;
} else {
printf("Holding article %d\n", oobit),
set(oobit);
}
} else {
printf("Holding article %d\n", bit),
set(bit);
goto caseplus; /* skip this article for now */
}
break;
case 'H':
case 'h':
if (!hflag)
dash(8, ofp);
if (*bptr == '-') {
if (oobit > 0)
fprintf(ofp, "Article %d:\n", oobit);
hprint(&hbuf1, ofp, 1 + (i=='H'));
} else {
fprintf(ofp, "Article %d of %ld: %s\n",
rfq ? oobit : bit, pngsize, h.ident);
hprint(&h, ofp, 1 + (i=='H'));
}
if (!hflag)
dash(8, ofp);
break;
case '#':
fprintf(ofp, "Article %d of %ld: newsgroup %s\n",
rfq ? oobit : bit, pngsize, rfq ? ogroupdir : groupdir);
break;
/* error */
case '?':
help(ofp);
break;
default:
fprintf(ofp, "? for commands.\n");
break;
}
return FALSE;
}
\f
cancel_command()
{
tfilename = filename;
hptr = &h;
if (*bptr == '-') {
if (*ofilename1) {
tfilename = ofilename1;
hptr = &hbuf1;
}
bptr++;
}
EOL();
readmode = SPEC;
strcpy(rcbuf, hptr->path);
ptr1 = index(rcbuf, ' ');
if (ptr1)
*ptr1 = 0;
if (uid == ROOTID)
i = 0; /* root gets to cancel */
else
i = strcmp(username, rcbuf);
if (i != 0) {
fprintf(ofp, "Can't cancel what you didn't write.\n");
return;
}
if (!cancel(ofp, hptr, i) && hptr == &h) {
clear(bit);
saveart;
nextbit();
obit = -1;
fp = NULL;
if (!cflag)
putc('\n', ofp);
}
if (fp != NULL)
fclose(fp);
fp = NULL;
}
\f
reply_command()
{
register char *pathptr, *ptr;
int edit = 1;
char *ed;
FILE *tfp;
char curberk[BUFLEN];
char *replyname();
char subj[100];
char folbuf[100];
extern char MAILPARSER[];
hptr = &h;
while (*bptr && index("d-", *bptr)) {
switch (*bptr) {
/* Followup the previous article. */
case '-':
hptr = &hbuf1;
break;
/* Don't edit the headers */
case 'd':
edit = 0;
break;
}
bptr++;
}
EOL();
if (edit && access(MAILPARSER, 1)) {
#ifdef IHCC
fprintf(stderr, "Can't edit headers, 'recmail' missing.\n");
#else
fprintf(stderr, "Can't edit headers without %s\n", MAILPARSER);
#endif
edit = 0;
}
*rcbuf = '\0';
*curberk = '\0';
pathptr = replyname(hptr);;
ptr = pathptr - 1;
i = 0;
for (ptr1 = address, ptr2 = pathptr; *ptr2; ptr1++, ptr2++) {
if (index("\"\\$", *ptr2))
*ptr1++ = '\\';
*ptr1 = *ptr2;
}
*ptr1 = '\0';
folbuf[0] = 0; /* References */
if (hptr->followid[0]) {
strcpy(folbuf, hptr->followid);
strcat(folbuf, ", ");
}
strcat(folbuf, hptr->ident);
strcpy(subj, hptr->title); /* Subject */
while (isspace(*bptr))
bptr++;
if (*bptr != '\0')
strcpy(subj, bptr);
if (!prefix(subj, "Re:") && !prefix(subj, "re:")) {
strcpy(bfr, subj);
sprintf(subj, "Re: %s", bfr);
}
if (!edit) {
fprintf(ofp, "To: %s\n", pathptr);
ed = index(MAILER, '%');
if (ed && ed[1] == 's')
fprintf(ofp, "Subject: %s\n", subj);
fflush(ofp);
}
/* Put the user in the editor to create the body of the followup. */
if (edit) {
strcpy(tf, tft);
mktemp(tf);
ed = getenv("EDITOR");
if (ed == NULL)
ed = DFTEDITOR;
tfp = fopen(tf, "w");
fprintf(tfp, "To: %s\n", pathptr);
fprintf(tfp, "Subject: %s\n", subj);
fprintf(tfp, "References: %s\n\n", folbuf);
fclose(tfp);
sprintf(edcmdbuf, "%s %s", ed, tf);
system(edcmdbuf);
strcpy(rcbuf, MAILPARSER);
strcat(rcbuf, " -t");
strcat(rcbuf, " < ");
strcat(rcbuf, tf);
if (access(tf, 4)) {
fprintf(stderr, "Reply not sent: no input file.\n");
return;
}
printf("Sending reply.\n");
fflush(stdout);
if (fork() == 0) {
system(rcbuf);
unlink(tf);
_exit(0);
}
} else {
sprintf(rcbuf, MAILER, hptr->title);
sprintf(bfr, "%s %s", rcbuf, address);
system(bfr);
}
hdr();
}
\f
xmit_command()
{
tfilename = filename;
if (*bptr == '-') {
if (*ofilename1)
tfilename = ofilename1;
bptr++;
}
if (*bptr != '\0' && *bptr != ' ') {
fprintf(ofp, "Bad system name.\n");
return;
}
while (*bptr == ' ')
bptr++;
if (*bptr == '\0') {
fprintf(ofp, "Missing system name.\n");
return;
}
if (s_find(&srec, bptr) == NULL) {
fprintf(ofp, "%s not in SYSFILE\n", bptr);
return;
}
transmit(&srec, tfilename);
}
\f
next_ng_command()
{
if (!*bptr || *bptr == '-') {
obit = -1;
if (cflag)
clear(bit);
else
putc('\n', ofp);
if (*bptr)
actdirect = BACKWARD;
rfq = 0;
saveart;
if (nextng()) {
if (actdirect == BACKWARD)
fprintf(ofp, "Can't back up.\n");
else
return TRUE;
}
return FALSE;
}
while (isspace(*bptr))
bptr++;
if (!validng(bptr)) {
fprintf(ofp, "No such group.\n");
return FALSE;
}
obit = -1;
if (cflag)
clear(bit);
else
putc('\n', ofp);
readmode = SPEC;
rfq = 0;
saveart;
back();
selectng(bptr);
return FALSE;
}
\f
followup_command()
{
int edit = 1;
char subj[100];
char folbuf[100];
char *ng;
FILE *tfp;
hptr = &h;
while (*bptr && index("d-", *bptr)) {
switch (*bptr) {
/* Followup the previous article. */
case '-':
hptr = &hbuf1;
break;
/* Don't edit the headers */
case 'd':
edit = 0;
break;
}
bptr++;
}
/* Figure out the subject, newsgroups, and references for the followup. */
ng = hptr->nbuf; /* Newsgroups */
if (hptr->followto[0])
ng = hptr->followto;
launder(ng);
folbuf[0] = 0; /* References */
if (hptr->followid[0]) {
strcpy(folbuf, hptr->followid);
strcat(folbuf, ", ");
}
strcat(folbuf, hptr->ident);
strcpy(subj, hptr->title); /* Subject */
while (isspace(*bptr))
bptr++;
if (*bptr != '\0')
strcpy(subj, bptr);
if (!prefix(subj, "Re:") && !prefix(subj, "re:")) {
strcpy(bfr, subj);
sprintf(subj, "Re: %s", bfr);
}
/* Determine the command line for the shell. */
if (edit) {
sprintf(bfr, "%s -h -D", FOLLOWUP);
} else {
sprintf(bfr, "%s -D -F '%s' -n %s -t \'", FOLLOWUP, folbuf, ng);
strqcat(bfr, subj);
strcat(bfr, "\'");
}
/* backslash special characters */
for (ptr1 = rcbuf, ptr2 = bfr; *ptr2; ptr1++, ptr2++) {
if (index("\\", *ptr2))
*ptr1++ = '\\';
*ptr1 = *ptr2;
}
*ptr1 = '\0';
/* Let the user know what's going on. */
fprintf(ofp, "Posting followup article to network. Please use\n");
fprintf(ofp, "reply ('r') instead unless your article is of general\n");
fprintf(ofp, "interest. (To abort press BREAK.)\n");
fprintf(ofp, "Subject: %s\n", subj);
fprintf(ofp, "Newsgroups: %s\n", ng);
fprintf(ofp, "Hit <return> to continue, BREAK to abort: ");
fflush(ofp);
/* Give the user a chance to hit BREAK and back out. */
hascaught = 0;
oldsig = (char *) signal(SIGINT, catchintr);
gets(edcmdbuf);
signal(SIGINT, oldsig);
if (hascaught)
return;
/* Play obnoxious warnings, if necessary. */
if (recording(hptr->nbuf, 0))
return;
/* Put the user in the editor to create the body of the followup. */
ed = getenv("EDITOR");
if (ed == NULL || *ed == '\0')
ed = DFTEDITOR;
if (ed) {
strcpy(tf, tft);
mktemp(tf);
tfp = fopen(tf, "w");
if (edit) {
fprintf(tfp, "Newsgroups: %s\n", ng);
fprintf(tfp, "Subject: %s\n", subj);
fprintf(tfp, "References: %s\n", folbuf);
if (hptr->keywords[0])
fprintf(tfp, "Keywords: %s\n", hptr->keywords);
fprintf(tfp, "\n");
}
fclose(tfp);
sprintf(edcmdbuf, "%s %s", ed, tf);
system(edcmdbuf);
strcat(rcbuf, "< ");
strcat(rcbuf, tf);
if (access(tf, 4)) {
fprintf(stderr, "Article not posted: no input file.\n");
return;
}
printf("Posting article.\n");
fflush(stdout);
if (fork() == 0) {
system(rcbuf);
unlink(tf);
_exit(0);
}
} else {
printf("%s\n", rcbuf);
system(rcbuf);
}
hdr();
}
\f
caesar_command()
{
char temp[100];
char *pp = bptr;
FILE *pfp, *popen();
fprintf(stderr, "Caesar decoding:\n");
strcpy(temp, CAESAR);
if (*bptr) {
strcat(temp, " ");
strcat(temp, bptr);
}
if (NLINES(h, fp) > LNCNT && *PAGER) {
strcat(temp, " | ");
strcat(temp, PAGER);
}
pfp = popen(temp, "w");
tprint(fp, pfp, FALSE);
itsbeenseen(h.ident);
fclose(fp);
fp = NULL;
pclose(pfp);
}
\f
/*
* Show the user the tail, if any, of the message on file
* descriptor fd, and close fd. The digester is considered,
* and the pager is used if appropriate.
*/
showtail(fd)
FILE *fd;
{
if (fd == NULL)
return;
if (dgest) {
digest(fd, ofp, &h);
} else if (!lflag && !pflag && !eflag) {
#ifdef PAGE
/* Filter the tail of long messages through PAGER. */
if (NLINES(h, fd) > LNCNT && *PAGER) {
if (!index(PAGER, FMETA)) {
FILE *pfp, *popen();
int cnt;
pfp = popen(PAGER, "w");
if (pfp == NULL)
pfp = ofp;
/*
* What follows is an attempt to prevent the
* next message from scrolling part of this
* message off the top of the screen before
* the poor luser can read it.
*/
tprint(fd, pfp, FALSE);
itsbeenseen(h.ident);
pclose(pfp);
}
else
pout(ofp);
# ifndef NOCOLON
holdup = TRUE;
# endif NOCOLON
}
else
#endif
tprint(fd, ofp, FALSE), itsbeenseen(h.ident);
}
fclose(fd);
}
\f
/*
* Find the next article we want to consider, if we're done with
* the last one, and show the header.
*/
getnextart(minus)
int minus;
{
if (minus)
goto nextart2; /* Kludge for "-" command. */
if (bit == obit) /* Return if still on same article as last time */
return 0;
sigtrap = FALSE;
nextart:
dgest = 0;
if (bit < 1 && !rflag)
bit = 1;
/* If done with this newsgroup, find the next one. */
while (((long) bit > ngsize) || (rflag && bit < 1)) {
int i;
if (i=nextng()) {
if (actdirect == BACKWARD) {
fprintf(ofp, "Can't back up.\n");
actdirect = FORWARD;
continue;
}
else if (rfq++ || pflag || cflag)
return 1;
}
if (rflag)
bit = ngsize + 1L;
else
bit = -1;
if (uflag) {
long now;
time(&now);
if (now - timelastsaved > 5*60 /* 5 minutes */) {
printf("[Saving .newsrc]\n");
fflush(stdout);
writeoutrc();
timelastsaved = now;
}
}
}
nextart2:
#ifdef DEBUG
fprintf(stderr, "article: %s/%d\n", groupdir, bit);
#endif
if (rcreadok)
rcreadok = 2; /* have seen >= 1 article */
sprintf(filename, "%s/%d", dirname(groupdir), bit);
if (rfq && goodone[0])
strcpy(filename, goodone);
if (sigtrap) {
if (sigtrap == SIGHUP)
return 1;
if (!rcreadok)
xxit(0);
fprintf(ofp, "Abort (n)? ");
fflush(ofp);
gets(bfr);
if (*bfr == 'y' || *bfr == 'Y')
xxit(0);
sigtrap = FALSE;
}
#ifdef DEBUG
fprintf(stderr, "filename = '%s'\n", filename);
#endif
/* Decide if we want to show this article. */
if (ignorenews
|| access(filename, 4)
|| ((fp = fopen(filename, "r")) == NULL)
|| (hread(&h, fp, TRUE) == NULL)
|| (!rfq && !select(&h, abs))) {
#ifdef DEBUG
fprintf(stderr, "Bad article '%s'\n", filename);
#endif
if (fp != NULL) {
fclose(fp);
fp = NULL;
}
clear(bit);
obit = -1;
nextbit();
abs = FALSE;
goto nextart;
}
abs = FALSE;
actdirect = FORWARD;
news = TRUE;
hdr();
if ((cflag && !lflag && !eflag) || pflag)
tprint(fp, ofp, FALSE);
if (cflag && lflag && eflag || pflag) {
itsbeenseen(h.ident);
sigtrap = FALSE;
fclose(fp);
fp = NULL;
}
obit = bit;
return 0;
}
/*
* Print out whatever the appropriate header is
*/
hdr()
{
if (rfq)
return;
#ifndef NOCOLON
/* Wait for user to read previous article. */
if (holdup) {
fprintf(ofp, ":");
fflush(ofp);
holdup = FALSE;
bfr[0] = '\0';
gets(bfr);
if (bfr[0])
explaincolon();
}
#endif NOCOLON
if (lflag || eflag) {
hprint(&h, ofp, 0);
return;
}
/* Print out a header */
if (ngrp) {
pngsize = ngsize;
ngrp--;
nghprint(groupdir);
}
if (!hflag)
fprintf(ofp, "Article %d of %ld, %s.\n",
bit, pngsize, briefdate(h.subdate));
hprint(&h, ofp, pflag ? 1 : 0);
}
explaincolon()
{
static int calledbefore = 0;
fprintf(ofp, "\n'%s' ignored.\n", bfr);
if (calledbefore++ == 0) {
fprintf(ofp, "The colon is to give you a chance to finish reading the\n");
fprintf(ofp, "previous article before the next header scrolls it off\n");
fprintf(ofp, "the top of the screen. You should hit `return' or `newline'\n");
fprintf(ofp, "when you are ready to go on to the next article.\n\n");
}
fflush(ofp);
}
nghprint(title)
char *title;
{
char *tstr = "Newsgroup ";
int l = strlen(title) + strlen(tstr);
fprintf(ofp, "\n");
if (!hflag) {
dash(l, ofp);
fprintf(ofp, "%s%s\n", tstr, title);
dash(l, ofp);
} else {
fprintf(ofp, "%s%s, ", tstr, title);
if (bit == pngsize)
fprintf(ofp, "%ld\n", pngsize);
else
fprintf(ofp, "%d-%ld\n", bit, pngsize);
}
fprintf(ofp, "\n");
}
/*
* Routine to catch a continue signal.
*/
catchcont()
{
#ifdef SIGCONT
signal(SIGCONT, catchcont);
sigtrap = SIGCONT;
#endif
hdr();
}