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: }

Defined functions

add_queue defined in line 992; used 4 times
evalvar defined in line 545; used 2 times
free_queue defined in line 1027; used 3 times
intrser defined in line 1293; used 3 times
m_pclose defined in line 1456; used 2 times
m_popen defined in line 1417; used 1 times
mcomp_add defined in line 888; used 2 times
mcomp_flags defined in line 875; used 1 times
mcomp_format defined in line 913; used 1 times
mhl defined in line 240; used 3 times
mhl_format defined in line 401; used 1 times
mhladios defined in line 1386; used 2 times
mhldone defined in line 1401; used 3 times
mhlfile defined in line 713; used 1 times
mhlsbr defined in line 1340; used 2 times
oneline defined in line 1151; used 3 times
parse defined in line 643; used 4 times
pipeser defined in line 1309; used 3 times
process defined in line 665; used 2 times
ptoi defined in line 595; used 5 times
ptos defined in line 611; used 3 times
putch defined in line 1224; used 5 times
putcomp defined in line 1054; used 5 times
putstr defined in line 1204; used 13 times
quitser defined in line 1322; used 4 times

Defined variables

bellflg defined in line 182; used 4 times
clearflg defined in line 183; used 8 times
column defined in line 198; used 10 times
delim3 defined in line 220; used 1 times
delim4 defined in line 222; used 2 times
digest defined in line 187; used 6 times
env defined in line 216; used 2 times
exitstat defined in line 189; used 7 times
fmthd defined in line 121; used 9 times
fmttl defined in line 122; used 3 times
forwall defined in line 185; used 4 times
forwflg defined in line 184; used 3 times
global defined in line 124; used 41 times
holder defined in line 127; used 16 times
ignores defined in line 213; used 2 times
llim defined in line 201; used 4 times
lm defined in line 200; used 11 times
m_pid defined in line 1413; used 4 times
mhldebug defined in line 190; used 2 times
mhlenv defined in line 217; used 2 times
mhlswitches defined in line 44; used 3 times
msghd defined in line 119; used 6 times
msgtl defined in line 120; used 3 times
onelp defined in line 209; used 18 times
ontty defined in line 195; used 11 times
ovoff defined in line 202; used 5 times
ovtxt defined in line 207; used 6 times
pairs defined in line 136; used 1 times
parptr defined in line 212; used 32 times
row defined in line 197; used 5 times
sd defined in line 1414; used 5 times
term defined in line 203; used 6 times
triples defined in line 159; used 1 times
wid defined in line 204; used 4 times

Defined struct's

mcomp defined in line 85; used 42 times
pair defined in line 133; used 2 times
  • in line 878(2)
pqpair defined in line 906; used 8 times
triple defined in line 155; used 2 times
  • in line 550(2)

Defined macros

ADDRFMT defined in line 108; used 19 times
BELL defined in line 109; used 7 times
BELLSW defined in line 45; never used
CENTER defined in line 101; used 4 times
CLEARSCR defined in line 105; used 8 times
CLEARTEXT defined in line 102; used 3 times
CLRSW defined in line 50; never used
COMPRESS defined in line 107; used 4 times
DATEFMT defined in line 110; used 8 times
DGSTSW defined in line 77; never used
EXTRA defined in line 103; used 2 times
FOLDSW defined in line 55; never used
FORMAT defined in line 111; used 1 times
FORMSW defined in line 57; never used
FORW1SW defined in line 73; never used
FORW2SW defined in line 75; never used
GFLAGS defined in line 114; used 1 times
HDROUTPUT defined in line 104; used 7 times
HELPSW defined in line 70; never used
INIT defined in line 112; used 3 times
ISTTY defined in line 194; used 2 times
LBITS defined in line 113; used 1 times
LEFTADJUST defined in line 106; used 4 times
LENSW defined in line 65; never used
NBELLSW defined in line 47; never used
NCLRSW defined in line 52; never used
NOCOMPONENT defined in line 99; used 7 times
NOTTY defined in line 193; used 4 times
NPROGSW defined in line 62; never used
ONECOMP defined in line 34; used 4 times
PITTY defined in line 192; used 5 times
PROGSW defined in line 60; never used
QUOTE defined in line 40; used 1 times
TWOCOMP defined in line 35; used 2 times
UPPERCASE defined in line 100; used 6 times
WIDSW defined in line 67; never used
adios defined in line 37; used 23 times
done defined in line 38; used 6 times
Last modified: 1986-03-07
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3463
Valid CSS Valid XHTML 1.0 Strict