home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume7
/
2.11news
/
part11
< prev
next >
Wrap
Text File
|
1986-11-30
|
63KB
|
2,867 lines
Subject: v07i051: 2.11 News Source, Part01/09
Newsgroups: mod.sources
Approved: mirror!rs
Submitted by: seismo!rick (Rick Adams)
Mod.sources: Volume 7, Issue 51
Archive-name: 2.11news/Part11
[ Again, notice the different between the Part# in the Subject line
and the Part# in the Archive-name. --r$ ]
# To extract, sh this file
#
# news 2.11 source part 1 of 9
#
if test ! -d src
then
mkdir src
fi
echo x - src/visual.c 1>&2
sed 's/.//' >src/visual.c <<'*-*-END-of-src/visual.c-*-*'
-/*
- * visual - visual news interface.
- * Kenneth Almquist
- */
-
-#ifdef SCCSID
-static char *SccsId = "@(#)visual.c 1.32 10/23/86";
-#endif /* SCCSID */
-
-#include "rparams.h"
-#ifdef USG
-#include <sys/ioctl.h>
-#include <termio.h>
-#include <fcntl.h>
-#else /* !USG */
-#include <sgtty.h>
-#endif /* !USG */
-
-#include <errno.h>
-#if defined(BSD4_2) || defined(BSD4_1C)
-#include <sys/dir.h>
-#else
-#include "ndir.h"
-#endif
-#ifdef BSD4_2
-#ifndef sigmask
-#define sigmask(m) (1<<((m)-1))
-#endif /* !sigmask */
-#endif /* BSD4_2 */
-#ifdef MYDB
-#include "db.h"
-#endif /* MYDB */
-
-extern int errno;
-
-#ifdef SIGTSTP
-#include <setjmp.h>
-#endif /* SIGTSTP */
-
-#define ARTWLEN (ROWS-2)/* number of lines used to display article */
-#define even(cols) ((cols&1) ? cols + 1 : cols)
-#ifdef STATTOP
-#define PRLINE 0 /* prompter line */
-#define SPLINE 1 /* secondary prompt line */
-#define ARTWIN 2 /* first line of article window */
-#define SECPRLEN 81 /* length of secondary prompter */
-#else
-#define PRLINE (ROWS-1)/* prompter line */
-#define SPLINE (ROWS-2)/* secondary prompt line */
-#define ARTWIN 0 /* first line of article window */
-#define SECPRLEN 100 /* length of secondary prompter */
-#endif
-
-#define PIPECHAR '|' /* indicate save command should pipe to program */
-#define META 0200 /* meta character bit (as in emacs) */
-/* print (display) flags */
-#define HDRONLY 0001 /* print header only */
-#define NOPRT 0002 /* don't print at all */
-#define NEWART 0004 /* force article display to be regenerated */
-#define HELPMSG 0010 /* display currently contains help message */
-/* prun flags */
-#define CWAIT 0001 /* type "continue?" and wait for return */
-#define BKGRND 0002 /* run process in the background */
-/* values of curflag */
-#define CURP1 1 /* cursor after prompt */
-#define CURP2 2 /* cursor after secondary prompt */
-#define CURHOME 3 /* cursor at home position */
-/* flags for vsave routine */
-#define SVHEAD 01 /* write out article header */
-#define OVWRITE 02 /* overwrite the file if it already exists */
-/* other files */
-
-#define saveart oobit = bit;strcpy(ofilename1, filename);strcpy(ogroupdir, groupdir);hptr = h;h = hold;hold = hptr;ongsize = pngsize
-#define NLINES(h, fp) (h->numlines[0] ? h->intnumlines : (h->intnumlines=linecnt(fp),sprintf(h->numlines, "%d", h->intnumlines), h->intnumlines))
-
-/* terminal handler stuff */
-extern int _junked;
-#define clearok(xxx, flag) _junked = flag
-extern int COLS;
-extern int ROWS;
-extern int hasscroll;
-
-FILE *tmpfile();
-char *getmailname();
-#ifdef MYDB
-char *findparent();
-#endif /* MYDB */
-int onint();
-int onstop();
-int xxit();
-
-char *Progname = "vnews"; /* for xerror */
-
-/* variables shared between vnews routines */
-static char linebuf[LBUFLEN]; /* temporary workspace */
-static FILE *tfp; /* temporary file */
-static char tfname[] = "/tmp/vnXXXXXX"; /* name of temp file */
-static long artbody; /* offset of body into article */
-static int quitflg; /* if set, then quit */
-static int erased; /* current article has been erased */
-static int artlines; /* # lines in article body */
-static int artread; /* entire article has been read */
-static int hdrstart; /* beginning of header */
-static int hdrend; /* end of header */
-static int lastlin; /* number of lines in tempfile */
-static int tflinno = 0; /* next line in tempfile */
-static int maxlinno; /* number of lines in file + folded */
-static char secpr[SECPRLEN]; /* secondary prompt */
-static char prompt[30]; /* prompter */
-static short prflags; /* print flags (controls updscr) */
-static short curflag; /* where to locate cursor */
-static int dlinno; /* top line on screen */
-static char timestr[20]; /* current time */
-static int ismail; /* true if user has mail */
-static char *mailf; /* user's mail file */
-static int alflag; /* set if unprocessed alarm signal */
-static int atend; /* set if at end of article */
-static char cerase; /* erase character */
-static char ckill; /* kill character */
-static char cintr; /* interrupt character */
-#ifdef TIOCGLTC
-static char cwerase; /* word erase character */
-#endif /* TIOCGLTC */
-short ospeed; /* terminal speed NOT STATIC */
-static int intflag; /* set if interrupt received */
-
-#ifdef SIGTSTP
-static int reading; /* to keep stupid BSD from restarting reads */
-jmp_buf intjmp, alrmjmp;
-#endif /* SIGTSTP */
-
-#ifdef MYDB
-static int hasdb; /* true if article data base exists */
-#endif /* MYDB */
-
-#ifdef DIGPAGE
-static int endsuba; /* end of sub-article in digest */
-#endif
-
-#ifdef MYDEBUG
-FILE *debugf; /* file to write debugging info on */
-#endif
-
-char *tft = "/tmp/folXXXXXX";
-
-/*
- * 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 warrant 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 edcmdbuf[128];
-static int rfq = 0; /* for last article */
-static long ongsize; /* Previous ngsize */
-static long pngsize; /* Printing ngsize */
-static char *bptr; /* temp pointer. */
-static char *tfilename; /* temporary file name */
-static char ofilename1[BUFLEN]; /* previous file name */
-static struct hbuf hbuf1, hbuf2; /* for minusing */
-static struct hbuf *h = &hbuf1, /* current header */
- *hold = &hbuf2, /* previous header */
- *hptr; /* temporary */
-static char *ptr1, *ptr2, *ptr3; /* for reply manipulation */
-static int aabs = FALSE; /* TRUE if we asked absolutely */
-static char *ed, tf[100];
-static long oobit; /* last bit, really */
-static int dgest = 0;
-static FILE *fp; /* current article to be printed*/
-
-readr()
-{
-
-#ifdef MYDEBUG
- debugf = fopen("DEBUG", "w");
- setbuf(debugf, (char *)NULL);
-#endif
- if (aflag) {
- if (*datebuf) {
- if ((atime = cgtdate(datebuf)) == -1)
- xerror("Cannot parse date string");
- } else
- atime = 0;
- }
-
- if (SigTrap)
- xxit(1);
- (void) mktemp(tfname);
- (void) close(creat(tfname,0666));
- if ((tfp = fopen(tfname, "w+")) == NULL)
- xerror("Can't create temp file");
- (void) unlink(tfname);
- mailf = getmailname();
-#ifdef MYDB
- if (opendb() >= 0) {
- hasdb = 1;
- fputs("Using article data base\n", stderr); /*DEBUG*/
- getng();
- }
-#endif
- ttysave();
- (void) signal(SIGINT, onint);
- (void) signal(SIGQUIT, xxit);
- if (SigTrap)
- xxit(1);
- ttyraw();
- timer();
-
- /* loop reading articles. */
- fp = NULL;
- obit = -1;
- nextng();
- quitflg = 0;
- while (quitflg == 0) {
- if (getnextart(FALSE))
- break;
- (void) strcpy(goodone, filename);
- if (SigTrap)
- return;
- vcmd();
- }
-
- if (!news) {
- fprintf(stderr, "No news.\n");
- }
-}
-
-/*
- * Read and execute a command.
- */
-vcmd() {
- register c;
- char *p;
- long count;
- int countset;
-
- if (prflags & HDRONLY)
- appfile(fp, lastlin + 1);
- else
- appfile(fp, dlinno + ARTWLEN + 1);
-
-#ifdef DIGPAGE
- endsuba = findend(dlinno);
- if (artlines > dlinno + ARTWLEN
- || endsuba > 0 && endsuba < artlines
-#else
- if (artlines > dlinno + ARTWLEN
-#endif
- || (prflags & HDRONLY) && artlines > hdrend) {
- atend = 0;
- if (prflags&HDRONLY || maxlinno == 0)
- (void) strcpy(prompt, "more? ");
- else
-#ifdef DIGPAGE
- (void) sprintf(prompt, "more(%d%%)? ",
- ((((endsuba > 0) ?
- endsuba : (dlinno + ARTWLEN)) -
- hdrend) * 100) / maxlinno);
-#else /* !DIGPAGE */
- (void) sprintf(prompt, "more(%d%%)? ",
- ((dlinno + ARTWLEN - hdrend) * 100) / maxlinno);
-#endif /* !DIGPAGE */
- } else {
- atend = 1;
- (void) strcpy(prompt, "next? ");
- if (!erased)
- clear(bit); /* article read */
- }
- curflag = CURP1;
- p = prompt + strlen(prompt);
- countset = 0;
- count = 0;
- /*
- * Loop while accumulating a count, until an action character
- * is entered. Also handle "meta" here.
- *
- * Count is the current count. Countset=0 means no count
- * currently exists. Countset=1, count=0 is valid and means
- * a count of 0 has been entered
- */
- for (;;) {
- c = vgetc();
- if (c == cerase || c == '\b' || c == '\177') {
- if (countset == 0)
- break; /* Use as action char */
- if (count < 10)
- countset = 0; /* Erase only char of count */
- else
- count /= 10L; /* Erase 1 char of count */
- } else {
-#ifdef TIOCGLTC
- if (c == ckill || c == cwerase) {
-#else
- if (c == ckill) {
-#endif
- if (countset == 0)
- break;
- countset = 0;
- } else if (c < '0' || c > '9')
- break;
- else {
- countset = 1;
- count = (count * 10) + (c - '0');
- }
- }
- if (countset) {
- (void) sprintf(p, "%ld", count);
- } else {
- *p = '\0';
- count = 0;
- }
- }
-
- if (c == '\033') { /* escape */
- (void) strcat(prompt, "M-");
- c = vgetc();
- if (c != cintr)
- c |= META;
- }
- secpr[0] = '\0';
- if (countset == 0)
- count = 1;
- docmd(c, count);
- if (c != '?' && c != 'H') /* UGGH */
- prflags &=~ HELPMSG;
- if (dlinno > hdrstart)
- prflags &=~ HDRONLY;
-}
-
-
-/*
- * Process one command, which has already been typed in.
- */
-docmd(c, count)
-int c;
-long count;
-{
- int i;
- long nart, Hoffset;
- char *findhist();
-
- switch (c) {
-
- /* Show more of current article, or advance to next article */
- case '\n':
- case ' ':
-#ifdef DIGPAGE
- case 'm':
-#endif /* DIGPAGE */
- case '\06': /* Control-F for vi compat */
- prflags &=~ NOPRT;
- if (atend)
- goto next;
- else if (prflags & HDRONLY) {
- prflags &=~ HDRONLY;
- if (hasscroll)
- dlinno = hdrstart;}
-#ifdef DIGPAGE
- else if (endsuba > 0)
- dlinno = endsuba;
- else if (c == 'm') {
- do {
- if (lastlin >= maxlinno)
- goto next;
- else
- appfile(fp, lastlin + 1);
- } while(strncmp(linebuf, "------------------------", 24)
- != 0);
- dlinno = endsuba = lastlin;
- }
-#endif
- else if ((appfile(fp, dlinno + 2 * ARTWLEN), artread)
- && hasscroll && artlines - dlinno <= ARTWLEN + 2)
- dlinno = artlines - ARTWLEN;
- else
- dlinno += ARTWLEN * count;
- break;
-
- /* No. Go on to next article. */
- case '.': /* useful if you have a keypad */
-next: case 'n':
- readmode = NEXT;
- FCLOSE(fp);
- clear(bit);
- saveart;
- nextbit();
- break;
-
-
- /* Back up count pages */
- case '\b':
- case '\177':
- if (dlinno == 0)
- goto backupone;
- /* NO BREAK */
- case META|'v':
- case '\002': /* Control-B */
- dlinno -= ARTWLEN * count;
- if (dlinno < 0)
- dlinno = 0;
- break;
-
- /* forward half a page */
- case '\004': /* Control-D, as in vi */
- if (!atend)
- dlinno += ARTWLEN/2 * count;
- break;
-
- /* backward half a page */
- case '\025': /* Control-U */
- dlinno -= ARTWLEN/2 * count;
- if (dlinno < 0)
- dlinno = 0;
- break;
-
- /* forward count lines */
- case '\016': /* Control-N */
- case '\005': /* Control-E */
- dlinno += count;
- break;
-
- /* backwards count lines */
- case '\020': /* Control-P */
- case '\031': /* Control-Y */
- dlinno -= count;
- if (dlinno < 0)
- dlinno = 0;
- break;
-
- /* Turn displaying of article back on */
- case 'l':
- case 'd':
- prflags &=~ NOPRT;
- break;
-
- /* display header */
- case 'h':
- dlinno = hdrstart;
- prflags |= HDRONLY;
- prflags &=~ NOPRT;
- break;
-
- /*
- * Unsubscribe to the newsgroup and go on to next group
- */
-
- case 'U':
- case 'u':
- strcat(prompt, "u");
- c = vgetc();
- if (c == 'g') {
- obit = -1;
- FCLOSE(fp);
- zapng = TRUE;
- saveart;
- if (nextng()) {
- if (actdirect == BACKWARD)
- msg("Can't back up.");
- else
- quitflg = 1; /* probably unnecessary */
- }
- } else {
- if (c != cintr && c != ckill)
- beep();
- msg("Illegal command");
- }
- break;
-
- /* Print the current version of news */
- case 'v':
- msg("News version: %s", news_version);
- break;
-
-
- /* Decrypt joke. Always does rot 13 */
- case 'D':
- appfile(fp, 32767);
- for (i = hdrend ; i < artlines ; i++) {
- register char ch, *p;
- tfget(linebuf, i);
- for (p = linebuf ; (ch = *p) != '\0' ; p++) {
- if (ch >= 'a' && ch <= 'z')
- *p = (ch - 'a' + 13) % 26 + 'a';
- else if (ch >= 'A' && ch <= 'Z')
- *p = (ch - 'A' + 13) % 26 + 'A';
- }
- tfput(linebuf, i);
- }
- prflags |= NEWART;
- prflags &=~ (HDRONLY|NOPRT);
- break;
-
- /* write out the article someplace */
- /* w writes out without the header */
- case 's':
- case 'w': {
- char *grn = groupdir;
- int wflags;
-
- msg("file: ");
- curflag = CURP2;
- while ((wflags = vgetc()) == ' ');
- if (wflags == cintr) {
- secpr[0] = '\0';
- break;
- }
- if (wflags == '|') {
- linebuf[0] = '|';
- if (prget("| ", linebuf+1))
- break;
- } else {
- pushback(wflags);
- if (prget("file: ", linebuf))
- break;
- }
- wflags = 0;
- if (c == 's')
- wflags |= SVHEAD;
- if (count != 1)
- wflags |= OVWRITE;
- bptr = linebuf;
- while( *bptr == ' ')
- bptr++; /* strip leading spaces */
-
- if (*bptr != PIPECHAR && *bptr != '/') {
- char hetyped[BUFLEN];
- char *boxptr;
- (void) strcpy(hetyped, bptr);
- if (hetyped[0] == '~' && hetyped[1] == '/') {
- strcpy(hetyped, bptr+2);
- strcpy(bptr, userhome);
- } else if (boxptr = getenv("NEWSBOX")) {
- if (index(boxptr, '%')) {
- struct stat stbf;
- sprintf(bptr, boxptr, grn);
- if (stat(bptr,&stbf) < 0) {
- if (mkdir(bptr, 0777) < 0) {
- msg("Cannot create directory %s", bptr);
- break;
- }
- } else if ((stbf.st_mode&S_IFMT) != S_IFDIR) {
- msg("%s not a directory", bptr);
- break;
- }
- } else
- strcpy(bptr, boxptr);
- } else
- bptr[0] = '\0';
-
- if (bptr[0])
- (void) strcat(bptr, "/");
- if (hetyped[0] != '\0')
- (void) strcat(bptr, hetyped);
- else
- (void) strcat(bptr, "Articles");
- }
- vsave(bptr, wflags);
- break;
- }
-
- /* back up */
- case '-':
-caseminus:
- aabs = TRUE;
- if (!*ofilename1) {
- msg("Can't back up.");
- break;
- }
- FCLOSE(fp);
- hptr = h;
- h = hold;
- hold = hptr;
- (void) strcpy(bfr, filename);
- (void) strcpy(filename, ofilename1);
- (void) strcpy(ofilename1, bfr);
- obit = bit;
- if (strcmp(groupdir, ogroupdir)) {
- (void) strcpy(bfr, groupdir);
- selectng(ogroupdir, FALSE, FALSE);
- (void) strcpy(groupdir, ogroupdir);
- (void) strcpy(ogroupdir, bfr);
- ngrp = 1;
- back();
- }
- bit = oobit;
- oobit = obit;
- obit = -1;
- getnextart(TRUE);
- break;
-
- /* skip forwards */
- case '+':
- case '=':
-caseplus: if (count == 0)
- break;
- saveart;
- last = bit;
- for (i = 0; i < count; i++) {
- nextbit();
- if ((bit > pngsize) || (rflag && bit < 1))
- break;
- }
- FCLOSE(fp);
- obit = -1;
- break;
-
- /* exit - time updated to that of most recently read article */
- case 'q':
- quitflg = 1;
- break;
-
- case 'x':
- xxit(0);
- break;
-
- /* cancel the article. */
- case 'c':
- strcpy(prompt, "cancel [n]? ");
- if (vgetc() != 'y') {
- msg("Article not cancelled");
- break;
- }
- cancel_command();
- break;
-
- /* escape to shell */
- case '!': {
- register char *p;
- int flags;
-
- p = linebuf;
- if (prget("!", p))
- break;
- flags = CWAIT;
- if (*p == '\0') {
- (void) strcpy(linebuf, SHELL);
- flags = 0;
- }
- while (*p) p++;
- while (p > linebuf && p[-1] == ' ')
- p--;
- if (*--p == '&') {
- *p = '\0';
- flags = BKGRND;
- } else if (*p == '|') {
- *p = '\0';
- (void) sprintf(bfr, "(%s)|mail '%s'", linebuf, username);
- (void) strcpy(linebuf, bfr);
- flags |= BKGRND;
- } else {
- prflags |= NOPRT;
- }
- shcmd(linebuf, flags);
- break;
- }
-
- /* mail reply */
- case 'r':
- reply(FALSE);
- break;
-
- case 'R':
- reply(TRUE);
- break;
-
- case META|'r':
- direct_reply();
- break;
-
- /* next newsgroup */
- case 'N':
- FCLOSE(fp);
- if (next_ng_command())
- quitflg = 1;
- break;
-
- /* mark the rest of the articles in this group as read */
- case 'K':
- saveart;
- while (bit <= ngsize && bit >= minartno) {
- clear(bit);
- nextbit();
- }
- FCLOSE(fp);
- break;
-
- /* Print the full header */
- case 'H':
- if (fp == NULL) {
- msg("No current article");
- break;
- }
- move(ARTWIN, 0);
- Hoffset = ftell(fp);
- (void) fseek(fp, 0L, 0);
- for (i = 0; i < ARTWLEN; i++) {
- if (fgets(linebuf, COLS, fp) == NULL)
- break;
- if (linebuf[0] == '\n')
- break;
- linebuf[COLS] = '\0';
- addstr(linebuf);
- }
- (void) fseek(fp, Hoffset, 0);
- for(; i < ARTWLEN; i++)
- addstr(linebuf);
- prflags |= HELPMSG|NEWART;
- break;
- case 'b': /* backup 1 article */
-backupone:
- count = bit - 1;
- /* NO BREAK */
-
- case 'A': /* specific number */
- if (count > pngsize) {
- msg("not that many articles");
- break;
- }
- readmode = SPEC;
- aabs = TRUE;
- bit = count;
- obit = -1;
- FCLOSE(fp);
- break;
-
- /* display parent article */
- case 'p':
-#ifdef MYDB
- if (hasdb && (ptr3 = findparent(h->ident, &nart)) != NULL) {
- msg("parent: %s/%ld", ptr3, nart); /*DEBUG*/
- updscr(); /*DEBUG*/
- goto selectart;
- }
-#endif
- if (h->followid[0] == '\0') {
- msg("no references line");
- break;
- }
- ptr1 = h->followid + strlen(h->followid);
- do {
- ptr2 = ptr1;
- if (*ptr2 == '\0')
- ptr1 = rindex(h->followid, ' ');
- else {
- *ptr2 = '\0';
- ptr1 = rindex(h->followid, ' ');
- *ptr2 = ' ';
- }
- } while (ptr1 != NULL && --count > 0);
- if (ptr1 == NULL)
- ptr1 = h->followid;
- else ++ptr1;
- (void) strncpy(linebuf, ptr1, ptr2 - ptr1);
- linebuf[ptr2 - ptr1] = '\0';
- msg("%s", linebuf);
- curflag = CURP2;
- updscr(); /* may take this out later */
- goto searchid;
- /* specific message ID. */
- case '<':
- /* could improve this */
- linebuf[0] = '<';
- if (prget("<", linebuf+1))
- break;
-searchid: secpr[0] = '\0';
- if (index(linebuf, '@') == NULL && index(linebuf, '>') == NULL) {
- ptr1 = linebuf;
- if (*ptr1 == '<')
- ptr1++;
- ptr2 = index(ptr1, '.');
- if (ptr2 != NULL) {
- *ptr2++ = '\0';
- (void) sprintf(bfr, "<%s@%s.UUCP>", ptr2, ptr1);
- (void) strcpy(linebuf, bfr);
- }
- }
- if (index(linebuf, '>') == NULL)
- (void) strcat(linebuf, ">");
-
- ptr1 = findhist(linebuf);
- if (ptr1 == NULL) {
- msg("%s not found", linebuf);
- break;
- }
- ptr2 = index(ptr1, '\t');
- ptr3 = index(++ptr2, '\t');
- ptr2 = index(++ptr3, ' ');
- if (ptr2)
- *ptr2 = '\0';
- ptr2 = index(ptr3, '/');
- if (!ptr2) {
- if (strcmp(++ptr3, "cancelled") == 0)
- msg("%s has been cancelled", linebuf);
- else
- msg("%s has expired", linebuf);
- break;
- }
- *ptr2++ = '\0';
- (void) sscanf(ptr2, "%ld", &nart);
-
- /*
- * Go to a given article. Ptr3 specifies the newsgroup
- * and nart specifies the article number.
- */
-#ifdef MYDB
-selectart:
-#endif /* MYDB */
- aabs = TRUE;
- FCLOSE(fp);
- saveart;
- (void) strcpy(ogroupdir, ptr3);
- if (strcmp(groupdir, ogroupdir)) {
- (void) strcpy(bfr, groupdir);
- selectng(ogroupdir, TRUE, PERHAPS);
- (void) strcpy(groupdir, ogroupdir);
- (void) strcpy(ogroupdir, bfr);
- ngrp = 1;
- back();
- }
- bit = nart;
- oobit = obit;
- obit = -1;
- getnextart(TRUE);
- if (bit != nart || strcmp(groupdir, ptr3) != 0) {
- msg("can't read %s/%ld", ptr3, nart);
- goto caseminus;
- }
- rfq = 0;
- break;
-
- /* follow-up article */
- case 'f':
- if (strcmp(h->followto, "poster") == 0) {
- reply(FALSE);
- break;
- }
- (void) sprintf(bfr, "%s/%s %s", BIN, "postnews", goodone);
- shcmd(bfr, CWAIT);
- break;
-
- /* erase - pretend we haven't seen this article. */
- case 'e':
- erased = 1;
- set(bit);
- goto caseplus; /* skip this article for now */
-
- case '#':
- msg("Article %ld of %ld", rfq ? oobit : bit, pngsize);
- break;
-
- /* error */
- case '?':
- {
- FILE *helpf;
- (void) sprintf(linebuf, "%s/vnews.help", LIB);
- if ((helpf = fopen(linebuf, "r")) == NULL) {
- msg("Can't open help file");
- break;
- }
- move(ARTWIN, 0);
- while (fgets(linebuf, LBUFLEN, helpf) != NULL)
- addstr(linebuf);
- (void) fclose(helpf);
- prflags |= HELPMSG|NEWART;
- }
- break;
-
- default:
- if (c != ckill && c != cintr && c != cerase)
-#ifdef TIOCGLTC
- if (c != cwerase)
-#endif
- {
- beep();
- msg("Illegal command");
- }
- break;
- }
-}
-
-cancel_command()
-{
- int notauthor;
-
- tfilename = filename;
- (void) strcpy(rcbuf, h->path);
- ptr1 = index(rcbuf, ' ');
- if (ptr1)
- *ptr1 = 0;
- notauthor = strcmp(username, rcbuf);
- if (uid != ROOTID && uid && notauthor) {
- msg("Can't cancel what you didn't write.");
- return;
- }
- if (!cancel(stderr, h, notauthor)) {
- clear(bit);
- saveart;
- nextbit();
- obit = -1;
- fp = NULL;
- }
- FCLOSE(fp);
-}
-/*
- * Generate replies
- */
-
-reply(include)
- int include;
-{
- char *arg[4];
- register FILE *rfp;
- char subj[132];
- register char *p;
- char *replyname();
- struct stat statb;
- time_t creatm;
-
- /* Put the user in the editor to create the body of the reply. */
- ed = getenv("EDITOR");
- if (ed == NULL || *ed == '\0')
- ed = DFTEDITOR;
- if (ed == NULL) {
- msg("You don't have an editor");
- return;
- }
-
- arg[0] = "/bin/sh";
- arg[1] = "-c";
-
- (void) strcpy(tf, tft);
- (void) mktemp(tf);
- (void) close(creat(tf,0600));
- if ((rfp = fopen(tf, "w")) == NULL) {
- msg("Can't create %s", tf) ;
- return;
- }
- (void) strcpy(subj, h->title);
- if (!prefix(subj, "Re:")){
- (void) strcpy(bfr, subj);
- (void) sprintf(subj, "Re: %s", bfr);
- }
-
- p = replyname(h);
- fprintf(rfp, "To: %s\n", p);
- fprintf(rfp, "Subject: %s\n", subj);
- fprintf(rfp, "In-reply-to: your article %s\n", h->ident);
-#ifdef INTERNET
- fprintf(rfp, "News-Path: %s\n", h->path);
-#endif /* INTERNET */
- (void) sprintf(rcbuf, "%s -t < %s; rm -f %s", MAILPARSER, tf, tf);
- putc('\n', rfp);
- if (include) {
- FILE *of;
- char buf[BUFSIZ];
-
- of = xart_open(goodone, "r");
- while (fgets(buf, sizeof buf, of) != NULL)
- if (buf[0] == '\n')
- break;
- while (fgets(buf, sizeof buf, of) != NULL)
- fprintf(rfp, "> %s", buf);
- fclose(of);
- putc('\n', rfp);
- }
- fflush(rfp);
- (void) fstat(fileno(rfp), &statb);
- creatm = statb.st_mtime;
- (void) fclose(rfp);
-
- (void) sprintf(edcmdbuf, "exec %s %s", ed, tf);
- arg[2] = edcmdbuf;
- arg[3] = NULL;
- if (prun(arg, 0) != 0) {
- msg("Couldn't run editor");
- (void) unlink(tf);
- return;
- }
-
- if (access(tf, 4) || stat(tf, &statb)) {
- msg("No input file - mail not sent");
- (void) unlink(tf);
- return;
- }
- if (statb.st_mtime == creatm || statb.st_size < 5) {
- msg("File unchanged - no message posted");
- (void) unlink(tf);
- return;
- }
-
- arg[2] = rcbuf;
- arg[3] = NULL;
- prun(arg, BKGRND);
- prflags |= NOPRT;
-}
-
-direct_reply()
-{
- register char *p;
- register char *q;
- char *arg[4];
- char address[PATHLEN];
- extern char *replyname();
- extern char *getenv();
-
- arg[0] = "/bin/sh";
- arg[1] = "-c";
- p = replyname(h);
- q = address;
- while (*p != '\0') {
- if (index("\"\\$", *p) != 0)
- *q++ = '\\';
- *q++ = *p++;
- }
- *q++ = '\0';
- if ((MAILER = getenv("MAILER")) == NULL)
- MAILER = "mail";
- sprintf(rcbuf, MAILER, hptr->title);
- sprintf(bfr, "%s %s", rcbuf, address);
- arg[2] = bfr;
- arg[3] = NULL;
- if (prun(arg, 0) != 0) {
- msg("Couldn't run mailer");
- return;
- }
- prflags |= NOPRT;
-}
-
-next_ng_command()
-{
- obit = -1;
- if (prget("group? ", linebuf))
- return FALSE;
- bptr = linebuf;
- if (!*bptr || *bptr == '-') {
- if (*bptr)
- actdirect = BACKWARD;
- saveart;
- if (nextng()) {
- if (actdirect == BACKWARD)
- msg("Can't back up.");
- else
- return TRUE;
- }
- return FALSE;
- }
- while (isspace(*bptr))
- bptr++;
- if (!validng(bptr)) {
- msg("No such group.");
- return FALSE;
- }
- saveart;
- back();
- selectng(bptr, TRUE, TRUE);
- return FALSE;
-}
-
-/*
- * Find the next article we want to consider, if we're done with
- * the last one, and show the header.
- */
-getnextart(minus)
-int minus;
-{
- int noaccess;
- register DIR *dirp;
- register struct direct *dir;
- long nextnum, tnum;
- long atol();
-
- noaccess = 0;
- if (minus)
- goto nextart2; /* Kludge for "-" command. */
-
- if (bit == obit) /* Return if still on same article as last time */
- return 0;
-
-nextart:
- if (news) {
- curflag = CURHOME;
- _amove(0, 0);
- vflush();
- }
- dgest = 0;
-
- /* If done with this newsgroup, find the next one. */
- while (ngsize <= 0 || (!rflag && ((long) bit > ngsize)) || (rflag && bit < minartno)) {
- if (nextng()) {
- if (actdirect == BACKWARD) {
- msg("Can't back up.");
- actdirect = FORWARD;
- continue;
- }
- else /* if (rfq++ || pflag || cflag) */
- return 1;
- }
- if (rflag)
- bit = ngsize + 1;
- else
- bit = -1;
- noaccess = 2;
- }
-
- /* speed things up by not searching for article -1 */
- if (bit < 0) {
- bit = minartno - 1;
- nextbit();
- aabs = FALSE;
- goto nextart;
- }
-
-nextart2:
- if (rcreadok)
- rcreadok = 2; /* have seen >= 1 article */
- (void) sprintf(filename, "%s/%ld", dirname(groupdir), bit);
- if (rfq && goodone[0]) /* ??? */
- strcpy(filename, goodone);
- if (SigTrap == SIGHUP)
- return 1;
- /* Decide if we want to show this article. */
- if ((fp = art_open(filename, "r")) == NULL) {
- /* since there can be holes in legal article numbers, */
- /* we wait till we hit 5 consecutive bad articles */
- /* before we haul off and scan the directory */
- if (++noaccess < 5)
- goto badart;
- noaccess = 0;
- dirp = opendir(dirname(groupdir));
- if (dirp == NULL) {
- if (errno != EACCES)
- msg("Can't open %s", dirname(groupdir));
- goto nextart;
- }
- nextnum = rflag ? minartno - 1 : ngsize + 1;
- while ((dir = readdir(dirp)) != NULL) {
- if (!dir->d_ino)
- continue;
- tnum = atol(dir->d_name);
- if (tnum <= 0)
- continue;
- if (rflag ? (tnum > nextnum && tnum < bit)
- : (tnum < nextnum && tnum > bit))
- nextnum = tnum;
- }
- closedir(dirp);
- if (rflag ? (nextnum >= bit) : (nextnum <= bit))
- goto badart;
- do {
- clear(bit);
- nextbit();
- } while (rflag ? (nextnum < bit) : (nextnum > bit));
- obit = -1;
- aabs = FALSE;
- goto nextart;
- } else
- noaccess = 0;
-
- if (hread(h, fp, TRUE) == NULL || (!rfq && !aselect(h, aabs))) {
-badart:
- FCLOSE(fp);
- clear(bit);
- obit = -1;
- nextbit();
- aabs = FALSE;
- goto nextart;
- }
- aabs = FALSE;
- actdirect = FORWARD;
- news = TRUE;
- artbody = ftell(fp);
- fmthdr();
- artlines = lastlin;
- artread = 0;
- prflags |= NEWART;
- prflags &=~ NOPRT;
- if (! cflag && hdrend < ARTWLEN && !cflag)
- prflags |= HDRONLY;
- dlinno = 0;
- maxlinno = NLINES(h, fp);
- erased = 0;
-
- obit = bit;
- return 0;
-}
-
-/*
- * Print out whatever the appropriate header is
- */
-fmthdr() {
- char *briefdate();
- static FILE *ngfd = NULL;
- static int triedopen = 0;
- char pbuf[BUFLEN], *printbuffer = groupdir;
-
- lastlin = 0;
- if (ngrp) {
- pngsize = ngsize;
- ngrp--;
- if (!hflag) {
- if (!triedopen) {
- (void) sprintf(pbuf,"%s/newsgroups", LIB);
- ngfd = fopen(pbuf, "r");
- triedopen++;
- }
- if (ngfd != NULL) {
- register char *p;
- char ibuf[BUFLEN];
- rewind(ngfd);
- while (fgets(ibuf, BUFLEN, ngfd) != NULL) {
- p = index(ibuf, '\t');
- if (p)
- *p++ = '\0';
- if (strcmp(ibuf, groupdir) == 0) {
- register char *q;
- q = rindex(p, '\t');
- if (q) {
- p = q;
- *p++ = '\0';
- }
- if (p) {
- q = index(p, '\n');
- if (q)
- *q = '\0';
- if (*--q == '.')
- *q = '\0';
- (void) sprintf(pbuf,"%s (%s)",
- groupdir, p);
- printbuffer = pbuf;
- }
- break;
- }
- }
- }
- (void) sprintf(linebuf, "Newsgroup %s", printbuffer);
- tfappend(linebuf);
- }
- }
- hdrstart = lastlin;
- if (!hflag) {
- (void) sprintf(linebuf, "Article %s %s",
- h->ident, briefdate(h->subdate));
- tfappend(linebuf);
- }
- xtabs(h);
- vhprint(h, pflag ? 1 : 0);
- (void) sprintf(linebuf, "(%d lines)", NLINES(h, fp)); tfappend(linebuf);
- tfappend("");
- hdrend = lastlin;
-}
-
-/*
- * Grow tabs into spaces in header fields, 'cause the rest of this
- * lax program drops turds all over tabs (so it does with \b's, but ..)
- */
-xtabs(p)
-register struct hbuf *p;
-{
- xtabf(p->from, sizeof p->from);
- xtabf(p->path, sizeof p->path);
- xtabf(p->nbuf, sizeof p->nbuf);
- xtabf(p->title, sizeof p->title);
- xtabf(p->ident, sizeof p->ident);
- xtabf(p->replyto, sizeof p->replyto);
- xtabf(p->followid, sizeof p->followid);
- xtabf(p->subdate, sizeof p->subdate);
- xtabf(p->expdate, sizeof p->expdate);
- xtabf(p->ctlmsg, sizeof p->ctlmsg);
- xtabf(p->sender, sizeof p->sender);
- xtabf(p->followto, sizeof p->followto);
- xtabf(p->distribution, sizeof p->distribution);
- xtabf(p->organization, sizeof p->organization);
- xtabf(p->numlines, sizeof p->numlines);
- xtabf(p->keywords, sizeof p->keywords);
- xtabf(p->summary, sizeof p->summary);
- xtabf(p->approved, sizeof p->approved);
- xtabf(p->nf_id, sizeof p->nf_id);
- xtabf(p->nf_from, sizeof p->nf_from);
-#ifdef DOXREFS
- xtabf(p->xref, sizeof p->xref);
-#endif /* DOXREFS */
-}
-
-xtabf(s, size)
-char *s;
-int size;
-{
- register char *p, *str;
- register c, i;
- char buf[LBUFLEN];
-
- str = s;
- if (index(str, '\t') == NULL)
- return;
- i = 0;
- for (p = buf; c = *str++; i++) {
- if (c == '\t') {
- *p++ = ' ';
- if ((i & 7) != 7)
- str--;
- } else if (c == '\n') {
- i = -1;
- *p++ = c;
- } else
- *p++ = c;
- }
- *p = '\0';
- strncpy(s, buf, size - 1);
-}
-
-/*
- * Print the file header to the temp file.
- */
-vhprint(hp, verbose)
-register struct hbuf *hp;
-int verbose;
-{
- register char *p1, *p2;
- char fname[BUFLEN];
- char *tailpath();
-
- fname[0] = '\0'; /* init name holder */
-
- p1 = index(hp->from, '('); /* Find the sender's full name. */
- if (p1 == NULL && hp->path[0])
- p1 = index(hp->path, '(');
- if (p1 != NULL) {
- (void) strcpy(fname, p1+1);
- p2 = index(fname, ')');
- if (p2 != NULL)
- *p2 = '\0';
- }
-
- (void) sprintf(linebuf, "Subject: %s", hp->title);
- tfappend(linebuf);
- if (!hflag && hp->summary[0])
- (void) sprintf(linebuf, "Summary: %s", hp->summary), tfappend(linebuf);
- if (!hflag && hp->keywords[0])
- (void) sprintf(linebuf, "Keywords: %s", hp->keywords), tfappend(linebuf);
- if (verbose) {
- (void) sprintf(linebuf, "From: %s", hp->from); tfappend(linebuf);
- (void) sprintf(linebuf, "Path: %s", hp->path); tfappend(linebuf);
- if (hp->organization[0]) {
- (void) sprintf(linebuf, "Organization: %s", hp->organization);
- tfappend(linebuf);
- }
- }
- else {
- if (p1 != NULL)
- *--p1 = '\0'; /* bump over the '(' */
-#ifdef INTERNET
- /*
- * Prefer Path line if it's in internet format, or if we don't
- * understand internet format here, or if there is no reply-to.
- */
- (void) sprintf(linebuf, "From: %s", hp->from);
-#else
- (void) sprintf(linebuf, "Path: %s", tailpath(hp));
-#endif
- if (fname[0] || (hp->organization[0] && !hflag)) {
- (void) strcat(linebuf, " (");
- if (fname[0] == '\0') {
- (void) strcpy(fname, hp->from);
- p2 = index(fname,'@');
- if (p2)
- *p2 = '\0';
- }
- (void) strcat(linebuf, fname);
- if (hp->organization[0] && !hflag) {
- (void) strcat(linebuf, " @ ");
- (void) strcat(linebuf, hp->organization);
- }
- (void) strcat(linebuf, ")");
- }
- tfappend(linebuf);
- if (p1 != NULL)
- *p1 = ' ';
- if (hp->ctlmsg[0]) {
- (void) sprintf(linebuf, "Control: %s", hp->ctlmsg);
- tfappend(linebuf);
- }
- }
-
- if (verbose) {
- (void) sprintf(linebuf, "Newsgroups: %s", hp->nbuf); tfappend(linebuf);
- (void) sprintf(linebuf, "Date: %s", hp->subdate); tfappend(linebuf);
- if (hp->sender[0]) {
- (void) sprintf(linebuf, "Sender: %s", hp->sender);
- tfappend(linebuf);
- }
- if (hp->replyto[0]) {
- (void) sprintf(linebuf, "Reply-To: %s", hp->replyto);
- tfappend(linebuf);
- }
- if (hp->followto[0]) {
- (void) sprintf(linebuf, "Followup-To: %s", hp->followto);
- tfappend(linebuf);
- }
- }
- else if (strcmp(hp->nbuf, groupdir) != 0) {
- (void) sprintf(linebuf, "Newsgroups: %s", hp->nbuf);
- tfappend(linebuf);
- timer();
- }
-}
-
-#ifdef MYDB
-
-char *
-findparent(id, num)
-char *id;
-long *num;
-{
- struct artrec a;
- char idbuf[BUFSIZE];
- char *ngname();
-
- strcpy(idbuf, id);
- lcase(idbuf);
-
- if (lookart(id, &a) == DNULL)
- return NULL;
- if (a.parent == DNULL)
- return NULL;
- readrec(a.parent, &a);
- *num = a.groups[0].artno;
- return ngname(a.groups[0].newsgroup);
-}
-
-#endif
-
-
-/*
- * Append file to temp file, handling control characters, folding lines, etc.
- * We don't grow the temp file to more than nlines so that a user won't have
- * to wait for 20 seconds to read in a monster file from net.sources.
- * What we really want is coroutines--any year now.
- */
-
-#define ULINE 0200
-static char *maxcol;
-
-appfile(iop, nlines)
-register FILE *iop;
-{
- register int c;
- register char *icol; /* &linebuf[0] <= icol <= maxcol */
-
- if (artread || artlines >= nlines || iop == NULL)
- return;
- maxcol = linebuf;
- icol = linebuf;
- while ((c = getc(iop)) != EOF) {
- switch (c) {
- case ' ':
- if (icol == maxcol && icol < linebuf + LBUFLEN - 1) {
- *icol++ = ' ';
- maxcol = icol;
- } else {
- if (*icol == '_')
- *icol++ = ULINE | ' ';
- else
- icol++;
- }
- break;
- case '\t':
- icol = (icol - linebuf &~ 07) + 8 + linebuf;
- growline(icol);
- break;
- case '\b':
- if (icol > linebuf) --icol;
- break;
- case '\n':
- outline();
- if (artlines >= nlines)
- return;
- icol = linebuf;
- break;
- case '\r':
- icol = linebuf;
- break;
- case '\f':
- outline(); outline(); outline();
- if (artlines >= nlines)
- return;
- icol = linebuf;
- break;
- default:
- if (c < ' ' || c > '~')
- break;
- else if (icol >= linebuf + LBUFLEN - 1)
- icol++;
- else if (icol == maxcol) {
- *icol++ = c;
- maxcol = icol; }
- else if (c == '_')
- *icol++ |= ULINE;
- else if (*icol == '_')
- *icol++ = (c | ULINE);
- else *icol++ = c;
- break;
- }
- }
- if (maxcol != linebuf) /* file not terminated with newline */
- outline();
- artread++;
-}
-
-growline(col)
-char *col;
-{
- while (maxcol < col && maxcol < linebuf + LBUFLEN - 1)
- *maxcol++ = ' ';
-}
-
-outline()
-{
- *maxcol = '\0';
- if (strncmp(linebuf, ">From ", 6) == 0) {
- register char *p;
- for (p = linebuf ; (*p = p[1]) != '\0' ; p++);
- }
- tfappend(linebuf);
- if (maxcol > linebuf)
- artlines = lastlin;
- maxcol = linebuf;
-}
-
-prget(prompter, buf)
-char *prompter, *buf;
-{
- char *p, *q, *r;
- int c, lastc;
-
- curflag = CURP2;
- r = buf;
- lastc = '\0';
- for (;;) {
- *r = '\0';
- p = secpr;
- for (q = prompter ; *q ; q++)
- *p++ = *q;
- for (q = buf ; *q ; q++) {
- if (p < &secpr[SECPRLEN-1] && *q >= ' ' && *p <= '~')
- *p++ = *q;
- }
- *p = '\0';
- c = vgetc();
- if (c == '\n' || c == cintr) {
- break;
- }
- if (c == cerase || c == '\b' || c == '\177') {
- if (lastc == '\\')
- r[-1] = c;
- else if (r > buf)
- r--;
- } else if (c == ckill) {
- if (lastc == '\\')
- r[-1] = c;
- else
- r = buf;
-#ifdef TIOCGLTC
- } else if (c == cwerase) {
- if (lastc == '\\')
- r[-1] = c;
- else {
- while (r > buf && (r[-1] == ' ' || r[-1] == '\t'))
- r--;
- while (r > buf && r[-1] != ' ' && r[-1] != '\t')
- r--;
- }
-#endif
- } else {
- *r++ = c;
- }
- lastc = c;
- }
- curflag = CURHOME;
- secpr[0] = '\0';
- return (c == cintr);
-}
-
-
-
-/*
- * Execute a shell command.
- */
-
-shcmd(cmd, flags)
-char *cmd;
-{
- char *arg[4];
-
- arg[0] = SHELL, arg[1] = "-c", arg[2] = cmd, arg[3] = NULL;
- return prun(arg, flags);
-}
-
-
-prun(args, flags)
-char **args;
-{
- int pid;
- int i;
- int (*savequit)();
- char *env[100], **envp, **oenvp;
- char a[BUFLEN + 2];
- extern char **environ;
- int pstatus, retval;
-
- if (!(flags & BKGRND)) {
- botscreen();
- ttycooked();
-#ifdef SIGTSTP
- (void) signal(SIGTSTP, SIG_DFL);
- (void) signal(SIGTTIN, SIG_DFL);
- (void) signal(SIGTTOU, SIG_DFL);
-#endif
- }
-#ifdef BSD4_2
- while ((pid = vfork()) == -1)
-#else /* !BSD4_2 */
- /* 4.1 BSD (at least) can't handle this vfork with -ljobs */
- while ((pid = fork()) == -1)
-#endif /* !BSD4_2 */
- sleep(1); /* must not clear alarm */
- if (pid == 0) {
- for (i = 3 ; i < 20 ; i++)
- close(i);
- if (flags & BKGRND) {
- (void) signal(SIGINT, SIG_IGN);
- (void) signal(SIGQUIT, SIG_IGN);
-#ifdef SIGTSTP
- (void) signal(SIGTSTP, SIG_IGN);
- (void) signal(SIGTTIN, SIG_IGN);
- (void) signal(SIGTTOU, SIG_IGN);
-#endif
- (void) close(0);
- (void) close(1);
- (void) open("/dev/null", 2);
- (void) dup(0);
- }
- /* set $A */
- (void) sprintf(a, "A=%s", filename);
- oenvp = environ;
- env[0] = a;
- for (envp = env + 1 ; *oenvp != NULL && envp < env + 98 ; oenvp++)
- if ((*oenvp)[0] != 'A' || (*oenvp)[1] != '=')
- *envp++ = *oenvp;
- *envp = NULL;
-
- (void) umask(savmask);
- execve(args[0], args, env);
- perror(args[0]);
- exit(20);
- }
- if (!(flags & BKGRND)) {
- savequit = signal(SIGQUIT, SIG_IGN);
- while ((i = wait(&pstatus)) != pid && (i != -1 || errno == EINTR))
- ;
- if (i == -1)
- retval = 1;
- else
- retval = pstatus;
- if (flags & CWAIT) {
- fprintf(stderr, "[Hit return to continue]");
- while ((errno = 0, i = getchar()) != '\n'
- && (i != EOF || errno == EINTR));
- }
- (void) signal(SIGQUIT, savequit);
- ttyraw();
- clearok(curscr, 1);
-#ifdef SIGTSTP
- (void) signal(SIGTSTP, onstop);
- (void) signal(SIGTTIN, onstop);
- (void) signal(SIGTTOU, onstop);
-#endif
- return retval;
- } else
- return 0;
-}
-
-#ifdef DIGPAGE
-
-
-/*
- * Find end of current subarticle in digest.
- */
-
-findend(l)
-{
- register int i, n;
- register char *p;
-
- for (i = l ; i < l + ARTWLEN && i < lastlin ; i++) {
- tfget(linebuf, i);
- for (p = linebuf ; *p == '-' ; p++)
- ;
- n = (int)p - (int)linebuf;
- if ( (n > 23 && n < 33) || (n > 65 && n < 79)) {
- tfget(linebuf, ++i);
- if (linebuf[0] == '\0')
- return i + 1;
- }
- }
- return 0;
-}
-
-#endif
-
-
-/*** Routines for handling temporary file ***/
-
-/*
- * Append to temp file.
- * Long lines are folded.
- */
-
-tfappend(tline)
-register char *tline;
-{
- register char *nxtlin;
-
- do {
- nxtlin = index(tline, '\n');
- if (nxtlin)
- *nxtlin++ = '\0';
-
- while (strlen(tline) > COLS) {
- tfput(tline, lastlin++);
- tline += COLS;
- maxlinno++;
- }
- tfput(tline, lastlin++);
- } while ((tline = nxtlin) != NULL);
-}
-
-
-tfput(tline, linno)
-char *tline;
-{
- register char *p;
- register FILE *rtfp; /* try to make it a little faster */
- register int i;
-
- p = tline, i = even(COLS);
- tfseek(linno, 1);
- rtfp = tfp;
- while (--i >= 0) {
- if (*p)
- putc(*p++, rtfp);
- else
- putc('\0', rtfp);
- }
- tflinno++;
-}
-
-
-tfget(tline, linno)
-char *tline;
-{
- tfseek(linno, 0);
- fread(tline, even(COLS), 1, tfp);
- tline[COLS] = '\0';
- tflinno++;
-}
-
-
-tfseek(linno, wrflag)
-{
- static int lastwrflag = 1;
-
- if (linno != tflinno || wrflag != lastwrflag) {
- (void) fseek(tfp, (long)linno * even(COLS), 0);
- tflinno = linno;
- lastwrflag = wrflag;
- }
-}
-
-/* VARARGS1 */
-msg(s, a1, a2, a3, a4)
-char *s;
-{
- (void) sprintf(secpr, s, a1, a2, a3, a4);
-}
-
-
-/*
- * Update the display.
- * The display is entirely controlled by this routine,
- * which means that this routine may get pretty snarled.
- */
-
-static int savelinno = -1; /* dlinno on last call to updscr */
-static int savepr; /* prflags on last call */
-#ifdef TIOCGWINSZ
-static int UPDATING = 0, WINCH = 0;
-
-/*
- * called by winch() from virtterm.c -- resets state information back
- * to start-up state and forces a full redraw of the screen. The
- * current article is rewound to the beginning because it's would
- * be very difficult to get the screen to return to the exact point
- * in the file that the user left off (I know, I tried).
- */
-winch_upd()
-{
- if(UPDATING) /* concurrency. wow! */
- WINCH++;
- else if((WINCH == 0) && (savelinno >= 0)) {
- int saveline = dlinno, saveflag = curflag;
-
- /* reread the article */
- FCLOSE(fp);
- obit = -1;
- getnextart(FALSE);
- appfile(fp, dlinno + ARTWLEN + 1);
-
- /* fix up the screen */
- curflag = saveflag;
- strcpy(prompt,"more? ");
- clearok(curscr, 1);
- updscr();
- }
-}
-#endif /* TIOCGWINSZ */
-
-
-updscr()
-{
- int count;
- int i;
-
-#ifdef TIOCGWINSZ
- UPDATING++;
-#endif /* TIOCGWINSZ */
- if (checkin())
- return;
- if ((prflags & HELPMSG) == 0
- && (dlinno != savelinno || savepr != prflags)
- && quitflg == 0) {
- if (dlinno != savelinno)
- prflags &=~ NOPRT;
- count = ARTWLEN;
- if (prflags & NOPRT)
- count = 0;
- if ((prflags & HDRONLY) && count > hdrend)
- count = hdrend - dlinno;
-#ifdef DIGPAGE
- if (endsuba > 0 && count > endsuba - dlinno)
- count = endsuba - dlinno;
-#endif
- if ((prflags & NEWART) == 0)
- ushift(ARTWIN, ARTWIN+ARTWLEN-1, dlinno - savelinno);
- if (count > lastlin - dlinno)
- count = lastlin - dlinno;
- for (i = ARTWIN ; i < ARTWIN + ARTWLEN ; i++)
- clrline(i);
- for (i = 0 ; i < count ; i++) {
- tfget(linebuf, dlinno + i);
- mvaddstr(ARTWIN + i, 0, linebuf);
- }
- prflags &=~ NEWART;
- savepr = prflags;
- savelinno = dlinno;
- }
- clrline(SPLINE), clrline(PRLINE);
-#ifdef STATTOP
- mvaddstr(PRLINE, 0, prompt);
-#else
- if (strlen(secpr) <= COLS)
- mvaddstr(PRLINE, 0, prompt);
-#endif
- mvaddstr(PRLINE, 59, timestr);
- mvaddstr(PRLINE, 17, groupdir);
- addch(' '); addnum(bit); addch('/'); addnum(pngsize); addch(' ');
- if (ismail)
- mvaddstr(PRLINE, 75, ismail > 1? "MAIL" : "mail");
- mvaddstr(SPLINE, 0, secpr);
- if (curflag == CURP1)
- move(PRLINE, strlen(prompt));
- else if (curflag == CURHOME)
- move(0, 0);
- refresh();
-#ifdef TIOCGWINSZ
- UPDATING=0;
- if (WINCH) { /* window changed while updating screen */
- WINCH = 0;
- winch_upd();
- }
-#endif /* TIOCGWINSZ */
-}
-
-addnum(n)
-register long n;
-{
- if (n >= 10)
- addnum(n / 10);
- addch((char)(n % 10 + '0'));
-}
-
-/*
- * Called on alarm signal.
- * Simply sets flag, signal processed later.
- */
-
-onalarm()
-{
-#ifdef SIGTSTP
- int dojump = reading;
-
- reading = FALSE;
- alflag++;
- if (dojump)
- longjmp(alrmjmp, 1);
-#else /* !SIGTSTP */
- alflag++;
-#endif
-}
-
-/*
- * Process alarm signal (or start clock)
- */
-timer()
-{
- time_t tod;
- int hour;
- int i;
- struct tm *t;
- struct stat statb;
- struct tm *localtime();
- static char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
- static long oldmsize = 1000000L;
- static int rccount = 10;
- static time_t lastismail = 0;
-
- alflag = 0;
- (void) signal(SIGALRM, onalarm);
- (void) time(&tod);
- t = localtime(&tod);
- i = 60 - t->tm_sec;
- (void) alarm(i > 30? 30 : i); /* reset alarm */
- hour = t->tm_hour % 12;
- if (hour == 0) hour = 12;
- (void) sprintf(timestr, "%.3s %d %d:%02d",
- months + 3 * t->tm_mon, t->tm_mday, hour, t->tm_min);
- if (mailf == NULL || stat(mailf, &statb) < 0) {
- statb.st_size = 0;
- }
- if (statb.st_size > oldmsize) {
- ismail = 2;
- beep();
- } else {
- if (statb.st_size == 0)
- ismail = 0;
- /* force MAIL for at least 30 seconds */
- else if (ismail > 1 && (lastismail+30) < tod)
- ismail = 1;
- }
- oldmsize = statb.st_size;
- lastismail = tod;
- if (uflag && !xflag && --rccount < 0) {
- writeoutrc();
- if (secpr[0] == '\0')
- (void) strcpy(secpr, ".newsrc updated");
- rccount = 10;
- }
-}
-
-char *
-getmailname()
-{
- static char mailname[32];
- register char *p;
-
- if( (p = getenv("MAIL")) != NULL)
- return p;
-#ifndef MMDF
- if (username[0] == '\0' || strlen(username) > 15)
- return NULL;
-#ifdef USG
- (void) sprintf(mailname, "/usr/mail/%s", username);
-#else /* !USG */
- (void) sprintf(mailname, "/usr/spool/mail/%s", username);
-#endif /* !USG */
-#else /* MMDF */
- (void) sprintf(mailname, "%s/mailbox", userhome);
-#endif /* MMDF */
- return mailname;
-}
-
-
-
-/*** Terminal I/O ***/
-
-#define INBUFSIZ 8
-
-char inbuf[INBUFSIZ]; /* input buffer */
-char outbuf[BUFSIZ]; /* output buffer */
-int innleft = 0; /* # of chars in input buffer */
-int outnleft = BUFSIZ; /* room left in output buffer */
-char *innext; /* next input character */
-char *outnext = outbuf; /* next space in output buffer */
-#ifdef USG
-int oflags; /* fcntl flags (for nodelay read) */
-#endif
-
-/*
- * Input a character
- */
-
-vgetc()
-{
- register c;
-#if defined(BSD4_2) || defined(BSD4_1C)
- int readfds, exceptfds;
-#endif
-
-recurse:
- if (--innleft >= 0) {
- c = *innext++;
- } else {
- if (alflag)
- timer();
- updscr(); /* update the display */
- for (;;) {
- if (innleft > 0 || alflag)
- goto recurse;
- intflag = 0;
-#ifdef USG
- if (oflags & O_NDELAY) {
- oflags &=~ O_NDELAY;
- fcntl(0, F_SETFL, oflags);
- }
-#endif
-#ifdef SIGTSTP
- if (setjmp(alrmjmp))
- continue;
- if (setjmp(intjmp))
- return cintr;
- reading = TRUE;
-#endif /* SIGTSTP */
-#if defined(BSD4_2) || defined(BSD4_1C)
- /* Use a select because it can be interrupted. */
- readfds = 1; exceptfds = 1;
- select(1, &readfds, (int *)0, &exceptfds, (int *)0);
- if (!(readfds & 1))
- break;
-#endif
- innleft = read(0, inbuf, INBUFSIZ);
-#ifdef SIGTSTP
- reading = FALSE;
-#endif /* SIGTSTP */
- if (innleft > 0)
- break;
- if (innleft == 0) {
- quitflg++;
- return cintr;
- }
- if (errno != EINTR)
- abort(); /* "Can't happen" */
- if (intflag) {
- intflag--;
- return cintr;
- }
- }
- innext = inbuf + 1;
- innleft--;
- c = inbuf[0];
- }
-#ifndef USG
-#ifndef CBREAK
- c &= 0177;
- if (c == '\034') /* FS character */
- xxit(0);
-#endif
-#endif
- if (c == '\f') {
- clearok(curscr, 1);
- prflags &=~ NOPRT;
- goto recurse;
- }
- if (c == '\r')
- c = '\n';
- return c;
-}
-
-
-/*
- * Push a character back onto the input stream.
- */
-
-pushback(c)
-{
- if (innext <= inbuf)
- abort();
- *--innext = c;
- innleft++;
-}
-
-/*
- * Check for terminal input
- */
-
-checkin()
-{
-#ifdef FIONREAD
- int count;
-#endif
-#ifdef STATTOP
- if (innleft > 0)
-#else
- if (innleft > 0 || alflag)
-#endif
- return 1;
-#if defined(USG) || defined(FIONREAD)
- if (ospeed >= B9600)
- return 0;
- vflush();
- if (ospeed <= B300)
- ttyowait();
-#ifdef USG
- if ((oflags & O_NDELAY) == 0) {
- oflags |= O_NDELAY;
- (void) fcntl(0, F_SETFL, oflags);
- }
- if ((innleft = read(0, inbuf, INBUFSIZ)) > 0) {
- innext = inbuf;
- return 1;
- }
-#endif
-#ifdef FIONREAD
- count = 0; /* in case FIONREAD fails */
- (void) ioctl(0, FIONREAD, (char *)&count);
- if (count)
- return 1;
-#endif
-#endif
- return 0;
-}
-
-
-
-/*
- * flush terminal input queue.
- */
-
-clearin()
-{
-#ifdef USG
- (void) ioctl(0, TCFLSH, (char *)0);
-#else
-#ifdef TIOCFLUSH
- (void) ioctl(0, TIOCFLUSH, (char *)0);
-#else
- struct sgttyb tty;
- (void) ioctl(0, TIOCGETP, &tty);
- (void) ioctl(0, TIOCSETP, &tty);
-#endif
-#endif
- innleft = 0;
-}
-
-vputc(c)
-{
- if (--outnleft < 0) {
- vflush();
- outnleft--;
- }
- *outnext++ = c;
-}
-
-/*
- * Flush the output buffer
- */
-
-vflush()
-{
- register char *p;
- register int i;
-#ifdef BSD4_2
- int mask;
-#else
- unsigned oalarm;
-#endif
-
-#ifdef BSD4_2
- mask = sigblock(1 << (SIGALRM-1));
-#else
- oalarm = alarm(0);
-#endif
- for (p = outbuf ; p < outnext ; p += i) {
- if ((i = write(1, p, outnext - p)) < 0) {
- if (errno != EINTR)
- abort(); /* "Can't happen" */
- i = 0;
- }
- }
- outnleft = BUFSIZ;
- outnext = outbuf;
-#ifdef BSD4_2
- sigsetmask(mask);
-#else
- (void) alarm(oalarm);
-#endif
-}
-
-/*** terminal modes ***/
-
-#ifdef USG
-static struct termio oldtty, newtty;
-
-/*
- * Save tty modes
- */
-
-ttysave()
-{
- if (ioctl(1, TCGETA, &oldtty) < 0)
- xerror("Can't get tty modes");
- newtty = oldtty;
- newtty.c_iflag &=~ (INLCR|IGNCR|ICRNL);
- newtty.c_oflag &=~ (OPOST);
- newtty.c_lflag &=~ (ICANON|ECHO|ECHOE|ECHOK|ECHONL);
- newtty.c_lflag |= (NOFLSH);
- newtty.c_cc[VMIN] = 1;
- newtty.c_cc[VTIME] = 0;
- cerase = oldtty.c_cc[VERASE];
- ckill = oldtty.c_cc[VKILL];
- cintr = oldtty.c_cc[VINTR];
- ospeed = oldtty.c_cflag & CBAUD;
- initterm();
-}
-
-
-/*
- * Set tty modes for visual processing
- */
-
-ttyraw()
-{
- while (ioctl(1, TCSETAF, &newtty) < 0 && errno == EINTR)
- ;
- rawterm();
-}
-
-ttyowait()
-{ /* wait for output queue to drain */
- while (ioctl(1, TCSETAW, &newtty) < 0 && errno == EINTR)
- ;
-}
-
-/*
- * Restore tty modes
- */
-
-ttycooked()
-{
- cookedterm();
- vflush();
- while (ioctl(1, TCSETAF, &oldtty) < 0 && errno == EINTR)
- ;
- oflags &=~ O_NDELAY;
- (void) fcntl(0, F_SETFL, oflags) ;
-}
-
-#else
-
-static struct sgttyb oldtty, newtty;
-#ifdef TIOCGLTC
-static struct ltchars oldltchars, newltchars;
-#endif
-
-/*
- * Save tty modes
- */
-
-ttysave()
-{
-#ifdef CBREAK
- struct tchars tchars; /* special characters, including interrupt */
-#endif
-#ifdef SIGTSTP
- int getpgrp();
-#if defined(BSD4_2) || defined(BSD4_1C)
- int tpgrp;
-#else /* BSD4_1 */
- short tpgrp;
-#endif /* BSD4_1 */
-
-retry:
-#ifdef BSD4_2
- (void) sigblock(sigmask(SIGTSTP)|sigmask(SIGTTIN)|sigmask(SIGTTOU));
-#else /* !BSD4_2 */
- (void) signal(SIGTSTP, SIG_HOLD);
- (void) signal(SIGTTIN, SIG_HOLD);
- (void) signal(SIGTTOU, SIG_HOLD);
-#endif /* !BSD4_2 */
- if (ioctl(2, TIOCGPGRP, (char *)&tpgrp) < 0)
- goto nottty;
- if (tpgrp != getpgrp(0)) { /* not in foreground */
- (void) signal(SIGTTOU, SIG_DFL);
-#ifdef BSD4_2
- (void) sigsetmask(sigblock(0) & ~sigmask(SIGTTOU));
-#endif /* BSD4_2 */
- (void) kill(0, SIGTTOU);
- /* job stops here waiting for SIGCONT */
- goto retry;
- }
- (void) signal(SIGTTIN, SIG_DFL);
- (void) signal(SIGTTOU, SIG_DFL);
- (void) signal(SIGTSTP, SIG_DFL);
-#ifdef BSD4_2
- (void) sigsetmask(sigblock(0) & ~(sigmask(SIGTSTP)|sigmask(SIGTTIN)|sigmask(SIGTTOU)));
-#endif /* BSD4_2 */
-#endif /* SIGTSTP */
- if (ioctl(1, TIOCGETP, (char *)&oldtty) < 0)
-nottty: xerror("Can't get tty modes");
- newtty = oldtty;
- newtty.sg_flags &=~ (CRMOD|ECHO|XTABS);
-#ifdef CBREAK
- newtty.sg_flags |= CBREAK;
- ioctl(1, TIOCGETC, (char *)&tchars);
- cintr = tchars.t_intrc;
-#else /* !CBREAK */
- newtty.sg_flags |= RAW;
- cintr = '\0177'; /* forcibly this on V6 systems */
-#endif /* !CBREAK */
- cerase = oldtty.sg_erase;
- ckill = oldtty.sg_kill;
- ospeed = oldtty.sg_ospeed;
-#ifdef TIOCGLTC
- if (ioctl(1, TIOCGLTC, (char *)&oldltchars) >= 0) {
- newltchars = oldltchars;
- newltchars.t_dsuspc = -1;
- cwerase = oldltchars.t_werasc;
- }
-#endif
- initterm();
-#ifdef SIGTSTP
- (void) signal(SIGTTIN, onstop);
- (void) signal(SIGTTOU, onstop);
- (void) signal(SIGTSTP, onstop);
-#endif /* SIGTSTP */
-}
-
-
-/*
- * Set tty modes for visual processing
- */
-
-ttyraw()
-{
- while (ioctl(1, TIOCSETN, (char *)&newtty) < 0 && errno == EINTR)
- ;
-#ifdef TIOCGLTC
- if (newltchars.t_dsuspc == '\377')
- while (ioctl(1, TIOCSLTC, (char *)&newltchars) < 0 && errno == EINTR)
- ;
-#endif
- rawterm();
-}
-
-ttyowait()
-{ /* wait for output queue to drain */
-#ifdef TIOCDRAIN /* This ioctl is a local mod on linus */
- (void) ioctl(1, TIOCDRAIN, (char *)0);
-#endif
-}
-
-
-/*
- * Restore tty modes
- */
-
-ttycooked()
-{
- cookedterm();
- vflush();
- while (ioctl(1, TIOCSETN, (char *)&oldtty) < 0 && errno == EINTR)
- ;
-#ifdef TIOCGLTC
- if (newltchars.t_dsuspc == '\377')
- while (ioctl(1, TIOCSLTC, (char *)&oldltchars) < 0 && errno == EINTR)
- ;
-#endif
-}
-
-#endif
-
-
-
-/*** signal handlers ***/
-
-onint() {
-#ifdef SIGTSTP
- int dojump = reading;
-
- reading = FALSE;
-#endif /* SIGTSTP */
- if (!news) {
- ttycooked();
- xxit(1);
- }
- (void) signal(SIGINT, onint);
- clearin(); /* flush input queue */
-#ifdef SIGTSTP
- if (dojump)
- longjmp(intjmp, 1);
-#endif /* SIGTSTP */
- intflag++;
-}
-
-#ifdef SIGTSTP
-onstop(signo)
-int signo;
-{
- /* restore old terminal state */
- botscreen();
- vflush();
- ttycooked();
- (void) signal(signo, SIG_DFL);
-#ifdef BSD4_2
- (void) sigblock(sigmask(SIGALRM)|sigmask(SIGINT));
- (void) sigsetmask(sigblock(0) & ~sigmask(signo));
-#else /* BSD4_1 */
- (void) alarm(0);
-#endif /* BSD4_1 */
- (void) kill(0, signo); /* stop here until continued */
-
- (void) signal(signo, onstop);
- /* restore our special terminal state */
- ttyraw();
-#ifdef TIOCGWINSZ
- winch(); /* get current window size and redraw screen */
-#endif /* TIOCGWINSZ */
- clearok(curscr, 1);
- updscr();
-#ifdef BSD4_2
- (void) sigsetmask(sigblock(0) & ~(sigmask(SIGALRM)|sigmask(SIGINT)));
-#else /* BSD4_1 */
- timer();
-#endif /* BSD4_1 */
-}
-#endif
-
-/*** stolen from rfuncs2.c and modified ***/
-
-vsave(to, flags)
-register char *to;
-{
- register FILE *ufp;
- int isprogram = 0;
- int isnew = 1;
- long saveoff;
- char temp[20];
- char *fname;
- char prog[BUFLEN + 24];
-
- saveoff = ftell(fp);
- (void) fseek(fp, artbody, 0);
- fname = to;
- if (*to == PIPECHAR) {
- if (strlen(to) > BUFLEN) {
- msg("Command name too long");
- goto out;
- }
- flags |= OVWRITE;
- (void) strcpy(temp, "/tmp/vnXXXXXX");
- (void) mktemp(temp);
- fname = temp;
- _amove(ROWS - 1, 0);
- vflush();
- }
- if ((flags & OVWRITE) == 0) {
- ufp = fopen(fname, "r");
- if (ufp != NULL) {
- (void) fclose(ufp);
- isnew = 0;
- }
- }
- (void) umask(savmask);
-
- if (*to == PIPECHAR)
- isprogram++;
- if ((ufp = fopen(fname, (flags & OVWRITE) == 0? "a" : "w")) == NULL) {
- msg("Cannot open %s", fname);
- goto out;
- }
- /*
- * V7MAIL code is here to conform to V7 mail format.
- * If you need a different format to be able to
- * use your local mail command (such as four ^A's
- * on the end of articles) substitute it here.
- */
- if (flags & SVHEAD) {
-#ifdef MMDF
- if (!isprogram)
- fprintf(ufp, "\001\001\001\001\n");
-#endif /* MMDF */
-#ifdef V7MAIL
- h->subtime = cgtdate(h->subdate);
- fprintf(ufp, "From %s %s", replyname(h), ctime(&h->subtime));
-#endif
- hprint(h, ufp, 2);
-#ifdef V7MAIL
- tprint(fp, ufp, TRUE);
- putc('\n', ufp); /* force blank line at end (ugh) */
-#else
- tprint(fp, ufp, FALSE);
-#endif
- } else {
- tprint(fp, ufp, FALSE);
- }
-
- fclose(ufp);
- if (isprogram) {
- (void) sprintf(prog, "(%s)<%s", to + 1, fname);
- shcmd(prog, CWAIT);
- prflags |= NOPRT;
- } else {
- if ((flags & OVWRITE) == 0)
- msg("file: %s %s", to, isnew ? "created" : "appended");
- else
- msg("file: %s written", to);
- }
-
-out:
- if (isprogram) {
- (void) unlink(fname);
- }
- (void) umask(N_UMASK);
- (void) fseek(fp, saveoff, 0);
-}
-
-xxit(status)
-int status;
-{
- (void) unlink(infile);
- (void) unlink(outfile);
-#ifdef SORTACTIVE
- if (strncmp(ACTIVE,"/tmp/", 5) == 0)
- (void) unlink(ACTIVE);
-#endif /* SORTACTIVE */
- if (ospeed) { /* is == 0, we haven't been in raw mode yet */
- botscreen();
- vflush();
- ttycooked();
- }
- exit(status);
-}
*-*-END-of-src/visual.c-*-*
echo x - src/recmail.c 1>&2
sed 's/.//' >src/recmail.c <<'*-*-END-of-src/recmail.c-*-*'
-/*
- * This software is Copyright (c) 1986 by Rick Adams.
- *
- * Permission is hereby granted to copy, reproduce, redistribute or
- * otherwise use this software as long as: there is no monetary
- * profit gained specifically from the use or reproduction or this
- * software, it is not sold, rented, traded or otherwise marketed, and
- * this copyright notice is included prominently in any copy
- * made.
- *
- * The author make no claims as to the fitness or correctness of
- * this software for any use whatsoever, and it is provided as is.
- * Any use of this software is at the user's own risk.
- *
- * recmail: read a mail message on stdin, grab all addresses in To and Cc
- * lines, and pass the full message to all addressees. This is useful to
- * send the output of a recently edited mail message (with headers edited too).
- * It is similar to sendmail -t, but only assumes /bin/mail.
- * To use your own mailer, e. g. nmail, compile with -DMAILER=my_mailer.
- */
-
-#ifdef SCCSID
-static char *SccsId = "@(#)recmail.c 1.15 10/23/86";
-#endif /* SCCSID */
-
-#include "params.h"
-
-#ifndef MAILER
-#define MAILER "/bin/mail"
-#endif
-char mailer[] = MAILER;
-
-#define MAXRECIPS 100
-char *recips[MAXRECIPS];
-int nrecips = 0;
-
-main()
-{
- FILE *fd;
- char *tmpf;
- FILE *errfd;
- char *errf;
- char linebuf[1024];
- int i, pid, wpid;
- int exstat;
- char *mypath;
- int goodcnt, badcnt;
- char *mktemp(), *getenv();
-
- tmpf = mktemp("/tmp/rmXXXXXX");
- (void) close(creat(tmpf,0666));
- fd = fopen(tmpf, "w");
- errf = mktemp("/tmp/rmXXXXXX");
- (void) close(creat(errf,0666));
- errfd = fopen(errf, "w");
- fprintf(errfd, "Subject: Returned mail\n");
- fprintf(errfd, "\n ----- Transcript of session follows -----\n");
- (void) fflush(errfd);
- goodcnt = badcnt = 0;
-
- while (fgets(linebuf, sizeof linebuf, stdin) != NULL) {
- if ((strncmp(linebuf, "Bcc: ", 5) == 0 ||
- strncmp(linebuf, "bcc: ", 5) == 0 ||
- strncmp(linebuf, "BCC: ", 5) == 0)) {
- if (linebuf[5] != '\n')
- addrecips(linebuf+5);
- }
- else if (fputs(linebuf, fd) == EOF)
- goto werror;
- if (linebuf[0] == '\n')
- break;
- if ((strncmp(linebuf, "To: ", 4) == 0 ||
- strncmp(linebuf, "to: ", 4) == 0 ||
- strncmp(linebuf, "TO: ", 4) == 0 ||
- strncmp(linebuf, "Cc: ", 4) == 0 ||
- strncmp(linebuf, "cc: ", 4) == 0 ||
- strncmp(linebuf, "CC: ", 4) == 0) &&
- linebuf[4] != '\n')
- addrecips(linebuf+4);
- }
- if (!feof(stdin)) {
- while (fgets(linebuf, sizeof linebuf, stdin) != NULL) {
- if (fputs(linebuf, fd) == EOF) {
-werror:
- printf("write error on temp file\n");
- exit(2);
- }
- }
- }
- /*
- * Append the contents of the .signature file (if it exists) to
- * the end of the mail message
- */
- {
- char sigbuf[BUFSIZ];
- register c;
- register char *p = getenv("HOME");
- FILE *infp;
-
- if (p) {
- (void) sprintf(sigbuf, "%s/%s", p, ".signature");
- if (infp = fopen(sigbuf, "r")) {
- fprintf(fd,"---\n");
- while ((c = getc(infp)) != EOF)
- putc(c,fd);
- (void) fclose(infp);
- }
- }
- }
- (void) fclose(fd);
-
- /*
- * Force the path to only consider /bin and /usr/bin, since
- * that's the version of mail we want (not /usr/ucb/mail)
- */
- if (mailer[0] != '/') {
- register int e;
- extern char **environ;
- for (e = 0; environ[e] != NULL; ++e)
- if (strncmp(environ[e], "PATH=", 5) == 0) {
- environ[e] = "PATH=/bin:/usr/bin";
- break;
- }
- }
- mypath = getenv("PATH");
- if (mypath)
- strcpy(mypath, "/bin:/usr/bin");
-
- /*
- * We send the copies out separately, because of a bug in
- * USG's /bin/mail which will generate ANOTHER To: line,
- * even though we already have one, if there are at least
- * two recipients.
- */
- for (i=0; i<nrecips; i++) {
- /*
- * mail recips[i] < tmpf
- */
- pid = mailto(tmpf, errfd, recips[i]);
- exstat = -1;
- while ((wpid = wait(&exstat)) >= 0 && wpid != pid)
- ;
- if (exstat == 0)
- goodcnt++;
- else
- badcnt++;
- }
- if (badcnt) {
- mailback(errfd, tmpf, errf);
- (void) unlink(tmpf);
- (void) unlink(errf);
- exit(1);
- } else if (goodcnt == 0) {
- fprintf(errfd, "recmail: no 'To:' line\n");
- mailback(errfd, tmpf, errf);
- (void) unlink(tmpf);
- (void) unlink(errf);
- exit (1);
- }
- (void) unlink(tmpf);
- (void) unlink(errf);
- exit (0);
-}
-
-#define isok(c) (isprint(c) && (c) != ' ' && c != ',')
-addrecips(line)
-char *line;
-{
- char *front, *back, *tail;
- char *malloc();
-
- tail = line + strlen(line);
- for (front=line; front < tail; ) {
- while (!isok(*front) && front < tail)
- front++;
- if (front >= tail)
- break; /* skip end of line garbage */
- for (back=front; isok(*back); back++)
- ;
- *back=0;
- if (nrecips >= MAXRECIPS) {
- printf("Too many destinations\n");
- exit(2);
- }
- if ((recips[nrecips] = malloc(strlen(front) + 1)) == NULL) {
- printf("Out of space\n");
- exit(2);
- }
- (void) strcpy(recips[nrecips], front);
- nrecips++;
- front = back+1;
- }
-}
-
-int
-mailto(tmpf, errfd, recip)
-char *tmpf;
-FILE *errfd;
-char *recip;
-{
- register int pid;
-
- /*
- * mail recips < tmpf
- */
- while ((pid = vfork()) == -1) {
- fprintf(stderr, "fork failed, waiting...\r\n");
- sleep(60);
- }
- if (pid == 0) {
- (void) close(0);
- (void) open(tmpf, 0);
- if (errfd != NULL) {
- (void) close(1);
- (void) dup(fileno(errfd));
- (void) fclose(errfd);
- (void) close(2);
- (void) dup(1);
- }
- execlp(mailer, mailer, recip, (char *)0);
- perror(mailer);
- exit(1);
- }
- return pid;
-}
-
-mailback(errfd, tmpf, errf)
-register FILE *errfd;
-char *tmpf;
-char *errf;
-{
- register FILE *fd;
- register int c;
- int exstat;
- register int pid, wpid;
- char *logn;
- char *getlogin(), *getenv();
- register struct passwd *pwd;
-
- if ((fd = fopen(tmpf, "r")) != NULL) {
- fprintf(errfd, "\n ----- Unsent message follows -----\n");
- while ((c = getc(fd)) != EOF)
- putc(c, errfd);
- (void) fclose(fd);
- }
- (void) fclose(errfd);
- if ((logn = getlogin()) == NULL && (logn = getenv("USER")) == NULL) {
- if ((pwd = getpwent(getuid())) == NULL)
- return;
- logn = pwd->pw_name;
- }
- pid = mailto(errf, (FILE *)NULL, logn);
- while ((wpid = wait(&exstat)) >= 0 && wpid != pid)
- ;
-}
*-*-END-of-src/recmail.c-*-*
echo x - src/ftime.c 1>&2
sed 's/.//' >src/ftime.c <<'*-*-END-of-src/ftime.c-*-*'
-#ifdef SCCSID
-static char *SccsId = "@(#)ftime.c 2.5 4/26/85";
-#endif /* SCSCID */
-
-#include <sys/types.h>
-struct timeb
-{
- time_t time;
- unsigned short millitm;
- short timezone;
- short dstflag;
-};
-
-extern long timezone;
-extern int daylight;
-
-ftime(tp)
-struct timeb *tp;
-{
- long t;
-
- time(&t);
- tp->time = t;
- tp->millitm = 0;
- tp->timezone = timezone/60;
- tp->dstflag = daylight;
-}
*-*-END-of-src/ftime.c-*-*
exit