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