/* * 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(); 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); } #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; } 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; } 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(); } 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); } 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; } 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 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(); } 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); } /* * 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); } /* * 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(); }