|
|
1.1 ! root 1: /* mshcmds.c - command handlers in msh */ ! 2: ! 3: #include "../h/mh.h" ! 4: #include "../h/dropsbr.h" ! 5: #include "../h/formatsbr.h" ! 6: #include "../h/scansbr.h" ! 7: #include "../zotnet/tws.h" ! 8: #include <stdio.h> ! 9: #include "../zotnet/mts.h" ! 10: #include <ctype.h> ! 11: #include <errno.h> ! 12: #include <setjmp.h> ! 13: #include <signal.h> ! 14: #include "../h/mshsbr.h" ! 15: #include <sys/types.h> ! 16: #include <sys/stat.h> ! 17: ! 18: /* */ ! 19: ! 20: extern int errno; ! 21: ! 22: /* BURST */ ! 23: static char delim3[] = "-------";/* from burst.c */ ! 24: ! 25: ! 26: /* SHOW */ ! 27: static int mhlnum; ! 28: static FILE *mhlfp; ! 29: ! 30: void clear_screen (); ! 31: int eom_action (); ! 32: FP mhl_action (); ! 33: ! 34: ! 35: /* SORTM */ ! 36: int msgsort (); ! 37: struct tws *getws (); ! 38: ! 39: /* */ ! 40: ! 41: forkcmd (args, pgm) ! 42: char **args, ! 43: *pgm; ! 44: { ! 45: int child_id; ! 46: char *vec[MAXARGS]; ! 47: ! 48: vec[0] = r1bindex (pgm, '/'); ! 49: (void) copyip (args, vec + 1); ! 50: ! 51: if (fmsh) { ! 52: (void) m_delete (pfolder); ! 53: m_replace (pfolder, fmsh); ! 54: m_sync (mp); ! 55: m_update (); ! 56: } ! 57: (void) fflush (stdout); ! 58: switch (child_id = fork ()) { ! 59: case NOTOK: ! 60: advise ("fork", "unable to"); ! 61: return; ! 62: ! 63: case OK: ! 64: closefds (3); ! 65: (void) signal (SIGINT, istat); ! 66: (void) signal (SIGQUIT, qstat); ! 67: ! 68: execvp (pgm, vec); ! 69: fprintf (stderr, "unable to exec "); ! 70: perror (cmd_name); ! 71: _exit (1); ! 72: ! 73: default: ! 74: (void) pidXwait (child_id, NULLCP); ! 75: break; ! 76: } ! 77: if (fmsh) { /* assume the worst case */ ! 78: mp -> msgflags |= MODIFIED; ! 79: modified++; ! 80: } ! 81: } ! 82: ! 83: /* */ ! 84: ! 85: static struct swit distswit[] = { ! 86: #define DIANSW 0 ! 87: "annotate", 0, ! 88: #define DINANSW 1 ! 89: "noannotate", 0, ! 90: #define DIDFSW 2 ! 91: "draftfolder +folder", 0, ! 92: #define DIDMSW 3 ! 93: "draftmessage msg", 0, ! 94: #define DINDFSW 4 ! 95: "nodraftfolder", 0, ! 96: #define DIEDTSW 5 ! 97: "editor editor", 0, ! 98: #define DINEDSW 6 ! 99: "noedit", 0, ! 100: #define DIFRMSW 7 ! 101: "form formfile", 0, ! 102: #define DIINSW 8 ! 103: "inplace", 0, ! 104: #define DININSW 9 ! 105: "noinplace", 0, ! 106: #define DIWHTSW 10 ! 107: "whatnowproc program", 0, ! 108: #define DINWTSW 11 ! 109: "nowhatnowproc", 0, ! 110: #define DIHELP 12 ! 111: "help", 4, ! 112: ! 113: NULL, NULL ! 114: }; ! 115: ! 116: /* */ ! 117: ! 118: distcmd (args) ! 119: char **args; ! 120: { ! 121: int vecp = 1; ! 122: char *cp, ! 123: *msg = NULL, ! 124: buf[BUFSIZ], ! 125: *vec[MAXARGS]; ! 126: ! 127: if (fmsh) { ! 128: forkcmd (args, cmd_name); ! 129: return; ! 130: } ! 131: ! 132: while (cp = *args++) { ! 133: if (*cp == '-') ! 134: switch (smatch (++cp, distswit)) { ! 135: case AMBIGSW: ! 136: ambigsw (cp, distswit); ! 137: return; ! 138: case UNKWNSW: ! 139: fprintf (stderr, "-%s unknown\n", cp); ! 140: return; ! 141: case DIHELP: ! 142: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); ! 143: help (buf, distswit); ! 144: return; ! 145: ! 146: case DIANSW: /* not implemented */ ! 147: case DINANSW: ! 148: case DIINSW: ! 149: case DININSW: ! 150: continue; ! 151: ! 152: case DINDFSW: ! 153: case DINEDSW: ! 154: case DINWTSW: ! 155: vec[vecp++] = --cp; ! 156: continue; ! 157: ! 158: case DIEDTSW: ! 159: case DIFRMSW: ! 160: case DIDFSW: ! 161: case DIDMSW: ! 162: case DIWHTSW: ! 163: vec[vecp++] = --cp; ! 164: if (!(cp = *args++) || *cp == '-') { ! 165: advise (NULLCP, "missing argument to %s", args[-2]); ! 166: return; ! 167: } ! 168: vec[vecp++] = cp; ! 169: continue; ! 170: } ! 171: if (*cp == '+' || *cp == '@') { ! 172: advise (NULLCP, "sorry, no folders allowed!"); ! 173: return; ! 174: } ! 175: else ! 176: if (msg) { ! 177: advise (NULLCP, "only one message at a time!"); ! 178: return; ! 179: } ! 180: else ! 181: msg = cp; ! 182: } ! 183: ! 184: vec[0] = cmd_name; ! 185: vec[vecp++] = "-file"; ! 186: vec[vecp] = NULL; ! 187: if (!msg) ! 188: msg = "cur"; ! 189: if (!m_convert (mp, msg)) ! 190: return; ! 191: m_setseq (mp); ! 192: ! 193: if (mp -> numsel > 1) { ! 194: advise (NULLCP, "only one message at a time!"); ! 195: return; ! 196: } ! 197: (void) process (mp -> hghsel, cmd_name, vecp, vec); ! 198: m_setcur (mp, mp -> hghsel); ! 199: } ! 200: ! 201: /* */ ! 202: ! 203: static struct swit explswit[] = { ! 204: #define EXINSW 0 ! 205: "inplace", 0, ! 206: #define EXNINSW 1 ! 207: "noinplace", 0, ! 208: #define EXQISW 2 ! 209: "quiet", 0, ! 210: #define EXNQISW 3 ! 211: "noquiet", 0, ! 212: #define EXVBSW 4 ! 213: "verbose", 0, ! 214: #define EXNVBSW 5 ! 215: "noverbose", 0, ! 216: #define EXHELP 6 ! 217: "help", 4, ! 218: ! 219: NULL, NULL ! 220: }; ! 221: ! 222: /* */ ! 223: ! 224: explcmd (args) ! 225: char **args; ! 226: { ! 227: int inplace = 0, ! 228: quietsw = 0, ! 229: verbosw = 0, ! 230: msgp = 0, ! 231: hi, ! 232: msgnum; ! 233: char *cp, ! 234: buf[BUFSIZ], ! 235: *msgs[MAXARGS]; ! 236: struct Msg *smsgs; ! 237: ! 238: if (fmsh) { ! 239: forkcmd (args, cmd_name); ! 240: return; ! 241: } ! 242: ! 243: while (cp = *args++) { ! 244: if (*cp == '-') ! 245: switch (smatch (++cp, explswit)) { ! 246: case AMBIGSW: ! 247: ambigsw (cp, explswit); ! 248: return; ! 249: case UNKWNSW: ! 250: fprintf (stderr, "-%s unknown\n", cp); ! 251: return; ! 252: case EXHELP: ! 253: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); ! 254: help (buf, explswit); ! 255: return; ! 256: ! 257: case EXINSW: ! 258: inplace++; ! 259: continue; ! 260: case EXNINSW: ! 261: inplace = 0; ! 262: continue; ! 263: case EXQISW: ! 264: quietsw++; ! 265: continue; ! 266: case EXNQISW: ! 267: quietsw = 0; ! 268: continue; ! 269: case EXVBSW: ! 270: verbosw++; ! 271: continue; ! 272: case EXNVBSW: ! 273: verbosw = 0; ! 274: continue; ! 275: } ! 276: if (*cp == '+' || *cp == '@') { ! 277: advise (NULLCP, "sorry, no folders allowed!"); ! 278: return; ! 279: } ! 280: else ! 281: msgs[msgp++] = cp; ! 282: } ! 283: ! 284: if (!msgp) ! 285: msgs[msgp++] = "cur"; ! 286: for (msgnum = 0; msgnum < msgp; msgnum++) ! 287: if (!m_convert (mp, msgs[msgnum])) ! 288: return; ! 289: m_setseq (mp); ! 290: ! 291: smsgs = (struct Msg *) ! 292: calloc ((unsigned) (MAXFOLDER + 2), sizeof *smsgs); ! 293: if (smsgs == NULL) ! 294: adios (NULLCP, "unable to allocate folder storage"); ! 295: ! 296: hi = mp -> hghmsg + 1; ! 297: interrupted = 0; ! 298: for (msgnum = mp -> lowsel; ! 299: msgnum <= mp -> hghsel && !interrupted; ! 300: msgnum++) ! 301: if (mp -> msgstats[msgnum] & SELECTED) ! 302: if (burst (smsgs, msgnum, inplace, quietsw, verbosw) != OK) ! 303: break; ! 304: ! 305: free ((char *) smsgs); ! 306: ! 307: if (inplace) ! 308: m_setcur (mp, mp -> lowsel); ! 309: else ! 310: if (hi <= mp -> hghmsg) ! 311: m_setcur (mp, hi); ! 312: ! 313: mp -> msgflags |= MODIFIED; ! 314: modified++; ! 315: } ! 316: ! 317: /* */ ! 318: ! 319: static burst (smsgs, msgnum, inplace, quietsw, verbosw) ! 320: struct Msg *smsgs; ! 321: int msgnum, ! 322: inplace, ! 323: quietsw, ! 324: verbosw; ! 325: { ! 326: int i, ! 327: j, ! 328: ld3, ! 329: wasdlm, ! 330: msgp; ! 331: long pos; ! 332: char c, ! 333: buffer[BUFSIZ]; ! 334: register FILE *zp; ! 335: ! 336: ld3 = strlen (delim3); ! 337: ! 338: if (Msgs[msgnum].m_scanl) { ! 339: free (Msgs[msgnum].m_scanl); ! 340: Msgs[msgnum].m_scanl = NULL; ! 341: } ! 342: ! 343: pos = ftell (zp = msh_ready (msgnum, 1)); ! 344: for (msgp = 1; msgp <= MAXFOLDER;) { ! 345: while (fgets (buffer, sizeof buffer, zp) != NULL ! 346: && buffer[0] == '\n' ! 347: && pos < Msgs[msgnum].m_stop) ! 348: pos += (long) strlen (buffer); ! 349: if (feof (zp) || pos >= Msgs[msgnum].m_stop) ! 350: break; ! 351: (void) fseek (zp, pos, 0); ! 352: smsgs[msgp].m_start = pos; ! 353: ! 354: for (c = NULL; ! 355: fgets (buffer, sizeof buffer, zp) != NULL ! 356: && pos < Msgs[msgnum].m_stop; ! 357: c = buffer[0]) ! 358: if (strncmp (buffer, delim3, ld3) == 0 ! 359: && peekc (zp) == '\n' ! 360: && (msgp == 1 || c == '\n')) ! 361: break; ! 362: else ! 363: pos += (long) strlen (buffer); ! 364: ! 365: wasdlm = strncmp (buffer, delim3, ld3) == 0; ! 366: if (smsgs[msgp].m_start != pos) ! 367: smsgs[msgp++].m_stop = c == '\n' && wasdlm ? pos - 1 : pos; ! 368: if (feof (zp) || pos >= Msgs[msgnum].m_stop) { ! 369: if (wasdlm) { ! 370: smsgs[msgp - 1].m_stop -= ((long) strlen (buffer) + 1); ! 371: msgp++; /* fake "End of XXX Digest" */ ! 372: } ! 373: break; ! 374: } ! 375: pos += (long) strlen (buffer); ! 376: } ! 377: ! 378: switch (--msgp) { /* toss "End of XXX Digest" */ ! 379: case 0: ! 380: adios (NULLCP, "burst() botch -- you lose big"); ! 381: ! 382: case 1: ! 383: if (!quietsw) ! 384: printf ("message %d not in digest format\n", msgnum); ! 385: return OK; ! 386: ! 387: default: ! 388: if (verbosw) ! 389: printf ("%d message%s exploded from digest %d\n", ! 390: msgp - 1, msgp - 1 != 1 ? "s" : "", msgnum); ! 391: if (msgp == 2) ! 392: msgp++; ! 393: break; ! 394: } ! 395: ! 396: msgp--; ! 397: if ((i = msgp + mp -> hghmsg) > MAXFOLDER) { ! 398: advise (NULLCP, "more than %d messages", MAXFOLDER); ! 399: return NOTOK; ! 400: } ! 401: if ((mp = m_remsg (mp, 0, i)) == NULL) ! 402: adios (NULLCP, "unable to allocate folder storage"); ! 403: ! 404: j = mp -> hghmsg; ! 405: mp -> hghmsg += msgp - 1; ! 406: mp -> nummsg += msgp - 1; ! 407: if (mp -> hghsel > msgnum) ! 408: mp -> hghsel += msgp - 1; ! 409: ! 410: if (inplace && msgp > 1) ! 411: for (i = mp -> hghmsg; j > msgnum; i--, j--) { ! 412: if (verbosw) ! 413: printf ("message %d becomes message %d\n", j, i); ! 414: ! 415: Msgs[i].m_bboard_id = Msgs[j].m_bboard_id; ! 416: Msgs[i].m_top = Msgs[j].m_top; ! 417: Msgs[i].m_start = Msgs[j].m_start; ! 418: Msgs[i].m_stop = Msgs[j].m_stop; ! 419: Msgs[i].m_scanl = NULL; ! 420: if (Msgs[j].m_scanl) { ! 421: free (Msgs[j].m_scanl); ! 422: Msgs[j].m_scanl = NULL; ! 423: } ! 424: mp -> msgstats[i] = mp -> msgstats[j]; ! 425: } ! 426: ! 427: if (Msgs[msgnum].m_bboard_id == 0) ! 428: (void) readid (msgnum); ! 429: ! 430: mp -> msgstats[msgnum] &= ~SELECTED; ! 431: i = inplace ? msgnum + msgp - 1 : mp -> hghmsg; ! 432: for (j = msgp; j >= (inplace ? 1 : 2); i--, j--) { ! 433: if (verbosw && i != msgnum) ! 434: printf ("message %d of digest %d becomes message %d\n", ! 435: j, msgnum, i); ! 436: ! 437: Msgs[i].m_bboard_id = Msgs[msgnum].m_bboard_id; ! 438: Msgs[i].m_top = Msgs[j].m_top; ! 439: Msgs[i].m_start = smsgs[j].m_start; ! 440: Msgs[i].m_stop = smsgs[j].m_stop; ! 441: Msgs[i].m_scanl = NULL; ! 442: mp -> msgstats[i] = mp -> msgstats[msgnum]; ! 443: } ! 444: ! 445: return OK; ! 446: } ! 447: ! 448: /* */ ! 449: ! 450: static struct swit fileswit[] = { ! 451: #define FIDRFT 0 ! 452: "draft", 0, ! 453: #define FILINK 1 ! 454: "link", 0, ! 455: #define FINLINK 2 ! 456: "nolink", 0, ! 457: #define FIPRES 3 ! 458: "preserve", 0, ! 459: #define FINPRES 4 ! 460: "nopreserve", 0, ! 461: #define FISRC 5 ! 462: "src +folder", 0, ! 463: #define FIFILE 6 ! 464: "file file", 0, ! 465: #define FIHELP 7 ! 466: "help", 4, ! 467: ! 468: NULL, NULL ! 469: }; ! 470: ! 471: /* */ ! 472: ! 473: filecmd (args) ! 474: char **args; ! 475: { ! 476: int linksw = 0, ! 477: msgp = 0, ! 478: vecp = 1, ! 479: i, ! 480: msgnum; ! 481: char *cp, ! 482: buf[BUFSIZ], ! 483: *msgs[MAXARGS], ! 484: *vec[MAXARGS]; ! 485: ! 486: if (fmsh) { ! 487: forkcmd (args, cmd_name); ! 488: return; ! 489: } ! 490: ! 491: while (cp = *args++) { ! 492: if (*cp == '-') ! 493: switch (i = smatch (++cp, fileswit)) { ! 494: case AMBIGSW: ! 495: ambigsw (cp, fileswit); ! 496: return; ! 497: case UNKWNSW: ! 498: fprintf (stderr, "-%s unknown\n", cp); ! 499: return; ! 500: case FIHELP: ! 501: (void) sprintf (buf, "%s +folder... [msgs] [switches]", ! 502: cmd_name); ! 503: help (buf, fileswit); ! 504: return; ! 505: ! 506: case FILINK: ! 507: linksw++; ! 508: continue; ! 509: case FINLINK: ! 510: linksw = 0; ! 511: continue; ! 512: ! 513: case FIPRES: ! 514: case FINPRES: ! 515: continue; ! 516: ! 517: case FISRC: ! 518: case FIDRFT: ! 519: case FIFILE: ! 520: advise (NULLCP, "sorry, -%s not allowed!", fileswit[i].sw); ! 521: return; ! 522: } ! 523: if (*cp == '+' || *cp == '@') ! 524: vec[vecp++] = cp; ! 525: else ! 526: msgs[msgp++] = cp; ! 527: } ! 528: ! 529: vec[0] = cmd_name; ! 530: vec[vecp++] = "-file"; ! 531: vec[vecp] = NULL; ! 532: if (!msgp) ! 533: msgs[msgp++] = "cur"; ! 534: for (msgnum = 0; msgnum < msgp; msgnum++) ! 535: if (!m_convert (mp, msgs[msgnum])) ! 536: return; ! 537: m_setseq (mp); ! 538: ! 539: interrupted = 0; ! 540: for (msgnum = mp -> lowsel; ! 541: msgnum <= mp -> hghsel && !interrupted; ! 542: msgnum++) ! 543: if (mp -> msgstats[msgnum] & SELECTED) ! 544: if (process (msgnum, fileproc, vecp, vec)) { ! 545: mp -> msgstats[msgnum] &= ~SELECTED; ! 546: mp -> numsel--; ! 547: } ! 548: ! 549: if (mp -> numsel != mp -> nummsg || linksw) ! 550: m_setcur (mp, mp -> hghsel); ! 551: if (!linksw) ! 552: rmm (); ! 553: } ! 554: ! 555: /* */ ! 556: ! 557: int filehak (args) ! 558: char **args; ! 559: { ! 560: int result, ! 561: vecp = 0; ! 562: char *cp, ! 563: *cwd, ! 564: *vec[MAXARGS]; ! 565: ! 566: while (cp = *args++) { ! 567: if (*cp == '-') ! 568: switch (smatch (++cp, fileswit)) { ! 569: case AMBIGSW: ! 570: case UNKWNSW: ! 571: case FIHELP: ! 572: return NOTOK; ! 573: ! 574: case FILINK: ! 575: case FINLINK: ! 576: case FIPRES: ! 577: case FINPRES: ! 578: continue; ! 579: ! 580: case FISRC: ! 581: case FIDRFT: ! 582: case FIFILE: ! 583: return NOTOK; ! 584: } ! 585: if (*cp == '+' || *cp == '@') ! 586: vec[vecp++] = cp; ! 587: } ! 588: vec[vecp] = NULL; ! 589: ! 590: result = NOTOK; ! 591: cwd = NULL; ! 592: for (vecp = 0; (cp = vec[vecp]) && result == NOTOK; vecp++) { ! 593: if (cwd == NULL) ! 594: cwd = getcpy (pwd ()); ! 595: (void) chdir (m_maildir ("")); ! 596: cp = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF); ! 597: if (access (m_maildir (cp), 0) == NOTOK) ! 598: result = OK; ! 599: free (cp); ! 600: } ! 601: if (cwd) ! 602: (void) chdir (cwd); ! 603: ! 604: return result; ! 605: } ! 606: ! 607: /* */ ! 608: ! 609: static struct swit foldswit[] = { ! 610: #define FLALSW 0 ! 611: "all", 0, ! 612: #define FLFASW 1 ! 613: "fast", 0, ! 614: #define FLNFASW 2 ! 615: "nofast", 0, ! 616: #define FLHDSW 3 ! 617: "header", 0, ! 618: #define FLNHDSW 4 ! 619: "noheader", 0, ! 620: #define FLPKSW 5 ! 621: "pack", 0, ! 622: #define FLNPKSW 6 ! 623: "nopack", 0, ! 624: #define FLRCSW 7 ! 625: "recurse", 0, ! 626: #define FLNRCSW 8 ! 627: "norecurse", 0, ! 628: #define FLTLSW 9 ! 629: "total", 0, ! 630: #define FLNTLSW 10 ! 631: "nototal", 0, ! 632: #define FLPRSW 11 ! 633: "print", 0, ! 634: #define FLPUSW 12 ! 635: "push", 0, ! 636: #define FLPOSW 13 ! 637: "pop", 0, ! 638: #define FLLISW 14 ! 639: "list", 0, ! 640: #define FLHELP 15 ! 641: "help", 4, ! 642: ! 643: NULL, NULL ! 644: }; ! 645: ! 646: /* */ ! 647: ! 648: foldcmd (args) ! 649: char **args; ! 650: { ! 651: int fastsw = 0, ! 652: headersw = 0, ! 653: packsw = 0, ! 654: hole, ! 655: msgnum; ! 656: char *cp, ! 657: *folder = NULL, ! 658: *msg = NULL, ! 659: buf[BUFSIZ], ! 660: **vec = args; ! 661: ! 662: if (args == NULL) ! 663: goto fast; ! 664: ! 665: while (cp = *args++) { ! 666: if (*cp == '-') ! 667: switch (smatch (++cp, foldswit)) { ! 668: case AMBIGSW: ! 669: ambigsw (cp, foldswit); ! 670: return; ! 671: case UNKWNSW: ! 672: fprintf (stderr, "-%s unknown\n", cp); ! 673: return; ! 674: case FLHELP: ! 675: (void) sprintf (buf, "%s [+folder] [msg] [switches]", ! 676: cmd_name); ! 677: help (buf, foldswit); ! 678: return; ! 679: ! 680: case FLALSW: /* not implemented */ ! 681: case FLRCSW: ! 682: case FLNRCSW: ! 683: case FLTLSW: ! 684: case FLNTLSW: ! 685: case FLPRSW: ! 686: case FLPUSW: ! 687: case FLPOSW: ! 688: case FLLISW: ! 689: continue; ! 690: ! 691: case FLFASW: ! 692: fastsw++; ! 693: continue; ! 694: case FLNFASW: ! 695: fastsw = 0; ! 696: continue; ! 697: case FLHDSW: ! 698: headersw++; ! 699: continue; ! 700: case FLNHDSW: ! 701: headersw = 0; ! 702: continue; ! 703: case FLPKSW: ! 704: packsw++; ! 705: continue; ! 706: case FLNPKSW: ! 707: packsw = 0; ! 708: continue; ! 709: } ! 710: if (*cp == '+' || *cp == '@') ! 711: if (folder) { ! 712: advise (NULLCP, "only one folder at a time!\n"); ! 713: return; ! 714: } ! 715: else ! 716: folder = fmsh ? path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF) ! 717: : cp + 1; ! 718: else ! 719: if (msg) { ! 720: advise (NULLCP, "only one message at a time!\n"); ! 721: return; ! 722: } ! 723: else ! 724: msg = cp; ! 725: } ! 726: ! 727: if (folder) { ! 728: if (*folder == NULL) { ! 729: advise (NULLCP, "null folder names are not permitted"); ! 730: return; ! 731: } ! 732: if (fmsh) { ! 733: if (access (m_maildir (folder), 04) == NOTOK) { ! 734: advise (folder, "unable to read"); ! 735: return; ! 736: } ! 737: } ! 738: else { ! 739: (void) strcpy (buf, folder); ! 740: if (expand (buf) == NOTOK) ! 741: return; ! 742: folder = buf; ! 743: if (access (folder, 04) == NOTOK) { ! 744: advise (folder, "unable to read"); ! 745: return; ! 746: } ! 747: } ! 748: m_reset (); ! 749: ! 750: if (fmsh) ! 751: fsetup (folder); ! 752: else ! 753: setup (folder); ! 754: readids (0); ! 755: display_info (0); ! 756: } ! 757: ! 758: if (msg) { ! 759: if (!m_convert (mp, msg)) ! 760: return; ! 761: m_setseq (mp); ! 762: ! 763: if (mp -> numsel > 1) { ! 764: advise (NULLCP, "only one message at a time!"); ! 765: return; ! 766: } ! 767: m_setcur (mp, mp -> hghsel); ! 768: } ! 769: ! 770: if (packsw) { ! 771: if (fmsh) { ! 772: forkcmd (vec, cmd_name); ! 773: return; ! 774: } ! 775: ! 776: if (mp -> lowmsg > 1 && (mp = m_remsg (mp, 1, mp -> hghmsg)) == NULL) ! 777: adios (NULLCP, "unable to allocate folder storage"); ! 778: for (msgnum = mp -> lowmsg, hole = 1; msgnum <= mp -> hghmsg; msgnum++) ! 779: if (mp -> msgstats[msgnum] & EXISTS) { ! 780: if (msgnum != hole) { ! 781: Msgs[hole].m_bboard_id = Msgs[msgnum].m_bboard_id; ! 782: Msgs[hole].m_top = Msgs[msgnum].m_top; ! 783: Msgs[hole].m_start = Msgs[msgnum].m_start; ! 784: Msgs[hole].m_stop = Msgs[msgnum].m_stop; ! 785: Msgs[hole].m_scanl = NULL; ! 786: if (Msgs[msgnum].m_scanl) { ! 787: free (Msgs[msgnum].m_scanl); ! 788: Msgs[msgnum].m_scanl = NULL; ! 789: } ! 790: mp -> msgstats[hole] = mp -> msgstats[msgnum]; ! 791: if (mp -> curmsg == msgnum) ! 792: m_setcur (mp, hole); ! 793: } ! 794: hole++; ! 795: } ! 796: if (mp -> nummsg > 0) { ! 797: mp -> lowmsg = 1; ! 798: mp -> hghmsg = hole - 1; ! 799: } ! 800: mp -> msgflags |= MODIFIED; ! 801: modified++; ! 802: } ! 803: ! 804: fast: ; ! 805: if (fastsw) ! 806: printf ("%s\n", fmsh ? fmsh : mp -> foldpath); ! 807: else { ! 808: if (headersw) ! 809: printf ("\t\tFolder %*s# of messages (%*srange%*s); cur%*smsg\n", ! 810: DMAXFOLDER, "", DMAXFOLDER - 2, "", DMAXFOLDER - 2, "", ! 811: DMAXFOLDER - 2, ""); ! 812: printf (args ? "%22s " : "%s ", fmsh ? fmsh : mp -> foldpath); ! 813: if (mp -> hghmsg == 0) ! 814: printf ("has no messages%*s", ! 815: mp -> msgflags & OTHERS ? DMAXFOLDER * 2 + 4 : 0, ""); ! 816: else { ! 817: printf ("has %*d message%s (%*d-%*d)", ! 818: DMAXFOLDER, mp -> nummsg, mp -> nummsg != 1 ? "s" : "", ! 819: DMAXFOLDER, mp -> lowmsg, DMAXFOLDER, mp -> hghmsg); ! 820: if (mp -> curmsg >= mp -> lowmsg ! 821: && mp -> curmsg <= mp -> hghmsg) ! 822: printf ("; cur=%*d", DMAXFOLDER, mp -> curmsg); ! 823: } ! 824: printf (".\n"); ! 825: } ! 826: } ! 827: ! 828: /* */ ! 829: ! 830: static struct swit forwswit[] = { ! 831: #define FOANSW 0 ! 832: "annotate", 0, ! 833: #define FONANSW 1 ! 834: "noannotate", 0, ! 835: #define FODFSW 2 ! 836: "draftfolder +folder", 0, ! 837: #define FODMSW 3 ! 838: "draftmessage msg", 0, ! 839: #define FONDFSW 4 ! 840: "nodraftfolder", 0, ! 841: #define FOEDTSW 5 ! 842: "editor editor", 0, ! 843: #define FONEDSW 6 ! 844: "noedit", 0, ! 845: #define FOFTRSW 7 ! 846: "filter filterfile", 0, ! 847: #define FOFRMSW 8 ! 848: "form formfile", 0, ! 849: #define FOFTSW 9 ! 850: "format", 5, ! 851: #define FONFTSW 10 ! 852: "noformat", 7, ! 853: #define FOINSW 11 ! 854: "inplace", 0, ! 855: #define FONINSW 12 ! 856: "noinplace", 0, ! 857: #define FOWHTSW 13 ! 858: "whatnowproc program", 0, ! 859: #define FONWTSW 14 ! 860: "nowhatnow", 0, ! 861: #define FOHELP 15 ! 862: "help", 4, ! 863: ! 864: NULL, NULL ! 865: }; ! 866: ! 867: /* */ ! 868: ! 869: forwcmd (args) ! 870: char **args; ! 871: { ! 872: int msgp = 0, ! 873: vecp = 1, ! 874: msgnum; ! 875: char *cp, ! 876: *filter = NULL, ! 877: buf[BUFSIZ], ! 878: *msgs[MAXARGS], ! 879: *vec[MAXARGS]; ! 880: ! 881: if (fmsh) { ! 882: forkcmd (args, cmd_name); ! 883: return; ! 884: } ! 885: ! 886: while (cp = *args++) { ! 887: if (*cp == '-') ! 888: switch (smatch (++cp, forwswit)) { ! 889: case AMBIGSW: ! 890: ambigsw (cp, forwswit); ! 891: return; ! 892: case UNKWNSW: ! 893: fprintf (stderr, "-%s unknown\n", cp); ! 894: return; ! 895: case FOHELP: ! 896: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); ! 897: help (buf, forwswit); ! 898: return; ! 899: ! 900: case FOANSW: /* not implemented */ ! 901: case FONANSW: ! 902: case FOINSW: ! 903: case FONINSW: ! 904: continue; ! 905: ! 906: case FONDFSW: ! 907: case FONEDSW: ! 908: case FONWTSW: ! 909: vec[vecp++] = --cp; ! 910: continue; ! 911: ! 912: case FOEDTSW: ! 913: case FOFRMSW: ! 914: case FODFSW: ! 915: case FODMSW: ! 916: case FOWHTSW: ! 917: vec[vecp++] = --cp; ! 918: if (!(cp = *args++) || *cp == '-') { ! 919: advise (NULLCP, "missing argument to %s", args[-2]); ! 920: return; ! 921: } ! 922: vec[vecp++] = cp; ! 923: continue; ! 924: case FOFTRSW: ! 925: if (!(filter = *args++) || *filter == '-') { ! 926: advise (NULLCP, "missing argument to %s", args[-2]); ! 927: return; ! 928: } ! 929: continue; ! 930: case FOFTSW: ! 931: if (access (filter = myfilter, 04) == NOTOK) { ! 932: advise (filter, "unable to read default filter file"); ! 933: return; ! 934: } ! 935: continue; ! 936: case FONFTSW: ! 937: filter = NULL; ! 938: continue; ! 939: } ! 940: if (*cp == '+' || *cp == '@') { ! 941: advise (NULLCP, "sorry, no folders allowed!"); ! 942: return; ! 943: } ! 944: else ! 945: msgs[msgp++] = cp; ! 946: } ! 947: ! 948: /* foil search of .mh_profile */ ! 949: (void) sprintf (buf, "%sXXXXXX", invo_name); ! 950: vec[0] = mktemp (buf); ! 951: vec[vecp++] = "-file"; ! 952: vec[vecp] = NULL; ! 953: if (!msgp) ! 954: msgs[msgp++] = "cur"; ! 955: for (msgnum = 0; msgnum < msgp; msgnum++) ! 956: if (!m_convert (mp, msgs[msgnum])) ! 957: return; ! 958: m_setseq (mp); ! 959: ! 960: if (filter) { ! 961: (void) strcpy (buf, filter); ! 962: if (expand (buf) == NOTOK) ! 963: return; ! 964: if (access (filter = getcpy (libpath (buf)), 04) == NOTOK) { ! 965: advise (filter, "unable to read"); ! 966: free (filter); ! 967: return; ! 968: } ! 969: } ! 970: forw (cmd_name, filter, vecp, vec); ! 971: m_setcur (mp, mp -> hghsel); ! 972: if (filter) ! 973: free (filter); ! 974: } ! 975: ! 976: /* */ ! 977: ! 978: static forw (proc, filter, vecp, vec) ! 979: int vecp; ! 980: char *proc, ! 981: *filter, ! 982: **vec; ! 983: { ! 984: int i, ! 985: child_id, ! 986: msgnum, ! 987: msgcnt; ! 988: char tmpfil[80], ! 989: *args[MAXARGS]; ! 990: FILE *out; ! 991: ! 992: (void) strcpy (tmpfil, m_tmpfil (invo_name)); ! 993: interrupted = 0; ! 994: if (filter) ! 995: switch (child_id = fork ()) { ! 996: case NOTOK: ! 997: advise ("fork", "unable to"); ! 998: return; ! 999: ! 1000: case OK: /* "trust me" */ ! 1001: if (freopen (tmpfil, "w", stdout) == NULL) { ! 1002: fprintf (stderr, "unable to create "); ! 1003: perror (tmpfil); ! 1004: _exit (1); ! 1005: } ! 1006: args[0] = r1bindex (mhlproc, '/'); ! 1007: i = 1; ! 1008: args[i++] = "-forwall"; ! 1009: args[i++] = "-form"; ! 1010: args[i++] = filter; ! 1011: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 1012: if (mp -> msgstats[msgnum] & SELECTED) ! 1013: args[i++] = getcpy (m_name (msgnum)); ! 1014: args[i] = NULL; ! 1015: (void) mhlsbr (i, args, mhl_action); ! 1016: m_eomsbr ((int (*) ()) 0); ! 1017: (void) fclose (stdout); ! 1018: _exit (0); ! 1019: ! 1020: default: ! 1021: if (pidXwait (child_id, NULLCP)) ! 1022: interrupted++; ! 1023: break; ! 1024: } ! 1025: else { ! 1026: if ((out = fopen (tmpfil, "w")) == NULL) { ! 1027: advise (tmpfil, "unable to create temporary file"); ! 1028: return; ! 1029: } ! 1030: ! 1031: msgcnt = 1; ! 1032: for (msgnum = mp -> lowsel; ! 1033: msgnum <= mp -> hghsel && !interrupted; ! 1034: msgnum++) ! 1035: if (mp -> msgstats[msgnum] & SELECTED) { ! 1036: fprintf (out, "\n\n-------"); ! 1037: if (msgnum == mp -> lowsel) ! 1038: fprintf (out, " Forwarded Message%s", ! 1039: mp -> numsel > 1 ? "s" : ""); ! 1040: else ! 1041: fprintf (out, " Message %d", msgcnt); ! 1042: fprintf (out, "\n\n"); ! 1043: copy_digest (msgnum, out); ! 1044: msgcnt++; ! 1045: } ! 1046: ! 1047: fprintf (out, "\n\n------- End of Forwarded Message%s\n", ! 1048: mp -> numsel > 1 ? "s" : ""); ! 1049: (void) fclose (out); ! 1050: } ! 1051: ! 1052: (void) fflush (stdout); ! 1053: if (!interrupted) ! 1054: switch (child_id = fork ()) { ! 1055: case NOTOK: ! 1056: advise ("fork", "unable to"); ! 1057: break; ! 1058: ! 1059: case OK: ! 1060: closefds (3); ! 1061: (void) signal (SIGINT, istat); ! 1062: (void) signal (SIGQUIT, qstat); ! 1063: ! 1064: vec[vecp++] = tmpfil; ! 1065: vec[vecp] = NULL; ! 1066: ! 1067: execvp (proc, vec); ! 1068: fprintf (stderr, "unable to exec "); ! 1069: perror (proc); ! 1070: _exit (1); ! 1071: ! 1072: default: ! 1073: (void) pidXwait (child_id, NULLCP); ! 1074: break; ! 1075: } ! 1076: ! 1077: (void) unlink (tmpfil); ! 1078: } ! 1079: ! 1080: /* */ ! 1081: ! 1082: static char *hlpmsg[] = { ! 1083: "The %s program emulates many of the commands found in the Rand MH", ! 1084: "system. Instead of operating on MH folders, commands to %s concern", ! 1085: "a single file.", ! 1086: "", ! 1087: "To see the list of commands available, just type a ``?'' followed by", ! 1088: "the RETURN key. To find out what switches each command takes, type", ! 1089: "the name of the command followed by ``-help''. To leave %s, use the", ! 1090: "``quit'' command.", ! 1091: "", ! 1092: "Although a lot of MH commands are found in %s, not all are fully", ! 1093: "implemented. %s will always recognize all legal switches for a", ! 1094: "given command though, and will let you know when you ask for an", ! 1095: "option that it is unable to perform.", ! 1096: "", ! 1097: "Running %s is fun, but using MH from your shell is far superior.", ! 1098: "After you have familiarized yourself with the MH style by using %s,", ! 1099: "you should try using MH from the shell. You can still use %s for", ! 1100: "message files that aren't in MH format, such as BBoard files.", ! 1101: NULL ! 1102: }; ! 1103: ! 1104: ! 1105: /* ARGSUSED */ ! 1106: ! 1107: helpcmd (args) ! 1108: char **args; ! 1109: { ! 1110: int i; ! 1111: ! 1112: for (i = 0; hlpmsg[i]; i++) { ! 1113: printf (hlpmsg[i], invo_name); ! 1114: (void) putchar ('\n'); ! 1115: } ! 1116: } ! 1117: ! 1118: /* */ ! 1119: ! 1120: static struct swit markswit[] = { ! 1121: #define MADDSW 0 ! 1122: "add", 0, ! 1123: #define MDELSW 1 ! 1124: "delete", 0, ! 1125: #define MLSTSW 2 ! 1126: "list", 0, ! 1127: #define MSEQSW 3 ! 1128: "sequence name", 0, ! 1129: #define MPUBSW 4 ! 1130: "public", 0, ! 1131: #define MNPUBSW 5 ! 1132: "nopublic", 0, ! 1133: #define MZERSW 6 ! 1134: "zero", 0, ! 1135: #define MNZERSW 7 ! 1136: "nozero", 0, ! 1137: #define MHELP 8 ! 1138: "help", 4, ! 1139: #define MDBUGSW 9 ! 1140: "debug", -5, ! 1141: ! 1142: NULL, NULL ! 1143: }; ! 1144: ! 1145: /* */ ! 1146: ! 1147: markcmd (args) ! 1148: char **args; ! 1149: { ! 1150: int addsw = 0, ! 1151: deletesw = 0, ! 1152: debugsw = 0, ! 1153: listsw = 0, ! 1154: zerosw = 0, ! 1155: seqp = 0, ! 1156: msgp = 0, ! 1157: i, ! 1158: msgnum; ! 1159: char *cp, ! 1160: buf[BUFSIZ], ! 1161: *seqs[NATTRS + 1], ! 1162: *msgs[MAXARGS]; ! 1163: ! 1164: while (cp = *args++) { ! 1165: if (*cp == '-') ! 1166: switch (smatch (++cp, markswit)) { ! 1167: case AMBIGSW: ! 1168: ambigsw (cp, markswit); ! 1169: return; ! 1170: case UNKWNSW: ! 1171: fprintf (stderr, "-%s unknown\n", cp); ! 1172: return; ! 1173: case MHELP: ! 1174: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); ! 1175: help (buf, markswit); ! 1176: return; ! 1177: ! 1178: case MADDSW: ! 1179: addsw++; ! 1180: deletesw = listsw = 0; ! 1181: continue; ! 1182: case MDELSW: ! 1183: deletesw++; ! 1184: addsw = listsw = 0; ! 1185: continue; ! 1186: case MLSTSW: ! 1187: listsw++; ! 1188: addsw = deletesw = 0; ! 1189: continue; ! 1190: ! 1191: case MSEQSW: ! 1192: if (!(cp = *args++) || *cp == '-') { ! 1193: advise (NULLCP, "missing argument to %s", args[-2]); ! 1194: return; ! 1195: } ! 1196: if (seqp < NATTRS) ! 1197: seqs[seqp++] = cp; ! 1198: else { ! 1199: advise (NULLCP, "only %d sequences allowed!", NATTRS); ! 1200: return; ! 1201: } ! 1202: continue; ! 1203: ! 1204: case MPUBSW: /* not implemented */ ! 1205: case MNPUBSW: ! 1206: continue; ! 1207: ! 1208: case MDBUGSW: ! 1209: debugsw++; ! 1210: continue; ! 1211: ! 1212: case MZERSW: ! 1213: zerosw++; ! 1214: continue; ! 1215: case MNZERSW: ! 1216: zerosw = 0; ! 1217: continue; ! 1218: } ! 1219: if (*cp == '+' || *cp == '@') { ! 1220: advise (NULLCP, "sorry, no folders allowed!"); ! 1221: return; ! 1222: } ! 1223: else ! 1224: msgs[msgp++] = cp; ! 1225: } ! 1226: ! 1227: if (!addsw && !deletesw && !listsw) ! 1228: if (seqp) ! 1229: addsw++; ! 1230: else ! 1231: if (debugsw) ! 1232: listsw++; ! 1233: else { ! 1234: seqs[seqp++] = "unseen"; ! 1235: deletesw++; ! 1236: zerosw = 0; ! 1237: if (!msgp) ! 1238: msgs[msgp++] = "all"; ! 1239: } ! 1240: ! 1241: if (!msgp) ! 1242: msgs[msgp++] = listsw ? "all" :"cur"; ! 1243: for (msgnum = 0; msgnum < msgp; msgnum++) ! 1244: if (!m_convert (mp, msgs[msgnum])) ! 1245: return; ! 1246: ! 1247: if (debugsw) { ! 1248: printf ("invo_name=%s mypath=%s defpath=%s\n", ! 1249: invo_name, mypath, defpath); ! 1250: printf ("ctxpath=%s context flags=%s\n", ! 1251: ctxpath, sprintb (buf, (unsigned) ctxflags, DBITS)); ! 1252: printf ("foldpath=%s flags=%s\n", ! 1253: mp -> foldpath, ! 1254: sprintb (buf, (unsigned) mp -> msgflags, FBITS)); ! 1255: printf ("hghmsg=%d lowmsg=%d nummsg=%d curmsg=%d\n", ! 1256: mp -> hghmsg, mp -> lowmsg, mp -> nummsg, mp -> curmsg); ! 1257: printf ("lowsel=%d hghsel=%d numsel=%d\n", ! 1258: mp -> lowsel, mp -> hghsel, mp -> numsel); ! 1259: #ifndef MTR ! 1260: printf ("lowoff=%d hghoff=%d\n", ! 1261: mp -> lowoff, mp -> hghoff); ! 1262: #else MTR ! 1263: printf ("lowoff=%d hghoff=%d msgbase=0x%x msgstats=0x%x\n", ! 1264: mp -> lowoff, mp -> hghoff, mp -> msgbase, mp -> msgstats); ! 1265: #endif MTR ! 1266: } ! 1267: ! 1268: if (seqp == 0 && (addsw || deletesw)) { ! 1269: advise (NULLCP, "-%s requires at least one -sequence argument", ! 1270: addsw ? "add" : "delete"); ! 1271: return; ! 1272: } ! 1273: seqs[seqp] = NULL; ! 1274: ! 1275: if (addsw) ! 1276: for (seqp = 0; seqs[seqp]; seqp++) { ! 1277: if (zerosw && !m_seqnew (mp, seqs[seqp], 0)) ! 1278: return; ! 1279: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 1280: if (mp -> msgstats[msgnum] & SELECTED) ! 1281: if (!m_seqadd (mp, seqs[seqp], msgnum, 0)) ! 1282: return; ! 1283: } ! 1284: ! 1285: if (deletesw) ! 1286: for (seqp = 0; seqs[seqp]; seqp++) { ! 1287: if (zerosw) ! 1288: for (msgnum = mp -> lowmsg; msgnum <= mp -> hghmsg; msgnum++) ! 1289: if (mp -> msgstats[msgnum] & EXISTS) ! 1290: if (!m_seqadd (mp, seqs[seqp], msgnum, 0)) ! 1291: return; ! 1292: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 1293: if (mp -> msgstats[msgnum] & SELECTED) ! 1294: if (!m_seqdel (mp, seqs[seqp], msgnum)) ! 1295: return; ! 1296: } ! 1297: ! 1298: if (listsw) { ! 1299: int bits = FFATTRSLOT; ! 1300: ! 1301: if (seqp == 0) ! 1302: for (i = 0; mp -> msgattrs[i]; i++) ! 1303: printf ("%s%s: %s\n", mp -> msgattrs[i], ! 1304: mp -> attrstats & (1 << (bits + i)) ! 1305: ? " (private)" : "", ! 1306: m_seq (mp, mp -> msgattrs[i])); ! 1307: else ! 1308: for (seqp = 0; seqs[seqp]; seqp++) ! 1309: printf ("%s%s: %s\n", seqs[seqp], m_seq (mp, seqs[seqp])); ! 1310: ! 1311: interrupted = 0; ! 1312: if (debugsw) ! 1313: for (msgnum = mp -> lowsel; ! 1314: msgnum <= mp -> hghsel && !interrupted; ! 1315: msgnum++) ! 1316: if (mp -> msgstats[msgnum] & SELECTED) { ! 1317: printf ("%*d: id=%d top=%d start=%ld stop=%ld %s\n", ! 1318: DMAXFOLDER, msgnum, ! 1319: Msgs[msgnum].m_bboard_id, Msgs[msgnum].m_top, ! 1320: Msgs[msgnum].m_start, Msgs[msgnum].m_stop, ! 1321: sprintb (buf, (unsigned) mp -> msgstats[msgnum], ! 1322: m_seqbits (mp))); ! 1323: if (Msgs[msgnum].m_scanl) ! 1324: printf ("%s", Msgs[msgnum].m_scanl); ! 1325: } ! 1326: } ! 1327: } ! 1328: ! 1329: /* */ ! 1330: ! 1331: static struct swit packswit[] = { ! 1332: #define PAFISW 0 ! 1333: "file name", 0, ! 1334: ! 1335: #define PAHELP 1 ! 1336: "help", 4, ! 1337: ! 1338: NULL, NULL ! 1339: }; ! 1340: ! 1341: /* */ ! 1342: ! 1343: packcmd (args) ! 1344: char **args; ! 1345: { ! 1346: int msgp = 0, ! 1347: md, ! 1348: msgnum; ! 1349: char *cp, ! 1350: *file = NULL, ! 1351: buf[BUFSIZ], ! 1352: *msgs[MAXARGS]; ! 1353: struct stat st; ! 1354: ! 1355: if (fmsh) { ! 1356: forkcmd (args, cmd_name); ! 1357: return; ! 1358: } ! 1359: ! 1360: while (cp = *args++) { ! 1361: if (*cp == '-') ! 1362: switch (smatch (++cp, packswit)) { ! 1363: case AMBIGSW: ! 1364: ambigsw (cp, packswit); ! 1365: return; ! 1366: case UNKWNSW: ! 1367: fprintf (stderr, "-%s unknown\n", cp); ! 1368: return; ! 1369: case PAHELP: ! 1370: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); ! 1371: help (buf, packswit); ! 1372: return; ! 1373: ! 1374: case PAFISW: ! 1375: if (!(file = *args++) || *file == '-') { ! 1376: advise (NULLCP, "missing argument to %s", args[-2]); ! 1377: return; ! 1378: } ! 1379: continue; ! 1380: } ! 1381: if (*cp == '+' || *cp == '@') { ! 1382: advise (NULLCP, "sorry, no folders allowed!"); ! 1383: return; ! 1384: } ! 1385: else ! 1386: msgs[msgp++] = cp; ! 1387: } ! 1388: ! 1389: if (!file) ! 1390: file = "./msgbox"; ! 1391: file = path (file, TFILE); ! 1392: if (stat (file, &st) == NOTOK) { ! 1393: if (errno != ENOENT) { ! 1394: advise (file, "error on file"); ! 1395: goto done_pack; ! 1396: } ! 1397: md = getanswer (cp = concat ("Create file \"", file, "\"? ", NULLCP)); ! 1398: free (cp); ! 1399: if (!md) ! 1400: goto done_pack; ! 1401: } ! 1402: ! 1403: if (!msgp) ! 1404: msgs[msgp++] = "all"; ! 1405: for (msgnum = 0; msgnum < msgp; msgnum++) ! 1406: if (!m_convert (mp, msgs[msgnum])) ! 1407: goto done_pack; ! 1408: m_setseq (mp); ! 1409: ! 1410: if ((md = mbx_open (file, getuid (), getgid (), m_gmprot ())) == NOTOK) { ! 1411: advise (file, "unable to open"); ! 1412: goto done_pack; ! 1413: } ! 1414: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 1415: if (mp -> msgstats[msgnum] & SELECTED) ! 1416: if (pack (file, md, msgnum) == NOTOK) ! 1417: break; ! 1418: (void) mbx_close (file, md); ! 1419: ! 1420: if (mp -> hghsel != mp -> curmsg) ! 1421: m_setcur (mp, mp -> lowsel); ! 1422: ! 1423: done_pack: ; ! 1424: free (file); ! 1425: } ! 1426: ! 1427: /* */ ! 1428: ! 1429: int pack (mailbox, md, msgnum) ! 1430: char *mailbox; ! 1431: int md, ! 1432: msgnum; ! 1433: { ! 1434: register FILE *zp; ! 1435: ! 1436: if (Msgs[msgnum].m_bboard_id == 0) ! 1437: (void) readid (msgnum); ! 1438: ! 1439: zp = msh_ready (msgnum, 1); ! 1440: return mbx_write (mailbox, md, zp, Msgs[msgnum].m_bboard_id, ! 1441: ftell (zp), Msgs[msgnum].m_stop, 1, 1); ! 1442: } ! 1443: ! 1444: /* */ ! 1445: ! 1446: int packhak (args) ! 1447: char **args; ! 1448: { ! 1449: int result; ! 1450: char *cp, ! 1451: *file = NULL; ! 1452: ! 1453: while (cp = *args++) { ! 1454: if (*cp == '-') ! 1455: switch (smatch (++cp, packswit)) { ! 1456: case AMBIGSW: ! 1457: case UNKWNSW: ! 1458: case PAHELP: ! 1459: return NOTOK; ! 1460: ! 1461: case PAFISW: ! 1462: if (!(file = *args++) || *file == '-') ! 1463: return NOTOK; ! 1464: continue; ! 1465: } ! 1466: if (*cp == '+' || *cp == '@') ! 1467: return NOTOK; ! 1468: } ! 1469: ! 1470: file = path (file ? file : "./msgbox", TFILE); ! 1471: result = access (file, 0) == NOTOK ? OK : NOTOK; ! 1472: free (file); ! 1473: ! 1474: return result; ! 1475: } ! 1476: ! 1477: /* */ ! 1478: ! 1479: static struct swit pickswit[] = { ! 1480: #define PIANSW 0 ! 1481: "and", 0, ! 1482: #define PIORSW 1 ! 1483: "or", 0, ! 1484: #define PINTSW 2 ! 1485: "not", 0, ! 1486: #define PILBSW 3 ! 1487: "lbrace", 0, ! 1488: #define PIRBSW 4 ! 1489: "rbrace", 0, ! 1490: ! 1491: #define PICCSW 5 ! 1492: "cc pattern", 0, ! 1493: #define PIDASW 6 ! 1494: "date pattern", 0, ! 1495: #define PIFRSW 7 ! 1496: "from pattern", 0, ! 1497: #define PISESW 8 ! 1498: "search pattern", 0, ! 1499: #define PISUSW 9 ! 1500: "subject pattern", 0, ! 1501: #define PITOSW 10 ! 1502: "to pattern", 0, ! 1503: #define PIOTSW 11 ! 1504: "-othercomponent pattern", 15, ! 1505: #define PIAFSW 12 ! 1506: "after date", 0, ! 1507: #define PIBFSW 13 ! 1508: "before date", 0, ! 1509: #define PIDFSW 14 ! 1510: "datefield field", 5, ! 1511: #define PISQSW 15 ! 1512: "sequence name", 0, ! 1513: #define PIPUSW 16 ! 1514: "public", 0, ! 1515: #define PINPUSW 17 ! 1516: "nopublic", 0, ! 1517: #define PIZRSW 18 ! 1518: "zero", 0, ! 1519: #define PINZRSW 19 ! 1520: "nozero", 0, ! 1521: #define PILISW 20 ! 1522: "list", 0, ! 1523: #define PINLISW 21 ! 1524: "nolist", 0, ! 1525: #define PIHELP 22 ! 1526: "help", 4, ! 1527: ! 1528: NULL, NULL ! 1529: }; ! 1530: ! 1531: /* */ ! 1532: ! 1533: pickcmd (args) ! 1534: char **args; ! 1535: { ! 1536: int zerosw = 1, ! 1537: msgp = 0, ! 1538: seqp = 0, ! 1539: vecp = 0, ! 1540: hi, ! 1541: lo, ! 1542: msgnum; ! 1543: char *cp, ! 1544: buf[BUFSIZ], ! 1545: *msgs[MAXARGS], ! 1546: *seqs[NATTRS], ! 1547: *vec[MAXARGS]; ! 1548: register FILE *zp; ! 1549: ! 1550: while (cp = *args++) { ! 1551: if (*cp == '-') { ! 1552: if (*++cp == '-') { ! 1553: vec[vecp++] = --cp; ! 1554: goto pattern; ! 1555: } ! 1556: switch (smatch (cp, pickswit)) { ! 1557: case AMBIGSW: ! 1558: ambigsw (cp, pickswit); ! 1559: return; ! 1560: case UNKWNSW: ! 1561: fprintf (stderr, "-%s unknown\n", cp); ! 1562: return; ! 1563: case PIHELP: ! 1564: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); ! 1565: help (buf, pickswit); ! 1566: return; ! 1567: ! 1568: case PICCSW: ! 1569: case PIDASW: ! 1570: case PIFRSW: ! 1571: case PISUSW: ! 1572: case PITOSW: ! 1573: case PIDFSW: ! 1574: case PIAFSW: ! 1575: case PIBFSW: ! 1576: case PISESW: ! 1577: vec[vecp++] = --cp; ! 1578: pattern: ; ! 1579: if (!(cp = *args++)) {/* allow -xyz arguments */ ! 1580: advise (NULLCP, "missing argument to %s", args[-2]); ! 1581: return; ! 1582: } ! 1583: vec[vecp++] = cp; ! 1584: continue; ! 1585: case PIOTSW: ! 1586: advise (NULLCP, "internal error!"); ! 1587: return; ! 1588: case PIANSW: ! 1589: case PIORSW: ! 1590: case PINTSW: ! 1591: case PILBSW: ! 1592: case PIRBSW: ! 1593: vec[vecp++] = --cp; ! 1594: continue; ! 1595: ! 1596: case PISQSW: ! 1597: if (!(cp = *args++) || *cp == '-') { ! 1598: advise (NULLCP, "missing argument to %s", args[-2]); ! 1599: return; ! 1600: } ! 1601: if (seqp < NATTRS) ! 1602: seqs[seqp++] = cp; ! 1603: else { ! 1604: advise (NULLCP, "only %d sequences allowed!", NATTRS); ! 1605: return; ! 1606: } ! 1607: continue; ! 1608: case PIZRSW: ! 1609: zerosw++; ! 1610: continue; ! 1611: case PINZRSW: ! 1612: zerosw = 0; ! 1613: continue; ! 1614: ! 1615: case PIPUSW: /* not implemented */ ! 1616: case PINPUSW: ! 1617: case PILISW: ! 1618: case PINLISW: ! 1619: continue; ! 1620: } ! 1621: } ! 1622: if (*cp == '+' || *cp == '@') { ! 1623: advise (NULLCP, "sorry, no folders allowed!"); ! 1624: return; ! 1625: } ! 1626: else ! 1627: msgs[msgp++] = cp; ! 1628: } ! 1629: vec[vecp] = NULL; ! 1630: ! 1631: if (!msgp) ! 1632: msgs[msgp++] = "all"; ! 1633: for (msgnum = 0; msgnum < msgp; msgnum++) ! 1634: if (!m_convert (mp, msgs[msgnum])) ! 1635: return; ! 1636: m_setseq (mp); ! 1637: ! 1638: interrupted = 0; ! 1639: if (!pcompile (vec, NULLCP)) ! 1640: return; ! 1641: ! 1642: lo = mp -> lowsel; ! 1643: hi = mp -> hghsel; ! 1644: ! 1645: for (msgnum = mp -> lowsel; ! 1646: msgnum <= mp -> hghsel && !interrupted; ! 1647: msgnum++) ! 1648: if (mp -> msgstats[msgnum] & SELECTED) { ! 1649: zp = msh_ready (msgnum, 1); ! 1650: if (pmatches (zp, msgnum, fmsh ? 0L : Msgs[msgnum].m_start, ! 1651: fmsh ? 0L : Msgs[msgnum].m_stop)) { ! 1652: if (msgnum < lo) ! 1653: lo = msgnum; ! 1654: if (msgnum > hi) ! 1655: hi = msgnum; ! 1656: } ! 1657: else { ! 1658: mp -> msgstats[msgnum] &= ~SELECTED; ! 1659: mp -> numsel--; ! 1660: } ! 1661: } ! 1662: ! 1663: if (interrupted) ! 1664: return; ! 1665: ! 1666: mp -> lowsel = lo; ! 1667: mp -> hghsel = hi; ! 1668: ! 1669: if (mp -> numsel <= 0) { ! 1670: advise (NULLCP, "no messages match specification"); ! 1671: return; ! 1672: } ! 1673: ! 1674: seqs[seqp] = NULL; ! 1675: for (seqp = 0; seqs[seqp]; seqp++) { ! 1676: if (zerosw && !m_seqnew (mp, seqs[seqp], 0)) ! 1677: return; ! 1678: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 1679: if (mp -> msgstats[msgnum] & SELECTED) ! 1680: if (!m_seqadd (mp, seqs[seqp], msgnum, 0)) ! 1681: return; ! 1682: } ! 1683: ! 1684: printf ("%d hit%s\n", mp -> numsel, mp -> numsel == 1 ? "" : "s"); ! 1685: } ! 1686: ! 1687: /* */ ! 1688: ! 1689: static struct swit replswit[] = { ! 1690: #define REANSW 0 ! 1691: "annotate", 0, ! 1692: #define RENANSW 1 ! 1693: "noannotate", 0, ! 1694: #define RECCSW 2 ! 1695: "cc type", 0, ! 1696: #define RENCCSW 3 ! 1697: "nocc type", 0, ! 1698: #define REDFSW 4 ! 1699: "draftfolder +folder", 0, ! 1700: #define REDMSW 5 ! 1701: "draftmessage msg", 0, ! 1702: #define RENDFSW 6 ! 1703: "nodraftfolder", 0, ! 1704: #define REEDTSW 7 ! 1705: "editor editor", 0, ! 1706: #define RENEDSW 8 ! 1707: "noedit", 0, ! 1708: #define REFCCSW 9 ! 1709: "fcc +folder", 0, ! 1710: #define REFLTSW 10 ! 1711: "filter filterfile", 0, ! 1712: #define REFRMSW 11 ! 1713: "form formfile", 0, ! 1714: #define REFRSW 12 ! 1715: "format", 5, ! 1716: #define RENFRSW 13 ! 1717: "noformat", 7, ! 1718: #define REINSW 14 ! 1719: "inplace", 0, ! 1720: #define RENINSW 15 ! 1721: "noinplace", 0, ! 1722: #define REQUSW 16 ! 1723: "query", 0, ! 1724: #define RENQUSW 17 ! 1725: "noquery", 0, ! 1726: #define REWHTSW 18 ! 1727: "whatnowproc program", 0, ! 1728: #define RENWTSW 19 ! 1729: "nowhatnow", 0, ! 1730: #define REWIDSW 20 ! 1731: "width columns", 0, ! 1732: #define REHELP 21 ! 1733: "help", 4, ! 1734: ! 1735: NULL, NULL ! 1736: }; ! 1737: ! 1738: /* */ ! 1739: ! 1740: replcmd (args) ! 1741: char **args; ! 1742: { ! 1743: int vecp = 1; ! 1744: char *cp, ! 1745: *msg = NULL, ! 1746: buf[BUFSIZ], ! 1747: *vec[MAXARGS]; ! 1748: ! 1749: if (fmsh) { ! 1750: forkcmd (args, cmd_name); ! 1751: return; ! 1752: } ! 1753: ! 1754: while (cp = *args++) { ! 1755: if (*cp == '-') ! 1756: switch (smatch (++cp, replswit)) { ! 1757: case AMBIGSW: ! 1758: ambigsw (cp, replswit); ! 1759: return; ! 1760: case UNKWNSW: ! 1761: fprintf (stderr, "-%s unknown\n", cp); ! 1762: return; ! 1763: case REHELP: ! 1764: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); ! 1765: help (buf, replswit); ! 1766: return; ! 1767: ! 1768: case REANSW: /* not implemented */ ! 1769: case RENANSW: ! 1770: case REINSW: ! 1771: case RENINSW: ! 1772: continue; ! 1773: ! 1774: case REFRSW: ! 1775: case RENFRSW: ! 1776: case REQUSW: ! 1777: case RENQUSW: ! 1778: case RENDFSW: ! 1779: case RENEDSW: ! 1780: case RENWTSW: ! 1781: vec[vecp++] = --cp; ! 1782: continue; ! 1783: ! 1784: case RECCSW: ! 1785: case RENCCSW: ! 1786: case REEDTSW: ! 1787: case REFCCSW: ! 1788: case REFLTSW: ! 1789: case REFRMSW: ! 1790: case REWIDSW: ! 1791: case REDFSW: ! 1792: case REDMSW: ! 1793: case REWHTSW: ! 1794: vec[vecp++] = --cp; ! 1795: if (!(cp = *args++) || *cp == '-') { ! 1796: advise (NULLCP, "missing argument to %s", args[-2]); ! 1797: return; ! 1798: } ! 1799: vec[vecp++] = cp; ! 1800: continue; ! 1801: } ! 1802: if (*cp == '+' || *cp == '@') { ! 1803: advise (NULLCP, "sorry, no folders allowed!"); ! 1804: return; ! 1805: } ! 1806: else ! 1807: if (msg) { ! 1808: advise (NULLCP, "only one message at a time!"); ! 1809: return; ! 1810: } ! 1811: else ! 1812: msg = cp; ! 1813: } ! 1814: ! 1815: vec[0] = cmd_name; ! 1816: vec[vecp++] = "-file"; ! 1817: vec[vecp] = NULL; ! 1818: if (!msg) ! 1819: msg = "cur"; ! 1820: if (!m_convert (mp, msg)) ! 1821: return; ! 1822: m_setseq (mp); ! 1823: ! 1824: if (mp -> numsel > 1) { ! 1825: advise (NULLCP, "only one message at a time!"); ! 1826: return; ! 1827: } ! 1828: (void) process (mp -> hghsel, cmd_name, vecp, vec); ! 1829: m_setcur (mp, mp -> hghsel); ! 1830: } ! 1831: ! 1832: /* */ ! 1833: ! 1834: static struct swit rmmswit[] = { ! 1835: #define RMHELP 0 ! 1836: "help", 4, ! 1837: ! 1838: NULL, NULL ! 1839: }; ! 1840: ! 1841: /* */ ! 1842: ! 1843: rmmcmd (args) ! 1844: char **args; ! 1845: { ! 1846: int msgp = 0, ! 1847: msgnum; ! 1848: char *cp, ! 1849: buf[BUFSIZ], ! 1850: *msgs[MAXARGS]; ! 1851: ! 1852: while (cp = *args++) { ! 1853: if (*cp == '-') ! 1854: switch (smatch (++cp, rmmswit)) { ! 1855: case AMBIGSW: ! 1856: ambigsw (cp, rmmswit); ! 1857: return; ! 1858: case UNKWNSW: ! 1859: fprintf (stderr, "-%s unknown\n", cp); ! 1860: return; ! 1861: case RMHELP: ! 1862: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); ! 1863: help (buf, rmmswit); ! 1864: return; ! 1865: } ! 1866: if (*cp == '+' || *cp == '@') { ! 1867: advise (NULLCP, "sorry, no folders allowed!"); ! 1868: return; ! 1869: } ! 1870: else ! 1871: msgs[msgp++] = cp; ! 1872: } ! 1873: ! 1874: if (!msgp) ! 1875: msgs[msgp++] = "cur"; ! 1876: for (msgnum = 0; msgnum < msgp; msgnum++) ! 1877: if (!m_convert (mp, msgs[msgnum])) ! 1878: return; ! 1879: m_setseq (mp); ! 1880: ! 1881: rmm (); ! 1882: } ! 1883: ! 1884: /* */ ! 1885: ! 1886: static rmm () { ! 1887: register int msgnum, ! 1888: vecp; ! 1889: register char *cp; ! 1890: char buffer[BUFSIZ], ! 1891: *vec[MAXARGS]; ! 1892: ! 1893: if (fmsh) { ! 1894: if (rmmproc) { ! 1895: if (mp -> numsel > MAXARGS - 1) { ! 1896: advise (NULLCP, "more than %d messages for %s exec", ! 1897: MAXARGS - 1, rmmproc); ! 1898: return; ! 1899: } ! 1900: vecp = 0; ! 1901: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 1902: if (mp -> msgstats[msgnum] & SELECTED) ! 1903: vec[vecp++] = getcpy (m_name (msgnum)); ! 1904: vec[vecp] = NULL; ! 1905: forkcmd (vec, rmmproc); ! 1906: for (vecp = 0; vec[vecp]; vecp++) ! 1907: free (vec[vecp]); ! 1908: } ! 1909: else ! 1910: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 1911: if (mp -> msgstats[msgnum] & SELECTED) { ! 1912: (void) strcpy (buffer, m_backup (cp = m_name (msgnum))); ! 1913: if (rename (cp, buffer) == NOTOK) ! 1914: admonish (buffer, "unable to rename %s to", cp); ! 1915: } ! 1916: } ! 1917: ! 1918: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 1919: if (mp -> msgstats[msgnum] & SELECTED) { ! 1920: mp -> msgstats[msgnum] |= DELETED; ! 1921: mp -> msgstats[msgnum] &= ~EXISTS; ! 1922: } ! 1923: ! 1924: if ((mp -> nummsg -= mp -> numsel) <= 0) { ! 1925: if (fmsh) ! 1926: admonish (NULLCP, "no messages remaining in +%s", fmsh); ! 1927: else ! 1928: admonish (NULLCP, "no messages remaining in %s", mp -> foldpath); ! 1929: mp -> lowmsg = mp -> hghmsg = mp -> nummsg = 0; ! 1930: } ! 1931: if (mp -> lowsel == mp -> lowmsg) { ! 1932: for (msgnum = mp -> lowmsg + 1; msgnum <= mp -> hghmsg; msgnum++) ! 1933: if (mp -> msgstats[msgnum] & EXISTS) ! 1934: break; ! 1935: mp -> lowmsg = msgnum; ! 1936: } ! 1937: if (mp -> hghsel == mp -> hghmsg) { ! 1938: for (msgnum = mp -> hghmsg - 1; msgnum >= mp -> lowmsg; msgnum--) ! 1939: if (mp -> msgstats[msgnum] & EXISTS) ! 1940: break; ! 1941: mp -> hghmsg = msgnum; ! 1942: } ! 1943: ! 1944: mp -> msgflags |= MODIFIED; ! 1945: modified++; ! 1946: } ! 1947: ! 1948: /* */ ! 1949: ! 1950: static struct swit scanswit[] = { ! 1951: #define SCCLR 0 ! 1952: "clear", 0, ! 1953: #define SCNCLR 1 ! 1954: "noclear", 0, ! 1955: #define SCFORM 2 ! 1956: "form formatfile", 0, ! 1957: #define SCFMT 3 ! 1958: "format string", 5, ! 1959: #define SCHEAD 4 ! 1960: "header", 0, ! 1961: #define SCNHEAD 5 ! 1962: "noheader", 0, ! 1963: #define SCWID 6 ! 1964: "width columns", 0, ! 1965: #define SCHELP 7 ! 1966: "help", 4, ! 1967: ! 1968: NULL, NULL ! 1969: }; ! 1970: ! 1971: /* */ ! 1972: ! 1973: scancmd (args) ! 1974: char **args; ! 1975: { ! 1976: #define equiv(a,b) (a ? b && !strcmp (a, b) : !b) ! 1977: ! 1978: int clearsw = 0, ! 1979: headersw = 0, ! 1980: width = 0, ! 1981: msgp = 0, ! 1982: msgnum, ! 1983: optim, ! 1984: state; ! 1985: char *cp, ! 1986: *form = NULL, ! 1987: *format = NULL, ! 1988: buf[BUFSIZ], ! 1989: *nfs, ! 1990: *msgs[MAXARGS]; ! 1991: register FILE *zp; ! 1992: static int s_optim = 0; ! 1993: static char *s_form = NULL, ! 1994: *s_format = NULL; ! 1995: ! 1996: while (cp = *args++) { ! 1997: if (*cp == '-') ! 1998: switch (smatch (++cp, scanswit)) { ! 1999: case AMBIGSW: ! 2000: ambigsw (cp, scanswit); ! 2001: return; ! 2002: case UNKWNSW: ! 2003: fprintf (stderr, "-%s unknown\n", cp); ! 2004: return; ! 2005: case SCHELP: ! 2006: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); ! 2007: help (buf, scanswit); ! 2008: return; ! 2009: ! 2010: case SCCLR: ! 2011: clearsw++; ! 2012: continue; ! 2013: case SCNCLR: ! 2014: clearsw = 0; ! 2015: continue; ! 2016: case SCHEAD: ! 2017: headersw++; ! 2018: continue; ! 2019: case SCNHEAD: ! 2020: headersw = 0; ! 2021: continue; ! 2022: case SCFORM: ! 2023: if (!(form = *args++) || *form == '-') { ! 2024: advise (NULLCP, "missing argument to %s", args[-2]); ! 2025: return; ! 2026: } ! 2027: format = NULL; ! 2028: continue; ! 2029: case SCFMT: ! 2030: if (!(format = *args++) || *format == '-') { ! 2031: advise (NULLCP, "missing argument to %s", args[-2]); ! 2032: return; ! 2033: } ! 2034: form = NULL; ! 2035: continue; ! 2036: case SCWID: ! 2037: if (!(cp = *args++) || *cp == '-') { ! 2038: advise (NULLCP, "missing argument to %s", args[-2]); ! 2039: return; ! 2040: } ! 2041: width = atoi (cp); ! 2042: continue; ! 2043: } ! 2044: if (*cp == '+' || *cp == '@') { ! 2045: advise (NULLCP, "sorry, no folders allowed!"); ! 2046: return; ! 2047: } ! 2048: else ! 2049: msgs[msgp++] = cp; ! 2050: } ! 2051: ! 2052: if (!msgp) ! 2053: msgs[msgp++] = "all"; ! 2054: for (msgnum = 0; msgnum < msgp; msgnum++) ! 2055: if (!m_convert (mp, msgs[msgnum])) ! 2056: return; ! 2057: m_setseq (mp); ! 2058: ! 2059: nfs = new_fs (form, format, FORMAT); ! 2060: if (scanl) { /* force scansbr to (re)compile format */ ! 2061: (void) free (scanl); ! 2062: scanl = NULL; ! 2063: } ! 2064: ! 2065: if (s_optim == 0) { ! 2066: s_optim = optim = 1; ! 2067: s_form = form ? getcpy (form) : NULL; ! 2068: s_format = format ? getcpy (format) : NULL; ! 2069: } ! 2070: else ! 2071: optim = equiv (s_form, form) && equiv (s_format, format); ! 2072: ! 2073: interrupted = 0; ! 2074: for (msgnum = mp -> lowsel; ! 2075: msgnum <= mp -> hghsel && !interrupted; ! 2076: msgnum++) ! 2077: if (mp -> msgstats[msgnum] & SELECTED) { ! 2078: if (optim && Msgs[msgnum].m_scanl) ! 2079: printf ("%s", Msgs[msgnum].m_scanl); ! 2080: else { ! 2081: zp = msh_ready (msgnum, 0); ! 2082: switch (state = scan (zp, msgnum, 0, nfs, width, ! 2083: msgnum == mp -> curmsg, headersw, ! 2084: fmsh ? 0L : (long) (Msgs[msgnum].m_stop - Msgs[msgnum].m_start), ! 2085: 1)) { ! 2086: case SCNMSG: ! 2087: case SCNERR: ! 2088: if (optim) ! 2089: Msgs[msgnum].m_scanl = getcpy (scanl); ! 2090: break; ! 2091: ! 2092: default: ! 2093: advise (NULLCP, "scan() botch (%d)", state); ! 2094: return; ! 2095: ! 2096: case SCNEOF: ! 2097: printf ("%*d empty\n", DMAXFOLDER, msgnum); ! 2098: break; ! 2099: } ! 2100: } ! 2101: headersw = 0; ! 2102: } ! 2103: ! 2104: if (clearsw) ! 2105: clear_screen (); ! 2106: } ! 2107: ! 2108: /* */ ! 2109: ! 2110: static struct swit showswit[] = { ! 2111: #define SHDRAFT 0 ! 2112: "draft", 5, ! 2113: #define SHFORM 1 ! 2114: "form formfile", 4, ! 2115: #define SHPROG 2 ! 2116: "moreproc program", 4, ! 2117: #define SHNPROG 3 ! 2118: "nomoreproc", 3, ! 2119: #define SHLEN 4 ! 2120: "length lines", 4, ! 2121: #define SHWID 5 ! 2122: "width columns", 4, ! 2123: #define SHSHOW 6 ! 2124: "showproc program", 4, ! 2125: #define SHNSHOW 7 ! 2126: "noshowproc", 3, ! 2127: #define SHHEAD 8 ! 2128: "header", 4, ! 2129: #define SHNHEAD 9 ! 2130: "noheader", 3, ! 2131: #define SHHELP 10 ! 2132: "help", 4, ! 2133: ! 2134: NULL, NULL ! 2135: }; ! 2136: ! 2137: /* */ ! 2138: ! 2139: showcmd (args) ! 2140: char **args; ! 2141: { ! 2142: int headersw = 1, ! 2143: nshow = 0, ! 2144: msgp = 0, ! 2145: vecp = 1, ! 2146: mhl = 0, ! 2147: seen = 0, ! 2148: mode = 0, ! 2149: i, ! 2150: msgnum; ! 2151: char *cp, ! 2152: *proc = showproc, ! 2153: buf[BUFSIZ], ! 2154: *msgs[MAXARGS], ! 2155: *vec[MAXARGS]; ! 2156: ! 2157: if (uleq (cmd_name, "next")) ! 2158: mode = 1; ! 2159: else ! 2160: if (uleq (cmd_name, "prev")) ! 2161: mode = -1; ! 2162: while (cp = *args++) { ! 2163: if (*cp == '-') ! 2164: switch (i = smatch (++cp, showswit)) { ! 2165: case AMBIGSW: ! 2166: ambigsw (cp, showswit); ! 2167: return; ! 2168: case UNKWNSW: ! 2169: case SHNPROG: ! 2170: vec[vecp++] = --cp; ! 2171: continue; ! 2172: case SHHELP: ! 2173: (void) sprintf (buf, ! 2174: "%s %s[switches] [switches for showproc]", ! 2175: cmd_name, mode ? NULL : "[msgs] "); ! 2176: help (buf, showswit); ! 2177: return; ! 2178: ! 2179: case SHFORM: ! 2180: case SHPROG: ! 2181: case SHLEN: ! 2182: case SHWID: ! 2183: vec[vecp++] = --cp; ! 2184: if (!(cp = *args++) || *cp == '-') { ! 2185: advise (NULLCP, "missing argument to %s", args[-2]); ! 2186: return; ! 2187: } ! 2188: vec[vecp++] = cp; ! 2189: continue; ! 2190: case SHHEAD: ! 2191: headersw++; ! 2192: continue; ! 2193: case SHNHEAD: ! 2194: headersw = 0; ! 2195: continue; ! 2196: case SHSHOW: ! 2197: if (!(proc = *args++) || *proc == '-') { ! 2198: advise (NULLCP, "missing argument to %s", args[-2]); ! 2199: return; ! 2200: } ! 2201: nshow = 0; ! 2202: continue; ! 2203: case SHNSHOW: ! 2204: nshow++; ! 2205: continue; ! 2206: ! 2207: case SHDRAFT: ! 2208: advise (NULLCP, "sorry, -%s not allowed!", showswit[i].sw); ! 2209: return; ! 2210: } ! 2211: if (*cp == '+' || *cp == '@') { ! 2212: advise (NULLCP, "sorry, no folders allowed!"); ! 2213: return; ! 2214: } ! 2215: else ! 2216: if (mode) { ! 2217: fprintf (stderr, ! 2218: "usage: %s [switches] [switches for showproc]\n", ! 2219: cmd_name); ! 2220: return; ! 2221: } ! 2222: else ! 2223: msgs[msgp++] = cp; ! 2224: } ! 2225: vec[vecp] = NULL; ! 2226: ! 2227: if (!msgp) ! 2228: msgs[msgp++] = mode > 0 ? "next" : mode < 0 ? "prev" : "cur"; ! 2229: for (msgnum = 0; msgnum < msgp; msgnum++) ! 2230: if (!m_convert (mp, msgs[msgnum])) ! 2231: return; ! 2232: m_setseq (mp); ! 2233: ! 2234: if (nshow) ! 2235: proc = "cat"; ! 2236: else ! 2237: if (strcmp (showproc, "mhl") == 0) { ! 2238: proc = mhlproc; ! 2239: mhl++; ! 2240: } ! 2241: ! 2242: seen = m_seqflag (mp, "unseen"); ! 2243: vec[0] = r1bindex (proc, '/'); ! 2244: if (mhl) { ! 2245: msgp = vecp; ! 2246: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 2247: if (mp -> msgstats[msgnum] & SELECTED) { ! 2248: vec[vecp++] = getcpy (m_name (msgnum)); ! 2249: if (seen) ! 2250: (void) m_seqdel (mp, "unseen", msgnum); ! 2251: } ! 2252: vec[vecp] = NULL; ! 2253: if (mp -> numsel == 1 && headersw) ! 2254: show (mp -> lowsel); ! 2255: (void) mhlsbr (vecp, vec, mhl_action); ! 2256: m_eomsbr ((int (*)()) 0); ! 2257: while (msgp < vecp) ! 2258: free (vec[msgp++]); ! 2259: } ! 2260: else { ! 2261: interrupted = 0; ! 2262: for (msgnum = mp -> lowsel; ! 2263: msgnum <= mp -> hghsel && !interrupted; ! 2264: msgnum++) ! 2265: if (mp -> msgstats[msgnum] & SELECTED) { ! 2266: switch (ask (msgnum)) { ! 2267: case NOTOK: /* QUIT */ ! 2268: break; ! 2269: ! 2270: case OK: /* INTR */ ! 2271: continue; ! 2272: ! 2273: default: ! 2274: if (mp -> numsel == 1 && headersw) ! 2275: show (msgnum); ! 2276: if (nshow) ! 2277: copy_message (msgnum, stdout); ! 2278: else ! 2279: (void) process (msgnum, proc, vecp, vec); ! 2280: ! 2281: if (seen) ! 2282: (void) m_seqdel (mp, "unseen", msgnum); ! 2283: continue; ! 2284: } ! 2285: break; ! 2286: } ! 2287: } ! 2288: ! 2289: m_setcur (mp, mp -> hghsel); ! 2290: } ! 2291: ! 2292: /* */ ! 2293: ! 2294: static show (msgnum) ! 2295: int msgnum; ! 2296: { ! 2297: if (Msgs[msgnum].m_bboard_id == 0) ! 2298: (void) readid (msgnum); ! 2299: ! 2300: printf ("(Message %d", msgnum); ! 2301: if (Msgs[msgnum].m_bboard_id > 0) ! 2302: printf (", %s: %d", BBoard_ID, Msgs[msgnum].m_bboard_id); ! 2303: printf (")\n"); ! 2304: } ! 2305: ! 2306: ! 2307: /* ARGSUSED */ ! 2308: ! 2309: static int eom_action (c) ! 2310: int c; ! 2311: { ! 2312: return (ftell (mhlfp) >= Msgs[mhlnum].m_stop); ! 2313: } ! 2314: ! 2315: ! 2316: static FP mhl_action (name) ! 2317: char *name; ! 2318: { ! 2319: int msgnum; ! 2320: ! 2321: if ((msgnum = m_atoi (name)) < mp -> lowmsg ! 2322: || msgnum > mp -> hghmsg ! 2323: || !(mp -> msgstats[msgnum] & EXISTS)) ! 2324: return NULL; ! 2325: mhlnum = msgnum; ! 2326: ! 2327: mhlfp = msh_ready (msgnum, 1); ! 2328: if (!fmsh) ! 2329: m_eomsbr (eom_action); ! 2330: ! 2331: return mhlfp; ! 2332: } ! 2333: ! 2334: ! 2335: /* */ ! 2336: ! 2337: static ask (msgnum) ! 2338: int msgnum; ! 2339: { ! 2340: char buf[BUFSIZ]; ! 2341: ! 2342: if (mp -> numsel == 1 || !interactive || redirected) ! 2343: return DONE; ! 2344: ! 2345: if (SOprintf ("Press <return> to list \"%d\"...", msgnum)) { ! 2346: if (mp -> lowsel != msgnum) ! 2347: printf ("\n\n\n"); ! 2348: printf ("Press <return> to list \"%d\"...", msgnum); ! 2349: } ! 2350: (void) fflush (stdout); ! 2351: buf[0] = NULL; ! 2352: #ifndef BSD42 ! 2353: (void) read (fileno (stdout), buf, sizeof buf); ! 2354: #else BSD42 ! 2355: switch (setjmp (sigenv)) { ! 2356: case OK: ! 2357: should_intr = 1; ! 2358: (void) read (fileno (stdout), buf, sizeof buf);/* fall... */ ! 2359: ! 2360: default: ! 2361: should_intr = 0; ! 2362: break; ! 2363: } ! 2364: #endif BSD42 ! 2365: if (index (buf, '\n') == NULL) ! 2366: (void) putchar ('\n'); ! 2367: ! 2368: if (told_to_quit) { ! 2369: told_to_quit = interrupted = 0; ! 2370: return NOTOK; ! 2371: } ! 2372: if (interrupted) { ! 2373: interrupted = 0; ! 2374: return OK; ! 2375: } ! 2376: ! 2377: return DONE; ! 2378: } ! 2379: ! 2380: /* */ ! 2381: ! 2382: static struct swit sortswit[] = { ! 2383: #define SODATE 0 ! 2384: "datefield field", 0, ! 2385: #define SOVERB 1 ! 2386: "verbose", 0, ! 2387: #define SONVERB 2 ! 2388: "noverbose", 0, ! 2389: #define SOHELP 3 ! 2390: "help", 4, ! 2391: ! 2392: NULL, NULL ! 2393: }; ! 2394: ! 2395: /* */ ! 2396: ! 2397: sortcmd (args) ! 2398: char **args; ! 2399: { ! 2400: int msgp = 0, ! 2401: msgnum; ! 2402: char *cp, ! 2403: *datesw = NULL, ! 2404: buf[BUFSIZ], ! 2405: *msgs[MAXARGS]; ! 2406: struct tws tb, ! 2407: *tw; ! 2408: ! 2409: if (fmsh) { ! 2410: forkcmd (args, cmd_name); ! 2411: return; ! 2412: } ! 2413: ! 2414: while (cp = *args++) { ! 2415: if (*cp == '-') ! 2416: switch (smatch (++cp, sortswit)) { ! 2417: case AMBIGSW: ! 2418: ambigsw (cp, sortswit); ! 2419: return; ! 2420: case UNKWNSW: ! 2421: fprintf (stderr, "-%s unknown\n", cp); ! 2422: return; ! 2423: case SOHELP: ! 2424: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); ! 2425: help (buf, sortswit); ! 2426: return; ! 2427: ! 2428: case SODATE: ! 2429: if (datesw) { ! 2430: advise (NULLCP, "only one date field at a time!"); ! 2431: return; ! 2432: } ! 2433: if (!(datesw = *args++) || *datesw == '-') { ! 2434: advise (NULLCP, "missing argument to %s", args[-2]); ! 2435: return; ! 2436: } ! 2437: continue; ! 2438: ! 2439: case SOVERB: /* not implemented */ ! 2440: case SONVERB: ! 2441: continue; ! 2442: } ! 2443: if (*cp == '+' || *cp == '@') { ! 2444: advise (NULLCP, "sorry, no folders allowed!"); ! 2445: return; ! 2446: } ! 2447: else ! 2448: msgs[msgp++] = cp; ! 2449: } ! 2450: ! 2451: if (!msgp) ! 2452: msgs[msgp++] = "all"; ! 2453: if (!datesw) ! 2454: datesw = "Date"; ! 2455: for (msgnum = 0; msgnum < msgp; msgnum++) ! 2456: if (!m_convert (mp, msgs[msgnum])) ! 2457: return; ! 2458: m_setseq (mp); ! 2459: ! 2460: twscopy (&tb, dtwstime ()); ! 2461: ! 2462: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) { ! 2463: if (Msgs[msgnum].m_scanl) { ! 2464: free (Msgs[msgnum].m_scanl); ! 2465: Msgs[msgnum].m_scanl = NULL; ! 2466: } ! 2467: if (mp -> msgstats[msgnum] & SELECTED) { ! 2468: if ((tw = getws (datesw, msgnum)) == NULL) ! 2469: tw = msgnum != mp -> lowsel ? &Msgs[msgnum - 1].m_tb : &tb; ! 2470: } ! 2471: else ! 2472: tw = &tb; ! 2473: twscopy (&Msgs[msgnum].m_tb, tw); ! 2474: Msgs[msgnum].m_stats = mp -> msgstats[msgnum]; ! 2475: if (mp -> curmsg == msgnum) ! 2476: Msgs[msgnum].m_stats |= CUR; ! 2477: } ! 2478: ! 2479: qsort ((char *) &Msgs[mp -> lowsel], mp -> hghsel - mp -> lowsel + 1, ! 2480: sizeof (struct Msg), msgsort); ! 2481: ! 2482: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) { ! 2483: mp -> msgstats[msgnum] = Msgs[msgnum].m_stats & ~CUR; ! 2484: if (Msgs[msgnum].m_stats & CUR) ! 2485: m_setcur (mp, msgnum); ! 2486: } ! 2487: ! 2488: mp -> msgflags |= MODIFIED; ! 2489: modified++; ! 2490: } ! 2491: ! 2492: /* */ ! 2493: ! 2494: static struct tws *getws (datesw, msgnum) ! 2495: char *datesw; ! 2496: int msgnum; ! 2497: { ! 2498: int state; ! 2499: char *bp, ! 2500: buf[BUFSIZ], ! 2501: name[NAMESZ]; ! 2502: struct tws *tw; ! 2503: register FILE *zp; ! 2504: ! 2505: zp = msh_ready (msgnum, 0); ! 2506: for (state = FLD;;) ! 2507: switch (state = m_getfld (state, name, buf, sizeof buf, zp)) { ! 2508: case FLD: ! 2509: case FLDEOF: ! 2510: case FLDPLUS: ! 2511: if (uleq (name, datesw)) { ! 2512: bp = getcpy (buf); ! 2513: while (state == FLDPLUS) { ! 2514: state = m_getfld (state, name, buf, sizeof buf, zp); ! 2515: bp = add (buf, bp); ! 2516: } ! 2517: if ((tw = dparsetime (bp)) == NULL) ! 2518: admonish (NULLCP, ! 2519: "unable to parse %s field in message %d", ! 2520: datesw, msgnum); ! 2521: free (bp); ! 2522: return tw; ! 2523: } ! 2524: while (state == FLDPLUS) ! 2525: state = m_getfld (state, name, buf, sizeof buf, zp); ! 2526: if (state != FLDEOF) ! 2527: continue; ! 2528: ! 2529: case BODY: ! 2530: case BODYEOF: ! 2531: case FILEEOF: ! 2532: admonish (NULLCP, "no %s field in message %d", datesw, msgnum); ! 2533: return NULL; ! 2534: ! 2535: case LENERR: ! 2536: case FMTERR: ! 2537: admonish (NULLCP, "format error in message %d", msgnum); ! 2538: return NULL; ! 2539: ! 2540: default: ! 2541: adios (NULLCP, "internal error -- you lose"); ! 2542: } ! 2543: } ! 2544: ! 2545: ! 2546: static int msgsort (a, b) ! 2547: struct Msg *a, ! 2548: *b; ! 2549: { ! 2550: return twsort (&a -> m_tb, &b -> m_tb); ! 2551: } ! 2552: ! 2553: /* */ ! 2554: ! 2555: static int process (msgnum, proc, vecp, vec) ! 2556: int msgnum, ! 2557: vecp; ! 2558: char *proc, ! 2559: **vec; ! 2560: { ! 2561: int child_id, ! 2562: status; ! 2563: char tmpfil[80]; ! 2564: FILE *out; ! 2565: ! 2566: if (fmsh) { ! 2567: (void) strcpy (tmpfil, m_name (msgnum)); ! 2568: (void) m_delete (pfolder); ! 2569: m_replace (pfolder, fmsh); ! 2570: m_sync (mp); ! 2571: m_update (); ! 2572: goto ready; ! 2573: } ! 2574: ! 2575: (void) strcpy (tmpfil, m_scratch ("", invo_name)); ! 2576: if ((out = fopen (tmpfil, "w")) == NULL) { ! 2577: int olderr; ! 2578: extern int errno; ! 2579: char newfil[80]; ! 2580: ! 2581: olderr = errno; ! 2582: (void) strcpy (newfil, m_tmpfil (invo_name)); ! 2583: if ((out = fopen (newfil, "w")) == NULL) { ! 2584: errno = olderr; ! 2585: advise (tmpfil, "unable to create temporary file"); ! 2586: return NOTOK; ! 2587: } ! 2588: else ! 2589: (void) strcpy (tmpfil, newfil); ! 2590: } ! 2591: copy_message (msgnum, out); ! 2592: (void) fclose (out); ! 2593: ! 2594: ready: ; ! 2595: (void) fflush (stdout); ! 2596: switch (child_id = fork ()) { ! 2597: case NOTOK: ! 2598: advise ("fork", "unable to"); ! 2599: status = NOTOK; ! 2600: break; ! 2601: ! 2602: case OK: ! 2603: closefds (3); ! 2604: (void) signal (SIGINT, istat); ! 2605: (void) signal (SIGQUIT, qstat); ! 2606: ! 2607: vec[vecp++] = tmpfil; ! 2608: vec[vecp] = NULL; ! 2609: ! 2610: execvp (proc, vec); ! 2611: fprintf (stderr, "unable to exec "); ! 2612: perror (proc); ! 2613: _exit (1); ! 2614: ! 2615: default: ! 2616: status = pidXwait (child_id, NULLCP); ! 2617: break; ! 2618: } ! 2619: ! 2620: if (!fmsh) ! 2621: (void) unlink (tmpfil); ! 2622: return status; ! 2623: } ! 2624: ! 2625: /* */ ! 2626: ! 2627: static copy_message (msgnum, out) ! 2628: int msgnum; ! 2629: FILE * out; ! 2630: { ! 2631: long pos; ! 2632: static char buffer[BUFSIZ]; ! 2633: register FILE * zp; ! 2634: ! 2635: zp = msh_ready (msgnum, 1); ! 2636: if (fmsh) { ! 2637: while (fgets (buffer, sizeof buffer, zp) != NULL) { ! 2638: fputs (buffer, out); ! 2639: if (interrupted && out == stdout) ! 2640: break; ! 2641: } ! 2642: } ! 2643: else { ! 2644: pos = ftell (zp); ! 2645: while (fgets (buffer, sizeof buffer, zp) != NULL ! 2646: && pos < Msgs[msgnum].m_stop) { ! 2647: fputs (buffer, out); ! 2648: pos += (long) strlen (buffer); ! 2649: if (interrupted && out == stdout) ! 2650: break; ! 2651: } ! 2652: } ! 2653: } ! 2654: ! 2655: ! 2656: static copy_digest (msgnum, out) ! 2657: int msgnum; ! 2658: FILE * out; ! 2659: { ! 2660: char c; ! 2661: long pos; ! 2662: static char buffer[BUFSIZ]; ! 2663: register FILE *zp; ! 2664: ! 2665: c = '\n'; ! 2666: zp = msh_ready (msgnum, 1); ! 2667: if (!fmsh) ! 2668: pos = ftell (zp); ! 2669: while (fgets (buffer, sizeof buffer, zp) != NULL ! 2670: && !fmsh && pos < Msgs[msgnum].m_stop) { ! 2671: if (c == '\n' && *buffer == '-') ! 2672: (void) fputc (' ', out); ! 2673: fputs (buffer, out); ! 2674: c = buffer[strlen (buffer) - 1]; ! 2675: if (!fmsh) ! 2676: pos += (long) strlen (buffer); ! 2677: if (interrupted && out == stdout) ! 2678: break; ! 2679: } ! 2680: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.