Annotation of 43BSD/contrib/mh/uip/mhlsbr.c, revision 1.1.1.1

1.1       root        1: /* mhlsbr.c - implement the "nifty" message lister */
                      2: 
                      3: #include "../h/mh.h"
                      4: #include "../h/addrsbr.h"
                      5: #include "../h/formatsbr.h"
                      6: #include "../zotnet/tws.h"
                      7: #include <ctype.h>
                      8: #include <setjmp.h>
                      9: #include <signal.h>
                     10: #include <stdio.h>
                     11: #include <sys/types.h>
                     12: #include <sys/stat.h>
                     13: 
                     14: 
                     15: /* MAJOR BUG:
                     16:    for a component containing addresses, ADDRFMT, if COMPRESS is also
                     17:    set, then addresses get split wrong (not at the spaces between commas).
                     18:    To fix this correctly, putstr() should know about "atomic" strings that
                     19:    must NOT be broken across lines.  That's too difficult for right now
                     20:    (it turns out that there are a number of degernate cases), so in
                     21:    oneline(), instead of
                     22: 
                     23:                     (*onelp == '\n' && !onelp[1])
                     24: 
                     25:    being a terminating condition,
                     26: 
                     27:         (*onelp == '\n' && (!onelp[1] || (flags & ADDRFMT)))
                     28: 
                     29:    is used instead.  This cuts the line prematurely, and gives us a much
                     30:    better chance of getting things right.
                     31:  */
                     32: 
                     33: 
                     34: #define ONECOMP        0
                     35: #define TWOCOMP        1
                     36: 
                     37: #define        adios   mhladios
                     38: #define        done    mhldone
                     39: 
                     40: #define        QUOTE   '\\'
                     41: 
                     42: /*  */
                     43: 
                     44: static struct swit mhlswitches[] = {
                     45: #define        BELLSW  0
                     46:     "bell", 0,
                     47: #define        NBELLSW 1
                     48:     "nobell", 0,
                     49: 
                     50: #define        CLRSW   2
                     51:     "clear", 0,
                     52: #define        NCLRSW  3
                     53:     "noclear", 0,
                     54: 
                     55: #define        FOLDSW  4
                     56:     "folder +folder", 0,
                     57: #define        FORMSW  5
                     58:     "form formfile", 0,
                     59: 
                     60: #define        PROGSW  6
                     61:     "moreproc program", 0,
                     62: #define        NPROGSW 7
                     63:     "nomoreproc", 0,
                     64: 
                     65: #define        LENSW   8
                     66:     "length lines", 0,
                     67: #define        WIDSW   9
                     68:     "width columns", 0,
                     69: 
                     70: #define        HELPSW  10
                     71:     "help", 4,
                     72: 
                     73: #define        FORW1SW 11
                     74:     "forward", -7,             /* interface from forw */
                     75: #define        FORW2SW 12
                     76:     "forwall", -7,             /*   .. */
                     77: #define        DGSTSW  13
                     78:     "digest list", -6,
                     79: 
                     80:     NULL, NULL
                     81: };
                     82: 
                     83: /*  */
                     84: 
                     85: struct mcomp {
                     86:     char   *c_name;            /* component name                       */
                     87:     char   *c_text;            /* component text                       */
                     88:     char   *c_ovtxt;           /* text overflow indicator              */
                     89:     char   *c_nfs;             /* iff FORMAT                           */
                     90:     struct format *c_fmt;      /*   ..                                 */
                     91: 
                     92:     int     c_offset;          /* left margin indentation              */
                     93:     int     c_ovoff;           /* overflow indentation                 */
                     94:     int     c_width;           /* width of field                       */
                     95:     int     c_cwidth;          /* width of component                   */
                     96:     int     c_length;          /* length in lines                      */
                     97:        
                     98:     short   c_flags;
                     99: #define NOCOMPONENT    0x0001  /* don't show component name            */
                    100: #define UPPERCASE       0x0002 /* display in all upper case            */
                    101: #define CENTER          0x0004 /* center line                          */
                    102: #define CLEARTEXT       0x0008 /* cleartext                            */
                    103: #define EXTRA          0x0010  /* an "extra" component                 */
                    104: #define HDROUTPUT      0x0020  /* already output                       */
                    105: #define CLEARSCR       0x0040  /* clear screen                         */
                    106: #define LEFTADJUST     0x0080  /* left justify multiple lines          */
                    107: #define COMPRESS       0x0100  /* compress text                        */
                    108: #define        ADDRFMT         0x0200  /* contains addresses                   */
                    109: #define        BELL            0x0400  /* sound bell at EOP                    */
                    110: #define        DATEFMT         0x0800  /* contains dates                       */
                    111: #define        FORMAT          0x1000  /* parse address/date                   */
                    112: #define        INIT            0x2000
                    113: #define        LBITS   "\020\01NOCOMPONENT\02UPPERCASE\03CENTER\04CLEARTEXT\05EXTRA\06HDROUTPUT\07CLEARSCR\010LEFTADJUST\011COMPRESS\012ADDRFMT\013BELL\014DATEFMT\015FORMAT\016INIT"
                    114: #define        GFLAGS  (NOCOMPONENT | UPPERCASE | CENTER | LEFTADJUST | COMPRESS)
                    115: 
                    116:     struct mcomp *c_next;
                    117: };
                    118: 
                    119: static struct mcomp *msghd = NULL;
                    120: static struct mcomp *msgtl = NULL;
                    121: static struct mcomp *fmthd = NULL;
                    122: static struct mcomp *fmttl = NULL;
                    123: 
                    124: static struct mcomp global = {
                    125:     NULL, NULL, "", NULL, NULL, 0, -1, 80, -1, 40, BELL, NULL
                    126: };
                    127: static struct mcomp  holder =
                    128: {
                    129:     NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0, NOCOMPONENT, NULL
                    130: };
                    131: 
                    132: 
                    133: static struct pair {
                    134:     char   *p_name;
                    135:     short   p_flags;
                    136: }                   pairs[] = {
                    137:                        "Date", DATEFMT,
                    138:                         "From", ADDRFMT,
                    139:                         "Sender", ADDRFMT,
                    140:                         "Reply-To", ADDRFMT,
                    141:                         "To", ADDRFMT,
                    142:                         "cc", ADDRFMT,
                    143:                         "Bcc", ADDRFMT,
                    144:                        "Resent-Date", DATEFMT,
                    145:                         "Resent-From", ADDRFMT,
                    146:                         "Resent-Sender", ADDRFMT,
                    147:                         "Resent-Reply-To", ADDRFMT,
                    148:                         "Resent-To", ADDRFMT,
                    149:                         "Resent-cc", ADDRFMT,
                    150:                         "Resent-Bcc", ADDRFMT,
                    151: 
                    152:                         NULL
                    153: };
                    154: 
                    155: static struct triple {
                    156:     char   *t_name;
                    157:     short   t_on;
                    158:     short   t_off;
                    159: }                       triples[] = {
                    160:                            "nocomponent", NOCOMPONENT, 0,
                    161:                             "uppercase", UPPERCASE, 0,
                    162:                             "nouppercase", 0, UPPERCASE,
                    163:                             "center", CENTER, 0,
                    164:                             "nocenter", 0, CENTER,
                    165:                             "clearscreen", CLEARSCR, 0,
                    166:                             "noclearscreen", 0, CLEARSCR,
                    167:                             "noclear", 0, CLEARSCR,
                    168:                             "leftadjust", LEFTADJUST, 0,
                    169:                             "noleftadjust", 0, LEFTADJUST,
                    170:                             "compress", COMPRESS, 0,
                    171:                             "nocompress", 0, COMPRESS,
                    172:                             "addrfield", ADDRFMT, DATEFMT,
                    173:                             "bell", BELL, 0,
                    174:                             "nobell", 0, BELL,
                    175:                             "datefield", DATEFMT, ADDRFMT,
                    176: 
                    177:                             NULL
                    178: };
                    179: 
                    180: /*  */
                    181: 
                    182: static int  bellflg = 0;
                    183: static int  clearflg = 0;
                    184: static int  forwflg = 0;
                    185: static int  forwall = 0;
                    186: 
                    187: static char *digest = NULL;
                    188: 
                    189: static int  exitstat = 0;
                    190: static int  mhldebug = 0;
                    191: 
                    192: #define        PITTY   (-1)
                    193: #define        NOTTY   0
                    194: #define        ISTTY   1
                    195: static int  ontty = NOTTY;
                    196: 
                    197: static int  row;
                    198: static int  column;
                    199: 
                    200: static int  lm;
                    201: static int  llim;
                    202: static int  ovoff;
                    203: static int  term;
                    204: static int  wid;
                    205: 
                    206: 
                    207: static char *ovtxt;
                    208: 
                    209: static char *onelp;
                    210: 
                    211: 
                    212: static char *parptr;
                    213: static char *ignores[MAXARGS];
                    214: 
                    215: 
                    216: static  jmp_buf env;
                    217: static  jmp_buf mhlenv;
                    218: 
                    219: 
                    220: static char delim3[] =         /* from forw.c */
                    221:     "\n------------------------------------------------------------\n\n";
                    222: static char delim4[] = "\n------------------------------\n\n";
                    223: 
                    224: 
                    225: static  FP (*mhl_action) () = (FP (*) ()) 0;
                    226: 
                    227: 
                    228: void   mhladios (), mhldone ();
                    229: int    intrser (), pipeser (), quitser ();
                    230: char   *mcomp_add (), *oneline (), *parse ();
                    231: struct mcomp *add_queue ();
                    232: 
                    233: 
                    234: void   clear_screen ();
                    235: 
                    236: /*  */
                    237: 
                    238: /* ARGSUSED */
                    239: 
                    240: int     mhl (argc, argv)
                    241: int     argc;
                    242: char   *argv[];
                    243: {
                    244:     int     length = 0,
                    245:            nomore = 0,
                    246:             width = 0,
                    247:             vecp = 0,
                    248:             i;
                    249:     register char   *cp,
                    250:                    *folder = NULL,
                    251:                    *form = NULL,
                    252:                    **ap,
                    253:                    **argp;
                    254:     char    buf[80],
                    255:            *arguments[MAXARGS],
                    256:            *files[MAXARGS];
                    257: 
                    258:     invo_name = r1bindex (argv[0], '/');
                    259:     if ((cp = getenv ("MHLDEBUG")) && *cp)
                    260:        mhldebug++;
                    261:     if ((cp = m_find (invo_name)) != NULL) {
                    262:        ap = brkstring (getcpy (cp), " ", "\n");
                    263:        ap = copyip (ap, arguments);
                    264:     }
                    265:     else
                    266:        ap = arguments;
                    267:     (void) copyip (argv + 1, ap);
                    268:     argp = arguments;
                    269: 
                    270: /*  */
                    271: 
                    272:     vecp = 0;
                    273:     while (cp = *argp++) {
                    274:        if (*cp == '-')
                    275:            switch (smatch (++cp, mhlswitches)) {
                    276:                case AMBIGSW:
                    277:                    ambigsw (cp, mhlswitches);
                    278:                    done (1);
                    279:                case UNKWNSW:
                    280:                    adios (NULLCP, "-%s unknown\n", cp);
                    281:                case HELPSW:
                    282:                    (void) sprintf (buf, "%s [switches] [files ...]",
                    283:                            invo_name);
                    284:                    help (buf, mhlswitches);
                    285:                    done (1);
                    286: 
                    287:                case BELLSW:
                    288:                    bellflg = 1;
                    289:                    continue;
                    290:                case NBELLSW:
                    291:                    bellflg = -1;
                    292:                    continue;
                    293: 
                    294:                case CLRSW:
                    295:                    clearflg = 1;
                    296:                    continue;
                    297:                case NCLRSW:
                    298:                    clearflg = -1;
                    299:                    continue;
                    300: 
                    301:                case FOLDSW:
                    302:                    if (!(folder = *argp++) || *folder == '-')
                    303:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    304:                    continue;
                    305:                case FORMSW:
                    306:                    if (!(form = *argp++) || *form == '-')
                    307:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    308:                    continue;
                    309: 
                    310:                case PROGSW:
                    311:                    if (!(moreproc = *argp++) || *moreproc == '-')
                    312:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    313:                    continue;
                    314:                case NPROGSW:
                    315:                    nomore++;
                    316:                    continue;
                    317: 
                    318:                case LENSW:
                    319:                    if (!(cp = *argp++) || *cp == '-')
                    320:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    321:                    if ((length = atoi (cp)) < 1)
                    322:                        adios (NULLCP, "bad argument %s %s", argp[-2], cp);
                    323:                    continue;
                    324:                case WIDSW:
                    325:                    if (!(cp = *argp++) || *cp == '-')
                    326:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    327:                    if ((width = atoi (cp)) < 1)
                    328:                        adios (NULLCP, "bad argument %s %s", argp[-2], cp);
                    329:                    continue;
                    330: 
                    331:                case DGSTSW:
                    332:                    if (!(digest = *argp++) || *digest == '-')
                    333:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    334:                case FORW2SW:
                    335:                    forwall++;  /* fall */
                    336:                case FORW1SW:
                    337:                    forwflg++;
                    338:                    clearflg = -1;/* XXX */
                    339:                    continue;
                    340:            }
                    341:        files[vecp++] = cp;
                    342:     }
                    343: 
                    344: /*  */
                    345: 
                    346:     if (!folder)
                    347:        folder = getenv ("mhfolder");
                    348: 
                    349:     if (isatty (fileno (stdout)))
                    350:        if (!nomore && moreproc && *moreproc) {
                    351:            if (mhl_action) {
                    352:                setsig (SIGINT, SIG_IGN);
                    353:                setsig (SIGQUIT, quitser);
                    354:            }
                    355:            m_popen (moreproc);
                    356:            ontty = PITTY;
                    357:        }
                    358:        else {
                    359:            setsig (SIGINT, SIG_IGN);
                    360:            setsig (SIGQUIT, quitser);
                    361:            ontty = ISTTY;
                    362:        }
                    363:     else
                    364:        ontty = NOTTY;
                    365: 
                    366:     mhl_format (form ? form : mhlformat, length, width);
                    367: 
                    368:     if (vecp == 0)
                    369:        process (folder, NULLCP, 1, vecp = 1);
                    370:     else
                    371:        for (i = 0; i < vecp; i++)
                    372:            process (folder, files[i], i + 1, vecp);
                    373: 
                    374:     if (forwall) {
                    375:        if (digest) {
                    376:            printf ("%s", delim4);
                    377:            (void) sprintf (buf, "End of %s Digest\n", digest);
                    378:            i = strlen (buf);
                    379:            for (cp = buf + i; i > 1; i--)
                    380:                *cp++ = '*';
                    381:            *cp++ = '\n';
                    382:            *cp = NULL;
                    383:            printf ("%s", buf);
                    384:        }
                    385:        else
                    386:            printf ("\n------- End of Forwarded Message%s\n\n",
                    387:                    vecp > 1 ? "s" : "");
                    388:     }
                    389: 
                    390:     if (clearflg > 0 && ontty == NOTTY)
                    391:        clear_screen ();
                    392: 
                    393:     if (ontty == PITTY)
                    394:        m_pclose ();
                    395: 
                    396:     return exitstat;
                    397: }
                    398: 
                    399: /*  */
                    400: 
                    401: static  mhl_format (file, length, width)
                    402: register char   *file;
                    403: int     length,
                    404:         width;
                    405: {
                    406:     int     i;
                    407:     register char  *bp,
                    408:                   *cp,
                    409:                   **ip;
                    410:     char   *ap,
                    411:            buffer[BUFSIZ],
                    412:             name[NAMESZ];
                    413:     register struct mcomp   *c1;
                    414:     struct stat st;
                    415:     register    FILE *fp;
                    416:     static  dev_t dev = 0;
                    417:     static  ino_t ino = 0;
                    418:     static  time_t mtime = 0;
                    419: 
                    420:     if (fmthd != NULL)
                    421:        if (stat (libpath (file), &st) != NOTOK
                    422:                && mtime == st.st_mtime
                    423:                && dev == st.st_dev
                    424:                && ino == st.st_ino)
                    425:            goto out;
                    426:        else
                    427:            free_queue (&fmthd, &fmttl);
                    428: 
                    429:     if ((fp = fopen (libpath (file), "r")) == NULL)
                    430:        adios (file, "unable to open format file");
                    431: 
                    432:     if (fstat (fileno (fp), &st) != NOTOK)
                    433:        mtime = st.st_mtime, dev = st.st_dev, ino = st.st_ino;
                    434: 
                    435:     global.c_ovtxt = global.c_nfs = NULL;
                    436:     global.c_fmt = NULL;
                    437:     global.c_offset = 0;
                    438:     global.c_ovoff = -1;
                    439:     if ((i = sc_width ()) > 5)
                    440:        global.c_width = i;
                    441:     global.c_cwidth = -1;
                    442:     if ((i = sc_length ()) > 5)
                    443:        global.c_length = i - 1;
                    444:     global.c_flags = BELL;             /* BELL is default */
                    445:     *(ip = ignores) = NULL;
                    446: 
                    447:     while (vfgets (fp, &ap) == OK) {
                    448:        bp = ap;
                    449:        if (*bp == ';')
                    450:            continue;
                    451: 
                    452:        if (cp = index (bp, '\n'))
                    453:            *cp = NULL;
                    454: 
                    455:        if (*bp == ':') {
                    456:            c1 = add_queue (&fmthd, &fmttl, NULLCP, bp + 1, CLEARTEXT);
                    457:            continue;
                    458:        }
                    459: 
                    460:        parptr = bp;
                    461:        (void) strcpy (name, parse ());
                    462:        switch (*parptr) {
                    463:            case '\0':
                    464:            case ',':
                    465:            case '=':
                    466:                if (uleq (name, "ignores")) {
                    467:                    ip = copyip (brkstring (getcpy (++parptr), ",", NULLCP), ip);
                    468:                    continue;
                    469:                }
                    470:                parptr = bp;
                    471:                while (*parptr) {
                    472:                    if (evalvar (&global))
                    473:                        adios (NULLCP, "format file syntax error: %s", bp);
                    474:                    if (*parptr)
                    475:                        parptr++;
                    476:                }
                    477:                continue;
                    478: 
                    479:            case ':':
                    480:                c1 = add_queue (&fmthd, &fmttl, name, NULLCP, INIT);
                    481:                while (*parptr == ':' || *parptr == ',') {
                    482:                    parptr++;
                    483:                    if (evalvar (c1))
                    484:                        adios (NULLCP, "format file syntax error: %s", bp);
                    485:                }
                    486:                if (!c1 -> c_nfs && global.c_nfs)
                    487:                    if (c1 -> c_flags & DATEFMT) {
                    488:                        if (global.c_flags & DATEFMT)
                    489:                            c1 -> c_nfs = getcpy (global.c_nfs);
                    490:                    }
                    491:                    else
                    492:                        if (c1 -> c_flags & ADDRFMT) {
                    493:                            if (global.c_flags & ADDRFMT)
                    494:                                c1 -> c_nfs = getcpy (global.c_nfs);
                    495:                        }
                    496:                continue;
                    497: 
                    498:            default:
                    499:                adios (NULLCP, "format file syntax error: %s", bp);
                    500:        }
                    501:     }
                    502:     (void) fclose (fp);
                    503: 
                    504:     if (mhldebug)
                    505:        for (c1 = fmthd; c1; c1 = c1 -> c_next) {
                    506:            fprintf (stderr, "c1: name=\"%s\" text=\"%s\" ovtxt=\"%s\"\n",
                    507:                    c1 -> c_name, c1 -> c_text, c1 -> c_ovtxt);
                    508:            fprintf (stderr, "\tnfs=0x%x fmt=0x%x\n",
                    509:                    c1 -> c_nfs, c1 -> c_fmt);
                    510:            fprintf (stderr, "\toffset=%d ovoff=%d width=%d cwidth=%d length=%d\n",
                    511:                    c1 -> c_offset, c1 -> c_ovoff, c1 -> c_width,
                    512:                    c1 -> c_cwidth, c1 -> c_length);
                    513:            fprintf (stderr, "\tflags=%s\n",
                    514:                    sprintb (buffer, (unsigned) c1 -> c_flags, LBITS));
                    515:        }
                    516: 
                    517: out: ;
                    518:     if (clearflg == 1)
                    519:        global.c_flags |= CLEARSCR;
                    520:     else
                    521:        if (clearflg == -1)
                    522:            global.c_flags &= ~CLEARSCR;
                    523: 
                    524:     switch (bellflg) {         /* command line may override format file */
                    525:        case 1:
                    526:            global.c_flags |= BELL;
                    527:            break;
                    528:        case -1:
                    529:            global.c_flags &= ~BELL;
                    530:            break;
                    531:     }
                    532: 
                    533:     if (length)
                    534:        global.c_length = length;
                    535:     if (width)
                    536:        global.c_width = width;
                    537:     if (global.c_length < 5)
                    538:        global.c_length = 10000;
                    539:     if (global.c_width < 5)
                    540:        global.c_width = 10000;
                    541: }
                    542: 
                    543: /*  */
                    544: 
                    545: static  evalvar (c1)
                    546: register struct mcomp *c1;
                    547: {
                    548:     char   *cp,
                    549:             name[NAMESZ];
                    550:     register struct triple *ap;
                    551: 
                    552:     if (!*parptr)
                    553:        return 0;
                    554:     (void) strcpy (name, parse ());
                    555: 
                    556:     if (uleq (name, "component")) {
                    557:        if (ptos (name, &c1 -> c_text))
                    558:            return 1;
                    559:        c1 -> c_flags &= ~NOCOMPONENT;
                    560:        return 0;
                    561:     }
                    562:     if (uleq (name, "overflowtext"))
                    563:        return ptos (name, &c1 -> c_ovtxt);
                    564:     if (uleq (name, "formatfield")) {
                    565:        if (ptos (name, &cp))
                    566:            return 1;
                    567:        c1 -> c_nfs = getcpy (new_fs (NULLCP, NULLCP, cp));
                    568:        c1 -> c_flags |= FORMAT;
                    569:        return 0;
                    570:     }
                    571: 
                    572:     if (uleq (name, "offset"))
                    573:        return ptoi (name, &c1 -> c_offset);
                    574:     if (uleq (name, "overflowoffset"))
                    575:        return ptoi (name, &c1 -> c_ovoff);
                    576:     if (uleq (name, "width"))
                    577:        return ptoi (name, &c1 -> c_width);
                    578:     if (uleq (name, "compwidth"))
                    579:        return ptoi (name, &c1 -> c_cwidth);
                    580:     if (uleq (name, "length"))
                    581:        return ptoi (name, &c1 -> c_length);
                    582: 
                    583:     for (ap = triples; ap -> t_name; ap++)
                    584:        if (uleq (ap -> t_name, name)) {
                    585:            c1 -> c_flags |= ap -> t_on;
                    586:            c1 -> c_flags &= ~ap -> t_off;
                    587:            return 0;
                    588:        }
                    589: 
                    590:     return 1;
                    591: }
                    592: 
                    593: /*  */
                    594: 
                    595: static int  ptoi (name, i)
                    596: register char  *name;
                    597: register int   *i;
                    598: {
                    599:     char   *cp;
                    600: 
                    601:     if (*parptr++ != '=' || !*(cp = parse ())) {
                    602:        advise (NULLCP, "missing argument to variable %s", name);
                    603:        return 1;
                    604:     }
                    605: 
                    606:     *i = atoi (cp);
                    607:     return 0;
                    608: }
                    609: 
                    610: 
                    611: static int  ptos (name, s)
                    612: register char  *name,
                    613:              **s;
                    614: {
                    615:     char    c,
                    616:            *cp;
                    617: 
                    618:     if (*parptr++ != '=') {
                    619:        advise (NULLCP, "missing argument to variable %s", name);
                    620:        return 1;
                    621:     }
                    622: 
                    623:     if (*parptr != '"')
                    624:        for (cp = parptr;
                    625:                *parptr && *parptr != ':' && *parptr != ',';
                    626:                parptr++)
                    627:            continue;
                    628:     else
                    629:        for (cp = ++parptr; *parptr && *parptr != '"'; parptr++)
                    630:            if (*parptr == QUOTE)
                    631:                if (!*++parptr)
                    632:                    parptr--;
                    633:     c = *parptr;
                    634:     *parptr = NULL;
                    635:     *s = getcpy (cp);
                    636:     if ((*parptr = c) == '"')
                    637:        parptr++;
                    638:     return 0;
                    639: }
                    640: 
                    641: /*  */
                    642: 
                    643: static char *parse () {
                    644:     int     c;
                    645:     register char   *cp;
                    646:     static char result[NAMESZ];
                    647: 
                    648:     for (cp = result; c = *parptr; parptr++)
                    649:        if (isalnum (c)
                    650:                || c == '.'
                    651:                || c == '-'
                    652:                || c == '_'
                    653:                || c =='['
                    654:                || c == ']')
                    655:            *cp++ = c;
                    656:        else
                    657:            break;
                    658:     *cp = NULL;
                    659: 
                    660:     return result;
                    661: }
                    662: 
                    663: /*  */
                    664: 
                    665: static  process (folder, fname, ofilen, ofilec)
                    666: register char   *folder,
                    667:                *fname;
                    668: int    ofilen,
                    669:        ofilec;
                    670: {
                    671:     register char  *cp;
                    672:     register struct mcomp  *c1;
                    673:     register FILE  *fp;
                    674: 
                    675:     switch (setjmp (env)) {
                    676:        case OK:
                    677:            if (fname) {
                    678:                fp = mhl_action ? (*mhl_action) (fname) : fopen (fname, "r");
                    679:                if (fp == NULL) {
                    680:                    advise (fname, "unable to open");
                    681:                    exitstat++;
                    682:                    return;
                    683:                }
                    684:            }
                    685:            else {
                    686:                fname = "(stdin)";
                    687:                fp = stdin;
                    688:            }
                    689:            cp = folder ? concat (folder, ":", fname, NULLCP) : getcpy (fname);
                    690:            if (ontty != PITTY)
                    691:                (void) signal (SIGINT, intrser);
                    692:            mhlfile (fp, cp, ofilen, ofilec);/* fall */
                    693: 
                    694:        default:
                    695:            if (ontty != PITTY)
                    696:                (void) signal (SIGINT, SIG_IGN);
                    697:            if (mhl_action == NULL && fp != stdin)
                    698:                (void) fclose (fp);
                    699:            free (cp);
                    700:            if (holder.c_text) {
                    701:                free (holder.c_text);
                    702:                holder.c_text = NULL;
                    703:            }
                    704:            free_queue (&msghd, &msgtl);
                    705:            for (c1 = fmthd; c1; c1 = c1 -> c_next)
                    706:                c1 -> c_flags &= ~HDROUTPUT;
                    707:            break;
                    708:     }
                    709: }
                    710: 
                    711: /*  */
                    712: 
                    713: static mhlfile (fp, mname, ofilen, ofilec)
                    714: register FILE   *fp;
                    715: register char   *mname;
                    716: int    ofilen,
                    717:        ofilec;
                    718: {
                    719:     int     state;
                    720:     register struct mcomp  *c1,
                    721:                            *c2;
                    722:     register char **ip;
                    723:     char    name[NAMESZ],
                    724:             buf[BUFSIZ];
                    725: 
                    726:     if (forwall) {
                    727:        if (digest)
                    728:            printf ("%s", ofilen == 1 ? delim3 : delim4);
                    729:        else {
                    730:            printf ("\n-------");
                    731:            if (ofilen == 1)
                    732:                printf (" Forwarded Message%s", ofilec > 1 ? "s" : "");
                    733:            else
                    734:                printf (" Message %d", ofilen);
                    735:            printf ("\n\n");
                    736:        }
                    737:     }
                    738:     else
                    739:        switch (ontty) {
                    740:            case PITTY:
                    741:                if (ofilec > 1) {
                    742:                    if (ofilen > 1) {
                    743:                        if ((global.c_flags & CLEARSCR))
                    744:                            clear_screen ();
                    745:                        else
                    746:                            printf ("\n\n\n");
                    747:                    }
                    748:                    printf (">>> %s\n\n", mname);
                    749:                }
                    750:                break;
                    751: 
                    752:            case ISTTY:
                    753:                (void) strcpy (buf, "\n");
                    754:                if (ofilec > 1) {
                    755:                    if (SOprintf ("Press <return> to list \"%s\"...", mname)) {
                    756:                        if (ofilen > 1)
                    757:                            printf ("\n\n\n");
                    758:                        printf ("Press <return> to list \"%s\"...", mname);
                    759:                    }
                    760:                    (void) fflush (stdout);
                    761:                    buf[0] = NULL;
                    762:                    (void) read (fileno (stdout), buf, sizeof buf);
                    763:                }
                    764:                if (index (buf, '\n')) {
                    765:                    if ((global.c_flags & CLEARSCR))
                    766:                        clear_screen ();
                    767:                }
                    768:                else
                    769:                    printf ("\n");
                    770:                break;
                    771: 
                    772:            default:
                    773:                if (ofilec > 1) {
                    774:                    if (ofilen > 1) {
                    775:                        printf ("\n\n\n");
                    776:                        if (clearflg > 0)
                    777:                            clear_screen ();
                    778:                    }
                    779:                    printf (">>> %s\n\n", mname);
                    780:                }
                    781:                break;
                    782:        }
                    783: 
                    784: /*  */
                    785: 
                    786:     for (state = FLD;;)
                    787:        switch (state = m_getfld (state, name, buf, sizeof buf, fp)) {
                    788:            case FLD:
                    789:            case FLDPLUS:
                    790:                for (ip = ignores; *ip; ip++)
                    791:                    if (uleq (name, *ip)) {
                    792:                        while (state == FLDPLUS)
                    793:                            state = m_getfld (state, name, buf, sizeof buf, fp);
                    794:                        break;
                    795:                    }
                    796:                if (*ip)
                    797:                    continue;
                    798: 
                    799:                for (c1 = msghd; c1; c1 = c1 -> c_next)
                    800:                    if (uleq (name, c1 -> c_name)) {
                    801:                        c1 -> c_text =
                    802:                            mcomp_add (c1 -> c_flags, buf, c1 -> c_text);
                    803:                        break;
                    804:                    }
                    805:                if (c1 == NULL)
                    806:                    c1 = add_queue (&msghd, &msgtl, name, buf, 0);
                    807:                while (state == FLDPLUS) {
                    808:                    state = m_getfld (state, name, buf, sizeof buf, fp);
                    809:                    c1 -> c_text = add (buf, c1 -> c_text);
                    810:                }
                    811: 
                    812:                for (c2 = fmthd; c2; c2 = c2 -> c_next)
                    813:                    if (uleq (c2 -> c_name, c1 -> c_name))
                    814:                        break;
                    815:                if (c2 == NULL)
                    816:                    c1 -> c_flags |= EXTRA;
                    817:                continue;
                    818: 
                    819:            case BODY:
                    820:            case FILEEOF:
                    821:                row = column = 0;
                    822:                for (c1 = fmthd; c1; c1 = c1 -> c_next) {
                    823:                    if (c1 -> c_flags & CLEARTEXT) {
                    824:                        putcomp (c1, c1, ONECOMP);
                    825:                        continue;
                    826:                    }
                    827:                    if (uleq (c1 -> c_name, "messagename")) {
                    828:                        holder.c_text = concat ("(Message ", mname, ")\n",
                    829:                                            NULLCP);
                    830:                        putcomp (c1, &holder, ONECOMP);
                    831:                        free (holder.c_text);
                    832:                        holder.c_text = NULL;
                    833:                        continue;
                    834:                    }
                    835:                    if (uleq (c1 -> c_name, "extras")) {
                    836:                        for (c2 = msghd; c2; c2 = c2 -> c_next)
                    837:                            if (c2 -> c_flags & EXTRA)
                    838:                                putcomp (c1, c2, TWOCOMP);
                    839:                        continue;
                    840:                    }
                    841:                    if (uleq (c1 -> c_name, "body")) {
                    842:                        if ((holder.c_text = malloc (sizeof buf)) == NULL)
                    843:                            adios (NULLCP, "unable to allocate buffer memory");
                    844:                        (void) strcpy (holder.c_text, buf);
                    845:                        while (state == BODY) {
                    846:                            putcomp (c1, &holder, ONECOMP);
                    847:                            state = m_getfld (state, name, holder.c_text,
                    848:                                        sizeof buf, fp);
                    849:                        }
                    850:                        free (holder.c_text);
                    851:                        holder.c_text = NULL;
                    852:                        continue;
                    853:                    }
                    854:                    for (c2 = msghd; c2; c2 = c2 -> c_next)
                    855:                        if (uleq (c2 -> c_name, c1 -> c_name)) {
                    856:                            putcomp (c1, c2, ONECOMP);
                    857:                            break;
                    858:                        }
                    859:                }
                    860:                return;
                    861: 
                    862:            case LENERR:
                    863:            case FMTERR:
                    864:                advise (NULLCP, "format error in message %s", mname);
                    865:                exitstat++;
                    866:                return;
                    867: 
                    868:            default:
                    869:                adios (NULLCP, "getfld() returned %d", state);
                    870:        }
                    871: }
                    872: 
                    873: /*  */
                    874: 
                    875: static int  mcomp_flags (name)
                    876: register char   *name;
                    877: {
                    878:     register struct pair   *ap;
                    879: 
                    880:     for (ap = pairs; ap -> p_name; ap++)
                    881:        if (uleq (ap -> p_name, name))
                    882:            return (ap -> p_flags);
                    883: 
                    884:     return NULL;
                    885: }
                    886: 
                    887: 
                    888: static char *mcomp_add (flags, s1, s2)
                    889: short   flags;
                    890: register char   *s1,
                    891:                *s2;
                    892: {
                    893:     register char   *dp;
                    894: 
                    895:     if (!(flags & ADDRFMT))
                    896:        return add (s1, s2);
                    897: 
                    898:     if (s2 && *(dp = s2 + strlen (s2) - 1) == '\n')
                    899:        *dp = NULL;
                    900: 
                    901:     return add (s1, add (",\n", s2));
                    902: }
                    903: 
                    904: /*  */
                    905: 
                    906: struct pqpair {
                    907:     char    *pq_text;
                    908:     char    *pq_error;
                    909:     struct pqpair *pq_next;
                    910: };
                    911: 
                    912: 
                    913: static mcomp_format (c1, c2)
                    914: register struct mcomp *c1,
                    915:                      *c2;
                    916: {
                    917:     int     dat[4];
                    918:     register char  *ap,
                    919:                    *cp;
                    920:     char    buffer[BUFSIZ],
                    921:             error[BUFSIZ];
                    922:     register struct comp   *cptr;
                    923:     register struct pqpair *p,
                    924:                            *q;
                    925:     struct pqpair   pq;
                    926:     register struct mailname   *mp;
                    927: 
                    928:     ap = c2 -> c_text;
                    929:     c2 -> c_text = NULL;
                    930:     dat[0] = dat[1] = dat[2] = 0;
                    931:     dat[3] = sizeof buffer - 1;
                    932:     (void) fmt_compile (c1 -> c_nfs, &c1 -> c_fmt);
                    933: 
                    934:     if (c1 -> c_flags & DATEFMT) {
                    935:        FINDCOMP (cptr, "text");
                    936:        if (cptr)
                    937:            cptr -> c_text = ap;
                    938: 
                    939:        (void) fmtscan (c1 -> c_fmt, buffer, sizeof buffer - 1, dat);
                    940:        c2 -> c_text = concat (buffer, "\n", NULLCP);
                    941: 
                    942:        free (ap);
                    943:        return;
                    944:     }
                    945: 
                    946:     (q = &pq) -> pq_next = NULL;
                    947:     while (cp = getname (ap)) {
                    948:        if ((p = (struct pqpair *) calloc ((unsigned) 1, sizeof *p)) == NULL)
                    949:            adios (NULLCP, "unable to allocate pqpair memory");
                    950: 
                    951:        if ((mp = getm (cp, NULLCP, 0, AD_NAME, error)) == NULL) {
                    952:            p -> pq_text = getcpy (cp);
                    953:            p -> pq_error = getcpy (error);
                    954:        }
                    955:        else {
                    956:            p -> pq_text = getcpy (mp -> m_text);
                    957:            mnfree (mp);
                    958:        }
                    959:        q = (q -> pq_next = p);
                    960:     }
                    961: 
                    962:     for (p = pq.pq_next; p; p = q) {
                    963:        FINDCOMP (cptr, "text");
                    964:        if (cptr)
                    965:            cptr -> c_text = p -> pq_text;
                    966:        FINDCOMP (cptr, "error");
                    967:        if (cptr)
                    968:            cptr -> c_text = p -> pq_error;
                    969: 
                    970:        (void) fmtscan (c1 -> c_fmt, buffer, sizeof buffer - 1, dat);
                    971:        if (*buffer) {
                    972:            if (c2 -> c_text)
                    973:                c2 -> c_text = add (",\n", c2 -> c_text);
                    974:            if (*(cp = buffer + strlen (buffer) - 1) == '\n')
                    975:                *cp = NULL;
                    976:            c2 -> c_text = add (buffer, c2 -> c_text);
                    977:        }
                    978: 
                    979:        free (p -> pq_text);
                    980:        if (p -> pq_error)
                    981:            free (p -> pq_error);
                    982:        q = p -> pq_next;
                    983:        free ((char *) p);
                    984:     }
                    985: 
                    986:     c2 -> c_text = add ("\n", c2 -> c_text);
                    987:     free (ap);
                    988: }
                    989: 
                    990: /*  */
                    991: 
                    992: static struct mcomp *add_queue (head, tail, name, text, flags)
                    993: register struct mcomp **head,
                    994:                      **tail;
                    995: register char   *name,
                    996:                *text;
                    997: int     flags;
                    998: {
                    999:     register struct mcomp  *c1;
                   1000: 
                   1001:     if ((c1 = (struct mcomp *) calloc ((unsigned) 1, sizeof *c1)) == NULL)
                   1002:        adios (NULLCP, "unable to allocate comp memory");
                   1003: 
                   1004:     c1 -> c_flags = flags & ~INIT;
                   1005:     if (c1 -> c_name = name ? getcpy (name) : NULL)
                   1006:        c1 -> c_flags |= mcomp_flags (c1 -> c_name);
                   1007:     c1 -> c_text = text ? getcpy (text) : NULL;
                   1008:     if (flags & INIT) {
                   1009:        if (global.c_ovtxt)
                   1010:            c1 -> c_ovtxt = getcpy (global.c_ovtxt);
                   1011:        c1 -> c_offset = global.c_offset;
                   1012:        c1 -> c_ovoff = global. c_ovoff;
                   1013:        c1 -> c_width = c1 -> c_length = 0;
                   1014:        c1 -> c_cwidth = global.c_cwidth;
                   1015:        c1 -> c_flags |= global.c_flags & GFLAGS;
                   1016:     }
                   1017:     if (*head == NULL)
                   1018:        *head = c1;
                   1019:     if (*tail != NULL)
                   1020:        (*tail) -> c_next = c1;
                   1021:     *tail = c1;
                   1022: 
                   1023:     return c1;
                   1024: }
                   1025: 
                   1026: 
                   1027: static  free_queue (head, tail)
                   1028: register struct mcomp **head,
                   1029:                      **tail;
                   1030: {
                   1031:     register struct mcomp *c1,
                   1032:                          *c2;
                   1033: 
                   1034:     for (c1 = *head; c1; c1 = c2) {
                   1035:        c2 = c1 -> c_next;
                   1036:        if (c1 -> c_name)
                   1037:            free (c1 -> c_name);
                   1038:        if (c1 -> c_text)
                   1039:            free (c1 -> c_text);
                   1040:        if (c1 -> c_ovtxt)
                   1041:            free (c1 -> c_ovtxt);
                   1042:        if (c1 -> c_nfs)
                   1043:            free (c1 -> c_nfs);
                   1044:        if (c1 -> c_fmt)
                   1045:            free ((char *) c1 -> c_fmt);
                   1046:        free ((char *) c1);
                   1047:     }
                   1048: 
                   1049:     *head = *tail = NULL;
                   1050: }
                   1051: 
                   1052: /*  */
                   1053: 
                   1054: static  putcomp (c1, c2, flag)
                   1055: register struct mcomp *c1,
                   1056:                      *c2;
                   1057: int     flag;
                   1058: {
                   1059:     int     count,
                   1060:             cchdr;
                   1061:     register char   *cp;
                   1062: 
                   1063:     cchdr = 0;
                   1064:     lm = 0;
                   1065:     llim = c1 -> c_length ? c1 -> c_length : -1;
                   1066:     wid = c1 -> c_width ? c1 -> c_width : global.c_width;
                   1067:     ovoff = (c1 -> c_ovoff >= 0 ? c1 -> c_ovoff : global.c_ovoff)
                   1068:        + c1 -> c_offset;
                   1069:     if ((ovtxt = c1 -> c_ovtxt ? c1 -> c_ovtxt : global.c_ovtxt) == NULL)
                   1070:        ovtxt = "";
                   1071:     if (wid < ovoff + strlen (ovtxt) + 5)
                   1072:        adios (NULLCP, "component: %s width(%d) too small for overflow(%d)",
                   1073:                c1 -> c_name, wid, ovoff + strlen (ovtxt) + 5);
                   1074:     onelp = NULL;
                   1075: 
                   1076:     if (c1 -> c_flags & CLEARTEXT) {
                   1077:        putstr (c1 -> c_text);
                   1078:        putstr ("\n");
                   1079:        return;
                   1080:     }
                   1081: 
                   1082:     if (c1 -> c_nfs && (c1 -> c_flags & (ADDRFMT | DATEFMT)))
                   1083:        mcomp_format (c1, c2);
                   1084: 
                   1085:     if (c1 -> c_flags & CENTER) {
                   1086:        count = (c1 -> c_width ? c1 -> c_width : global.c_width)
                   1087:            - c1 -> c_offset - strlen (c2 -> c_text);
                   1088:        if (!(c1 -> c_flags & HDROUTPUT) && !(c1 -> c_flags & NOCOMPONENT))
                   1089:            count -= strlen (c1 -> c_text ? c1 -> c_text : c1 -> c_name) + 2;
                   1090:        lm = c1 -> c_offset + (count / 2);
                   1091:     }
                   1092:     else
                   1093:        if (c1 -> c_offset)
                   1094:            lm = c1 -> c_offset;
                   1095: 
                   1096:     if (!(c1 -> c_flags & HDROUTPUT) && !(c1 -> c_flags & NOCOMPONENT)) {
                   1097:         if (c1 -> c_flags & UPPERCASE)         /* uppercase component also */
                   1098:            for (cp = (c1 -> c_text ? c1 -> c_text : c1 -> c_name); *cp; cp++)
                   1099:                if (islower (*cp))
                   1100:                    *cp = toupper (*cp);
                   1101:        putstr (c1 -> c_text ? c1 -> c_text : c1 -> c_name);
                   1102:        putstr (": ");
                   1103:        c1 -> c_flags |= HDROUTPUT;
                   1104: 
                   1105:        cchdr++;
                   1106:        if ((count = c1 -> c_cwidth -
                   1107:                strlen (c1 -> c_text ? c1 -> c_text : c1 -> c_name) - 2) > 0)
                   1108:            while (count--)
                   1109:                putstr (" ");
                   1110:     }
                   1111: 
                   1112:     if (flag == TWOCOMP
                   1113:            && !(c2 -> c_flags & HDROUTPUT)
                   1114:            && !(c2 -> c_flags & NOCOMPONENT)) {
                   1115:         if (c1 -> c_flags & UPPERCASE)
                   1116:            for (cp = c2 -> c_name; *cp; cp++)
                   1117:                if (islower (*cp))
                   1118:                    *cp = toupper (*cp);
                   1119:        putstr (c2 -> c_name);
                   1120:        putstr (": ");
                   1121:        c2 -> c_flags |= HDROUTPUT;
                   1122:     }
                   1123:     if (c1 -> c_flags & UPPERCASE)
                   1124:        for (cp = c2 -> c_text; *cp; cp++)
                   1125:            if (islower (*cp))
                   1126:                *cp = toupper (*cp);
                   1127: 
                   1128:     count = 0;
                   1129:     if (cchdr)
                   1130:        count = (c1 -> c_cwidth >= 0) ? c1 -> c_cwidth
                   1131:                    : strlen (c1 -> c_text ? c1 -> c_text : c1 -> c_name) + 2;
                   1132:     count += c1 -> c_offset;
                   1133: 
                   1134:     putstr (oneline (c2 -> c_text, c1 -> c_flags));
                   1135:     if (term == '\n')
                   1136:        putstr ("\n");
                   1137:     while (cp = oneline (c2 -> c_text, c1 -> c_flags))
                   1138:        if (*cp) {
                   1139:            lm = count;
                   1140:            putstr (cp);
                   1141:            if (term == '\n')
                   1142:                putstr ("\n");
                   1143:        }
                   1144:        else
                   1145:            if (term == '\n')
                   1146:                putstr ("\n");
                   1147: }
                   1148: 
                   1149: /*  */
                   1150: 
                   1151: static char *oneline (stuff, flags)
                   1152: register char   *stuff;
                   1153: short   flags;
                   1154: {
                   1155:     int     spc;
                   1156:     register char   *cp,
                   1157:                    *ret;
                   1158: 
                   1159:     if (onelp == NULL)
                   1160:        onelp = stuff;
                   1161:     if (*onelp == NULL)
                   1162:        return (onelp = NULL);
                   1163: 
                   1164:     ret = onelp;
                   1165:     term = 0;
                   1166:     if (flags & COMPRESS) {
                   1167:        for (spc = 1, cp = ret; *onelp; onelp++)
                   1168:            if (isspace (*onelp)) {
                   1169:                if (*onelp == '\n' && (!onelp[1] || (flags & ADDRFMT))) {
                   1170:                    term = '\n';
                   1171:                    *onelp++ = NULL;
                   1172:                    break;
                   1173:                }
                   1174:                else
                   1175:                    if (!spc) {
                   1176:                        *cp++ = ' ';
                   1177:                        spc++;
                   1178:                    }
                   1179:            }
                   1180:            else {
                   1181:                *cp++ = *onelp;
                   1182:                spc = 0;
                   1183:            }
                   1184: 
                   1185:        *cp = NULL;
                   1186:     }
                   1187:     else {
                   1188:        while (*onelp && *onelp != '\n')
                   1189:            onelp++;
                   1190:        if (*onelp == '\n') {
                   1191:            term = '\n';
                   1192:            *onelp++ = NULL;
                   1193:        }
                   1194:        if (flags & LEFTADJUST)
                   1195:            while (*ret == ' ' || *ret == '\t')
                   1196:                ret++;
                   1197:     }
                   1198: 
                   1199:     return ret;
                   1200: }
                   1201: 
                   1202: /*  */
                   1203: 
                   1204: static  putstr (string)
                   1205: register char   *string;
                   1206: {
                   1207:     if (!column && lm > 0)
                   1208:        while (lm > 0)
                   1209:            if (lm >= 8) {
                   1210:                putch ('\t');
                   1211:                lm -= 8;
                   1212:            }
                   1213:            else {
                   1214:                putch (' ');
                   1215:                lm--;
                   1216:            }
                   1217:     lm = 0;
                   1218:     while (*string)
                   1219:        putch (*string++);
                   1220: }
                   1221: 
                   1222: /*  */
                   1223: 
                   1224: static putch (ch)
                   1225: register char  ch;
                   1226: {
                   1227:     char    buf[BUFSIZ];
                   1228: 
                   1229:     if (llim == 0)
                   1230:        return;
                   1231: 
                   1232:     switch (ch) {
                   1233:        case '\n':
                   1234:            if (llim > 0)
                   1235:                llim--;
                   1236:            column = 0;
                   1237:            row++;
                   1238:            if (ontty != ISTTY || row != global.c_length)
                   1239:                break;
                   1240:            if (global.c_flags & BELL)
                   1241:                (void) putchar ('\007');
                   1242:            (void) fflush (stdout);
                   1243:            buf[0] = NULL;
                   1244:            (void) read (fileno (stdout), buf, sizeof buf);
                   1245:            if (index (buf, '\n')) {
                   1246:                if (global.c_flags & CLEARSCR)
                   1247:                    clear_screen ();
                   1248:                row = 0;
                   1249:            }
                   1250:            else {
                   1251:                (void) putchar ('\n');
                   1252:                row = global.c_length / 3;
                   1253:            }
                   1254:            return;
                   1255: 
                   1256:        case '\t':
                   1257:            column |= 07;
                   1258:            column++;
                   1259:            break;
                   1260: 
                   1261:        case '\b':
                   1262:            column--;
                   1263:            break;
                   1264: 
                   1265:        case '\r':
                   1266:            column = 0;
                   1267:            break;
                   1268: 
                   1269:        default:
                   1270:            if (column == 0 && forwflg && ch == '-')
                   1271:                (void) putchar ('-'), putchar (' ');
                   1272:            if (ch >= ' ')
                   1273:                column++;
                   1274:            break;
                   1275:     }
                   1276: 
                   1277:     if (column >= wid) {
                   1278:        putch ('\n');
                   1279:        if (ovoff > 0)
                   1280:            lm = ovoff;
                   1281:        putstr (ovtxt ? ovtxt : "");
                   1282:        putch (ch);
                   1283:        return;
                   1284:     }
                   1285: 
                   1286:     (void) putchar (ch);
                   1287: }
                   1288: 
                   1289: /*  */
                   1290: 
                   1291: /* ARGSUSED */
                   1292: 
                   1293: static int intrser (i)
                   1294: int     i;
                   1295: {
                   1296: #ifndef        BSD42
                   1297:     (void) signal (SIGINT, intrser);
                   1298: #endif BSD42
                   1299: 
                   1300:     discard (stdout);
                   1301:     (void) putchar ('\n');
                   1302: 
                   1303:     longjmp (env, DONE);
                   1304: }
                   1305: 
                   1306: 
                   1307: /* ARGSUSED */
                   1308: 
                   1309: static int pipeser (i)
                   1310: int     i;
                   1311: {
                   1312: #ifndef        BSD42
                   1313:     (void) signal (SIGPIPE, pipeser);
                   1314: #endif BSD42
                   1315: 
                   1316:     done (NOTOK);
                   1317: }
                   1318: 
                   1319: 
                   1320: /* ARGSUSED */
                   1321: 
                   1322: static int quitser (i)
                   1323: int     i;
                   1324: {
                   1325: #ifndef        BSD42
                   1326:     (void) signal (SIGQUIT, quitser);
                   1327: #endif BSD42
                   1328: 
                   1329:     (void) putchar ('\n');
                   1330:     (void) fflush (stdout);
                   1331: 
                   1332:     done (NOTOK);
                   1333: }
                   1334: 
                   1335: /*  */
                   1336: 
                   1337: #undef adios
                   1338: #undef done
                   1339: 
                   1340: int     mhlsbr (argc, argv, action)
                   1341: int     argc;
                   1342: register char  **argv;
                   1343: register FP (*action) ();
                   1344: {
                   1345:     int     (*istat) (), (*pstat) (), (*qstat) ();
                   1346:     register char   *cp;
                   1347:     register struct mcomp  *c1;
                   1348: 
                   1349:     switch (setjmp (mhlenv)) {
                   1350:        case OK:
                   1351:            cp = invo_name;
                   1352:            bellflg = clearflg = forwflg = forwall = exitstat = 0;
                   1353:            digest = NULL;
                   1354:            ontty = NOTTY;
                   1355:            mhl_action = action;
                   1356:            if ((istat = signal (SIGINT, SIG_IGN)) != SIG_DFL)
                   1357:                (void) signal (SIGINT, istat);
                   1358:            if ((qstat = signal (SIGQUIT, SIG_IGN)) != SIG_DFL)
                   1359:                (void) signal (SIGQUIT, qstat);
                   1360:            pstat = signal (SIGPIPE, pipeser);
                   1361:            (void) mhl (argc, argv);    /* fall */
                   1362: 
                   1363:        default:
                   1364:            (void) signal (SIGINT, istat);
                   1365:            (void) signal (SIGQUIT, qstat);
                   1366:            (void) signal (SIGPIPE, SIG_IGN);/* XXX */
                   1367:            if (ontty == PITTY)
                   1368:                m_pclose ();
                   1369:            (void) signal (SIGPIPE, pstat);
                   1370:            invo_name = cp;
                   1371:            if (holder.c_text) {
                   1372:                free (holder.c_text);
                   1373:                holder.c_text = NULL;
                   1374:            }
                   1375:            free_queue (&msghd, &msgtl);
                   1376:            for (c1 = fmthd; c1; c1 = c1 -> c_next)
                   1377:                c1 -> c_flags &= ~HDROUTPUT;
                   1378:            return exitstat;
                   1379:     }
                   1380: }
                   1381: 
                   1382: /*  */
                   1383: 
                   1384: /* VARARGS2 */
                   1385: 
                   1386: static void mhladios (what, fmt, a, b, c, d, e, f)
                   1387: char   *what,
                   1388:        *fmt,
                   1389:        *a,
                   1390:        *b,
                   1391:        *c,
                   1392:        *d,
                   1393:        *e,
                   1394:        *f;
                   1395: {
                   1396:     advise (what, fmt, a, b, c, d, e, f);
                   1397:     mhldone (1);
                   1398: }
                   1399: 
                   1400: 
                   1401: static void mhldone (status)
                   1402: int     status;
                   1403: {
                   1404:     exitstat = status;
                   1405:     if (mhl_action)
                   1406:        longjmp (mhlenv, DONE);
                   1407:     else
                   1408:        done (exitstat);
                   1409: }
                   1410: 
                   1411: /*  */
                   1412: 
                   1413: static int m_pid = NOTOK;
                   1414: static  int sd = NOTOK;
                   1415: 
                   1416: 
                   1417: static m_popen (name)
                   1418: char *name;
                   1419: {
                   1420:     int     pd[2];
                   1421: 
                   1422:     if (mhl_action && (sd = dup (fileno (stdout))) == NOTOK)
                   1423:        adios ("standard output", "unable to dup()");
                   1424: 
                   1425:     if (pipe (pd) == NOTOK)
                   1426:        adios ("pipe", "unable to");
                   1427: 
                   1428:     switch (m_pid = vfork ()) {
                   1429:        case NOTOK:
                   1430:            adios ("fork", "unable to");
                   1431: 
                   1432:        case OK:
                   1433:            (void) signal (SIGINT, SIG_DFL);
                   1434:            (void) signal (SIGQUIT, SIG_DFL);
                   1435: 
                   1436:            (void) close (pd[1]);
                   1437:            if (pd[0] != fileno (stdin)) {
                   1438:                (void) dup2 (pd[0], fileno (stdin));
                   1439:                (void) close (pd[0]);
                   1440:            }
                   1441:            execlp (name, r1bindex (name, '/'), NULLCP);
                   1442:            fprintf (stderr, "unable to exec ");
                   1443:            perror (name);
                   1444:            _exit (-1);
                   1445: 
                   1446:        default:
                   1447:            (void) close (pd[0]);
                   1448:            if (pd[1] != fileno (stdout)) {
                   1449:                (void) dup2 (pd[1], fileno (stdout));
                   1450:                (void) close (pd[1]);
                   1451:            }
                   1452:     }
                   1453: }
                   1454: 
                   1455: 
                   1456: m_pclose () {
                   1457:     if (m_pid == NOTOK)
                   1458:        return;
                   1459: 
                   1460:     if (sd != NOTOK) {
                   1461:        (void) fflush (stdout);
                   1462:        if (dup2 (sd, fileno (stdout)) == NOTOK)
                   1463:            adios ("standard output", "unable to dup2()");
                   1464: 
                   1465:        clearerr (stdout);
                   1466:        (void) close (sd);
                   1467:        sd = NOTOK;
                   1468:     }
                   1469:     else
                   1470:        (void) fclose (stdout);
                   1471: 
                   1472:     (void) pidwait (m_pid, OK);
                   1473:     m_pid = NOTOK;
                   1474: }

unix.superglobalmegacorp.com

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