|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.