Annotation of 42BSD/ucb/Mail/collect.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)collect.c  2.15 (Berkeley) 8/11/83";
        !             3: #endif
        !             4: 
        !             5: /*
        !             6:  * Mail -- a mail program
        !             7:  *
        !             8:  * Collect input from standard input, handling
        !             9:  * ~ escapes.
        !            10:  */
        !            11: 
        !            12: #include "rcv.h"
        !            13: #include <sys/stat.h>
        !            14: 
        !            15: /*
        !            16:  * Read a message from standard output and return a read file to it
        !            17:  * or NULL on error.
        !            18:  */
        !            19: 
        !            20: /*
        !            21:  * The following hokiness with global variables is so that on
        !            22:  * receipt of an interrupt signal, the partial message can be salted
        !            23:  * away on dead.letter.  The output file must be available to flush,
        !            24:  * and the input to read.  Several open files could be saved all through
        !            25:  * Mail if stdio allowed simultaneous read/write access.
        !            26:  */
        !            27: 
        !            28: static int     (*savesig)();           /* Previous SIGINT value */
        !            29: static int     (*savehup)();           /* Previous SIGHUP value */
        !            30: # ifdef VMUNIX
        !            31: static int     (*savecont)();          /* Previous SIGCONT value */
        !            32: # endif VMUNIX
        !            33: static FILE    *newi;                  /* File for saving away */
        !            34: static FILE    *newo;                  /* Output side of same */
        !            35: static int     hf;                     /* Ignore interrups */
        !            36: static int     hadintr;                /* Have seen one SIGINT so far */
        !            37: 
        !            38: static jmp_buf coljmp;                 /* To get back to work */
        !            39: 
        !            40: FILE *
        !            41: collect(hp)
        !            42:        struct header *hp;
        !            43: {
        !            44:        FILE *ibuf, *fbuf, *obuf;
        !            45:        int lc, cc, escape, collrub(), intack(), collhup, collcont(), eof;
        !            46:        register int c, t;
        !            47:        char linebuf[LINESIZE], *cp;
        !            48:        extern char tempMail[];
        !            49:        int notify();
        !            50:        extern collintsig(), collhupsig();
        !            51: 
        !            52:        noreset++;
        !            53:        ibuf = obuf = NULL;
        !            54:        if (value("ignore") != NOSTR)
        !            55:                hf = 1;
        !            56:        else
        !            57:                hf = 0;
        !            58:        hadintr = 0;
        !            59: # ifdef VMUNIX
        !            60:        if ((savesig = sigset(SIGINT, SIG_IGN)) != SIG_IGN)
        !            61:                sigset(SIGINT, hf ? intack : collrub), sigblock(mask(SIGINT));
        !            62:        if ((savehup = sigset(SIGHUP, SIG_IGN)) != SIG_IGN)
        !            63:                sigset(SIGHUP, collrub), sigblock(mask(SIGHUP));
        !            64:        savecont = sigset(SIGCONT, collcont);
        !            65: # else VMUNIX
        !            66:        savesig = signal(SIGINT, SIG_IGN);
        !            67:        savehup = signal(SIGHUP, SIG_IGN);
        !            68: # endif VMUNIX
        !            69:        newi = NULL;
        !            70:        newo = NULL;
        !            71:        if ((obuf = fopen(tempMail, "w")) == NULL) {
        !            72:                perror(tempMail);
        !            73:                goto err;
        !            74:        }
        !            75:        newo = obuf;
        !            76:        if ((ibuf = fopen(tempMail, "r")) == NULL) {
        !            77:                perror(tempMail);
        !            78:                newo = NULL;
        !            79:                fclose(obuf);
        !            80:                goto err;
        !            81:        }
        !            82:        newi = ibuf;
        !            83:        remove(tempMail);
        !            84: 
        !            85:        /*
        !            86:         * If we are going to prompt for a subject,
        !            87:         * refrain from printing a newline after
        !            88:         * the headers (since some people mind).
        !            89:         */
        !            90: 
        !            91:        t = GTO|GSUBJECT|GCC|GNL;
        !            92:        c = 0;
        !            93:        if (intty && sflag == NOSTR && hp->h_subject == NOSTR && value("ask"))
        !            94:                t &= ~GNL, c++;
        !            95:        if (hp->h_seq != 0) {
        !            96:                puthead(hp, stdout, t);
        !            97:                fflush(stdout);
        !            98:        }
        !            99:        if (c)
        !           100:                grabh(hp, GSUBJECT);
        !           101:        escape = ESCAPE;
        !           102:        if ((cp = value("escape")) != NOSTR)
        !           103:                escape = *cp;
        !           104:        eof = 0;
        !           105:        for (;;) {
        !           106:                int omask = sigblock(0) &~ (mask(SIGINT)|mask(SIGHUP));
        !           107: 
        !           108:                setjmp(coljmp);
        !           109: # ifdef VMUNIX
        !           110:                sigsetmask(omask);
        !           111: # else VMUNIX
        !           112:                if (savesig != SIG_IGN)
        !           113:                        signal(SIGINT, hf ? intack : collintsig);
        !           114:                if (savehup != SIG_IGN)
        !           115:                        signal(SIGHUP, collhupsig);
        !           116: # endif VMUNIX
        !           117:                flush();
        !           118:                if (readline(stdin, linebuf) <= 0) {
        !           119:                        if (intty && value("ignoreeof") != NOSTR) {
        !           120:                                if (++eof > 35)
        !           121:                                        break;
        !           122:                                printf("Use \".\" to terminate letter\n",
        !           123:                                    escape);
        !           124:                                continue;
        !           125:                        }
        !           126:                        break;
        !           127:                }
        !           128:                eof = 0;
        !           129:                hadintr = 0;
        !           130:                if (intty && equal(".", linebuf) &&
        !           131:                    (value("dot") != NOSTR || value("ignoreeof") != NOSTR))
        !           132:                        break;
        !           133:                if (linebuf[0] != escape || rflag != NOSTR) {
        !           134:                        if ((t = putline(obuf, linebuf)) < 0)
        !           135:                                goto err;
        !           136:                        continue;
        !           137:                }
        !           138:                c = linebuf[1];
        !           139:                switch (c) {
        !           140:                default:
        !           141:                        /*
        !           142:                         * On double escape, just send the single one.
        !           143:                         * Otherwise, it's an error.
        !           144:                         */
        !           145: 
        !           146:                        if (c == escape) {
        !           147:                                if (putline(obuf, &linebuf[1]) < 0)
        !           148:                                        goto err;
        !           149:                                else
        !           150:                                        break;
        !           151:                        }
        !           152:                        printf("Unknown tilde escape.\n");
        !           153:                        break;
        !           154: 
        !           155:                case 'C':
        !           156:                        /*
        !           157:                         * Dump core.
        !           158:                         */
        !           159: 
        !           160:                        core();
        !           161:                        break;
        !           162: 
        !           163:                case '!':
        !           164:                        /*
        !           165:                         * Shell escape, send the balance of the
        !           166:                         * line to sh -c.
        !           167:                         */
        !           168: 
        !           169:                        shell(&linebuf[2]);
        !           170:                        break;
        !           171: 
        !           172:                case ':':
        !           173:                case '_':
        !           174:                        /*
        !           175:                         * Escape to command mode, but be nice!
        !           176:                         */
        !           177: 
        !           178:                        execute(&linebuf[2], 1);
        !           179:                        printf("(continue)\n");
        !           180:                        break;
        !           181: 
        !           182:                case '.':
        !           183:                        /*
        !           184:                         * Simulate end of file on input.
        !           185:                         */
        !           186:                        goto eofl;
        !           187: 
        !           188:                case 'q':
        !           189:                case 'Q':
        !           190:                        /*
        !           191:                         * Force a quit of sending mail.
        !           192:                         * Act like an interrupt happened.
        !           193:                         */
        !           194: 
        !           195:                        hadintr++;
        !           196:                        collrub(SIGINT);
        !           197:                        exit(1);
        !           198: 
        !           199:                case 'h':
        !           200:                        /*
        !           201:                         * Grab a bunch of headers.
        !           202:                         */
        !           203:                        if (!intty || !outtty) {
        !           204:                                printf("~h: no can do!?\n");
        !           205:                                break;
        !           206:                        }
        !           207:                        grabh(hp, GTO|GSUBJECT|GCC|GBCC);
        !           208:                        printf("(continue)\n");
        !           209:                        break;
        !           210: 
        !           211:                case 't':
        !           212:                        /*
        !           213:                         * Add to the To list.
        !           214:                         */
        !           215: 
        !           216:                        hp->h_to = addto(hp->h_to, &linebuf[2]);
        !           217:                        hp->h_seq++;
        !           218:                        break;
        !           219: 
        !           220:                case 's':
        !           221:                        /*
        !           222:                         * Set the Subject list.
        !           223:                         */
        !           224: 
        !           225:                        cp = &linebuf[2];
        !           226:                        while (any(*cp, " \t"))
        !           227:                                cp++;
        !           228:                        hp->h_subject = savestr(cp);
        !           229:                        hp->h_seq++;
        !           230:                        break;
        !           231: 
        !           232:                case 'c':
        !           233:                        /*
        !           234:                         * Add to the CC list.
        !           235:                         */
        !           236: 
        !           237:                        hp->h_cc = addto(hp->h_cc, &linebuf[2]);
        !           238:                        hp->h_seq++;
        !           239:                        break;
        !           240: 
        !           241:                case 'b':
        !           242:                        /*
        !           243:                         * Add stuff to blind carbon copies list.
        !           244:                         */
        !           245:                        hp->h_bcc = addto(hp->h_bcc, &linebuf[2]);
        !           246:                        hp->h_seq++;
        !           247:                        break;
        !           248: 
        !           249:                case 'd':
        !           250:                        copy(deadletter, &linebuf[2]);
        !           251:                        /* fall into . . . */
        !           252: 
        !           253:                case 'r':
        !           254:                        /*
        !           255:                         * Invoke a file:
        !           256:                         * Search for the file name,
        !           257:                         * then open it and copy the contents to obuf.
        !           258:                         */
        !           259: 
        !           260:                        cp = &linebuf[2];
        !           261:                        while (any(*cp, " \t"))
        !           262:                                cp++;
        !           263:                        if (*cp == '\0') {
        !           264:                                printf("Interpolate what file?\n");
        !           265:                                break;
        !           266:                        }
        !           267:                        cp = expand(cp);
        !           268:                        if (cp == NOSTR)
        !           269:                                break;
        !           270:                        if (isdir(cp)) {
        !           271:                                printf("%s: directory\n");
        !           272:                                break;
        !           273:                        }
        !           274:                        if ((fbuf = fopen(cp, "r")) == NULL) {
        !           275:                                perror(cp);
        !           276:                                break;
        !           277:                        }
        !           278:                        printf("\"%s\" ", cp);
        !           279:                        flush();
        !           280:                        lc = 0;
        !           281:                        cc = 0;
        !           282:                        while (readline(fbuf, linebuf) > 0) {
        !           283:                                lc++;
        !           284:                                if ((t = putline(obuf, linebuf)) < 0) {
        !           285:                                        fclose(fbuf);
        !           286:                                        goto err;
        !           287:                                }
        !           288:                                cc += t;
        !           289:                        }
        !           290:                        fclose(fbuf);
        !           291:                        printf("%d/%d\n", lc, cc);
        !           292:                        break;
        !           293: 
        !           294:                case 'w':
        !           295:                        /*
        !           296:                         * Write the message on a file.
        !           297:                         */
        !           298: 
        !           299:                        cp = &linebuf[2];
        !           300:                        while (any(*cp, " \t"))
        !           301:                                cp++;
        !           302:                        if (*cp == '\0') {
        !           303:                                fprintf(stderr, "Write what file!?\n");
        !           304:                                break;
        !           305:                        }
        !           306:                        if ((cp = expand(cp)) == NOSTR)
        !           307:                                break;
        !           308:                        fflush(obuf);
        !           309:                        rewind(ibuf);
        !           310:                        exwrite(cp, ibuf, 1);
        !           311:                        break;
        !           312: 
        !           313:                case 'm':
        !           314:                case 'f':
        !           315:                        /*
        !           316:                         * Interpolate the named messages, if we
        !           317:                         * are in receiving mail mode.  Does the
        !           318:                         * standard list processing garbage.
        !           319:                         * If ~f is given, we don't shift over.
        !           320:                         */
        !           321: 
        !           322:                        if (!rcvmode) {
        !           323:                                printf("No messages to send from!?!\n");
        !           324:                                break;
        !           325:                        }
        !           326:                        cp = &linebuf[2];
        !           327:                        while (any(*cp, " \t"))
        !           328:                                cp++;
        !           329:                        if (forward(cp, obuf, c) < 0)
        !           330:                                goto err;
        !           331:                        printf("(continue)\n");
        !           332:                        break;
        !           333: 
        !           334:                case '?':
        !           335:                        if ((fbuf = fopen(THELPFILE, "r")) == NULL) {
        !           336:                                perror(THELPFILE);
        !           337:                                break;
        !           338:                        }
        !           339:                        t = getc(fbuf);
        !           340:                        while (t != -1) {
        !           341:                                putchar(t);
        !           342:                                t = getc(fbuf);
        !           343:                        }
        !           344:                        fclose(fbuf);
        !           345:                        break;
        !           346: 
        !           347:                case 'p':
        !           348:                        /*
        !           349:                         * Print out the current state of the
        !           350:                         * message without altering anything.
        !           351:                         */
        !           352: 
        !           353:                        fflush(obuf);
        !           354:                        rewind(ibuf);
        !           355:                        printf("-------\nMessage contains:\n");
        !           356:                        puthead(hp, stdout, GTO|GSUBJECT|GCC|GBCC|GNL);
        !           357:                        t = getc(ibuf);
        !           358:                        while (t != EOF) {
        !           359:                                putchar(t);
        !           360:                                t = getc(ibuf);
        !           361:                        }
        !           362:                        printf("(continue)\n");
        !           363:                        break;
        !           364: 
        !           365:                case '^':
        !           366:                case '|':
        !           367:                        /*
        !           368:                         * Pipe message through command.
        !           369:                         * Collect output as new message.
        !           370:                         */
        !           371: 
        !           372:                        obuf = mespipe(ibuf, obuf, &linebuf[2]);
        !           373:                        newo = obuf;
        !           374:                        ibuf = newi;
        !           375:                        newi = ibuf;
        !           376:                        printf("(continue)\n");
        !           377:                        break;
        !           378: 
        !           379:                case 'v':
        !           380:                case 'e':
        !           381:                        /*
        !           382:                         * Edit the current message.
        !           383:                         * 'e' means to use EDITOR
        !           384:                         * 'v' means to use VISUAL
        !           385:                         */
        !           386: 
        !           387:                        if ((obuf = mesedit(ibuf, obuf, c)) == NULL)
        !           388:                                goto err;
        !           389:                        newo = obuf;
        !           390:                        ibuf = newi;
        !           391:                        printf("(continue)\n");
        !           392:                        break;
        !           393:                        break;
        !           394:                }
        !           395:        }
        !           396: eofl:
        !           397:        fclose(obuf);
        !           398:        rewind(ibuf);
        !           399:        sigset(SIGINT, savesig);
        !           400:        sigset(SIGHUP, savehup);
        !           401: # ifdef VMUNIX
        !           402:        sigset(SIGCONT, savecont);
        !           403:        sigsetmask(0);
        !           404: # endif VMUNIX
        !           405:        noreset = 0;
        !           406:        return(ibuf);
        !           407: 
        !           408: err:
        !           409:        if (ibuf != NULL)
        !           410:                fclose(ibuf);
        !           411:        if (obuf != NULL)
        !           412:                fclose(obuf);
        !           413:        sigset(SIGINT, savesig);
        !           414:        sigset(SIGHUP, savehup);
        !           415: # ifdef VMUNIX
        !           416:        sigset(SIGCONT, savecont);
        !           417:        sigsetmask(0);
        !           418: # endif VMUNIX
        !           419:        noreset = 0;
        !           420:        return(NULL);
        !           421: }
        !           422: 
        !           423: /*
        !           424:  * Non destructively interrogate the value of the given signal.
        !           425:  */
        !           426: 
        !           427: psig(n)
        !           428: {
        !           429:        register (*wassig)();
        !           430: 
        !           431:        wassig = sigset(n, SIG_IGN);
        !           432:        sigset(n, wassig);
        !           433:        return((int) wassig);
        !           434: }
        !           435: 
        !           436: /*
        !           437:  * Write a file, ex-like if f set.
        !           438:  */
        !           439: 
        !           440: exwrite(name, ibuf, f)
        !           441:        char name[];
        !           442:        FILE *ibuf;
        !           443: {
        !           444:        register FILE *of;
        !           445:        register int c;
        !           446:        long cc;
        !           447:        int lc;
        !           448:        struct stat junk;
        !           449: 
        !           450:        if (f) {
        !           451:                printf("\"%s\" ", name);
        !           452:                fflush(stdout);
        !           453:        }
        !           454:        if (stat(name, &junk) >= 0 && (junk.st_mode & S_IFMT) == S_IFREG) {
        !           455:                if (!f)
        !           456:                        fprintf(stderr, "%s: ", name);
        !           457:                fprintf(stderr, "File exists\n", name);
        !           458:                return(-1);
        !           459:        }
        !           460:        if ((of = fopen(name, "w")) == NULL) {
        !           461:                perror(NOSTR);
        !           462:                return(-1);
        !           463:        }
        !           464:        lc = 0;
        !           465:        cc = 0;
        !           466:        while ((c = getc(ibuf)) != EOF) {
        !           467:                cc++;
        !           468:                if (c == '\n')
        !           469:                        lc++;
        !           470:                putc(c, of);
        !           471:                if (ferror(of)) {
        !           472:                        perror(name);
        !           473:                        fclose(of);
        !           474:                        return(-1);
        !           475:                }
        !           476:        }
        !           477:        fclose(of);
        !           478:        printf("%d/%ld\n", lc, cc);
        !           479:        fflush(stdout);
        !           480:        return(0);
        !           481: }
        !           482: 
        !           483: /*
        !           484:  * Edit the message being collected on ibuf and obuf.
        !           485:  * Write the message out onto some poorly-named temp file
        !           486:  * and point an editor at it.
        !           487:  *
        !           488:  * On return, make the edit file the new temp file.
        !           489:  */
        !           490: 
        !           491: FILE *
        !           492: mesedit(ibuf, obuf, c)
        !           493:        FILE *ibuf, *obuf;
        !           494: {
        !           495:        int pid, s;
        !           496:        FILE *fbuf;
        !           497:        register int t;
        !           498:        int (*sig)(), (*scont)(), signull();
        !           499:        struct stat sbuf;
        !           500:        extern char tempMail[], tempEdit[];
        !           501:        register char *edit;
        !           502: 
        !           503:        sig = sigset(SIGINT, SIG_IGN);
        !           504: # ifdef VMUNIX
        !           505:        scont = sigset(SIGCONT, signull);
        !           506: # endif VMUNIX
        !           507:        if (stat(tempEdit, &sbuf) >= 0) {
        !           508:                printf("%s: file exists\n", tempEdit);
        !           509:                goto out;
        !           510:        }
        !           511:        close(creat(tempEdit, 0600));
        !           512:        if ((fbuf = fopen(tempEdit, "w")) == NULL) {
        !           513:                perror(tempEdit);
        !           514:                goto out;
        !           515:        }
        !           516:        fflush(obuf);
        !           517:        rewind(ibuf);
        !           518:        t = getc(ibuf);
        !           519:        while (t != EOF) {
        !           520:                putc(t, fbuf);
        !           521:                t = getc(ibuf);
        !           522:        }
        !           523:        fflush(fbuf);
        !           524:        if (ferror(fbuf)) {
        !           525:                perror(tempEdit);
        !           526:                remove(tempEdit);
        !           527:                goto fix;
        !           528:        }
        !           529:        fclose(fbuf);
        !           530:        if ((edit = value(c == 'e' ? "EDITOR" : "VISUAL")) == NOSTR)
        !           531:                edit = c == 'e' ? EDITOR : VISUAL;
        !           532:        pid = vfork();
        !           533:        if (pid == 0) {
        !           534:                sigchild();
        !           535:                if (sig != SIG_IGN)
        !           536:                        sigsys(SIGINT, SIG_DFL);
        !           537:                execl(edit, edit, tempEdit, 0);
        !           538:                perror(edit);
        !           539:                _exit(1);
        !           540:        }
        !           541:        if (pid == -1) {
        !           542:                perror("fork");
        !           543:                remove(tempEdit);
        !           544:                goto out;
        !           545:        }
        !           546:        while (wait(&s) != pid)
        !           547:                ;
        !           548:        if ((s & 0377) != 0) {
        !           549:                printf("Fatal error in \"%s\"\n", edit);
        !           550:                remove(tempEdit);
        !           551:                goto out;
        !           552:        }
        !           553: 
        !           554:        /*
        !           555:         * Now switch to new file.
        !           556:         */
        !           557: 
        !           558:        if ((fbuf = fopen(tempEdit, "a")) == NULL) {
        !           559:                perror(tempEdit);
        !           560:                remove(tempEdit);
        !           561:                goto out;
        !           562:        }
        !           563:        if ((ibuf = fopen(tempEdit, "r")) == NULL) {
        !           564:                perror(tempEdit);
        !           565:                fclose(fbuf);
        !           566:                remove(tempEdit);
        !           567:                goto out;
        !           568:        }
        !           569:        remove(tempEdit);
        !           570:        fclose(obuf);
        !           571:        fclose(newi);
        !           572:        obuf = fbuf;
        !           573:        goto out;
        !           574: fix:
        !           575:        perror(tempEdit);
        !           576: out:
        !           577: # ifdef VMUNIX
        !           578:        sigset(SIGCONT, scont);
        !           579: # endif VMUNIX
        !           580:        sigset(SIGINT, sig);
        !           581:        newi = ibuf;
        !           582:        return(obuf);
        !           583: }
        !           584: 
        !           585: /*
        !           586:  * Pipe the message through the command.
        !           587:  * Old message is on stdin of command;
        !           588:  * New message collected from stdout.
        !           589:  * Sh -c must return 0 to accept the new message.
        !           590:  */
        !           591: 
        !           592: FILE *
        !           593: mespipe(ibuf, obuf, cmd)
        !           594:        FILE *ibuf, *obuf;
        !           595:        char cmd[];
        !           596: {
        !           597:        register FILE *ni, *no;
        !           598:        int pid, s;
        !           599:        int (*savesig)();
        !           600:        char *Shell;
        !           601: 
        !           602:        newi = ibuf;
        !           603:        if ((no = fopen(tempEdit, "w")) == NULL) {
        !           604:                perror(tempEdit);
        !           605:                return(obuf);
        !           606:        }
        !           607:        if ((ni = fopen(tempEdit, "r")) == NULL) {
        !           608:                perror(tempEdit);
        !           609:                fclose(no);
        !           610:                remove(tempEdit);
        !           611:                return(obuf);
        !           612:        }
        !           613:        remove(tempEdit);
        !           614:        savesig = sigset(SIGINT, SIG_IGN);
        !           615:        fflush(obuf);
        !           616:        rewind(ibuf);
        !           617:        if ((Shell = value("SHELL")) == NULL)
        !           618:                Shell = "/bin/sh";
        !           619:        if ((pid = vfork()) == -1) {
        !           620:                perror("fork");
        !           621:                goto err;
        !           622:        }
        !           623:        if (pid == 0) {
        !           624:                /*
        !           625:                 * stdin = current message.
        !           626:                 * stdout = new message.
        !           627:                 */
        !           628: 
        !           629:                sigchild();
        !           630:                close(0);
        !           631:                dup(fileno(ibuf));
        !           632:                close(1);
        !           633:                dup(fileno(no));
        !           634:                for (s = 4; s < 15; s++)
        !           635:                        close(s);
        !           636:                execl(Shell, Shell, "-c", cmd, 0);
        !           637:                perror(Shell);
        !           638:                _exit(1);
        !           639:        }
        !           640:        while (wait(&s) != pid)
        !           641:                ;
        !           642:        if (s != 0 || pid == -1) {
        !           643:                fprintf(stderr, "\"%s\" failed!?\n", cmd);
        !           644:                goto err;
        !           645:        }
        !           646:        if (fsize(ni) == 0) {
        !           647:                fprintf(stderr, "No bytes from \"%s\" !?\n", cmd);
        !           648:                goto err;
        !           649:        }
        !           650: 
        !           651:        /*
        !           652:         * Take new files.
        !           653:         */
        !           654: 
        !           655:        newi = ni;
        !           656:        fclose(ibuf);
        !           657:        fclose(obuf);
        !           658:        sigset(SIGINT, savesig);
        !           659:        return(no);
        !           660: 
        !           661: err:
        !           662:        fclose(no);
        !           663:        fclose(ni);
        !           664:        sigset(SIGINT, savesig);
        !           665:        return(obuf);
        !           666: }
        !           667: 
        !           668: /*
        !           669:  * Interpolate the named messages into the current
        !           670:  * message, preceding each line with a tab.
        !           671:  * Return a count of the number of characters now in
        !           672:  * the message, or -1 if an error is encountered writing
        !           673:  * the message temporary.  The flag argument is 'm' if we
        !           674:  * should shift over and 'f' if not.
        !           675:  */
        !           676: forward(ms, obuf, f)
        !           677:        char ms[];
        !           678:        FILE *obuf;
        !           679: {
        !           680:        register int *msgvec, *ip;
        !           681:        extern char tempMail[];
        !           682: 
        !           683:        msgvec = (int *) salloc((msgCount+1) * sizeof *msgvec);
        !           684:        if (msgvec == (int *) NOSTR)
        !           685:                return(0);
        !           686:        if (getmsglist(ms, msgvec, 0) < 0)
        !           687:                return(0);
        !           688:        if (*msgvec == NULL) {
        !           689:                *msgvec = first(0, MMNORM);
        !           690:                if (*msgvec == NULL) {
        !           691:                        printf("No appropriate messages\n");
        !           692:                        return(0);
        !           693:                }
        !           694:                msgvec[1] = NULL;
        !           695:        }
        !           696:        printf("Interpolating:");
        !           697:        for (ip = msgvec; *ip != NULL; ip++) {
        !           698:                touch(*ip);
        !           699:                printf(" %d", *ip);
        !           700:                if (f == 'm') {
        !           701:                        if (transmit(&message[*ip-1], obuf) < 0L) {
        !           702:                                perror(tempMail);
        !           703:                                return(-1);
        !           704:                        }
        !           705:                } else
        !           706:                        if (send(&message[*ip-1], obuf, 0) < 0) {
        !           707:                                perror(tempMail);
        !           708:                                return(-1);
        !           709:                        }
        !           710:        }
        !           711:        printf("\n");
        !           712:        return(0);
        !           713: }
        !           714: 
        !           715: /*
        !           716:  * Send message described by the passed pointer to the
        !           717:  * passed output buffer.  Insert a tab in front of each
        !           718:  * line.  Return a count of the characters sent, or -1
        !           719:  * on error.
        !           720:  */
        !           721: 
        !           722: long
        !           723: transmit(mailp, obuf)
        !           724:        struct message *mailp;
        !           725:        FILE *obuf;
        !           726: {
        !           727:        register struct message *mp;
        !           728:        register int ch;
        !           729:        long c, n;
        !           730:        int bol;
        !           731:        FILE *ibuf;
        !           732: 
        !           733:        mp = mailp;
        !           734:        ibuf = setinput(mp);
        !           735:        c = mp->m_size;
        !           736:        n = c;
        !           737:        bol = 1;
        !           738:        while (c-- > 0L) {
        !           739:                if (bol) {
        !           740:                        bol = 0;
        !           741:                        putc('\t', obuf);
        !           742:                        n++;
        !           743:                        if (ferror(obuf)) {
        !           744:                                perror("/tmp");
        !           745:                                return(-1L);
        !           746:                        }
        !           747:                }
        !           748:                ch = getc(ibuf);
        !           749:                if (ch == '\n')
        !           750:                        bol++;
        !           751:                putc(ch, obuf);
        !           752:                if (ferror(obuf)) {
        !           753:                        perror("/tmp");
        !           754:                        return(-1L);
        !           755:                }
        !           756:        }
        !           757:        return(n);
        !           758: }
        !           759: 
        !           760: /*
        !           761:  * Print (continue) when continued after ^Z.
        !           762:  */
        !           763: collcont(s)
        !           764: {
        !           765: 
        !           766:        printf("(continue)\n");
        !           767:        fflush(stdout);
        !           768: }
        !           769: 
        !           770: /*
        !           771:  * On interrupt, go here to save the partial
        !           772:  * message on ~/dead.letter.
        !           773:  * Then restore signals and execute the normal
        !           774:  * signal routine.  We only come here if signals
        !           775:  * were previously set anyway.
        !           776:  */
        !           777: 
        !           778: # ifndef VMUNIX
        !           779: collintsig()
        !           780: {
        !           781:        signal(SIGINT, SIG_IGN);
        !           782:        collrub(SIGINT);
        !           783: }
        !           784: 
        !           785: collhupsig()
        !           786: {
        !           787:        signal(SIGHUP, SIG_IGN);
        !           788:        collrub(SIGHUP);
        !           789: }
        !           790: # endif VMUNIX
        !           791: 
        !           792: collrub(s)
        !           793: {
        !           794:        register FILE *dbuf;
        !           795:        register int c;
        !           796: 
        !           797:        if (s == SIGINT && hadintr == 0) {
        !           798:                hadintr++;
        !           799:                clrbuf(stdout);
        !           800:                printf("\n(Interrupt -- one more to kill letter)\n");
        !           801:                longjmp(coljmp, 1);
        !           802:        }
        !           803:        fclose(newo);
        !           804:        rewind(newi);
        !           805:        if (s == SIGINT && value("nosave") != NOSTR || fsize(newi) == 0)
        !           806:                goto done;
        !           807:        if ((dbuf = fopen(deadletter, "w")) == NULL)
        !           808:                goto done;
        !           809:        chmod(deadletter, 0600);
        !           810:        while ((c = getc(newi)) != EOF)
        !           811:                putc(c, dbuf);
        !           812:        fclose(dbuf);
        !           813: 
        !           814: done:
        !           815:        fclose(newi);
        !           816:        sigset(SIGINT, savesig);
        !           817:        sigset(SIGHUP, savehup);
        !           818: # ifdef VMUNIX
        !           819:        sigset(SIGCONT, savecont);
        !           820: # endif VMUNIX
        !           821:        if (rcvmode) {
        !           822:                if (s == SIGHUP)
        !           823:                        hangup(SIGHUP);
        !           824:                else
        !           825:                        stop(s);
        !           826:        }
        !           827:        else
        !           828:                exit(1);
        !           829: }
        !           830: 
        !           831: /*
        !           832:  * Acknowledge an interrupt signal from the tty by typing an @
        !           833:  */
        !           834: 
        !           835: intack(s)
        !           836: {
        !           837:        
        !           838:        puts("@");
        !           839:        fflush(stdout);
        !           840:        clearerr(stdin);
        !           841: }
        !           842: 
        !           843: /*
        !           844:  * Add a string to the end of a header entry field.
        !           845:  */
        !           846: 
        !           847: char *
        !           848: addto(hf, news)
        !           849:        char hf[], news[];
        !           850: {
        !           851:        register char *cp, *cp2, *linebuf;
        !           852: 
        !           853:        if (hf == NOSTR)
        !           854:                hf = "";
        !           855:        if (*news == '\0')
        !           856:                return(hf);
        !           857:        linebuf = salloc(strlen(hf) + strlen(news) + 2);
        !           858:        for (cp = hf; any(*cp, " \t"); cp++)
        !           859:                ;
        !           860:        for (cp2 = linebuf; *cp;)
        !           861:                *cp2++ = *cp++;
        !           862:        *cp2++ = ' ';
        !           863:        for (cp = news; any(*cp, " \t"); cp++)
        !           864:                ;
        !           865:        while (*cp != '\0')
        !           866:                *cp2++ = *cp++;
        !           867:        *cp2 = '\0';
        !           868:        return(linebuf);
        !           869: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.