Annotation of 3BSD/cmd/ucbmail/collect.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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