9 date 95.12.11.18.19.26; author jromine; state Exp;
14 date 95.12.07.18.20.22; author jromine; state Exp;
19 date 95.12.06.23.44.31; author jromine; state Exp;
24 date 94.04.21.18.20.50; author jromine; state Exp;
29 date 93.12.01.03.50.31; author jromine; state Exp;
34 date 93.10.26.20.09.54; author jromine; state Exp;
39 date 93.08.27.23.23.26; author jromine; state Exp;
44 date 92.12.15.00.20.22; author jromine; state Exp;
49 date 92.11.24.18.26.05; author jromine; state Exp;
54 date 92.11.04.00.53.32; author jromine; state Exp;
59 date 92.10.29.03.49.31; author jromine; state Exp;
64 date 92.10.26.22.21.33; author jromine; state Exp;
69 date 92.10.17.00.24.25; author jromine; state Exp;
74 date 92.10.17.00.19.58; author jromine; state Exp;
79 date 92.10.16.22.34.17; author jromine; state Exp;
84 date 92.10.16.21.50.20; author jromine; state Exp;
89 date 92.10.16.21.47.40; author jromine; state Exp;
94 date 92.10.16.21.37.18; author jromine; state Exp;
99 date 92.10.16.16.51.55; author jromine; state Exp;
104 date 92.05.19.21.03.35; author jromine; state Exp;
109 date 92.03.03.17.09.57; author jromine; state Exp;
114 date 92.02.08.00.10.26; author jromine; state Exp;
119 date 92.02.05.07.26.30; author jromine; state Exp;
124 date 92.01.31.22.19.11; author jromine; state Exp;
129 date 92.01.31.16.33.46; author jromine; state Exp;
134 date 92.01.23.22.58.03; author jromine; state Exp;
139 date 91.01.14.16.48.39; author mh; state Exp;
144 date 90.04.05.15.01.41; author sources; state Exp;
149 date 90.03.23.14.14.55; author sources; state Exp;
154 date 90.03.22.16.59.48; author sources; state Exp;
159 date 90.02.06.13.23.35; author sources; state Exp;
164 date 90.02.06.13.23.00; author sources; state Exp;
175 @fix merge error (mtr fixes)
178 @/* mshcmds.c - command handlers in msh */
180 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.31 1995/12/07 18:20:22 jromine Exp jromine $";
184 #include "../h/dropsbr.h"
185 #include "../h/formatsbr.h"
186 #include "../h/scansbr.h"
187 #include "../zotnet/tws.h"
188 #ifdef _AIX /* AIX 1.2.1 <stdio.h> declares getws() */
195 #include "../zotnet/mts.h"
200 #include <sys/types.h>
201 #include <sys/stat.h>
202 #include "../h/mshsbr.h"
204 #include "../h/mhn.h"
212 static char delim3[] = "-------";/* from burst.c */
219 void clear_screen ();
220 static int eom_action ();
221 static FP mhl_action ();
223 static int nontext();
227 static burst(), forw(), rmm(), show(), ask(), copy_message(), copy_digest();
228 static int process();
230 static int msgsort (), subsort();
232 static char *sosmash ();
234 #if defined(NNTP) && defined(MPOP)
240 extern char response[];
253 vec[0] = r1bindex (pgm, '/');
254 (void) copyip (args, vec + 1);
257 (void) m_delete (pfolder);
258 m_replace (pfolder, fmsh);
262 (void) fflush (stdout);
263 switch (child_id = fork ()) {
265 advise ("fork", "unable to");
270 (void) signal (SIGINT, istat);
271 (void) signal (SIGQUIT, qstat);
274 fprintf (stderr, "unable to exec ");
279 (void) pidXwait (child_id, NULLCP);
282 if (fmsh) { /* assume the worst case */
283 mp -> msgflags |= MODIFIED;
290 static struct swit distswit[] = {
296 "draftfolder +folder", 0,
298 "draftmessage msg", 0,
312 "whatnowproc program", 0,
333 forkcmd (args, cmd_name);
337 while (cp = *args++) {
339 switch (smatch (++cp, distswit)) {
341 ambigsw (cp, distswit);
344 fprintf (stderr, "-%s unknown\n", cp);
347 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
348 help (buf, distswit);
351 case DIANSW: /* not implemented */
369 if (!(cp = *args++) || *cp == '-') {
370 advise (NULLCP, "missing argument to %s", args[-2]);
376 if (*cp == '+' || *cp == '@@') {
377 advise (NULLCP, "sorry, no folders allowed!");
382 advise (NULLCP, "only one message at a time!");
390 vec[vecp++] = "-file";
394 if (!m_convert (mp, msg))
398 if (mp -> numsel > 1) {
399 advise (NULLCP, "only one message at a time!");
402 (void) process (mp -> hghsel, cmd_name, vecp, vec);
403 m_setcur (mp, mp -> hghsel);
408 static struct swit explswit[] = {
444 forkcmd (args, cmd_name);
448 while (cp = *args++) {
450 switch (smatch (++cp, explswit)) {
452 ambigsw (cp, explswit);
455 fprintf (stderr, "-%s unknown\n", cp);
458 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
459 help (buf, explswit);
481 if (*cp == '+' || *cp == '@@') {
482 advise (NULLCP, "sorry, no folders allowed!");
490 msgs[msgp++] = "cur";
491 for (msgnum = 0; msgnum < msgp; msgnum++)
492 if (!m_convert (mp, msgs[msgnum]))
496 smsgs = (struct Msg *)
497 calloc ((unsigned) (MAXFOLDER + 2), sizeof *smsgs);
499 adios (NULLCP, "unable to allocate folder storage");
501 hi = mp -> hghmsg + 1;
503 for (msgnum = mp -> lowsel;
504 msgnum <= mp -> hghsel && !interrupted;
506 if (mp -> msgstats[msgnum] & SELECTED)
507 if (burst (smsgs, msgnum, inplace, quietsw, verbosw) != OK)
510 free ((char *) smsgs);
513 m_setcur (mp, mp -> lowsel);
515 if (hi <= mp -> hghmsg)
518 mp -> msgflags |= MODIFIED;
524 static burst (smsgs, msgnum, inplace, quietsw, verbosw)
542 ld3 = strlen (delim3);
544 if (Msgs[msgnum].m_scanl) {
545 free (Msgs[msgnum].m_scanl);
546 Msgs[msgnum].m_scanl = NULL;
549 pos = ftell (zp = msh_ready (msgnum, 1));
550 for (msgp = 0; msgp <= MAXFOLDER;) {
551 while (fgets (buffer, sizeof buffer, zp) != NULL
553 && pos < Msgs[msgnum].m_stop)
554 pos += (long) strlen (buffer);
555 if (feof (zp) || pos >= Msgs[msgnum].m_stop)
557 (void) fseek (zp, pos, 0);
558 smsgs[msgp].m_start = pos;
561 pos < Msgs[msgnum].m_stop
562 && fgets (buffer, sizeof buffer, zp) != NULL;
564 if (strncmp (buffer, delim3, ld3) == 0
565 && (msgp == 1 || c == '\n')
566 && peekc (zp) == '\n')
569 pos += (long) strlen (buffer);
571 wasdlm = strncmp (buffer, delim3, ld3) == 0;
572 if (smsgs[msgp].m_start != pos)
573 smsgs[msgp++].m_stop = (c == '\n' && wasdlm) ? pos - 1 : pos;
574 if (feof (zp) || pos >= Msgs[msgnum].m_stop) {
576 smsgs[msgp - 1].m_stop -= ((long) strlen (buffer) + 1);
579 pos += (long) strlen (buffer);
582 switch (msgp--) { /* toss "End of XXX Digest" */
584 adios (NULLCP, "burst() botch -- you lose big");
588 printf ("message %d not in digest format\n", msgnum);
593 printf ("%d message%s exploded from digest %d\n",
594 msgp, msgp != 1 ? "s" : "", msgnum);
598 if ((i = msgp + mp -> hghmsg) > MAXFOLDER) {
599 advise (NULLCP, "more than %d messages", MAXFOLDER);
602 if ((mp = m_remsg (mp, 0, i)) == NULL)
603 adios (NULLCP, "unable to allocate folder storage");
606 mp -> hghmsg += msgp;
607 mp -> nummsg += msgp;
608 if (mp -> hghsel > msgnum)
609 mp -> hghsel += msgp;
612 for (i = mp -> hghmsg; j > msgnum; i--, j--) {
614 printf ("message %d becomes message %d\n", j, i);
616 Msgs[i].m_bboard_id = Msgs[j].m_bboard_id;
617 Msgs[i].m_top = Msgs[j].m_top;
618 Msgs[i].m_start = Msgs[j].m_start;
619 Msgs[i].m_stop = Msgs[j].m_stop;
620 Msgs[i].m_scanl = NULL;
621 if (Msgs[j].m_scanl) {
622 free (Msgs[j].m_scanl);
623 Msgs[j].m_scanl = NULL;
625 mp -> msgstats[i] = mp -> msgstats[j];
628 if (Msgs[msgnum].m_bboard_id == 0)
629 (void) readid (msgnum);
631 mp -> msgstats[msgnum] &= ~SELECTED;
632 i = inplace ? msgnum + msgp : mp -> hghmsg;
633 for (j = msgp; j >= (inplace ? 0 : 1); i--, j--) {
634 if (verbosw && i != msgnum)
635 printf ("message %d of digest %d becomes message %d\n",
638 Msgs[i].m_bboard_id = Msgs[msgnum].m_bboard_id;
639 Msgs[i].m_top = Msgs[j].m_top;
640 Msgs[i].m_start = smsgs[j].m_start;
641 Msgs[i].m_stop = smsgs[j].m_stop;
642 Msgs[i].m_scanl = NULL;
643 mp -> msgstats[i] = mp -> msgstats[msgnum];
651 static struct swit fileswit[] = {
667 "rmmproc program", 0,
692 forkcmd (args, cmd_name);
696 while (cp = *args++) {
698 switch (i = smatch (++cp, fileswit)) {
700 ambigsw (cp, fileswit);
703 fprintf (stderr, "-%s unknown\n", cp);
706 (void) sprintf (buf, "%s +folder... [msgs] [switches]",
708 help (buf, fileswit);
727 advise (NULLCP, "sorry, -%s not allowed!", fileswit[i].sw);
730 if (*cp == '+' || *cp == '@@')
737 vec[vecp++] = "-file";
740 msgs[msgp++] = "cur";
741 for (msgnum = 0; msgnum < msgp; msgnum++)
742 if (!m_convert (mp, msgs[msgnum]))
747 for (msgnum = mp -> lowsel;
748 msgnum <= mp -> hghsel && !interrupted;
750 if (mp -> msgstats[msgnum] & SELECTED)
751 if (process (msgnum, fileproc, vecp, vec)) {
752 mp -> msgstats[msgnum] &= ~SELECTED;
756 if (mp -> numsel != mp -> nummsg || linksw)
757 m_setcur (mp, mp -> hghsel);
773 while (cp = *args++) {
775 switch (smatch (++cp, fileswit)) {
792 if (*cp == '+' || *cp == '@@')
799 for (vecp = 0; (cp = vec[vecp]) && result == NOTOK; vecp++) {
801 cwd = getcpy (pwd ());
802 (void) chdir (m_maildir (""));
803 cp = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
804 if (access (m_maildir (cp), 0) == NOTOK)
816 static struct swit foldswit[] = {
872 while (cp = *args++) {
874 switch (smatch (++cp, foldswit)) {
876 ambigsw (cp, foldswit);
879 fprintf (stderr, "-%s unknown\n", cp);
882 (void) sprintf (buf, "%s [+folder] [msg] [switches]",
884 help (buf, foldswit);
887 case FLALSW: /* not implemented */
917 if (*cp == '+' || *cp == '@@')
919 advise (NULLCP, "only one folder at a time!\n");
923 folder = fmsh ? path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF)
927 advise (NULLCP, "only one message at a time!\n");
936 advise (NULLCP, "null folder names are not permitted");
940 if (access (m_maildir (folder), 04) == NOTOK) {
941 advise (folder, "unable to read");
946 (void) strcpy (buf, folder);
947 if (expand (buf) == NOTOK)
950 if (access (folder, 04) == NOTOK) {
951 advise (folder, "unable to read");
966 if (!m_convert (mp, msg))
970 if (mp -> numsel > 1) {
971 advise (NULLCP, "only one message at a time!");
974 m_setcur (mp, mp -> hghsel);
979 forkcmd (vec, cmd_name);
983 if (mp -> lowmsg > 1 && (mp = m_remsg (mp, 1, mp -> hghmsg)) == NULL)
984 adios (NULLCP, "unable to allocate folder storage");
985 for (msgnum = mp -> lowmsg, hole = 1; msgnum <= mp -> hghmsg; msgnum++)
986 if (mp -> msgstats[msgnum] & EXISTS) {
987 if (msgnum != hole) {
988 Msgs[hole].m_bboard_id = Msgs[msgnum].m_bboard_id;
989 Msgs[hole].m_top = Msgs[msgnum].m_top;
990 Msgs[hole].m_start = Msgs[msgnum].m_start;
991 Msgs[hole].m_stop = Msgs[msgnum].m_stop;
992 Msgs[hole].m_scanl = NULL;
993 if (Msgs[msgnum].m_scanl) {
994 free (Msgs[msgnum].m_scanl);
995 Msgs[msgnum].m_scanl = NULL;
997 mp -> msgstats[hole] = mp -> msgstats[msgnum];
998 if (mp -> curmsg == msgnum)
1003 if (mp -> nummsg > 0) {
1005 mp -> hghmsg = hole - 1;
1007 mp -> msgflags |= MODIFIED;
1013 printf ("%s\n", fmsh ? fmsh : mp -> foldpath);
1016 printf ("\t\tFolder %*s# of messages (%*srange%*s); cur%*smsg\n",
1017 DMAXFOLDER, "", DMAXFOLDER - 2, "", DMAXFOLDER - 2, "",
1018 DMAXFOLDER - 2, "");
1019 printf (args ? "%22s " : "%s ", fmsh ? fmsh : mp -> foldpath);
1020 if (mp -> hghmsg == 0)
1021 printf ("has no messages%*s",
1022 mp -> msgflags & OTHERS ? DMAXFOLDER * 2 + 4 : 0, "");
1024 printf ("has %*d message%s (%*d-%*d)",
1025 DMAXFOLDER, mp -> nummsg, mp -> nummsg != 1 ? "s" : "",
1026 DMAXFOLDER, mp -> lowmsg, DMAXFOLDER, mp -> hghmsg);
1027 if (mp -> curmsg >= mp -> lowmsg
1028 && mp -> curmsg <= mp -> hghmsg)
1029 printf ("; cur=%*d", DMAXFOLDER, mp -> curmsg);
1038 #define MIMEminc(a) (a)
1040 #define MIMEminc(a) 0
1043 static struct swit forwswit[] = {
1049 "draftfolder +folder", 0,
1051 "draftmessage msg", 0,
1059 "filter filterfile", 0,
1071 "mime", MIMEminc(-4),
1073 "nomime", MIMEminc(-6),
1075 "whatnowproc program", 0,
1100 forkcmd (args, cmd_name);
1104 while (cp = *args++) {
1106 switch (smatch (++cp, forwswit)) {
1108 ambigsw (cp, forwswit);
1111 fprintf (stderr, "-%s unknown\n", cp);
1114 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
1115 help (buf, forwswit);
1118 case FOANSW: /* not implemented */
1146 if (!(cp = *args++) || *cp == '-') {
1147 advise (NULLCP, "missing argument to %s", args[-2]);
1153 if (!(filter = *args++) || *filter == '-') {
1154 advise (NULLCP, "missing argument to %s", args[-2]);
1160 if (access (filter = myfilter, 04) == NOTOK) {
1161 advise (filter, "unable to read default filter file");
1169 if (*cp == '+' || *cp == '@@') {
1170 advise (NULLCP, "sorry, no folders allowed!");
1177 /* foil search of .mh_profile */
1178 (void) sprintf (buf, "%sXXXXXX", invo_name);
1179 vec[0] = (char *)mktemp (buf);
1180 vec[vecp++] = "-file";
1183 msgs[msgp++] = "cur";
1184 for (msgnum = 0; msgnum < msgp; msgnum++)
1185 if (!m_convert (mp, msgs[msgnum]))
1190 (void) strcpy (buf, filter);
1191 if (expand (buf) == NOTOK)
1193 if (access (filter = getcpy (libpath (buf)), 04) == NOTOK) {
1194 advise (filter, "unable to read");
1199 forw (cmd_name, filter, vecp, vec, mime);
1200 m_setcur (mp, mp -> hghsel);
1207 static forw (proc, filter, vecp, vec, mime)
1226 (void) strcpy (tmpfil, m_tmpfil (invo_name));
1229 switch (child_id = fork ()) {
1231 advise ("fork", "unable to");
1234 case OK: /* "trust me" */
1235 if (freopen (tmpfil, "w", stdout) == NULL) {
1236 fprintf (stderr, "unable to create ");
1240 args[0] = r1bindex (mhlproc, '/');
1242 args[i++] = "-forwall";
1243 args[i++] = "-form";
1245 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
1246 if (mp -> msgstats[msgnum] & SELECTED)
1247 args[i++] = getcpy (m_name (msgnum));
1249 (void) mhlsbr (i, args, mhl_action);
1250 m_eomsbr ((int (*) ()) 0);
1251 (void) fclose (stdout);
1255 if (pidXwait (child_id, NULLCP))
1264 #define INITIAL_PREFIX "----- =_aaaaaaaaaa"
1268 prefix[sizeof INITIAL_PREFIX];
1272 for (vecp = 1; cp = vec[vecp++]; )
1274 switch (smatch (++cp, forwswit)) {
1295 /* ignore -draftfolder / -draftmessage / -nodraftfolder */
1302 (void) strcpy (tmpfil, m_draft (NULLCP, NULLCP, NOUSE, &isdf));
1303 if (!ed && !(ed = m_find ("editor")))
1306 (void) strcpy (prefix, INITIAL_PREFIX);
1307 cp = index (prefix, 'a');
1308 len = strlen (prefix);
1314 for (msgnum = mp -> lowsel;
1315 msgnum <= mp -> hghsel && !interrupted && !hit;
1317 if (mp -> msgstats[msgnum] & SELECTED) {
1318 zp = msh_ready (msgnum, 1);
1321 while (fgets (buffer, sizeof buffer, zp) != NULL
1323 && pos < Msgs[msgnum].m_stop) {
1326 if (buffer[0] != '-' || buffer[1] != '-')
1329 for (pp = buffer + strlen (buffer) - 1;
1336 if (strncmp (buffer + 2, prefix, len))
1352 "unable to determine unique delimiter string?!?");
1359 if ((out = fopen (tmpfil, "w")) == NULL) {
1360 advise (tmpfil, "unable to create temporary file");
1363 (void) chmod (tmpfil, m_gmprot ());
1365 fprintf (out, "%s: %s\n", VRSN_FIELD, VRSN_VALUE);
1366 fprintf (out, "%s: multipart/digest; boundary=\"%s\"\n", TYPE_FIELD,
1369 if (!(zp = fopen (libpath (form ? form : forwcomps), "r"))) {
1371 advise (form, "unable to open form file");
1373 advise (forwcomps, "unable to open default components file");
1374 (void) fclose (out);
1375 (void) unlink (tmpfil);
1378 while (fgets (buffer, sizeof buffer, zp))
1379 (void) fputs (buffer, out);
1382 for (msgnum = mp -> lowsel;
1383 msgnum <= mp -> hghsel && !interrupted;
1385 if (mp -> msgstats[msgnum] & SELECTED) {
1386 fprintf (out, "\n--%s\n%s: message/rfc822\n\n", prefix,
1389 copy_message (msgnum, out);
1391 fprintf (out, "\n--%s--\n", prefix);
1393 (void) fclose (out);
1399 if ((out = fopen (tmpfil, "w")) == NULL) {
1400 advise (tmpfil, "unable to create temporary file");
1405 for (msgnum = mp -> lowsel;
1406 msgnum <= mp -> hghsel && !interrupted;
1408 if (mp -> msgstats[msgnum] & SELECTED) {
1409 fprintf (out, "\n\n-------");
1410 if (msgnum == mp -> lowsel)
1411 fprintf (out, " Forwarded Message%s",
1412 mp -> numsel > 1 ? "s" : "");
1414 fprintf (out, " Message %d", msgcnt);
1415 fprintf (out, "\n\n");
1416 copy_digest (msgnum, out);
1420 fprintf (out, "\n\n------- End of Forwarded Message%s\n",
1421 mp -> numsel > 1 ? "s" : "");
1422 (void) fclose (out);
1425 (void) fflush (stdout);
1427 switch (child_id = fork ()) {
1429 advise ("fork", "unable to");
1434 (void) signal (SIGINT, istat);
1435 (void) signal (SIGQUIT, qstat);
1440 vec[vecp++] = r1bindex (proc, '/');
1441 (void) m_putenv ("mhdraft", tmpfil);
1442 (void) unputenv ("mhfolder");
1443 (void) unputenv ("mhaltmsg");
1444 (void) m_putenv ("mhdist", "0");
1446 (void) unputenv ("mheditor");
1448 (void) m_putenv ("mheditor", ed);
1449 (void) m_putenv ("mhuse", "0");
1450 (void) unputenv ("mhmessages");
1451 (void) unputenv ("mhannotate");
1452 (void) unputenv ("mhinplace");
1457 vec[vecp++] = tmpfil;
1461 fprintf (stderr, "unable to exec ");
1466 (void) pidXwait (child_id, NULLCP);
1473 (void) unlink (tmpfil);
1478 static char *hlpmsg[] = {
1479 "The %s program emulates many of the commands found in the Rand MH",
1480 "system. Instead of operating on MH folders, commands to %s concern",
1483 "To see the list of commands available, just type a ``?'' followed by",
1484 "the RETURN key. To find out what switches each command takes, type",
1485 "the name of the command followed by ``-help''. To leave %s, use the",
1486 "``quit'' command.",
1488 "Although a lot of MH commands are found in %s, not all are fully",
1489 "implemented. %s will always recognize all legal switches for a",
1490 "given command though, and will let you know when you ask for an",
1491 "option that it is unable to perform.",
1493 "Running %s is fun, but using MH from your shell is far superior.",
1494 "After you have familiarized yourself with the MH style by using %s,",
1495 "you should try using MH from the shell. You can still use %s for",
1496 "message files that aren't in MH format, such as BBoard files.",
1508 for (i = 0; hlpmsg[i]; i++) {
1509 printf (hlpmsg[i], invo_name);
1510 (void) putchar ('\n');
1516 static struct swit markswit[] = {
1560 while (cp = *args++) {
1562 switch (smatch (++cp, markswit)) {
1564 ambigsw (cp, markswit);
1567 fprintf (stderr, "-%s unknown\n", cp);
1570 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
1571 help (buf, markswit);
1576 deletesw = listsw = 0;
1584 addsw = deletesw = 0;
1588 if (!(cp = *args++) || *cp == '-') {
1589 advise (NULLCP, "missing argument to %s", args[-2]);
1595 advise (NULLCP, "only %d sequences allowed!", NATTRS);
1600 case MPUBSW: /* not implemented */
1615 if (*cp == '+' || *cp == '@@') {
1616 advise (NULLCP, "sorry, no folders allowed!");
1623 if (!addsw && !deletesw && !listsw)
1630 seqs[seqp++] = "unseen";
1634 msgs[msgp++] = "all";
1638 msgs[msgp++] = listsw ? "all" :"cur";
1639 for (msgnum = 0; msgnum < msgp; msgnum++)
1640 if (!m_convert (mp, msgs[msgnum]))
1644 printf ("invo_name=%s mypath=%s defpath=%s\n",
1645 invo_name, mypath, defpath);
1646 printf ("ctxpath=%s context flags=%s\n",
1647 ctxpath, sprintb (buf, (unsigned) ctxflags, DBITS));
1648 printf ("foldpath=%s flags=%s\n",
1650 sprintb (buf, (unsigned) mp -> msgflags, FBITS));
1651 printf ("hghmsg=%d lowmsg=%d nummsg=%d curmsg=%d\n",
1652 mp -> hghmsg, mp -> lowmsg, mp -> nummsg, mp -> curmsg);
1653 printf ("lowsel=%d hghsel=%d numsel=%d\n",
1654 mp -> lowsel, mp -> hghsel, mp -> numsel);
1656 printf ("lowoff=%d hghoff=%d\n",
1657 mp -> lowoff, mp -> hghoff);
1659 printf ("lowoff=%d hghoff=%d msgbase=0x%x msgstats=0x%x\n",
1660 mp -> lowoff, mp -> hghoff, mp -> msgbase, mp -> msgstats);
1664 if (seqp == 0 && (addsw || deletesw)) {
1665 advise (NULLCP, "-%s requires at least one -sequence argument",
1666 addsw ? "add" : "delete");
1672 for (seqp = 0; seqs[seqp]; seqp++) {
1673 if (zerosw && !m_seqnew (mp, seqs[seqp], 0))
1675 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
1676 if (mp -> msgstats[msgnum] & SELECTED)
1677 if (!m_seqadd (mp, seqs[seqp], msgnum, 0))
1682 for (seqp = 0; seqs[seqp]; seqp++) {
1684 for (msgnum = mp -> lowmsg; msgnum <= mp -> hghmsg; msgnum++)
1685 if (mp -> msgstats[msgnum] & EXISTS)
1686 if (!m_seqadd (mp, seqs[seqp], msgnum, 0))
1688 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
1689 if (mp -> msgstats[msgnum] & SELECTED)
1690 if (!m_seqdel (mp, seqs[seqp], msgnum))
1695 int bits = FFATTRSLOT;
1697 #define empty(s) ((s) ? (s) : "")
1699 for (i = 0; mp -> msgattrs[i]; i++)
1700 printf ("%s%s: %s\n", mp -> msgattrs[i],
1701 mp -> attrstats & (1 << (bits + i))
1702 ? " (private)" : "",
1703 empty(m_seq (mp, mp -> msgattrs[i])));
1705 for (seqp = 0; seqs[seqp]; seqp++)
1706 printf ("%s%s: %s\n", seqs[seqp],
1707 empty(m_seq (mp, seqs[seqp])));
1712 for (msgnum = mp -> lowsel;
1713 msgnum <= mp -> hghsel && !interrupted;
1715 if (mp -> msgstats[msgnum] & SELECTED) {
1716 printf ("%*d: id=%d top=%d start=%ld stop=%ld %s\n",
1718 Msgs[msgnum].m_bboard_id, Msgs[msgnum].m_top,
1719 Msgs[msgnum].m_start, Msgs[msgnum].m_stop,
1720 sprintb (buf, (unsigned) mp -> msgstats[msgnum],
1722 if (Msgs[msgnum].m_scanl)
1723 printf ("%s", Msgs[msgnum].m_scanl);
1731 static struct swit mhnswit[] = {
1734 #define MHNNAUTOSW 1
1736 #define MHNDEBUGSW 2
1738 #define MHNEBCDICSW 3
1740 #define MHNNEBCDICSW 4
1746 #define MHNNHEADSW 7
1750 #define MHNNLISTSW 9
1752 #define MHNPARTSW 10
1754 #define MHNSIZESW 11
1756 #define MHNNSIZESW 12
1758 #define MHNRFC934SW 13
1760 #define MHNNRFC934SW 14
1762 #define MHNSERIALSW 15
1764 #define MHNNSERIALSW 16
1766 #define MHNSHOWSW 17
1768 #define MHNNSHOWSW 18
1770 #define MHNSTORESW 19
1772 #define MHNNSTORESW 20
1774 #define MHNTYPESW 21
1776 #define MHNVERBSW 22
1778 #define MHNNVERBSW 23
1780 #define MHNHELPSW 24
1782 #define MHNPROGSW 25
1783 "moreproc program", -4,
1784 #define MHNNPROGSW 26
1789 "width columns", -4,
1809 forkcmd (args, cmd_name);
1813 while (cp = *args++) {
1815 switch (smatch (++cp, mhnswit)) {
1817 ambigsw (cp, mhnswit);
1820 fprintf (stderr, "-%s unknown\n", cp);
1823 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
1824 help (buf, mhnswit);
1859 if (!(cp = *args++) || *cp == '-') {
1860 advise (NULLCP, "missing argument to %s", args[-2]);
1866 if (*cp == '+' || *cp == '@@') {
1867 advise (NULLCP, "sorry, no folders allowed!");
1875 vec[vecp++] = "-file";
1878 msgs[msgp++] = "cur";
1879 for (msgnum = 0; msgnum < msgp; msgnum++)
1880 if (!m_convert (mp, msgs[msgnum]))
1885 for (msgnum = mp -> lowsel;
1886 msgnum <= mp -> hghsel && !interrupted;
1888 if (mp -> msgstats[msgnum] & SELECTED)
1889 if (process (msgnum, cmd_name, vecp, vec)) {
1890 mp -> msgstats[msgnum] &= ~SELECTED;
1894 m_setcur (mp, mp -> hghsel);
1900 static struct swit packswit[] = {
1925 forkcmd (args, cmd_name);
1929 while (cp = *args++) {
1931 switch (smatch (++cp, packswit)) {
1933 ambigsw (cp, packswit);
1936 fprintf (stderr, "-%s unknown\n", cp);
1939 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
1940 help (buf, packswit);
1944 if (!(file = *args++) || *file == '-') {
1945 advise (NULLCP, "missing argument to %s", args[-2]);
1950 if (*cp == '+' || *cp == '@@') {
1951 advise (NULLCP, "sorry, no folders allowed!");
1960 file = path (file, TFILE);
1961 if (stat (file, &st) == NOTOK) {
1962 if (errno != ENOENT) {
1963 advise (file, "error on file");
1966 md = getanswer (cp = concat ("Create file \"", file, "\"? ", NULLCP));
1973 msgs[msgp++] = "all";
1974 for (msgnum = 0; msgnum < msgp; msgnum++)
1975 if (!m_convert (mp, msgs[msgnum]))
1979 if ((md = mbx_open (file, getuid (), getgid (), m_gmprot ())) == NOTOK) {
1980 advise (file, "unable to open");
1983 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
1984 if (mp -> msgstats[msgnum] & SELECTED)
1985 if (pack (file, md, msgnum) == NOTOK)
1987 (void) mbx_close (file, md);
1989 if (mp -> hghsel != mp -> curmsg)
1990 m_setcur (mp, mp -> lowsel);
1998 int pack (mailbox, md, msgnum)
2005 if (Msgs[msgnum].m_bboard_id == 0)
2006 (void) readid (msgnum);
2008 zp = msh_ready (msgnum, 1);
2009 return mbx_write (mailbox, md, zp, Msgs[msgnum].m_bboard_id,
2010 0L, ftell (zp), Msgs[msgnum].m_stop, 1, 1);
2022 while (cp = *args++) {
2024 switch (smatch (++cp, packswit)) {
2031 if (!(file = *args++) || *file == '-')
2035 if (*cp == '+' || *cp == '@@')
2039 file = path (file ? file : "./msgbox", TFILE);
2040 result = access (file, 0) == NOTOK ? OK : NOTOK;
2048 static struct swit pickswit[] = {
2067 "search pattern", 0,
2069 "subject pattern", 0,
2073 "-othercomponent pattern", 15,
2079 "datefield field", 5,
2119 while (cp = *args++) {
2125 switch (smatch (cp, pickswit)) {
2127 ambigsw (cp, pickswit);
2130 fprintf (stderr, "-%s unknown\n", cp);
2133 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
2134 help (buf, pickswit);
2148 if (!(cp = *args++)) {/* allow -xyz arguments */
2149 advise (NULLCP, "missing argument to %s", args[-2]);
2155 advise (NULLCP, "internal error!");
2166 if (!(cp = *args++) || *cp == '-') {
2167 advise (NULLCP, "missing argument to %s", args[-2]);
2173 advise (NULLCP, "only %d sequences allowed!", NATTRS);
2184 case PIPUSW: /* not implemented */
2191 if (*cp == '+' || *cp == '@@') {
2192 advise (NULLCP, "sorry, no folders allowed!");
2201 msgs[msgp++] = "all";
2202 for (msgnum = 0; msgnum < msgp; msgnum++)
2203 if (!m_convert (mp, msgs[msgnum]))
2208 if (!pcompile (vec, NULLCP))
2214 for (msgnum = mp -> lowsel;
2215 msgnum <= mp -> hghsel && !interrupted;
2217 if (mp -> msgstats[msgnum] & SELECTED) {
2218 zp = msh_ready (msgnum, 1);
2219 if (pmatches (zp, msgnum, fmsh ? 0L : Msgs[msgnum].m_start,
2220 fmsh ? 0L : Msgs[msgnum].m_stop)) {
2227 mp -> msgstats[msgnum] &= ~SELECTED;
2238 if (mp -> numsel <= 0) {
2239 advise (NULLCP, "no messages match specification");
2244 for (seqp = 0; seqs[seqp]; seqp++) {
2245 if (zerosw && !m_seqnew (mp, seqs[seqp], 0))
2247 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
2248 if (mp -> msgstats[msgnum] & SELECTED)
2249 if (!m_seqadd (mp, seqs[seqp], msgnum, 0))
2253 printf ("%d hit%s\n", mp -> numsel, mp -> numsel == 1 ? "" : "s");
2258 static struct swit replswit[] = {
2268 "draftfolder +folder", 0,
2270 "draftmessage msg", 0,
2280 "filter filterfile", 0,
2292 "whatnowproc program", 0,
2315 forkcmd (args, cmd_name);
2319 while (cp = *args++) {
2321 switch (smatch (++cp, replswit)) {
2323 ambigsw (cp, replswit);
2326 fprintf (stderr, "-%s unknown\n", cp);
2329 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
2330 help (buf, replswit);
2333 case REANSW: /* not implemented */
2358 if (!(cp = *args++) || *cp == '-') {
2359 advise (NULLCP, "missing argument to %s", args[-2]);
2365 if (*cp == '+' || *cp == '@@') {
2366 advise (NULLCP, "sorry, no folders allowed!");
2371 advise (NULLCP, "only one message at a time!");
2379 vec[vecp++] = "-file";
2383 if (!m_convert (mp, msg))
2387 if (mp -> numsel > 1) {
2388 advise (NULLCP, "only one message at a time!");
2391 (void) process (mp -> hghsel, cmd_name, vecp, vec);
2392 m_setcur (mp, mp -> hghsel);
2397 static struct swit rmmswit[] = {
2415 while (cp = *args++) {
2417 switch (smatch (++cp, rmmswit)) {
2419 ambigsw (cp, rmmswit);
2422 fprintf (stderr, "-%s unknown\n", cp);
2425 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
2426 help (buf, rmmswit);
2429 if (*cp == '+' || *cp == '@@') {
2430 advise (NULLCP, "sorry, no folders allowed!");
2438 msgs[msgp++] = "cur";
2439 for (msgnum = 0; msgnum < msgp; msgnum++)
2440 if (!m_convert (mp, msgs[msgnum]))
2450 register int msgnum,
2453 char buffer[BUFSIZ],
2458 if (mp -> numsel > MAXARGS - 1) {
2459 advise (NULLCP, "more than %d messages for %s exec",
2460 MAXARGS - 1, rmmproc);
2464 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
2465 if (mp -> msgstats[msgnum] & SELECTED)
2466 vec[vecp++] = getcpy (m_name (msgnum));
2468 forkcmd (vec, rmmproc);
2469 for (vecp = 0; vec[vecp]; vecp++)
2473 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
2474 if (mp -> msgstats[msgnum] & SELECTED) {
2475 (void) strcpy (buffer, m_backup (cp = m_name (msgnum)));
2476 if (rename (cp, buffer) == NOTOK)
2477 admonish (buffer, "unable to rename %s to", cp);
2481 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
2482 if (mp -> msgstats[msgnum] & SELECTED) {
2483 mp -> msgstats[msgnum] |= DELETED;
2484 mp -> msgstats[msgnum] &= ~EXISTS;
2487 if (pmsh && pop_dele (msgnum) != OK)
2488 fprintf (stderr, "%s", response);
2493 if ((mp -> nummsg -= mp -> numsel) <= 0) {
2495 admonish (NULLCP, "no messages remaining in +%s", fmsh);
2497 admonish (NULLCP, "no messages remaining in %s", mp -> foldpath);
2498 mp -> lowmsg = mp -> hghmsg = mp -> nummsg = 0;
2500 if (mp -> lowsel == mp -> lowmsg) {
2501 for (msgnum = mp -> lowmsg + 1; msgnum <= mp -> hghmsg; msgnum++)
2502 if (mp -> msgstats[msgnum] & EXISTS)
2504 mp -> lowmsg = msgnum;
2506 if (mp -> hghsel == mp -> hghmsg) {
2507 for (msgnum = mp -> hghmsg - 1; msgnum >= mp -> lowmsg; msgnum--)
2508 if (mp -> msgstats[msgnum] & EXISTS)
2510 mp -> hghmsg = msgnum;
2513 mp -> msgflags |= MODIFIED;
2519 static struct swit scanswit[] = {
2525 "form formatfile", 0,
2545 #define equiv(a,b) (a ? b && !strcmp (a, b) : !b)
2563 static int p_optim = 0;
2566 static int s_optim = 0;
2567 static char *s_form = NULL,
2570 while (cp = *args++) {
2572 switch (smatch (++cp, scanswit)) {
2574 ambigsw (cp, scanswit);
2577 fprintf (stderr, "-%s unknown\n", cp);
2580 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
2581 help (buf, scanswit);
2597 if (!(form = *args++) || *form == '-') {
2598 advise (NULLCP, "missing argument to %s", args[-2]);
2604 if (!(format = *args++) || *format == '-') {
2605 advise (NULLCP, "missing argument to %s", args[-2]);
2611 if (!(cp = *args++) || *cp == '-') {
2612 advise (NULLCP, "missing argument to %s", args[-2]);
2618 if (*cp == '+' || *cp == '@@') {
2619 advise (NULLCP, "sorry, no folders allowed!");
2627 msgs[msgp++] = "all";
2628 for (msgnum = 0; msgnum < msgp; msgnum++)
2629 if (!m_convert (mp, msgs[msgnum]))
2633 nfs = new_fs (form, format, FORMAT);
2634 if (scanl) { /* force scansbr to (re)compile format */
2635 (void) free (scanl);
2640 s_optim = optim = 1;
2641 s_form = form ? getcpy (form) : NULL;
2642 s_format = format ? getcpy (format) : NULL;
2653 width = sc_width ();
2655 for (dp = nfs, i = 0; *dp; dp++, i++)
2656 if (*dp == '\\' || *dp == '"' || *dp == '\n')
2659 if ((ep = malloc ((unsigned) i)) == NULL)
2660 adios (NULLCP, "out of memory");
2661 for (dp = nfs, fp = ep; *dp; dp++) {
2663 *fp++ = '\\', *fp++ = 'n';
2666 if (*dp == '"' || *dp == '\\')
2672 if (pop_command ("XTND SCAN %d \"%s\"", width, ep) == OK)
2681 optim = equiv (s_form, form) && equiv (s_format, format);
2685 if (p_optim && optim) {
2686 for (msgnum = mp -> lowmsg; msgnum <= mp -> hghmsg; msgnum++)
2687 if (!(mp -> msgstats[msgnum] & SELECTED) || Msgs[msgnum].m_scanl)
2689 if (msgnum > mp -> hghmsg && pop_command ("LIST") == OK) {
2690 fprintf (stderr, "Stand-by...");
2696 switch (pop_multiline ()) {
2698 fprintf (stderr, "%s", response);
2701 fprintf (stderr,"\n");
2705 if (sscanf (response, "%d %d", &msgnum, &size) == 2
2706 && mp -> lowmsg <= msgnum
2707 && msgnum <= mp -> hghmsg
2708 && (cp = index (response, '#'))
2710 Msgs[msgnum].m_scanl = concat (cp, "\n", NULLCP);
2721 for (msgnum = mp -> lowsel;
2722 msgnum <= mp -> hghsel && !interrupted;
2724 if (mp -> msgstats[msgnum] & SELECTED) {
2725 if (optim && Msgs[msgnum].m_scanl)
2726 printf ("%s", Msgs[msgnum].m_scanl);
2732 && (mp -> msgstats[msgnum] & VIRTUAL)
2733 && pop_command ("LIST %d", msgnum) == OK
2734 && (cp = index (response, '#'))
2736 Msgs[msgnum].m_scanl = concat (cp, "\n", NULLCP);
2737 printf ("%s", Msgs[msgnum].m_scanl);
2743 zp = msh_ready (msgnum, 0);
2744 switch (state = scan (zp, msgnum, 0, nfs, width,
2745 msgnum == mp -> curmsg,
2746 mp -> msgstats[msgnum] & UNSEEN, /* ?? */
2747 headersw, fmsh ? fmsh : mp -> foldpath,
2748 fmsh ? 0L : (long) (Msgs[msgnum].m_stop - Msgs[msgnum].m_start),
2754 Msgs[msgnum].m_scanl = getcpy (scanl);
2758 advise (NULLCP, "scan() botch (%d)", state);
2762 printf ("%*d empty\n", DMAXFOLDER, msgnum);
2775 static struct swit showswit[] = {
2781 "moreproc program", 4,
2789 "showproc program", 4,
2822 if (uleq (cmd_name, "next"))
2825 if (uleq (cmd_name, "prev"))
2827 while (cp = *args++) {
2829 switch (i = smatch (++cp, showswit)) {
2831 ambigsw (cp, showswit);
2838 (void) sprintf (buf,
2839 "%s %s[switches] [switches for showproc]",
2840 cmd_name, mode ? NULL : "[msgs] ");
2841 help (buf, showswit);
2849 if (!(cp = *args++) || *cp == '-') {
2850 advise (NULLCP, "missing argument to %s", args[-2]);
2862 if (!(proc = *args++) || *proc == '-') {
2863 advise (NULLCP, "missing argument to %s", args[-2]);
2873 advise (NULLCP, "sorry, -%s not allowed!", showswit[i].sw);
2876 if (*cp == '+' || *cp == '@@') {
2877 advise (NULLCP, "sorry, no folders allowed!");
2883 "usage: %s [switches] [switches for showproc]\n",
2893 msgs[msgp++] = mode > 0 ? "next" : mode < 0 ? "prev" : "cur";
2894 for (msgnum = 0; msgnum < msgp; msgnum++)
2895 if (!m_convert (mp, msgs[msgnum]))
2900 if (!nshow && !getenv ("NOMHNPROC"))
2901 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
2902 if ((mp -> msgstats[msgnum] & SELECTED) && nontext (msgnum)) {
2903 proc = (cp = m_find ("mhnproc")) ? cp : "mhn";
2904 vec[vecp++] = "-show";
2905 vec[vecp++] = "-file";
2914 if (strcmp (showproc, "mhl") == 0) {
2920 seen = m_seqflag (mp, "unseen");
2921 vec[0] = r1bindex (proc, '/');
2924 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
2925 if (mp -> msgstats[msgnum] & SELECTED) {
2926 vec[vecp++] = getcpy (m_name (msgnum));
2928 (void) m_seqdel (mp, "unseen", msgnum);
2931 if (mp -> numsel == 1 && headersw)
2932 show (mp -> lowsel);
2933 (void) mhlsbr (vecp, vec, mhl_action);
2934 m_eomsbr ((int (*)()) 0);
2940 for (msgnum = mp -> lowsel;
2941 msgnum <= mp -> hghsel && !interrupted;
2943 if (mp -> msgstats[msgnum] & SELECTED) {
2944 switch (ask (msgnum)) {
2945 case NOTOK: /* QUIT */
2952 if (mp -> numsel == 1 && headersw)
2955 copy_message (msgnum, stdout);
2957 (void) process (msgnum, proc, vecp, vec);
2960 (void) m_seqdel (mp, "unseen", msgnum);
2967 m_setcur (mp, mp -> hghsel);
2972 static show (msgnum)
2975 if (Msgs[msgnum].m_bboard_id == 0)
2976 (void) readid (msgnum);
2978 printf ("(Message %d", msgnum);
2979 if (Msgs[msgnum].m_bboard_id > 0)
2980 printf (", %s: %d", BBoard_ID, Msgs[msgnum].m_bboard_id);
2987 static int eom_action (c)
2990 return (ftell (mhlfp) >= Msgs[mhlnum].m_stop);
2994 static FP mhl_action (name)
2999 if ((msgnum = m_atoi (name)) < mp -> lowmsg
3000 || msgnum > mp -> hghmsg
3001 || !(mp -> msgstats[msgnum] & EXISTS))
3005 mhlfp = msh_ready (msgnum, 1);
3007 m_eomsbr (eom_action);
3020 if (mp -> numsel == 1 || !interactive || redirected)
3023 if (SOprintf ("Press <return> to list \"%d\"...", msgnum)) {
3024 if (mp -> lowsel != msgnum)
3026 printf ("Press <return> to list \"%d\"...", msgnum);
3028 (void) fflush (stdout);
3031 (void) read (fileno (stdout), buf, sizeof buf);
3033 switch (setjmp (sigenv)) {
3036 (void) read (fileno (stdout), buf, sizeof buf);/* fall... */
3043 if (index (buf, '\n') == NULL)
3044 (void) putchar ('\n');
3047 told_to_quit = interrupted = 0;
3061 #include "../h/mhn.h"
3064 static int nontext (msgnum)
3077 if (Msgs[msgnum].m_flags & MHNCHK)
3078 return (Msgs[msgnum].m_flags & MHNYES);
3079 Msgs[msgnum].m_flags |= MHNCHK;
3081 fp = msh_ready (msgnum, 1);
3083 if (!(chset = getenv ("MM_CHARSET")))
3087 switch (state = m_getfld (state, name, buf, sizeof buf, fp)) {
3091 if (uleq (name, TYPE_FIELD)) {
3095 cp = add (buf, NULLCP);
3096 while (state == FLDPLUS) {
3097 state = m_getfld (state, name, buf, sizeof buf, fp);
3104 for (; isspace (*bp); bp++)
3109 for (bp++, i = 0;;) {
3139 for (dp = bp; istoken (*dp); dp++)
3141 c = *dp, *dp = NULL;
3145 if (result = !uleq (bp, "plain"))
3148 for (dp++; isspace (*dp); dp++)
3150 if (result = !uprf (dp, "charset"))
3152 dp += sizeof "charset" - 1;
3153 while (isspace (*dp))
3157 while (isspace (*dp))
3160 if (bp = index (++dp, '"'))
3164 for (bp = dp; *bp; bp++)
3165 if (isspace (*bp)) {
3169 if ((result = !uleq (dp, chset))
3170 && uleq (dp, "us-ascii")
3171 && uleq (chset, "iso-8859-1"))
3175 if (!(result = !uleq (bp, "text"))) {
3186 Msgs[msgnum].m_flags |= MHNYES;
3191 if (uleq (name, ENCODING_FIELD)) {
3192 cp = add (buf, NULLCP);
3193 while (state == FLDPLUS) {
3194 state = m_getfld (state, name, buf, sizeof buf, fp);
3197 for (bp = cp; isspace (*bp); bp++)
3199 for (dp = bp; istoken (*dp); dp++)
3202 result = !uleq (bp, "7bit")
3203 && !uleq (bp, "8bit")
3204 && !uleq (bp, "binary");
3208 Msgs[msgnum].m_flags |= MHNYES;
3213 while (state == FLDPLUS)
3214 state = m_getfld (state, name, buf, sizeof buf, fp);
3225 static struct swit sortswit[] = {
3227 "datefield field", 0,
3229 "textfield field", 0,
3262 forkcmd (args, cmd_name);
3266 while (cp = *args++) {
3268 switch (smatch (++cp, sortswit)) {
3270 ambigsw (cp, sortswit);
3273 fprintf (stderr, "-%s unknown\n", cp);
3276 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
3277 help (buf, sortswit);
3282 advise (NULLCP, "only one date field at a time!");
3285 if (!(datesw = *args++) || *datesw == '-') {
3286 advise (NULLCP, "missing argument to %s", args[-2]);
3293 advise (NULLCP, "only one text field at a time!");
3296 if (!(subjsw = *args++) || *subjsw == '-') {
3297 advise (NULLCP, "missing argument to %s", args[-2]);
3305 case SOLIMT: /* too hard */
3306 if (!(cp = *args++) || *cp == '-') {
3307 advise (NULLCP, "missing argument to %s", args[-2]);
3311 case SOVERB: /* not implemented */
3315 if (*cp == '+' || *cp == '@@') {
3316 advise (NULLCP, "sorry, no folders allowed!");
3324 msgs[msgp++] = "all";
3327 for (msgnum = 0; msgnum < msgp; msgnum++)
3328 if (!m_convert (mp, msgs[msgnum]))
3332 twscopy (&tb, dtwstime ());
3334 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) {
3335 if (Msgs[msgnum].m_scanl) {
3336 free (Msgs[msgnum].m_scanl);
3337 Msgs[msgnum].m_scanl = NULL;
3339 if (mp -> msgstats[msgnum] & SELECTED) {
3340 if (getws (datesw, subjsw, msgnum, &Msgs[msgnum]))
3341 twscopy (&Msgs[msgnum].m_tb,
3342 msgnum != mp -> lowsel ? &Msgs[msgnum - 1].m_tb : &tb);
3344 else /* m_scaln is already NULL */
3345 twscopy (&Msgs[msgnum].m_tb, &tb);
3346 Msgs[msgnum].m_stats = mp -> msgstats[msgnum];
3347 if (mp -> curmsg == msgnum)
3348 Msgs[msgnum].m_stats |= CUR;
3351 qsort ((char *) &Msgs[mp -> lowsel], mp -> hghsel - mp -> lowsel + 1,
3352 sizeof (struct Msg),
3353 subjsw ? subsort : msgsort);
3355 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) {
3356 if (subjsw && Msgs[msgnum].m_scanl) {
3357 free (Msgs[msgnum].m_scanl); /* from subjsort */
3358 Msgs[msgnum].m_scanl = NULL;
3360 mp -> msgstats[msgnum] = Msgs[msgnum].m_stats & ~CUR;
3361 if (Msgs[msgnum].m_stats & CUR)
3362 m_setcur (mp, msgnum);
3365 mp -> msgflags |= MODIFIED;
3372 * getws - parse message, and get date and subject if needed. We'll use
3373 * the msgp->m_tb tws struct for the date, and overload the msgp->m_scanl
3374 * field with our subject string.
3376 static int getws (datesw, subjsw, msgnum, msgp)
3387 struct tws *tw = (struct tws *)0;
3390 zp = msh_ready (msgnum, 0);
3391 for (state = FLD;;) {
3392 switch (state = m_getfld (state, name, buf, sizeof buf, zp)) {
3396 if (uleq (name, datesw)) {
3398 while (state == FLDPLUS) {
3399 state = m_getfld (state, name, buf, sizeof buf, zp);
3402 if ((tw = dparsetime (bp)) == NULL)
3404 "unable to parse %s field in message %d",
3407 twscopy (&(msgp->m_tb), tw);
3409 if (!subjsw) /* not using this, or already done */
3410 break; /* all done! */
3413 else if (subjsw && uleq(name, subjsw)) {
3415 while (state == FLDPLUS) {
3416 state = m_getfld (state, name, buf, sizeof buf, zp);
3419 msgp->m_scanl = sosmash(subjsw, bp);
3421 break; /* date done so we're done */
3423 subjsw = (char *)0;/* subject done, need date */
3425 while (state == FLDPLUS) /* flush this one */
3426 state = m_getfld (state, name, buf, sizeof buf, zp);
3437 admonish (NULLCP, "format error in message %d", msgnum);
3438 if (msgp->m_scanl) { /* this might need free'd */
3439 free (msgp->m_scanl); /* probably can't use subj anyway */
3440 msgp->m_scanl = NULL;
3445 adios (NULLCP, "internal error -- you lose");
3450 return OK; /* not an error if subj not found */
3452 admonish (NULLCP, "no %s field in message %d", datesw, msgnum);
3453 return NOTOK; /* NOTOK means use some other date */
3458 static int msgsort (a, b)
3462 return twsort (&a -> m_tb, &b -> m_tb);
3465 static int subsort (a, b)
3471 if (a->m_scanl && b->m_scanl)
3472 if (i = strcmp (a->m_scanl, b->m_scanl))
3475 return twsort (&a -> m_tb, &b -> m_tb);
3479 * try to make the subject "canonical": delete leading "re:", everything
3480 * but letters & smash letters to lower case.
3492 dp = s; /* dst pointer */
3493 if (uleq (subj, "subject"))
3500 *dp++ = isupper(c) ? tolower(c) : c;
3508 *dp++ = isupper(c) ? tolower(c) : c;
3518 static int process (msgnum, proc, vecp, vec)
3530 (void) strcpy (tmpfil, m_name (msgnum));
3531 (void) m_delete (pfolder);
3532 m_replace (pfolder, fmsh);
3538 (void) strcpy (tmpfil, m_scratch ("", invo_name));
3539 if ((out = fopen (tmpfil, "w")) == NULL) {
3545 (void) strcpy (newfil, m_tmpfil (invo_name));
3546 if ((out = fopen (newfil, "w")) == NULL) {
3548 advise (tmpfil, "unable to create temporary file");
3552 (void) strcpy (tmpfil, newfil);
3554 copy_message (msgnum, out);
3555 (void) fclose (out);
3558 (void) fflush (stdout);
3559 switch (child_id = fork ()) {
3561 advise ("fork", "unable to");
3567 (void) signal (SIGINT, istat);
3568 (void) signal (SIGQUIT, qstat);
3570 vec[vecp++] = tmpfil;
3574 fprintf (stderr, "unable to exec ");
3579 status = pidXwait (child_id, NULLCP);
3584 (void) unlink (tmpfil);
3590 static copy_message (msgnum, out)
3595 static char buffer[BUFSIZ];
3598 zp = msh_ready (msgnum, 1);
3600 while (fgets (buffer, sizeof buffer, zp) != NULL) {
3601 fputs (buffer, out);
3602 if (interrupted && out == stdout)
3608 while (fgets (buffer, sizeof buffer, zp) != NULL
3609 && pos < Msgs[msgnum].m_stop) {
3610 fputs (buffer, out);
3611 pos += (long) strlen (buffer);
3612 if (interrupted && out == stdout)
3619 static copy_digest (msgnum, out)
3625 static char buffer[BUFSIZ];
3629 zp = msh_ready (msgnum, 1);
3632 while (fgets (buffer, sizeof buffer, zp) != NULL
3633 && !fmsh && pos < Msgs[msgnum].m_stop) {
3634 if (c == '\n' && *buffer == '-')
3635 (void) fputc (' ', out);
3636 fputs (buffer, out);
3637 c = buffer[strlen (buffer) - 1];
3639 pos += (long) strlen (buffer);
3640 if (interrupted && out == stdout)
3649 @mime changes from mtr
3654 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.30 1995/12/06 23:44:31 jromine Exp jromine $";
3657 headersw ? (fmsh ? fmsh : mp -> foldpath) : (char *)0,
3668 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.29 1994/04/21 18:20:50 jromine Exp jromine $";
3678 forw (cmd_name, filter, vecp, vec);
3681 static forw (proc, filter, vecp, vec)
3689 headersw, fmsh ? fmsh : mp -> foldpath,
3698 @update for scansbr.c -- overload {folder}.c_flags with hdrflg
3703 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.28 1993/12/01 03:50:31 jromine Exp jromine $";
3707 m_seq (mp, mp -> msgattrs[i]));
3710 printf ("%s%s: %s\n", seqs[seqp], m_seq (mp, seqs[seqp]));
3721 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.27 1993/10/26 20:09:54 jromine Exp jromine $";
3724 headersw ? (fmsh ? fmsh : mp -> foldpath) : (char *)0,
3730 @test for iso-8859-1 and us-ascii, 8bit, binary and 7bit
3735 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.25 1992/12/15 00:20:22 jromine Exp $";
3737 #include "../h/mshsbr.h"
3744 @re-order mshsbr.h include
3749 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.25 1992/12/15 00:20:22 jromine Exp jromine $";
3752 #include "../h/mshsbr.h"
3760 if (strlen (dp) >= sizeof "us-ascii\""
3761 && *(bp = dp + sizeof "us-ascii" - 1)=='"')
3764 if (strlen (dp) >= sizeof "us-ascii"
3766 dp + sizeof "us-ascii" - 1)))
3768 result = !uleq (dp, "us-ascii");
3771 if (result = !uleq (bp, "7bit"))
3772 Msgs[msgnum].m_flags |= MHNYES;
3783 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.24 1992/11/24 18:26:05 jromine Exp jromine $";
3785 #include "../h/mshsbr.h"
3797 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.23 1992/11/04 00:53:32 jromine Exp jromine $";
3827 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.22 1992/10/29 03:49:31 jromine Exp jromine $";
3834 @fix burst -- previously it was losing the last message(!)
3839 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.21 1992/10/26 22:21:33 jromine Exp jromine $";
3845 if ((c == 'R' || c == 'r') &&
3846 (cp[0] == 'e' || cp[0] == 'E') && cp[1] == ':')
3853 @turn off MPOP if NNTP on
3858 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.20 1992/10/17 00:24:25 jromine Exp jromine $";
3862 for (msgp = 1; msgp <= MAXFOLDER;) {
3865 fgets (buffer, sizeof buffer, zp) != NULL
3866 && pos < Msgs[msgnum].m_stop;
3869 && peekc (zp) == '\n'
3870 && (msgp == 1 || c == '\n'))
3873 smsgs[msgp++].m_stop = c == '\n' && wasdlm ? pos - 1 : pos;
3878 msgp++; /* fake "End of XXX Digest" */
3882 switch (--msgp) { /* toss "End of XXX Digest" */
3885 msgp - 1, msgp - 1 != 1 ? "s" : "", msgnum);
3892 mp -> hghmsg += msgp - 1;
3893 mp -> nummsg += msgp - 1;
3896 mp -> hghsel += msgp - 1;
3899 if (inplace && msgp > 1)
3902 i = inplace ? msgnum + msgp - 1 : mp -> hghmsg;
3903 for (j = msgp; j >= (inplace ? 1 : 2); i--, j--) {
3914 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.19 1992/10/17 00:19:58 jromine Exp jromine $";
3926 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.18 1992/10/16 22:34:17 jromine Exp jromine $";
3939 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.17 1992/10/16 21:50:20 jromine Exp jromine $";
3945 extern char response[];
3958 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.16 1992/10/16 21:47:40 jromine Exp jromine $";
3961 if (!nshow && (cp = m_find ("mhnproc")) && !getenv ("NOMHNPROC"))
3982 c = *dp, *dp = '\0';
3986 Msgs[msgnum].m_flags |= MHNYES;
4000 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.15 1992/10/16 21:37:18 jromine Exp jromine $";
4013 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.14 1992/10/16 16:51:55 jromine Exp jromine $";
4021 @mobile pop (MPOP) ifdefs
4026 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.13 1992/05/19 21:03:35 jromine Exp jromine $";
4049 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.12 1992/03/03 17:09:57 jromine Exp jromine $";
4076 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.11 1992/02/08 00:10:26 jromine Exp jromine $";
4085 c = *dp, *dp = NULL;
4097 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.10 1992/02/05 07:26:30 jromine Exp jromine $";
4105 @put unseen sequence in mh-format
4110 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.9 1992/01/31 22:19:11 jromine Exp jromine $";
4122 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.8 1992/01/31 16:33:46 jromine Exp jromine $";
4129 msgnum == mp -> curmsg,
4140 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.7 1992/01/23 22:58:03 jromine Exp $";
4160 if (*folder == NULL) {
4166 vec[0] = mktemp (buf);
4199 @change call to scan(...hdrflag...)
4204 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.6 1991/01/14 16:48:39 mh Exp jromine $";
4213 @add -[no]rmmproc to refile
4214 delete -[no]format from repl
4215 still need to add -[no]dashmunging to forw
4221 static char ident[] = "@@(#)$Id: mshcmds.c,v 1.5 90/04/05 15:01:41 sources Exp Locker: mh $";
4224 msgnum == mp -> curmsg, headersw,
4235 static char ident[] = "@@(#)$Id:$";
4276 @all arbitrary textfields in sortm
4285 @add sortm -[no]subject and (unimplemented) -[no]limit
4305 register int subjsw = 0;
4317 subjsw; /* on entry, 0=no, 1=yes. internal -1=date_done */
4323 subjsw = -1; /* now looking for subject alone */
4326 else if (subjsw && uleq(name, "subject")) {
4329 msgp->m_scanl = sosmash(bp);
4333 subjsw = 0; /* subject done, need date */
4341 if ((c == 'R' || c == 'r') &&
4342 (cp[0] == 'e' || cp[0] == 'E') && cp[1] == ':')
4346 *dp++ = islower(c) ? c : tolower(c);
4353 *dp++ = islower(c) ? c : tolower(c);
4364 static int msgsort ();
4365 static struct tws *getws ();
4373 if ((tw = getws (datesw, msgnum)) == NULL)
4374 tw = msgnum != mp -> lowsel ? &Msgs[msgnum - 1].m_tb : &tb;
4379 twscopy (&Msgs[msgnum].m_tb, tw);
4382 sizeof (struct Msg), msgsort);
4386 static struct tws *getws (datesw, msgnum)
4402 while (state == FLDPLUS)
4403 state = m_getfld (state, name, buf, sizeof buf, zp);
4404 if (state != FLDEOF)
4408 admonish (NULLCP, "no %s field in message %d", datesw, msgnum);
4432 struct tws *getws ();