|
|
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: ! 32: static void forw(), rmm(), show(), copy_message(), copy_digest(); ! 33: static int burst(), eom_action(), ask(), msgsort(), process(); ! 34: static FP mhl_action(); ! 35: static struct tws *getws(); ! 36: ! 37: /* */ ! 38: ! 39: forkcmd (args, pgm) ! 40: char **args, ! 41: *pgm; ! 42: { ! 43: int child_id; ! 44: char *vec[MAXARGS]; ! 45: ! 46: vec[0] = r1bindex (pgm, '/'); ! 47: (void) copyip (args, vec + 1); ! 48: ! 49: if (fmsh) { ! 50: (void) m_delete (pfolder); ! 51: m_replace (pfolder, fmsh); ! 52: m_sync (mp); ! 53: m_update (); ! 54: } ! 55: (void) fflush (stdout); ! 56: switch (child_id = fork ()) { ! 57: case NOTOK: ! 58: advise ("fork", "unable to"); ! 59: return; ! 60: ! 61: case OK: ! 62: closefds (3); ! 63: (void) signal (SIGINT, istat); ! 64: (void) signal (SIGQUIT, qstat); ! 65: ! 66: execvp (pgm, vec); ! 67: fprintf (stderr, "unable to exec "); ! 68: perror (cmd_name); ! 69: _exit (1); ! 70: ! 71: default: ! 72: (void) pidXwait (child_id, NULLCP); ! 73: break; ! 74: } ! 75: if (fmsh) { /* assume the worst case */ ! 76: mp -> msgflags |= MODIFIED; ! 77: modified++; ! 78: } ! 79: } ! 80: ! 81: /* */ ! 82: ! 83: static struct swit distswit[] = { ! 84: #define DIANSW 0 ! 85: "annotate", 0, ! 86: #define DINANSW 1 ! 87: "noannotate", 0, ! 88: #define DIDFSW 2 ! 89: "draftfolder +folder", 0, ! 90: #define DIDMSW 3 ! 91: "draftmessage msg", 0, ! 92: #define DINDFSW 4 ! 93: "nodraftfolder", 0, ! 94: #define DIEDTSW 5 ! 95: "editor editor", 0, ! 96: #define DINEDSW 6 ! 97: "noedit", 0, ! 98: #define DIFRMSW 7 ! 99: "form formfile", 0, ! 100: #define DIINSW 8 ! 101: "inplace", 0, ! 102: #define DININSW 9 ! 103: "noinplace", 0, ! 104: #define DIWHTSW 10 ! 105: "whatnowproc program", 0, ! 106: #define DINWTSW 11 ! 107: "nowhatnowproc", 0, ! 108: #define DIHELP 12 ! 109: "help", 4, ! 110: ! 111: NULL, NULL ! 112: }; ! 113: ! 114: /* */ ! 115: ! 116: distcmd (args) ! 117: char **args; ! 118: { ! 119: int vecp = 1; ! 120: char *cp, ! 121: *msg = NULL, ! 122: buf[BUFSIZ], ! 123: *vec[MAXARGS]; ! 124: ! 125: if (fmsh) { ! 126: forkcmd (args, cmd_name); ! 127: return; ! 128: } ! 129: ! 130: while (cp = *args++) { ! 131: if (*cp == '-') ! 132: switch (smatch (++cp, distswit)) { ! 133: case AMBIGSW: ! 134: ambigsw (cp, distswit); ! 135: return; ! 136: case UNKWNSW: ! 137: fprintf (stderr, "-%s unknown\n", cp); ! 138: return; ! 139: case DIHELP: ! 140: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); ! 141: help (buf, distswit); ! 142: return; ! 143: ! 144: case DIANSW: /* not implemented */ ! 145: case DINANSW: ! 146: case DIINSW: ! 147: case DININSW: ! 148: continue; ! 149: ! 150: case DINDFSW: ! 151: case DINEDSW: ! 152: case DINWTSW: ! 153: vec[vecp++] = --cp; ! 154: continue; ! 155: ! 156: case DIEDTSW: ! 157: case DIFRMSW: ! 158: case DIDFSW: ! 159: case DIDMSW: ! 160: case DIWHTSW: ! 161: vec[vecp++] = --cp; ! 162: if (!(cp = *args++) || *cp == '-') { ! 163: advise (NULLCP, "missing argument to %s", args[-2]); ! 164: return; ! 165: } ! 166: vec[vecp++] = cp; ! 167: continue; ! 168: } ! 169: if (*cp == '+' || *cp == '@') { ! 170: advise (NULLCP, "sorry, no folders allowed!"); ! 171: return; ! 172: } ! 173: else ! 174: if (msg) { ! 175: advise (NULLCP, "only one message at a time!"); ! 176: return; ! 177: } ! 178: else ! 179: msg = cp; ! 180: } ! 181: ! 182: vec[0] = cmd_name; ! 183: vec[vecp++] = "-file"; ! 184: vec[vecp] = NULL; ! 185: if (!msg) ! 186: msg = "cur"; ! 187: if (!m_convert (mp, msg)) ! 188: return; ! 189: m_setseq (mp); ! 190: ! 191: if (mp -> numsel > 1) { ! 192: advise (NULLCP, "only one message at a time!"); ! 193: return; ! 194: } ! 195: (void) process (mp -> hghsel, cmd_name, vecp, vec); ! 196: m_setcur (mp, mp -> hghsel); ! 197: } ! 198: ! 199: /* */ ! 200: ! 201: static struct swit explswit[] = { ! 202: #define EXINSW 0 ! 203: "inplace", 0, ! 204: #define EXNINSW 1 ! 205: "noinplace", 0, ! 206: #define EXQISW 2 ! 207: "quiet", 0, ! 208: #define EXNQISW 3 ! 209: "noquiet", 0, ! 210: #define EXVBSW 4 ! 211: "verbose", 0, ! 212: #define EXNVBSW 5 ! 213: "noverbose", 0, ! 214: #define EXHELP 6 ! 215: "help", 4, ! 216: ! 217: NULL, NULL ! 218: }; ! 219: ! 220: /* */ ! 221: ! 222: explcmd (args) ! 223: char **args; ! 224: { ! 225: int inplace = 0, ! 226: quietsw = 0, ! 227: verbosw = 0, ! 228: msgp = 0, ! 229: hi, ! 230: msgnum; ! 231: char *cp, ! 232: buf[BUFSIZ], ! 233: *msgs[MAXARGS]; ! 234: struct Msg *smsgs; ! 235: ! 236: if (fmsh) { ! 237: forkcmd (args, cmd_name); ! 238: return; ! 239: } ! 240: ! 241: while (cp = *args++) { ! 242: if (*cp == '-') ! 243: switch (smatch (++cp, explswit)) { ! 244: case AMBIGSW: ! 245: ambigsw (cp, explswit); ! 246: return; ! 247: case UNKWNSW: ! 248: fprintf (stderr, "-%s unknown\n", cp); ! 249: return; ! 250: case EXHELP: ! 251: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); ! 252: help (buf, explswit); ! 253: return; ! 254: ! 255: case EXINSW: ! 256: inplace++; ! 257: continue; ! 258: case EXNINSW: ! 259: inplace = 0; ! 260: continue; ! 261: case EXQISW: ! 262: quietsw++; ! 263: continue; ! 264: case EXNQISW: ! 265: quietsw = 0; ! 266: continue; ! 267: case EXVBSW: ! 268: verbosw++; ! 269: continue; ! 270: case EXNVBSW: ! 271: verbosw = 0; ! 272: continue; ! 273: } ! 274: if (*cp == '+' || *cp == '@') { ! 275: advise (NULLCP, "sorry, no folders allowed!"); ! 276: return; ! 277: } ! 278: else ! 279: msgs[msgp++] = cp; ! 280: } ! 281: ! 282: if (!msgp) ! 283: msgs[msgp++] = "cur"; ! 284: for (msgnum = 0; msgnum < msgp; msgnum++) ! 285: if (!m_convert (mp, msgs[msgnum])) ! 286: return; ! 287: m_setseq (mp); ! 288: ! 289: smsgs = (struct Msg *) ! 290: calloc ((unsigned) (MAXFOLDER + 2), sizeof *smsgs); ! 291: if (smsgs == NULL) ! 292: adios (NULLCP, "unable to allocate folder storage"); ! 293: ! 294: hi = mp -> hghmsg + 1; ! 295: interrupted = 0; ! 296: for (msgnum = mp -> lowsel; ! 297: msgnum <= mp -> hghsel && !interrupted; ! 298: msgnum++) ! 299: if (mp -> msgstats[msgnum] & SELECTED) ! 300: if (burst (smsgs, msgnum, inplace, quietsw, verbosw) != OK) ! 301: break; ! 302: ! 303: free ((char *) smsgs); ! 304: ! 305: if (inplace) ! 306: m_setcur (mp, mp -> lowsel); ! 307: else ! 308: if (hi <= mp -> hghmsg) ! 309: m_setcur (mp, hi); ! 310: ! 311: mp -> msgflags |= MODIFIED; ! 312: modified++; ! 313: } ! 314: ! 315: /* */ ! 316: ! 317: static int burst (smsgs, msgnum, inplace, quietsw, verbosw) ! 318: struct Msg *smsgs; ! 319: int msgnum, ! 320: inplace, ! 321: quietsw, ! 322: verbosw; ! 323: { ! 324: int i, ! 325: j, ! 326: ld3, ! 327: wasdlm, ! 328: msgp; ! 329: long pos; ! 330: char c, ! 331: buffer[BUFSIZ]; ! 332: register FILE *zp; ! 333: ! 334: ld3 = strlen (delim3); ! 335: ! 336: if (Msgs[msgnum].m_scanl) { ! 337: free (Msgs[msgnum].m_scanl); ! 338: Msgs[msgnum].m_scanl = NULL; ! 339: } ! 340: ! 341: pos = ftell (zp = msh_ready (msgnum, 1)); ! 342: for (msgp = 1; msgp <= MAXFOLDER;) { ! 343: while (fgets (buffer, sizeof buffer, zp) != NULL ! 344: && buffer[0] == '\n' ! 345: && pos < Msgs[msgnum].m_stop) ! 346: pos += (long) strlen (buffer); ! 347: if (feof (zp) || pos >= Msgs[msgnum].m_stop) ! 348: break; ! 349: (void) fseek (zp, pos, 0); ! 350: smsgs[msgp].m_start = pos; ! 351: ! 352: for (c = NULL; ! 353: fgets (buffer, sizeof buffer, zp) != NULL ! 354: && pos < Msgs[msgnum].m_stop; ! 355: c = buffer[0]) ! 356: if (strncmp (buffer, delim3, ld3) == 0 ! 357: && peekc (zp) == '\n' ! 358: && (msgp == 1 || c == '\n')) ! 359: break; ! 360: else ! 361: pos += (long) strlen (buffer); ! 362: ! 363: wasdlm = strncmp (buffer, delim3, ld3) == 0; ! 364: if (smsgs[msgp].m_start != pos) ! 365: smsgs[msgp++].m_stop = c == '\n' && wasdlm ? pos - 1 : pos; ! 366: if (feof (zp) || pos >= Msgs[msgnum].m_stop) { ! 367: if (wasdlm) { ! 368: smsgs[msgp - 1].m_stop -= ((long) strlen (buffer) + 1); ! 369: msgp++; /* fake "End of XXX Digest" */ ! 370: } ! 371: break; ! 372: } ! 373: pos += (long) strlen (buffer); ! 374: } ! 375: ! 376: switch (--msgp) { /* toss "End of XXX Digest" */ ! 377: case 0: ! 378: adios (NULLCP, "burst() botch -- you lose big"); ! 379: ! 380: case 1: ! 381: if (!quietsw) ! 382: printf ("message %d not in digest format\n", msgnum); ! 383: return OK; ! 384: ! 385: default: ! 386: if (verbosw) ! 387: printf ("%d message%s exploded from digest %d\n", ! 388: msgp - 1, msgp - 1 != 1 ? "s" : "", msgnum); ! 389: if (msgp == 2) ! 390: msgp++; ! 391: break; ! 392: } ! 393: ! 394: msgp--; ! 395: if ((i = msgp + mp -> hghmsg) > MAXFOLDER) { ! 396: advise (NULLCP, "more than %d messages", MAXFOLDER); ! 397: return NOTOK; ! 398: } ! 399: if ((mp = m_remsg (mp, 0, i)) == NULL) ! 400: adios (NULLCP, "unable to allocate folder storage"); ! 401: ! 402: j = mp -> hghmsg; ! 403: mp -> hghmsg += msgp - 1; ! 404: mp -> nummsg += msgp - 1; ! 405: if (mp -> hghsel > msgnum) ! 406: mp -> hghsel += msgp - 1; ! 407: ! 408: if (inplace && msgp > 1) ! 409: for (i = mp -> hghmsg; j > msgnum; i--, j--) { ! 410: if (verbosw) ! 411: printf ("message %d becomes message %d\n", j, i); ! 412: ! 413: Msgs[i].m_bboard_id = Msgs[j].m_bboard_id; ! 414: Msgs[i].m_top = Msgs[j].m_top; ! 415: Msgs[i].m_start = Msgs[j].m_start; ! 416: Msgs[i].m_stop = Msgs[j].m_stop; ! 417: Msgs[i].m_scanl = NULL; ! 418: if (Msgs[j].m_scanl) { ! 419: free (Msgs[j].m_scanl); ! 420: Msgs[j].m_scanl = NULL; ! 421: } ! 422: mp -> msgstats[i] = mp -> msgstats[j]; ! 423: } ! 424: ! 425: if (Msgs[msgnum].m_bboard_id == 0) ! 426: (void) readid (msgnum); ! 427: ! 428: mp -> msgstats[msgnum] &= ~SELECTED; ! 429: i = inplace ? msgnum + msgp - 1 : mp -> hghmsg; ! 430: for (j = msgp; j >= (inplace ? 1 : 2); i--, j--) { ! 431: if (verbosw && i != msgnum) ! 432: printf ("message %d of digest %d becomes message %d\n", ! 433: j, msgnum, i); ! 434: ! 435: Msgs[i].m_bboard_id = Msgs[msgnum].m_bboard_id; ! 436: Msgs[i].m_top = Msgs[j].m_top; ! 437: Msgs[i].m_start = smsgs[j].m_start; ! 438: Msgs[i].m_stop = smsgs[j].m_stop; ! 439: Msgs[i].m_scanl = NULL; ! 440: mp -> msgstats[i] = mp -> msgstats[msgnum]; ! 441: } ! 442: ! 443: return OK; ! 444: } ! 445: ! 446: /* */ ! 447: ! 448: static struct swit fileswit[] = { ! 449: #define FIDRFT 0 ! 450: "draft", 0, ! 451: #define FILINK 1 ! 452: "link", 0, ! 453: #define FINLINK 2 ! 454: "nolink", 0, ! 455: #define FIPRES 3 ! 456: "preserve", 0, ! 457: #define FINPRES 4 ! 458: "nopreserve", 0, ! 459: #define FISRC 5 ! 460: "src +folder", 0, ! 461: #define FIFILE 6 ! 462: "file file", 0, ! 463: #define FIHELP 7 ! 464: "help", 4, ! 465: ! 466: NULL, NULL ! 467: }; ! 468: ! 469: /* */ ! 470: ! 471: filecmd (args) ! 472: char **args; ! 473: { ! 474: int linksw = 0, ! 475: msgp = 0, ! 476: vecp = 1, ! 477: i, ! 478: msgnum; ! 479: char *cp, ! 480: buf[BUFSIZ], ! 481: *msgs[MAXARGS], ! 482: *vec[MAXARGS]; ! 483: ! 484: if (fmsh) { ! 485: forkcmd (args, cmd_name); ! 486: return; ! 487: } ! 488: ! 489: while (cp = *args++) { ! 490: if (*cp == '-') ! 491: switch (i = smatch (++cp, fileswit)) { ! 492: case AMBIGSW: ! 493: ambigsw (cp, fileswit); ! 494: return; ! 495: case UNKWNSW: ! 496: fprintf (stderr, "-%s unknown\n", cp); ! 497: return; ! 498: case FIHELP: ! 499: (void) sprintf (buf, "%s +folder... [msgs] [switches]", ! 500: cmd_name); ! 501: help (buf, fileswit); ! 502: return; ! 503: ! 504: case FILINK: ! 505: linksw++; ! 506: continue; ! 507: case FINLINK: ! 508: linksw = 0; ! 509: continue; ! 510: ! 511: case FIPRES: ! 512: case FINPRES: ! 513: continue; ! 514: ! 515: case FISRC: ! 516: case FIDRFT: ! 517: case FIFILE: ! 518: advise (NULLCP, "sorry, -%s not allowed!", fileswit[i].sw); ! 519: return; ! 520: } ! 521: if (*cp == '+' || *cp == '@') ! 522: vec[vecp++] = cp; ! 523: else ! 524: msgs[msgp++] = cp; ! 525: } ! 526: ! 527: vec[0] = cmd_name; ! 528: vec[vecp++] = "-file"; ! 529: vec[vecp] = NULL; ! 530: if (!msgp) ! 531: msgs[msgp++] = "cur"; ! 532: for (msgnum = 0; msgnum < msgp; msgnum++) ! 533: if (!m_convert (mp, msgs[msgnum])) ! 534: return; ! 535: m_setseq (mp); ! 536: ! 537: interrupted = 0; ! 538: for (msgnum = mp -> lowsel; ! 539: msgnum <= mp -> hghsel && !interrupted; ! 540: msgnum++) ! 541: if (mp -> msgstats[msgnum] & SELECTED) ! 542: if (process (msgnum, fileproc, vecp, vec)) { ! 543: mp -> msgstats[msgnum] &= ~SELECTED; ! 544: mp -> numsel--; ! 545: } ! 546: ! 547: if (mp -> numsel != mp -> nummsg || linksw) ! 548: m_setcur (mp, mp -> hghsel); ! 549: if (!linksw) ! 550: rmm (); ! 551: } ! 552: ! 553: /* */ ! 554: ! 555: int filehak (args) ! 556: char **args; ! 557: { ! 558: int result, ! 559: vecp = 0; ! 560: char *cp, ! 561: *cwd, ! 562: *vec[MAXARGS]; ! 563: ! 564: while (cp = *args++) { ! 565: if (*cp == '-') ! 566: switch (smatch (++cp, fileswit)) { ! 567: case AMBIGSW: ! 568: case UNKWNSW: ! 569: case FIHELP: ! 570: return NOTOK; ! 571: ! 572: case FILINK: ! 573: case FINLINK: ! 574: case FIPRES: ! 575: case FINPRES: ! 576: continue; ! 577: ! 578: case FISRC: ! 579: case FIDRFT: ! 580: case FIFILE: ! 581: return NOTOK; ! 582: } ! 583: if (*cp == '+' || *cp == '@') ! 584: vec[vecp++] = cp; ! 585: } ! 586: vec[vecp] = NULL; ! 587: ! 588: result = NOTOK; ! 589: cwd = NULL; ! 590: for (vecp = 0; (cp = vec[vecp]) && result == NOTOK; vecp++) { ! 591: if (cwd == NULL) ! 592: cwd = getcpy (pwd ()); ! 593: (void) chdir (m_maildir ("")); ! 594: cp = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF); ! 595: if (access (m_maildir (cp), 0) == NOTOK) ! 596: result = OK; ! 597: free (cp); ! 598: } ! 599: if (cwd) ! 600: (void) chdir (cwd); ! 601: ! 602: return result; ! 603: } ! 604: ! 605: /* */ ! 606: ! 607: static struct swit foldswit[] = { ! 608: #define FLALSW 0 ! 609: "all", 0, ! 610: #define FLFASW 1 ! 611: "fast", 0, ! 612: #define FLNFASW 2 ! 613: "nofast", 0, ! 614: #define FLHDSW 3 ! 615: "header", 0, ! 616: #define FLNHDSW 4 ! 617: "noheader", 0, ! 618: #define FLPKSW 5 ! 619: "pack", 0, ! 620: #define FLNPKSW 6 ! 621: "nopack", 0, ! 622: #define FLRCSW 7 ! 623: "recurse", 0, ! 624: #define FLNRCSW 8 ! 625: "norecurse", 0, ! 626: #define FLTLSW 9 ! 627: "total", 0, ! 628: #define FLNTLSW 10 ! 629: "nototal", 0, ! 630: #define FLPRSW 11 ! 631: "print", 0, ! 632: #define FLPUSW 12 ! 633: "push", 0, ! 634: #define FLPOSW 13 ! 635: "pop", 0, ! 636: #define FLLISW 14 ! 637: "list", 0, ! 638: #define FLHELP 15 ! 639: "help", 4, ! 640: ! 641: NULL, NULL ! 642: }; ! 643: ! 644: /* */ ! 645: ! 646: foldcmd (args) ! 647: char **args; ! 648: { ! 649: int fastsw = 0, ! 650: headersw = 0, ! 651: packsw = 0, ! 652: hole, ! 653: msgnum; ! 654: char *cp, ! 655: *folder = NULL, ! 656: *msg = NULL, ! 657: buf[BUFSIZ], ! 658: **vec = args; ! 659: ! 660: if (args == NULL) ! 661: goto fast; ! 662: ! 663: while (cp = *args++) { ! 664: if (*cp == '-') ! 665: switch (smatch (++cp, foldswit)) { ! 666: case AMBIGSW: ! 667: ambigsw (cp, foldswit); ! 668: return; ! 669: case UNKWNSW: ! 670: fprintf (stderr, "-%s unknown\n", cp); ! 671: return; ! 672: case FLHELP: ! 673: (void) sprintf (buf, "%s [+folder] [msg] [switches]", ! 674: cmd_name); ! 675: help (buf, foldswit); ! 676: return; ! 677: ! 678: case FLALSW: /* not implemented */ ! 679: case FLRCSW: ! 680: case FLNRCSW: ! 681: case FLTLSW: ! 682: case FLNTLSW: ! 683: case FLPRSW: ! 684: case FLPUSW: ! 685: case FLPOSW: ! 686: case FLLISW: ! 687: continue; ! 688: ! 689: case FLFASW: ! 690: fastsw++; ! 691: continue; ! 692: case FLNFASW: ! 693: fastsw = 0; ! 694: continue; ! 695: case FLHDSW: ! 696: headersw++; ! 697: continue; ! 698: case FLNHDSW: ! 699: headersw = 0; ! 700: continue; ! 701: case FLPKSW: ! 702: packsw++; ! 703: continue; ! 704: case FLNPKSW: ! 705: packsw = 0; ! 706: continue; ! 707: } ! 708: if (*cp == '+' || *cp == '@') ! 709: if (folder) { ! 710: advise (NULLCP, "only one folder at a time!\n"); ! 711: return; ! 712: } ! 713: else ! 714: folder = fmsh ? path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF) ! 715: : cp + 1; ! 716: else ! 717: if (msg) { ! 718: advise (NULLCP, "only one message at a time!\n"); ! 719: return; ! 720: } ! 721: else ! 722: msg = cp; ! 723: } ! 724: ! 725: if (folder) { ! 726: if (*folder == NULL) { ! 727: advise (NULLCP, "null folder names are not permitted"); ! 728: return; ! 729: } ! 730: if (fmsh) { ! 731: if (access (m_maildir (folder), 04) == NOTOK) { ! 732: advise (folder, "unable to read"); ! 733: return; ! 734: } ! 735: } ! 736: else { ! 737: (void) strcpy (buf, folder); ! 738: if (expand (buf) == NOTOK) ! 739: return; ! 740: folder = buf; ! 741: if (access (folder, 04) == NOTOK) { ! 742: advise (folder, "unable to read"); ! 743: return; ! 744: } ! 745: } ! 746: m_reset (); ! 747: ! 748: if (fmsh) ! 749: fsetup (folder); ! 750: else ! 751: setup (folder); ! 752: readids (0); ! 753: display_info (0); ! 754: } ! 755: ! 756: if (msg) { ! 757: if (!m_convert (mp, msg)) ! 758: return; ! 759: m_setseq (mp); ! 760: ! 761: if (mp -> numsel > 1) { ! 762: advise (NULLCP, "only one message at a time!"); ! 763: return; ! 764: } ! 765: m_setcur (mp, mp -> hghsel); ! 766: } ! 767: ! 768: if (packsw) { ! 769: if (fmsh) { ! 770: forkcmd (vec, cmd_name); ! 771: return; ! 772: } ! 773: ! 774: if (mp -> lowmsg > 1 && (mp = m_remsg (mp, 1, mp -> hghmsg)) == NULL) ! 775: adios (NULLCP, "unable to allocate folder storage"); ! 776: for (msgnum = mp -> lowmsg, hole = 1; msgnum <= mp -> hghmsg; msgnum++) ! 777: if (mp -> msgstats[msgnum] & EXISTS) { ! 778: if (msgnum != hole) { ! 779: Msgs[hole].m_bboard_id = Msgs[msgnum].m_bboard_id; ! 780: Msgs[hole].m_top = Msgs[msgnum].m_top; ! 781: Msgs[hole].m_start = Msgs[msgnum].m_start; ! 782: Msgs[hole].m_stop = Msgs[msgnum].m_stop; ! 783: Msgs[hole].m_scanl = NULL; ! 784: if (Msgs[msgnum].m_scanl) { ! 785: free (Msgs[msgnum].m_scanl); ! 786: Msgs[msgnum].m_scanl = NULL; ! 787: } ! 788: mp -> msgstats[hole] = mp -> msgstats[msgnum]; ! 789: if (mp -> curmsg == msgnum) ! 790: m_setcur (mp, hole); ! 791: } ! 792: hole++; ! 793: } ! 794: if (mp -> nummsg > 0) { ! 795: mp -> lowmsg = 1; ! 796: mp -> hghmsg = hole - 1; ! 797: } ! 798: mp -> msgflags |= MODIFIED; ! 799: modified++; ! 800: } ! 801: ! 802: fast: ; ! 803: if (fastsw) ! 804: printf ("%s\n", fmsh ? fmsh : mp -> foldpath); ! 805: else { ! 806: if (headersw) ! 807: printf ("\t\tFolder %*s# of messages (%*srange%*s); cur%*smsg\n", ! 808: DMAXFOLDER, "", DMAXFOLDER - 2, "", DMAXFOLDER - 2, "", ! 809: DMAXFOLDER - 2, ""); ! 810: printf (args ? "%22s " : "%s ", fmsh ? fmsh : mp -> foldpath); ! 811: if (mp -> hghmsg == 0) ! 812: printf ("has no messages%*s", ! 813: mp -> msgflags & OTHERS ? DMAXFOLDER * 2 + 4 : 0, ""); ! 814: else { ! 815: printf ("has %*d message%s (%*d-%*d)", ! 816: DMAXFOLDER, mp -> nummsg, mp -> nummsg != 1 ? "s" : "", ! 817: DMAXFOLDER, mp -> lowmsg, DMAXFOLDER, mp -> hghmsg); ! 818: if (mp -> curmsg >= mp -> lowmsg ! 819: && mp -> curmsg <= mp -> hghmsg) ! 820: printf ("; cur=%*d", DMAXFOLDER, mp -> curmsg); ! 821: } ! 822: printf (".\n"); ! 823: } ! 824: } ! 825: ! 826: /* */ ! 827: ! 828: static struct swit forwswit[] = { ! 829: #define FOANSW 0 ! 830: "annotate", 0, ! 831: #define FONANSW 1 ! 832: "noannotate", 0, ! 833: #define FODFSW 2 ! 834: "draftfolder +folder", 0, ! 835: #define FODMSW 3 ! 836: "draftmessage msg", 0, ! 837: #define FONDFSW 4 ! 838: "nodraftfolder", 0, ! 839: #define FOEDTSW 5 ! 840: "editor editor", 0, ! 841: #define FONEDSW 6 ! 842: "noedit", 0, ! 843: #define FOFTRSW 7 ! 844: "filter filterfile", 0, ! 845: #define FOFRMSW 8 ! 846: "form formfile", 0, ! 847: #define FOFTSW 9 ! 848: "format", 5, ! 849: #define FONFTSW 10 ! 850: "noformat", 7, ! 851: #define FOINSW 11 ! 852: "inplace", 0, ! 853: #define FONINSW 12 ! 854: "noinplace", 0, ! 855: #define FOWHTSW 13 ! 856: "whatnowproc program", 0, ! 857: #define FONWTSW 14 ! 858: "nowhatnow", 0, ! 859: #define FOHELP 15 ! 860: "help", 4, ! 861: ! 862: NULL, NULL ! 863: }; ! 864: ! 865: /* */ ! 866: ! 867: forwcmd (args) ! 868: char **args; ! 869: { ! 870: int msgp = 0, ! 871: vecp = 1, ! 872: msgnum; ! 873: char *cp, ! 874: *filter = NULL, ! 875: buf[BUFSIZ], ! 876: *msgs[MAXARGS], ! 877: *vec[MAXARGS]; ! 878: ! 879: if (fmsh) { ! 880: forkcmd (args, cmd_name); ! 881: return; ! 882: } ! 883: ! 884: while (cp = *args++) { ! 885: if (*cp == '-') ! 886: switch (smatch (++cp, forwswit)) { ! 887: case AMBIGSW: ! 888: ambigsw (cp, forwswit); ! 889: return; ! 890: case UNKWNSW: ! 891: fprintf (stderr, "-%s unknown\n", cp); ! 892: return; ! 893: case FOHELP: ! 894: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); ! 895: help (buf, forwswit); ! 896: return; ! 897: ! 898: case FOANSW: /* not implemented */ ! 899: case FONANSW: ! 900: case FOINSW: ! 901: case FONINSW: ! 902: continue; ! 903: ! 904: case FONDFSW: ! 905: case FONEDSW: ! 906: case FONWTSW: ! 907: vec[vecp++] = --cp; ! 908: continue; ! 909: ! 910: case FOEDTSW: ! 911: case FOFRMSW: ! 912: case FODFSW: ! 913: case FODMSW: ! 914: case FOWHTSW: ! 915: vec[vecp++] = --cp; ! 916: if (!(cp = *args++) || *cp == '-') { ! 917: advise (NULLCP, "missing argument to %s", args[-2]); ! 918: return; ! 919: } ! 920: vec[vecp++] = cp; ! 921: continue; ! 922: case FOFTRSW: ! 923: if (!(filter = *args++) || *filter == '-') { ! 924: advise (NULLCP, "missing argument to %s", args[-2]); ! 925: return; ! 926: } ! 927: continue; ! 928: case FOFTSW: ! 929: if (access (filter = myfilter, 04) == NOTOK) { ! 930: advise (filter, "unable to read default filter file"); ! 931: return; ! 932: } ! 933: continue; ! 934: case FONFTSW: ! 935: filter = NULL; ! 936: continue; ! 937: } ! 938: if (*cp == '+' || *cp == '@') { ! 939: advise (NULLCP, "sorry, no folders allowed!"); ! 940: return; ! 941: } ! 942: else ! 943: msgs[msgp++] = cp; ! 944: } ! 945: ! 946: /* foil search of .mh_profile */ ! 947: (void) sprintf (buf, "%sXXXXXX", invo_name); ! 948: vec[0] = mktemp (buf); ! 949: vec[vecp++] = "-file"; ! 950: vec[vecp] = NULL; ! 951: if (!msgp) ! 952: msgs[msgp++] = "cur"; ! 953: for (msgnum = 0; msgnum < msgp; msgnum++) ! 954: if (!m_convert (mp, msgs[msgnum])) ! 955: return; ! 956: m_setseq (mp); ! 957: ! 958: if (filter) { ! 959: (void) strcpy (buf, filter); ! 960: if (expand (buf) == NOTOK) ! 961: return; ! 962: if (access (filter = getcpy (libpath (buf)), 04) == NOTOK) { ! 963: advise (filter, "unable to read"); ! 964: free (filter); ! 965: return; ! 966: } ! 967: } ! 968: forw (cmd_name, filter, vecp, vec); ! 969: m_setcur (mp, mp -> hghsel); ! 970: if (filter) ! 971: free (filter); ! 972: } ! 973: ! 974: /* */ ! 975: ! 976: static void forw (proc, filter, vecp, vec) ! 977: int vecp; ! 978: char *proc, ! 979: *filter, ! 980: **vec; ! 981: { ! 982: int i, ! 983: child_id, ! 984: msgnum, ! 985: msgcnt; ! 986: char tmpfil[80], ! 987: *args[MAXARGS]; ! 988: FILE *out; ! 989: ! 990: (void) strcpy (tmpfil, m_tmpfil (invo_name)); ! 991: interrupted = 0; ! 992: if (filter) ! 993: switch (child_id = fork ()) { ! 994: case NOTOK: ! 995: advise ("fork", "unable to"); ! 996: return; ! 997: ! 998: case OK: /* "trust me" */ ! 999: if (freopen (tmpfil, "w", stdout) == NULL) { ! 1000: fprintf (stderr, "unable to create "); ! 1001: perror (tmpfil); ! 1002: _exit (1); ! 1003: } ! 1004: args[0] = r1bindex (mhlproc, '/'); ! 1005: i = 1; ! 1006: args[i++] = "-forwall"; ! 1007: args[i++] = "-form"; ! 1008: args[i++] = filter; ! 1009: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 1010: if (mp -> msgstats[msgnum] & SELECTED) ! 1011: args[i++] = getcpy (m_name (msgnum)); ! 1012: args[i] = NULL; ! 1013: (void) mhlsbr (i, args, mhl_action); ! 1014: m_eomsbr ((int (*) ()) 0); ! 1015: (void) fclose (stdout); ! 1016: _exit (0); ! 1017: ! 1018: default: ! 1019: if (pidXwait (child_id, NULLCP)) ! 1020: interrupted++; ! 1021: break; ! 1022: } ! 1023: else { ! 1024: if ((out = fopen (tmpfil, "w")) == NULL) { ! 1025: advise (tmpfil, "unable to create temporary file"); ! 1026: return; ! 1027: } ! 1028: ! 1029: msgcnt = 1; ! 1030: for (msgnum = mp -> lowsel; ! 1031: msgnum <= mp -> hghsel && !interrupted; ! 1032: msgnum++) ! 1033: if (mp -> msgstats[msgnum] & SELECTED) { ! 1034: fprintf (out, "\n\n-------"); ! 1035: if (msgnum == mp -> lowsel) ! 1036: fprintf (out, " Forwarded Message%s", ! 1037: mp -> numsel > 1 ? "s" : ""); ! 1038: else ! 1039: fprintf (out, " Message %d", msgcnt); ! 1040: fprintf (out, "\n\n"); ! 1041: copy_digest (msgnum, out); ! 1042: msgcnt++; ! 1043: } ! 1044: ! 1045: fprintf (out, "\n\n------- End of Forwarded Message%s\n", ! 1046: mp -> numsel > 1 ? "s" : ""); ! 1047: (void) fclose (out); ! 1048: } ! 1049: ! 1050: (void) fflush (stdout); ! 1051: if (!interrupted) ! 1052: switch (child_id = fork ()) { ! 1053: case NOTOK: ! 1054: advise ("fork", "unable to"); ! 1055: break; ! 1056: ! 1057: case OK: ! 1058: closefds (3); ! 1059: (void) signal (SIGINT, istat); ! 1060: (void) signal (SIGQUIT, qstat); ! 1061: ! 1062: vec[vecp++] = tmpfil; ! 1063: vec[vecp] = NULL; ! 1064: ! 1065: execvp (proc, vec); ! 1066: fprintf (stderr, "unable to exec "); ! 1067: perror (proc); ! 1068: _exit (1); ! 1069: ! 1070: default: ! 1071: (void) pidXwait (child_id, NULLCP); ! 1072: break; ! 1073: } ! 1074: ! 1075: (void) unlink (tmpfil); ! 1076: } ! 1077: ! 1078: /* */ ! 1079: ! 1080: static char *hlpmsg[] = { ! 1081: "The %s program emulates many of the commands found in the Rand MH", ! 1082: "system. Instead of operating on MH folders, commands to %s concern", ! 1083: "a single file.", ! 1084: "", ! 1085: "To see the list of commands available, just type a ``?'' followed by", ! 1086: "the RETURN key. To find out what switches each command takes, type", ! 1087: "the name of the command followed by ``-help''. To leave %s, use the", ! 1088: "``quit'' command.", ! 1089: "", ! 1090: "Although a lot of MH commands are found in %s, not all are fully", ! 1091: "implemented. %s will always recognize all legal switches for a", ! 1092: "given command though, and will let you know when you ask for an", ! 1093: "option that it is unable to perform.", ! 1094: "", ! 1095: "Running %s is fun, but using MH from your shell is far superior.", ! 1096: "After you have familiarized yourself with the MH style by using %s,", ! 1097: "you should try using MH from the shell. You can still use %s for", ! 1098: "message files that aren't in MH format, such as BBoard files.", ! 1099: NULL ! 1100: }; ! 1101: ! 1102: ! 1103: /* ARGSUSED */ ! 1104: ! 1105: helpcmd (args) ! 1106: char **args; ! 1107: { ! 1108: int i; ! 1109: ! 1110: for (i = 0; hlpmsg[i]; i++) { ! 1111: printf (hlpmsg[i], invo_name); ! 1112: (void) putchar ('\n'); ! 1113: } ! 1114: } ! 1115: ! 1116: /* */ ! 1117: ! 1118: static struct swit markswit[] = { ! 1119: #define MADDSW 0 ! 1120: "add", 0, ! 1121: #define MDELSW 1 ! 1122: "delete", 0, ! 1123: #define MLSTSW 2 ! 1124: "list", 0, ! 1125: #define MSEQSW 3 ! 1126: "sequence name", 0, ! 1127: #define MPUBSW 4 ! 1128: "public", 0, ! 1129: #define MNPUBSW 5 ! 1130: "nopublic", 0, ! 1131: #define MZERSW 6 ! 1132: "zero", 0, ! 1133: #define MNZERSW 7 ! 1134: "nozero", 0, ! 1135: #define MHELP 8 ! 1136: "help", 4, ! 1137: #define MDBUGSW 9 ! 1138: "debug", -5, ! 1139: ! 1140: NULL, NULL ! 1141: }; ! 1142: ! 1143: /* */ ! 1144: ! 1145: markcmd (args) ! 1146: char **args; ! 1147: { ! 1148: int addsw = 0, ! 1149: deletesw = 0, ! 1150: debugsw = 0, ! 1151: listsw = 0, ! 1152: zerosw = 0, ! 1153: seqp = 0, ! 1154: msgp = 0, ! 1155: i, ! 1156: msgnum; ! 1157: char *cp, ! 1158: buf[BUFSIZ], ! 1159: *seqs[NATTRS + 1], ! 1160: *msgs[MAXARGS]; ! 1161: ! 1162: while (cp = *args++) { ! 1163: if (*cp == '-') ! 1164: switch (smatch (++cp, markswit)) { ! 1165: case AMBIGSW: ! 1166: ambigsw (cp, markswit); ! 1167: return; ! 1168: case UNKWNSW: ! 1169: fprintf (stderr, "-%s unknown\n", cp); ! 1170: return; ! 1171: case MHELP: ! 1172: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); ! 1173: help (buf, markswit); ! 1174: return; ! 1175: ! 1176: case MADDSW: ! 1177: addsw++; ! 1178: deletesw = listsw = 0; ! 1179: continue; ! 1180: case MDELSW: ! 1181: deletesw++; ! 1182: addsw = listsw = 0; ! 1183: continue; ! 1184: case MLSTSW: ! 1185: listsw++; ! 1186: addsw = deletesw = 0; ! 1187: continue; ! 1188: ! 1189: case MSEQSW: ! 1190: if (!(cp = *args++) || *cp == '-') { ! 1191: advise (NULLCP, "missing argument to %s", args[-2]); ! 1192: return; ! 1193: } ! 1194: if (seqp < NATTRS) ! 1195: seqs[seqp++] = cp; ! 1196: else { ! 1197: advise (NULLCP, "only %d sequences allowed!", NATTRS); ! 1198: return; ! 1199: } ! 1200: continue; ! 1201: ! 1202: case MPUBSW: /* not implemented */ ! 1203: case MNPUBSW: ! 1204: continue; ! 1205: ! 1206: case MDBUGSW: ! 1207: debugsw++; ! 1208: continue; ! 1209: ! 1210: case MZERSW: ! 1211: zerosw++; ! 1212: continue; ! 1213: case MNZERSW: ! 1214: zerosw = 0; ! 1215: continue; ! 1216: } ! 1217: if (*cp == '+' || *cp == '@') { ! 1218: advise (NULLCP, "sorry, no folders allowed!"); ! 1219: return; ! 1220: } ! 1221: else ! 1222: msgs[msgp++] = cp; ! 1223: } ! 1224: ! 1225: if (!addsw && !deletesw && !listsw) ! 1226: if (seqp) ! 1227: addsw++; ! 1228: else ! 1229: if (debugsw) ! 1230: listsw++; ! 1231: else { ! 1232: seqs[seqp++] = "unseen"; ! 1233: deletesw++; ! 1234: zerosw = 0; ! 1235: if (!msgp) ! 1236: msgs[msgp++] = "all"; ! 1237: } ! 1238: ! 1239: if (!msgp) ! 1240: msgs[msgp++] = listsw ? "all" :"cur"; ! 1241: for (msgnum = 0; msgnum < msgp; msgnum++) ! 1242: if (!m_convert (mp, msgs[msgnum])) ! 1243: return; ! 1244: ! 1245: if (debugsw) { ! 1246: printf ("invo_name=%s mypath=%s defpath=%s\n", ! 1247: invo_name, mypath, defpath); ! 1248: printf ("ctxpath=%s context flags=%s\n", ! 1249: ctxpath, sprintb (buf, (unsigned) ctxflags, DBITS)); ! 1250: printf ("foldpath=%s flags=%s\n", ! 1251: mp -> foldpath, ! 1252: sprintb (buf, (unsigned) mp -> msgflags, FBITS)); ! 1253: printf ("hghmsg=%d lowmsg=%d nummsg=%d curmsg=%d\n", ! 1254: mp -> hghmsg, mp -> lowmsg, mp -> nummsg, mp -> curmsg); ! 1255: printf ("lowsel=%d hghsel=%d numsel=%d\n", ! 1256: mp -> lowsel, mp -> hghsel, mp -> numsel); ! 1257: #ifndef MTR ! 1258: printf ("lowoff=%d hghoff=%d\n", ! 1259: mp -> lowoff, mp -> hghoff); ! 1260: #else MTR ! 1261: printf ("lowoff=%d hghoff=%d msgbase=0x%x msgstats=0x%x\n", ! 1262: mp -> lowoff, mp -> hghoff, mp -> msgbase, mp -> msgstats); ! 1263: #endif MTR ! 1264: } ! 1265: ! 1266: if (seqp == 0 && (addsw || deletesw)) { ! 1267: advise (NULLCP, "-%s requires at least one -sequence argument", ! 1268: addsw ? "add" : "delete"); ! 1269: return; ! 1270: } ! 1271: seqs[seqp] = NULL; ! 1272: ! 1273: if (addsw) ! 1274: for (seqp = 0; seqs[seqp]; seqp++) { ! 1275: if (zerosw && !m_seqnew (mp, seqs[seqp], 0)) ! 1276: return; ! 1277: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 1278: if (mp -> msgstats[msgnum] & SELECTED) ! 1279: if (!m_seqadd (mp, seqs[seqp], msgnum, 0)) ! 1280: return; ! 1281: } ! 1282: ! 1283: if (deletesw) ! 1284: for (seqp = 0; seqs[seqp]; seqp++) { ! 1285: if (zerosw) ! 1286: for (msgnum = mp -> lowmsg; msgnum <= mp -> hghmsg; msgnum++) ! 1287: if (mp -> msgstats[msgnum] & EXISTS) ! 1288: if (!m_seqadd (mp, seqs[seqp], msgnum, 0)) ! 1289: return; ! 1290: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 1291: if (mp -> msgstats[msgnum] & SELECTED) ! 1292: if (!m_seqdel (mp, seqs[seqp], msgnum)) ! 1293: return; ! 1294: } ! 1295: ! 1296: if (listsw) { ! 1297: int bits = FFATTRSLOT; ! 1298: ! 1299: if (seqp == 0) ! 1300: for (i = 0; mp -> msgattrs[i]; i++) ! 1301: printf ("%s%s: %s\n", mp -> msgattrs[i], ! 1302: mp -> attrstats & (1 << (bits + i)) ! 1303: ? " (private)" : "", ! 1304: m_seq (mp, mp -> msgattrs[i])); ! 1305: else ! 1306: for (seqp = 0; seqs[seqp]; seqp++) ! 1307: printf ("%s%s: %s\n", seqs[seqp], m_seq (mp, seqs[seqp])); ! 1308: ! 1309: interrupted = 0; ! 1310: if (debugsw) ! 1311: for (msgnum = mp -> lowsel; ! 1312: msgnum <= mp -> hghsel && !interrupted; ! 1313: msgnum++) ! 1314: if (mp -> msgstats[msgnum] & SELECTED) { ! 1315: printf ("%*d: id=%d top=%d start=%ld stop=%ld %s\n", ! 1316: DMAXFOLDER, msgnum, ! 1317: Msgs[msgnum].m_bboard_id, Msgs[msgnum].m_top, ! 1318: Msgs[msgnum].m_start, Msgs[msgnum].m_stop, ! 1319: sprintb (buf, (unsigned) mp -> msgstats[msgnum], ! 1320: m_seqbits (mp))); ! 1321: if (Msgs[msgnum].m_scanl) ! 1322: printf ("%s", Msgs[msgnum].m_scanl); ! 1323: } ! 1324: } ! 1325: } ! 1326: ! 1327: /* */ ! 1328: ! 1329: static struct swit packswit[] = { ! 1330: #define PAFISW 0 ! 1331: "file name", 0, ! 1332: ! 1333: #define PAHELP 1 ! 1334: "help", 4, ! 1335: ! 1336: NULL, NULL ! 1337: }; ! 1338: ! 1339: /* */ ! 1340: ! 1341: packcmd (args) ! 1342: char **args; ! 1343: { ! 1344: int msgp = 0, ! 1345: md, ! 1346: msgnum; ! 1347: char *cp, ! 1348: *file = NULL, ! 1349: buf[BUFSIZ], ! 1350: *msgs[MAXARGS]; ! 1351: struct stat st; ! 1352: ! 1353: if (fmsh) { ! 1354: forkcmd (args, cmd_name); ! 1355: return; ! 1356: } ! 1357: ! 1358: while (cp = *args++) { ! 1359: if (*cp == '-') ! 1360: switch (smatch (++cp, packswit)) { ! 1361: case AMBIGSW: ! 1362: ambigsw (cp, packswit); ! 1363: return; ! 1364: case UNKWNSW: ! 1365: fprintf (stderr, "-%s unknown\n", cp); ! 1366: return; ! 1367: case PAHELP: ! 1368: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); ! 1369: help (buf, packswit); ! 1370: return; ! 1371: ! 1372: case PAFISW: ! 1373: if (!(file = *args++) || *file == '-') { ! 1374: advise (NULLCP, "missing argument to %s", args[-2]); ! 1375: return; ! 1376: } ! 1377: continue; ! 1378: } ! 1379: if (*cp == '+' || *cp == '@') { ! 1380: advise (NULLCP, "sorry, no folders allowed!"); ! 1381: return; ! 1382: } ! 1383: else ! 1384: msgs[msgp++] = cp; ! 1385: } ! 1386: ! 1387: if (!file) ! 1388: file = "./msgbox"; ! 1389: file = path (file, TFILE); ! 1390: if (stat (file, &st) == NOTOK) { ! 1391: if (errno != ENOENT) { ! 1392: advise (file, "error on file"); ! 1393: goto done_pack; ! 1394: } ! 1395: md = getanswer (cp = concat ("Create file \"", file, "\"? ", NULLCP)); ! 1396: free (cp); ! 1397: if (!md) ! 1398: goto done_pack; ! 1399: } ! 1400: ! 1401: if (!msgp) ! 1402: msgs[msgp++] = "all"; ! 1403: for (msgnum = 0; msgnum < msgp; msgnum++) ! 1404: if (!m_convert (mp, msgs[msgnum])) ! 1405: goto done_pack; ! 1406: m_setseq (mp); ! 1407: ! 1408: if ((md = mbx_open (file, getuid (), getgid (), m_gmprot ())) == NOTOK) { ! 1409: advise (file, "unable to open"); ! 1410: goto done_pack; ! 1411: } ! 1412: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 1413: if (mp -> msgstats[msgnum] & SELECTED) ! 1414: if (pack (file, md, msgnum) == NOTOK) ! 1415: break; ! 1416: (void) mbx_close (file, md); ! 1417: ! 1418: if (mp -> hghsel != mp -> curmsg) ! 1419: m_setcur (mp, mp -> lowsel); ! 1420: ! 1421: done_pack: ; ! 1422: free (file); ! 1423: } ! 1424: ! 1425: /* */ ! 1426: ! 1427: int pack (mailbox, md, msgnum) ! 1428: char *mailbox; ! 1429: int md, ! 1430: msgnum; ! 1431: { ! 1432: register FILE *zp; ! 1433: ! 1434: if (Msgs[msgnum].m_bboard_id == 0) ! 1435: (void) readid (msgnum); ! 1436: ! 1437: zp = msh_ready (msgnum, 1); ! 1438: return mbx_write (mailbox, md, zp, Msgs[msgnum].m_bboard_id, ! 1439: ftell (zp), Msgs[msgnum].m_stop, 1, 1); ! 1440: } ! 1441: ! 1442: /* */ ! 1443: ! 1444: int packhak (args) ! 1445: char **args; ! 1446: { ! 1447: int result; ! 1448: char *cp, ! 1449: *file = NULL; ! 1450: ! 1451: while (cp = *args++) { ! 1452: if (*cp == '-') ! 1453: switch (smatch (++cp, packswit)) { ! 1454: case AMBIGSW: ! 1455: case UNKWNSW: ! 1456: case PAHELP: ! 1457: return NOTOK; ! 1458: ! 1459: case PAFISW: ! 1460: if (!(file = *args++) || *file == '-') ! 1461: return NOTOK; ! 1462: continue; ! 1463: } ! 1464: if (*cp == '+' || *cp == '@') ! 1465: return NOTOK; ! 1466: } ! 1467: ! 1468: file = path (file ? file : "./msgbox", TFILE); ! 1469: result = access (file, 0) == NOTOK ? OK : NOTOK; ! 1470: free (file); ! 1471: ! 1472: return result; ! 1473: } ! 1474: ! 1475: /* */ ! 1476: ! 1477: static struct swit pickswit[] = { ! 1478: #define PIANSW 0 ! 1479: "and", 0, ! 1480: #define PIORSW 1 ! 1481: "or", 0, ! 1482: #define PINTSW 2 ! 1483: "not", 0, ! 1484: #define PILBSW 3 ! 1485: "lbrace", 0, ! 1486: #define PIRBSW 4 ! 1487: "rbrace", 0, ! 1488: ! 1489: #define PICCSW 5 ! 1490: "cc pattern", 0, ! 1491: #define PIDASW 6 ! 1492: "date pattern", 0, ! 1493: #define PIFRSW 7 ! 1494: "from pattern", 0, ! 1495: #define PISESW 8 ! 1496: "search pattern", 0, ! 1497: #define PISUSW 9 ! 1498: "subject pattern", 0, ! 1499: #define PITOSW 10 ! 1500: "to pattern", 0, ! 1501: #define PIOTSW 11 ! 1502: "-othercomponent pattern", 15, ! 1503: #define PIAFSW 12 ! 1504: "after date", 0, ! 1505: #define PIBFSW 13 ! 1506: "before date", 0, ! 1507: #define PIDFSW 14 ! 1508: "datefield field", 5, ! 1509: #define PISQSW 15 ! 1510: "sequence name", 0, ! 1511: #define PIPUSW 16 ! 1512: "public", 0, ! 1513: #define PINPUSW 17 ! 1514: "nopublic", 0, ! 1515: #define PIZRSW 18 ! 1516: "zero", 0, ! 1517: #define PINZRSW 19 ! 1518: "nozero", 0, ! 1519: #define PILISW 20 ! 1520: "list", 0, ! 1521: #define PINLISW 21 ! 1522: "nolist", 0, ! 1523: #define PIHELP 22 ! 1524: "help", 4, ! 1525: ! 1526: NULL, NULL ! 1527: }; ! 1528: ! 1529: /* */ ! 1530: ! 1531: pickcmd (args) ! 1532: char **args; ! 1533: { ! 1534: int zerosw = 1, ! 1535: msgp = 0, ! 1536: seqp = 0, ! 1537: vecp = 0, ! 1538: hi, ! 1539: lo, ! 1540: msgnum; ! 1541: char *cp, ! 1542: buf[BUFSIZ], ! 1543: *msgs[MAXARGS], ! 1544: *seqs[NATTRS], ! 1545: *vec[MAXARGS]; ! 1546: register FILE *zp; ! 1547: ! 1548: while (cp = *args++) { ! 1549: if (*cp == '-') { ! 1550: if (*++cp == '-') { ! 1551: vec[vecp++] = --cp; ! 1552: goto pattern; ! 1553: } ! 1554: switch (smatch (cp, pickswit)) { ! 1555: case AMBIGSW: ! 1556: ambigsw (cp, pickswit); ! 1557: return; ! 1558: case UNKWNSW: ! 1559: fprintf (stderr, "-%s unknown\n", cp); ! 1560: return; ! 1561: case PIHELP: ! 1562: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); ! 1563: help (buf, pickswit); ! 1564: return; ! 1565: ! 1566: case PICCSW: ! 1567: case PIDASW: ! 1568: case PIFRSW: ! 1569: case PISUSW: ! 1570: case PITOSW: ! 1571: case PIDFSW: ! 1572: case PIAFSW: ! 1573: case PIBFSW: ! 1574: case PISESW: ! 1575: vec[vecp++] = --cp; ! 1576: pattern: ; ! 1577: if (!(cp = *args++)) {/* allow -xyz arguments */ ! 1578: advise (NULLCP, "missing argument to %s", args[-2]); ! 1579: return; ! 1580: } ! 1581: vec[vecp++] = cp; ! 1582: continue; ! 1583: case PIOTSW: ! 1584: advise (NULLCP, "internal error!"); ! 1585: return; ! 1586: case PIANSW: ! 1587: case PIORSW: ! 1588: case PINTSW: ! 1589: case PILBSW: ! 1590: case PIRBSW: ! 1591: vec[vecp++] = --cp; ! 1592: continue; ! 1593: ! 1594: case PISQSW: ! 1595: if (!(cp = *args++) || *cp == '-') { ! 1596: advise (NULLCP, "missing argument to %s", args[-2]); ! 1597: return; ! 1598: } ! 1599: if (seqp < NATTRS) ! 1600: seqs[seqp++] = cp; ! 1601: else { ! 1602: advise (NULLCP, "only %d sequences allowed!", NATTRS); ! 1603: return; ! 1604: } ! 1605: continue; ! 1606: case PIZRSW: ! 1607: zerosw++; ! 1608: continue; ! 1609: case PINZRSW: ! 1610: zerosw = 0; ! 1611: continue; ! 1612: ! 1613: case PIPUSW: /* not implemented */ ! 1614: case PINPUSW: ! 1615: case PILISW: ! 1616: case PINLISW: ! 1617: continue; ! 1618: } ! 1619: } ! 1620: if (*cp == '+' || *cp == '@') { ! 1621: advise (NULLCP, "sorry, no folders allowed!"); ! 1622: return; ! 1623: } ! 1624: else ! 1625: msgs[msgp++] = cp; ! 1626: } ! 1627: vec[vecp] = NULL; ! 1628: ! 1629: if (!msgp) ! 1630: msgs[msgp++] = "all"; ! 1631: for (msgnum = 0; msgnum < msgp; msgnum++) ! 1632: if (!m_convert (mp, msgs[msgnum])) ! 1633: return; ! 1634: m_setseq (mp); ! 1635: ! 1636: interrupted = 0; ! 1637: if (!pcompile (vec, NULLCP)) ! 1638: return; ! 1639: ! 1640: lo = mp -> lowsel; ! 1641: hi = mp -> hghsel; ! 1642: ! 1643: for (msgnum = mp -> lowsel; ! 1644: msgnum <= mp -> hghsel && !interrupted; ! 1645: msgnum++) ! 1646: if (mp -> msgstats[msgnum] & SELECTED) { ! 1647: zp = msh_ready (msgnum, 1); ! 1648: if (pmatches (zp, msgnum, fmsh ? 0L : Msgs[msgnum].m_start, ! 1649: fmsh ? 0L : Msgs[msgnum].m_stop)) { ! 1650: if (msgnum < lo) ! 1651: lo = msgnum; ! 1652: if (msgnum > hi) ! 1653: hi = msgnum; ! 1654: } ! 1655: else { ! 1656: mp -> msgstats[msgnum] &= ~SELECTED; ! 1657: mp -> numsel--; ! 1658: } ! 1659: } ! 1660: ! 1661: if (interrupted) ! 1662: return; ! 1663: ! 1664: mp -> lowsel = lo; ! 1665: mp -> hghsel = hi; ! 1666: ! 1667: if (mp -> numsel <= 0) { ! 1668: advise (NULLCP, "no messages match specification"); ! 1669: return; ! 1670: } ! 1671: ! 1672: seqs[seqp] = NULL; ! 1673: for (seqp = 0; seqs[seqp]; seqp++) { ! 1674: if (zerosw && !m_seqnew (mp, seqs[seqp], 0)) ! 1675: return; ! 1676: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 1677: if (mp -> msgstats[msgnum] & SELECTED) ! 1678: if (!m_seqadd (mp, seqs[seqp], msgnum, 0)) ! 1679: return; ! 1680: } ! 1681: ! 1682: printf ("%d hit%s\n", mp -> numsel, mp -> numsel == 1 ? "" : "s"); ! 1683: } ! 1684: ! 1685: /* */ ! 1686: ! 1687: static struct swit replswit[] = { ! 1688: #define REANSW 0 ! 1689: "annotate", 0, ! 1690: #define RENANSW 1 ! 1691: "noannotate", 0, ! 1692: #define RECCSW 2 ! 1693: "cc type", 0, ! 1694: #define RENCCSW 3 ! 1695: "nocc type", 0, ! 1696: #define REDFSW 4 ! 1697: "draftfolder +folder", 0, ! 1698: #define REDMSW 5 ! 1699: "draftmessage msg", 0, ! 1700: #define RENDFSW 6 ! 1701: "nodraftfolder", 0, ! 1702: #define REEDTSW 7 ! 1703: "editor editor", 0, ! 1704: #define RENEDSW 8 ! 1705: "noedit", 0, ! 1706: #define REFCCSW 9 ! 1707: "fcc +folder", 0, ! 1708: #define REFLTSW 10 ! 1709: "filter filterfile", 0, ! 1710: #define REFRMSW 11 ! 1711: "form formfile", 0, ! 1712: #define REFRSW 12 ! 1713: "format", 5, ! 1714: #define RENFRSW 13 ! 1715: "noformat", 7, ! 1716: #define REINSW 14 ! 1717: "inplace", 0, ! 1718: #define RENINSW 15 ! 1719: "noinplace", 0, ! 1720: #define REQUSW 16 ! 1721: "query", 0, ! 1722: #define RENQUSW 17 ! 1723: "noquery", 0, ! 1724: #define REWHTSW 18 ! 1725: "whatnowproc program", 0, ! 1726: #define RENWTSW 19 ! 1727: "nowhatnow", 0, ! 1728: #define REWIDSW 20 ! 1729: "width columns", 0, ! 1730: #define REHELP 21 ! 1731: "help", 4, ! 1732: ! 1733: NULL, NULL ! 1734: }; ! 1735: ! 1736: /* */ ! 1737: ! 1738: replcmd (args) ! 1739: char **args; ! 1740: { ! 1741: int vecp = 1; ! 1742: char *cp, ! 1743: *msg = NULL, ! 1744: buf[BUFSIZ], ! 1745: *vec[MAXARGS]; ! 1746: ! 1747: if (fmsh) { ! 1748: forkcmd (args, cmd_name); ! 1749: return; ! 1750: } ! 1751: ! 1752: while (cp = *args++) { ! 1753: if (*cp == '-') ! 1754: switch (smatch (++cp, replswit)) { ! 1755: case AMBIGSW: ! 1756: ambigsw (cp, replswit); ! 1757: return; ! 1758: case UNKWNSW: ! 1759: fprintf (stderr, "-%s unknown\n", cp); ! 1760: return; ! 1761: case REHELP: ! 1762: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); ! 1763: help (buf, replswit); ! 1764: return; ! 1765: ! 1766: case REANSW: /* not implemented */ ! 1767: case RENANSW: ! 1768: case REINSW: ! 1769: case RENINSW: ! 1770: continue; ! 1771: ! 1772: case REFRSW: ! 1773: case RENFRSW: ! 1774: case REQUSW: ! 1775: case RENQUSW: ! 1776: case RENDFSW: ! 1777: case RENEDSW: ! 1778: case RENWTSW: ! 1779: vec[vecp++] = --cp; ! 1780: continue; ! 1781: ! 1782: case RECCSW: ! 1783: case RENCCSW: ! 1784: case REEDTSW: ! 1785: case REFCCSW: ! 1786: case REFLTSW: ! 1787: case REFRMSW: ! 1788: case REWIDSW: ! 1789: case REDFSW: ! 1790: case REDMSW: ! 1791: case REWHTSW: ! 1792: vec[vecp++] = --cp; ! 1793: if (!(cp = *args++) || *cp == '-') { ! 1794: advise (NULLCP, "missing argument to %s", args[-2]); ! 1795: return; ! 1796: } ! 1797: vec[vecp++] = cp; ! 1798: continue; ! 1799: } ! 1800: if (*cp == '+' || *cp == '@') { ! 1801: advise (NULLCP, "sorry, no folders allowed!"); ! 1802: return; ! 1803: } ! 1804: else ! 1805: if (msg) { ! 1806: advise (NULLCP, "only one message at a time!"); ! 1807: return; ! 1808: } ! 1809: else ! 1810: msg = cp; ! 1811: } ! 1812: ! 1813: vec[0] = cmd_name; ! 1814: vec[vecp++] = "-file"; ! 1815: vec[vecp] = NULL; ! 1816: if (!msg) ! 1817: msg = "cur"; ! 1818: if (!m_convert (mp, msg)) ! 1819: return; ! 1820: m_setseq (mp); ! 1821: ! 1822: if (mp -> numsel > 1) { ! 1823: advise (NULLCP, "only one message at a time!"); ! 1824: return; ! 1825: } ! 1826: (void) process (mp -> hghsel, cmd_name, vecp, vec); ! 1827: m_setcur (mp, mp -> hghsel); ! 1828: } ! 1829: ! 1830: /* */ ! 1831: ! 1832: static struct swit rmmswit[] = { ! 1833: #define RMHELP 0 ! 1834: "help", 4, ! 1835: ! 1836: NULL, NULL ! 1837: }; ! 1838: ! 1839: /* */ ! 1840: ! 1841: rmmcmd (args) ! 1842: char **args; ! 1843: { ! 1844: int msgp = 0, ! 1845: msgnum; ! 1846: char *cp, ! 1847: buf[BUFSIZ], ! 1848: *msgs[MAXARGS]; ! 1849: ! 1850: while (cp = *args++) { ! 1851: if (*cp == '-') ! 1852: switch (smatch (++cp, rmmswit)) { ! 1853: case AMBIGSW: ! 1854: ambigsw (cp, rmmswit); ! 1855: return; ! 1856: case UNKWNSW: ! 1857: fprintf (stderr, "-%s unknown\n", cp); ! 1858: return; ! 1859: case RMHELP: ! 1860: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); ! 1861: help (buf, rmmswit); ! 1862: return; ! 1863: } ! 1864: if (*cp == '+' || *cp == '@') { ! 1865: advise (NULLCP, "sorry, no folders allowed!"); ! 1866: return; ! 1867: } ! 1868: else ! 1869: msgs[msgp++] = cp; ! 1870: } ! 1871: ! 1872: if (!msgp) ! 1873: msgs[msgp++] = "cur"; ! 1874: for (msgnum = 0; msgnum < msgp; msgnum++) ! 1875: if (!m_convert (mp, msgs[msgnum])) ! 1876: return; ! 1877: m_setseq (mp); ! 1878: ! 1879: rmm (); ! 1880: } ! 1881: ! 1882: /* */ ! 1883: ! 1884: static void rmm () ! 1885: { ! 1886: register int msgnum, ! 1887: vecp; ! 1888: register char *cp; ! 1889: char buffer[BUFSIZ], ! 1890: *vec[MAXARGS]; ! 1891: ! 1892: if (fmsh) { ! 1893: if (rmmproc) { ! 1894: if (mp -> numsel > MAXARGS - 1) { ! 1895: advise (NULLCP, "more than %d messages for %s exec", ! 1896: MAXARGS - 1, rmmproc); ! 1897: return; ! 1898: } ! 1899: vecp = 0; ! 1900: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 1901: if (mp -> msgstats[msgnum] & SELECTED) ! 1902: vec[vecp++] = getcpy (m_name (msgnum)); ! 1903: vec[vecp] = NULL; ! 1904: forkcmd (vec, rmmproc); ! 1905: for (vecp = 0; vec[vecp]; vecp++) ! 1906: free (vec[vecp]); ! 1907: } ! 1908: else ! 1909: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 1910: if (mp -> msgstats[msgnum] & SELECTED) { ! 1911: (void) strcpy (buffer, m_backup (cp = m_name (msgnum))); ! 1912: if (rename (cp, buffer) == NOTOK) ! 1913: admonish (buffer, "unable to rename %s to", cp); ! 1914: } ! 1915: } ! 1916: ! 1917: for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) ! 1918: if (mp -> msgstats[msgnum] & SELECTED) { ! 1919: mp -> msgstats[msgnum] |= DELETED; ! 1920: mp -> msgstats[msgnum] &= ~EXISTS; ! 1921: } ! 1922: ! 1923: if ((mp -> nummsg -= mp -> numsel) <= 0) { ! 1924: if (fmsh) ! 1925: admonish (NULLCP, "no messages remaining in +%s", fmsh); ! 1926: else ! 1927: admonish (NULLCP, "no messages remaining in %s", mp -> foldpath); ! 1928: mp -> lowmsg = mp -> hghmsg = mp -> nummsg = 0; ! 1929: } ! 1930: if (mp -> lowsel == mp -> lowmsg) { ! 1931: for (msgnum = mp -> lowmsg + 1; msgnum <= mp -> hghmsg; msgnum++) ! 1932: if (mp -> msgstats[msgnum] & EXISTS) ! 1933: break; ! 1934: mp -> lowmsg = msgnum; ! 1935: } ! 1936: if (mp -> hghsel == mp -> hghmsg) { ! 1937: for (msgnum = mp -> hghmsg - 1; msgnum >= mp -> lowmsg; msgnum--) ! 1938: if (mp -> msgstats[msgnum] & EXISTS) ! 1939: break; ! 1940: mp -> hghmsg = msgnum; ! 1941: } ! 1942: ! 1943: mp -> msgflags |= MODIFIED; ! 1944: modified++; ! 1945: } ! 1946: ! 1947: /* */ ! 1948: ! 1949: static struct swit scanswit[] = { ! 1950: #define SCCLR 0 ! 1951: "clear", 0, ! 1952: #define SCNCLR 1 ! 1953: "noclear", 0, ! 1954: #define SCFORM 2 ! 1955: "form formatfile", 0, ! 1956: #define SCFMT 3 ! 1957: "format string", 5, ! 1958: #define SCHEAD 4 ! 1959: "header", 0, ! 1960: #define SCNHEAD 5 ! 1961: "noheader", 0, ! 1962: #define SCWID 6 ! 1963: "width columns", 0, ! 1964: #define SCHELP 7 ! 1965: "help", 4, ! 1966: ! 1967: NULL, NULL ! 1968: }; ! 1969: ! 1970: /* */ ! 1971: ! 1972: scancmd (args) ! 1973: char **args; ! 1974: { ! 1975: #define equiv(a,b) (a ? b && !strcmp (a, b) : !b) ! 1976: ! 1977: int clearsw = 0, ! 1978: headersw = 0, ! 1979: width = 0, ! 1980: msgp = 0, ! 1981: msgnum, ! 1982: optim, ! 1983: state; ! 1984: char *cp, ! 1985: *form = NULL, ! 1986: *format = NULL, ! 1987: buf[BUFSIZ], ! 1988: *nfs, ! 1989: *msgs[MAXARGS]; ! 1990: register FILE *zp; ! 1991: static int s_optim = 0; ! 1992: static char *s_form = NULL, ! 1993: *s_format = NULL; ! 1994: ! 1995: while (cp = *args++) { ! 1996: if (*cp == '-') ! 1997: switch (smatch (++cp, scanswit)) { ! 1998: case AMBIGSW: ! 1999: ambigsw (cp, scanswit); ! 2000: return; ! 2001: case UNKWNSW: ! 2002: fprintf (stderr, "-%s unknown\n", cp); ! 2003: return; ! 2004: case SCHELP: ! 2005: (void) sprintf (buf, "%s [msgs] [switches]", cmd_name); ! 2006: help (buf, scanswit); ! 2007: return; ! 2008: ! 2009: case SCCLR: ! 2010: clearsw++; ! 2011: continue; ! 2012: case SCNCLR: ! 2013: clearsw = 0; ! 2014: continue; ! 2015: case SCHEAD: ! 2016: headersw++; ! 2017: continue; ! 2018: case SCNHEAD: ! 2019: headersw = 0; ! 2020: continue; ! 2021: case SCFORM: ! 2022: if (!(form = *args++) || *form == '-') { ! 2023: advise (NULLCP, "missing argument to %s", args[-2]); ! 2024: return; ! 2025: } ! 2026: format = NULL; ! 2027: continue; ! 2028: case SCFMT: ! 2029: if (!(format = *args++) || *format == '-') { ! 2030: advise (NULLCP, "missing argument to %s", args[-2]); ! 2031: return; ! 2032: } ! 2033: form = NULL; ! 2034: continue; ! 2035: case SCWID: ! 2036: if (!(cp = *args++) || *cp == '-') { ! 2037: advise (NULLCP, "missing argument to %s", args[-2]); ! 2038: return; ! 2039: } ! 2040: width = atoi (cp); ! 2041: continue; ! 2042: } ! 2043: if (*cp == '+' || *cp == '@') { ! 2044: advise (NULLCP, "sorry, no folders allowed!"); ! 2045: return; ! 2046: } ! 2047: else ! 2048: msgs[msgp++] = cp; ! 2049: } ! 2050: ! 2051: if (!msgp) ! 2052: msgs[msgp++] = "all"; ! 2053: for (msgnum = 0; msgnum < msgp; msgnum++) ! 2054: if (!m_convert (mp, msgs[msgnum])) ! 2055: return; ! 2056: m_setseq (mp); ! 2057: ! 2058: nfs = new_fs (form, format, FORMAT); ! 2059: if (scanl) { /* force scansbr to (re)compile format */ ! 2060: (void) free (scanl); ! 2061: scanl = NULL; ! 2062: } ! 2063: ! 2064: if (s_optim == 0) { ! 2065: s_optim = optim = 1; ! 2066: s_form = form ? getcpy (form) : NULL; ! 2067: s_format = format ? getcpy (format) : NULL; ! 2068: } ! 2069: else ! 2070: optim = equiv (s_form, form) && equiv (s_format, format); ! 2071: ! 2072: interrupted = 0; ! 2073: for (msgnum = mp -> lowsel; ! 2074: msgnum <= mp -> hghsel && !interrupted; ! 2075: msgnum++) ! 2076: if (mp -> msgstats[msgnum] & SELECTED) { ! 2077: if (optim && Msgs[msgnum].m_scanl) ! 2078: printf ("%s", Msgs[msgnum].m_scanl); ! 2079: else { ! 2080: zp = msh_ready (msgnum, 0); ! 2081: switch (state = scan(zp, msgnum, 0, nfs, width, ! 2082: msgnum == mp -> curmsg, headersw, fmsh ? 0L : ! 2083: (long) (Msgs[msgnum].m_stop - Msgs[msgnum].m_start), ! 2084: 1, 0)) { ! 2085: case SCNMSG: ! 2086: case SCNENC: ! 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 void 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 int 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 void 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 void 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.