Annotation of 43BSDTahoe/ucb/Mail/collect.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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