1 /* mshcmds.c - command handlers in msh */
3 static char ident[] = "@(#)$Id: mshcmds.c,v 1.32 1995/12/11 18:19:26 jromine Exp $";
7 #include "../h/dropsbr.h"
8 #include "../h/formatsbr.h"
9 #include "../h/scansbr.h"
10 #include "../zotnet/tws.h"
11 #ifdef _AIX /* AIX 1.2.1 <stdio.h> declares getws() */
18 #include "../zotnet/mts.h"
23 #include <sys/types.h>
25 #include "../h/mshsbr.h"
35 static char delim3[] = "-------";/* from burst.c */
43 static int eom_action ();
44 static FP mhl_action ();
50 static burst(), forw(), rmm(), show(), ask(), copy_message(), copy_digest();
53 static int msgsort (), subsort();
55 static char *sosmash ();
57 #if defined(NNTP) && defined(MPOP)
63 extern char response[];
76 vec[0] = r1bindex (pgm, '/');
77 (void) copyip (args, vec + 1);
80 (void) m_delete (pfolder);
81 m_replace (pfolder, fmsh);
85 (void) fflush (stdout);
86 switch (child_id = fork ()) {
88 advise ("fork", "unable to");
93 (void) signal (SIGINT, istat);
94 (void) signal (SIGQUIT, qstat);
97 fprintf (stderr, "unable to exec ");
102 (void) pidXwait (child_id, NULLCP);
105 if (fmsh) { /* assume the worst case */
106 mp -> msgflags |= MODIFIED;
113 static struct swit distswit[] = {
119 "draftfolder +folder", 0,
121 "draftmessage msg", 0,
135 "whatnowproc program", 0,
156 forkcmd (args, cmd_name);
160 while (cp = *args++) {
162 switch (smatch (++cp, distswit)) {
164 ambigsw (cp, distswit);
167 fprintf (stderr, "-%s unknown\n", cp);
170 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
171 help (buf, distswit);
174 case DIANSW: /* not implemented */
192 if (!(cp = *args++) || *cp == '-') {
193 advise (NULLCP, "missing argument to %s", args[-2]);
199 if (*cp == '+' || *cp == '@') {
200 advise (NULLCP, "sorry, no folders allowed!");
205 advise (NULLCP, "only one message at a time!");
213 vec[vecp++] = "-file";
217 if (!m_convert (mp, msg))
221 if (mp -> numsel > 1) {
222 advise (NULLCP, "only one message at a time!");
225 (void) process (mp -> hghsel, cmd_name, vecp, vec);
226 m_setcur (mp, mp -> hghsel);
231 static struct swit explswit[] = {
267 forkcmd (args, cmd_name);
271 while (cp = *args++) {
273 switch (smatch (++cp, explswit)) {
275 ambigsw (cp, explswit);
278 fprintf (stderr, "-%s unknown\n", cp);
281 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
282 help (buf, explswit);
304 if (*cp == '+' || *cp == '@') {
305 advise (NULLCP, "sorry, no folders allowed!");
313 msgs[msgp++] = "cur";
314 for (msgnum = 0; msgnum < msgp; msgnum++)
315 if (!m_convert (mp, msgs[msgnum]))
319 smsgs = (struct Msg *)
320 calloc ((unsigned) (MAXFOLDER + 2), sizeof *smsgs);
322 adios (NULLCP, "unable to allocate folder storage");
324 hi = mp -> hghmsg + 1;
326 for (msgnum = mp -> lowsel;
327 msgnum <= mp -> hghsel && !interrupted;
329 if (mp -> msgstats[msgnum] & SELECTED)
330 if (burst (smsgs, msgnum, inplace, quietsw, verbosw) != OK)
333 free ((char *) smsgs);
336 m_setcur (mp, mp -> lowsel);
338 if (hi <= mp -> hghmsg)
341 mp -> msgflags |= MODIFIED;
347 static burst (smsgs, msgnum, inplace, quietsw, verbosw)
365 ld3 = strlen (delim3);
367 if (Msgs[msgnum].m_scanl) {
368 free (Msgs[msgnum].m_scanl);
369 Msgs[msgnum].m_scanl = NULL;
372 pos = ftell (zp = msh_ready (msgnum, 1));
373 for (msgp = 0; msgp <= MAXFOLDER;) {
374 while (fgets (buffer, sizeof buffer, zp) != NULL
376 && pos < Msgs[msgnum].m_stop)
377 pos += (long) strlen (buffer);
378 if (feof (zp) || pos >= Msgs[msgnum].m_stop)
380 (void) fseek (zp, pos, 0);
381 smsgs[msgp].m_start = pos;
384 pos < Msgs[msgnum].m_stop
385 && fgets (buffer, sizeof buffer, zp) != NULL;
387 if (strncmp (buffer, delim3, ld3) == 0
388 && (msgp == 1 || c == '\n')
389 && peekc (zp) == '\n')
392 pos += (long) strlen (buffer);
394 wasdlm = strncmp (buffer, delim3, ld3) == 0;
395 if (smsgs[msgp].m_start != pos)
396 smsgs[msgp++].m_stop = (c == '\n' && wasdlm) ? pos - 1 : pos;
397 if (feof (zp) || pos >= Msgs[msgnum].m_stop) {
399 smsgs[msgp - 1].m_stop -= ((long) strlen (buffer) + 1);
402 pos += (long) strlen (buffer);
405 switch (msgp--) { /* toss "End of XXX Digest" */
407 adios (NULLCP, "burst() botch -- you lose big");
411 printf ("message %d not in digest format\n", msgnum);
416 printf ("%d message%s exploded from digest %d\n",
417 msgp, msgp != 1 ? "s" : "", msgnum);
421 if ((i = msgp + mp -> hghmsg) > MAXFOLDER) {
422 advise (NULLCP, "more than %d messages", MAXFOLDER);
425 if ((mp = m_remsg (mp, 0, i)) == NULL)
426 adios (NULLCP, "unable to allocate folder storage");
429 mp -> hghmsg += msgp;
430 mp -> nummsg += msgp;
431 if (mp -> hghsel > msgnum)
432 mp -> hghsel += msgp;
435 for (i = mp -> hghmsg; j > msgnum; i--, j--) {
437 printf ("message %d becomes message %d\n", j, i);
439 Msgs[i].m_bboard_id = Msgs[j].m_bboard_id;
440 Msgs[i].m_top = Msgs[j].m_top;
441 Msgs[i].m_start = Msgs[j].m_start;
442 Msgs[i].m_stop = Msgs[j].m_stop;
443 Msgs[i].m_scanl = NULL;
444 if (Msgs[j].m_scanl) {
445 free (Msgs[j].m_scanl);
446 Msgs[j].m_scanl = NULL;
448 mp -> msgstats[i] = mp -> msgstats[j];
451 if (Msgs[msgnum].m_bboard_id == 0)
452 (void) readid (msgnum);
454 mp -> msgstats[msgnum] &= ~SELECTED;
455 i = inplace ? msgnum + msgp : mp -> hghmsg;
456 for (j = msgp; j >= (inplace ? 0 : 1); i--, j--) {
457 if (verbosw && i != msgnum)
458 printf ("message %d of digest %d becomes message %d\n",
461 Msgs[i].m_bboard_id = Msgs[msgnum].m_bboard_id;
462 Msgs[i].m_top = Msgs[j].m_top;
463 Msgs[i].m_start = smsgs[j].m_start;
464 Msgs[i].m_stop = smsgs[j].m_stop;
465 Msgs[i].m_scanl = NULL;
466 mp -> msgstats[i] = mp -> msgstats[msgnum];
474 static struct swit fileswit[] = {
490 "rmmproc program", 0,
515 forkcmd (args, cmd_name);
519 while (cp = *args++) {
521 switch (i = smatch (++cp, fileswit)) {
523 ambigsw (cp, fileswit);
526 fprintf (stderr, "-%s unknown\n", cp);
529 (void) sprintf (buf, "%s +folder... [msgs] [switches]",
531 help (buf, fileswit);
550 advise (NULLCP, "sorry, -%s not allowed!", fileswit[i].sw);
553 if (*cp == '+' || *cp == '@')
560 vec[vecp++] = "-file";
563 msgs[msgp++] = "cur";
564 for (msgnum = 0; msgnum < msgp; msgnum++)
565 if (!m_convert (mp, msgs[msgnum]))
570 for (msgnum = mp -> lowsel;
571 msgnum <= mp -> hghsel && !interrupted;
573 if (mp -> msgstats[msgnum] & SELECTED)
574 if (process (msgnum, fileproc, vecp, vec)) {
575 mp -> msgstats[msgnum] &= ~SELECTED;
579 if (mp -> numsel != mp -> nummsg || linksw)
580 m_setcur (mp, mp -> hghsel);
596 while (cp = *args++) {
598 switch (smatch (++cp, fileswit)) {
615 if (*cp == '+' || *cp == '@')
622 for (vecp = 0; (cp = vec[vecp]) && result == NOTOK; vecp++) {
624 cwd = getcpy (pwd ());
625 (void) chdir (m_maildir (""));
626 cp = path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF);
627 if (access (m_maildir (cp), 0) == NOTOK)
639 static struct swit foldswit[] = {
695 while (cp = *args++) {
697 switch (smatch (++cp, foldswit)) {
699 ambigsw (cp, foldswit);
702 fprintf (stderr, "-%s unknown\n", cp);
705 (void) sprintf (buf, "%s [+folder] [msg] [switches]",
707 help (buf, foldswit);
710 case FLALSW: /* not implemented */
740 if (*cp == '+' || *cp == '@')
742 advise (NULLCP, "only one folder at a time!\n");
746 folder = fmsh ? path (cp + 1, *cp == '+' ? TFOLDER : TSUBCWF)
750 advise (NULLCP, "only one message at a time!\n");
759 advise (NULLCP, "null folder names are not permitted");
763 if (access (m_maildir (folder), 04) == NOTOK) {
764 advise (folder, "unable to read");
769 (void) strcpy (buf, folder);
770 if (expand (buf) == NOTOK)
773 if (access (folder, 04) == NOTOK) {
774 advise (folder, "unable to read");
789 if (!m_convert (mp, msg))
793 if (mp -> numsel > 1) {
794 advise (NULLCP, "only one message at a time!");
797 m_setcur (mp, mp -> hghsel);
802 forkcmd (vec, cmd_name);
806 if (mp -> lowmsg > 1 && (mp = m_remsg (mp, 1, mp -> hghmsg)) == NULL)
807 adios (NULLCP, "unable to allocate folder storage");
808 for (msgnum = mp -> lowmsg, hole = 1; msgnum <= mp -> hghmsg; msgnum++)
809 if (mp -> msgstats[msgnum] & EXISTS) {
810 if (msgnum != hole) {
811 Msgs[hole].m_bboard_id = Msgs[msgnum].m_bboard_id;
812 Msgs[hole].m_top = Msgs[msgnum].m_top;
813 Msgs[hole].m_start = Msgs[msgnum].m_start;
814 Msgs[hole].m_stop = Msgs[msgnum].m_stop;
815 Msgs[hole].m_scanl = NULL;
816 if (Msgs[msgnum].m_scanl) {
817 free (Msgs[msgnum].m_scanl);
818 Msgs[msgnum].m_scanl = NULL;
820 mp -> msgstats[hole] = mp -> msgstats[msgnum];
821 if (mp -> curmsg == msgnum)
826 if (mp -> nummsg > 0) {
828 mp -> hghmsg = hole - 1;
830 mp -> msgflags |= MODIFIED;
836 printf ("%s\n", fmsh ? fmsh : mp -> foldpath);
839 printf ("\t\tFolder %*s# of messages (%*srange%*s); cur%*smsg\n",
840 DMAXFOLDER, "", DMAXFOLDER - 2, "", DMAXFOLDER - 2, "",
842 printf (args ? "%22s " : "%s ", fmsh ? fmsh : mp -> foldpath);
843 if (mp -> hghmsg == 0)
844 printf ("has no messages%*s",
845 mp -> msgflags & OTHERS ? DMAXFOLDER * 2 + 4 : 0, "");
847 printf ("has %*d message%s (%*d-%*d)",
848 DMAXFOLDER, mp -> nummsg, mp -> nummsg != 1 ? "s" : "",
849 DMAXFOLDER, mp -> lowmsg, DMAXFOLDER, mp -> hghmsg);
850 if (mp -> curmsg >= mp -> lowmsg
851 && mp -> curmsg <= mp -> hghmsg)
852 printf ("; cur=%*d", DMAXFOLDER, mp -> curmsg);
861 #define MIMEminc(a) (a)
863 #define MIMEminc(a) 0
866 static struct swit forwswit[] = {
872 "draftfolder +folder", 0,
874 "draftmessage msg", 0,
882 "filter filterfile", 0,
894 "mime", MIMEminc(-4),
896 "nomime", MIMEminc(-6),
898 "whatnowproc program", 0,
923 forkcmd (args, cmd_name);
927 while (cp = *args++) {
929 switch (smatch (++cp, forwswit)) {
931 ambigsw (cp, forwswit);
934 fprintf (stderr, "-%s unknown\n", cp);
937 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
938 help (buf, forwswit);
941 case FOANSW: /* not implemented */
969 if (!(cp = *args++) || *cp == '-') {
970 advise (NULLCP, "missing argument to %s", args[-2]);
976 if (!(filter = *args++) || *filter == '-') {
977 advise (NULLCP, "missing argument to %s", args[-2]);
983 if (access (filter = myfilter, 04) == NOTOK) {
984 advise (filter, "unable to read default filter file");
992 if (*cp == '+' || *cp == '@') {
993 advise (NULLCP, "sorry, no folders allowed!");
1000 /* foil search of .mh_profile */
1001 (void) sprintf (buf, "%sXXXXXX", invo_name);
1002 vec[0] = (char *)mktemp (buf);
1003 vec[vecp++] = "-file";
1006 msgs[msgp++] = "cur";
1007 for (msgnum = 0; msgnum < msgp; msgnum++)
1008 if (!m_convert (mp, msgs[msgnum]))
1013 (void) strcpy (buf, filter);
1014 if (expand (buf) == NOTOK)
1016 if (access (filter = getcpy (libpath (buf)), 04) == NOTOK) {
1017 advise (filter, "unable to read");
1022 forw (cmd_name, filter, vecp, vec, mime);
1023 m_setcur (mp, mp -> hghsel);
1030 static forw (proc, filter, vecp, vec, mime)
1049 (void) strcpy (tmpfil, m_tmpfil (invo_name));
1052 switch (child_id = fork ()) {
1054 advise ("fork", "unable to");
1057 case OK: /* "trust me" */
1058 if (freopen (tmpfil, "w", stdout) == NULL) {
1059 fprintf (stderr, "unable to create ");
1063 args[0] = r1bindex (mhlproc, '/');
1065 args[i++] = "-forwall";
1066 args[i++] = "-form";
1068 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
1069 if (mp -> msgstats[msgnum] & SELECTED)
1070 args[i++] = getcpy (m_name (msgnum));
1072 (void) mhlsbr (i, args, mhl_action);
1073 m_eomsbr ((int (*) ()) 0);
1074 (void) fclose (stdout);
1078 if (pidXwait (child_id, NULLCP))
1087 #define INITIAL_PREFIX "----- =_aaaaaaaaaa"
1091 prefix[sizeof INITIAL_PREFIX];
1095 for (vecp = 1; cp = vec[vecp++]; )
1097 switch (smatch (++cp, forwswit)) {
1118 /* ignore -draftfolder / -draftmessage / -nodraftfolder */
1125 (void) strcpy (tmpfil, m_draft (NULLCP, NULLCP, NOUSE, &isdf));
1126 if (!ed && !(ed = m_find ("editor")))
1129 (void) strcpy (prefix, INITIAL_PREFIX);
1130 cp = index (prefix, 'a');
1131 len = strlen (prefix);
1137 for (msgnum = mp -> lowsel;
1138 msgnum <= mp -> hghsel && !interrupted && !hit;
1140 if (mp -> msgstats[msgnum] & SELECTED) {
1141 zp = msh_ready (msgnum, 1);
1144 while (fgets (buffer, sizeof buffer, zp) != NULL
1146 && pos < Msgs[msgnum].m_stop) {
1149 if (buffer[0] != '-' || buffer[1] != '-')
1152 for (pp = buffer + strlen (buffer) - 1;
1159 if (strncmp (buffer + 2, prefix, len))
1175 "unable to determine unique delimiter string?!?");
1182 if ((out = fopen (tmpfil, "w")) == NULL) {
1183 advise (tmpfil, "unable to create temporary file");
1186 (void) chmod (tmpfil, m_gmprot ());
1188 fprintf (out, "%s: %s\n", VRSN_FIELD, VRSN_VALUE);
1189 fprintf (out, "%s: multipart/digest; boundary=\"%s\"\n", TYPE_FIELD,
1192 if (!(zp = fopen (libpath (form ? form : forwcomps), "r"))) {
1194 advise (form, "unable to open form file");
1196 advise (forwcomps, "unable to open default components file");
1197 (void) fclose (out);
1198 (void) unlink (tmpfil);
1201 while (fgets (buffer, sizeof buffer, zp))
1202 (void) fputs (buffer, out);
1205 for (msgnum = mp -> lowsel;
1206 msgnum <= mp -> hghsel && !interrupted;
1208 if (mp -> msgstats[msgnum] & SELECTED) {
1209 fprintf (out, "\n--%s\n%s: message/rfc822\n\n", prefix,
1212 copy_message (msgnum, out);
1214 fprintf (out, "\n--%s--\n", prefix);
1216 (void) fclose (out);
1222 if ((out = fopen (tmpfil, "w")) == NULL) {
1223 advise (tmpfil, "unable to create temporary file");
1228 for (msgnum = mp -> lowsel;
1229 msgnum <= mp -> hghsel && !interrupted;
1231 if (mp -> msgstats[msgnum] & SELECTED) {
1232 fprintf (out, "\n\n-------");
1233 if (msgnum == mp -> lowsel)
1234 fprintf (out, " Forwarded Message%s",
1235 mp -> numsel > 1 ? "s" : "");
1237 fprintf (out, " Message %d", msgcnt);
1238 fprintf (out, "\n\n");
1239 copy_digest (msgnum, out);
1243 fprintf (out, "\n\n------- End of Forwarded Message%s\n",
1244 mp -> numsel > 1 ? "s" : "");
1245 (void) fclose (out);
1248 (void) fflush (stdout);
1250 switch (child_id = fork ()) {
1252 advise ("fork", "unable to");
1257 (void) signal (SIGINT, istat);
1258 (void) signal (SIGQUIT, qstat);
1263 vec[vecp++] = r1bindex (proc, '/');
1264 (void) m_putenv ("mhdraft", tmpfil);
1265 (void) unputenv ("mhfolder");
1266 (void) unputenv ("mhaltmsg");
1267 (void) m_putenv ("mhdist", "0");
1269 (void) unputenv ("mheditor");
1271 (void) m_putenv ("mheditor", ed);
1272 (void) m_putenv ("mhuse", "0");
1273 (void) unputenv ("mhmessages");
1274 (void) unputenv ("mhannotate");
1275 (void) unputenv ("mhinplace");
1280 vec[vecp++] = tmpfil;
1284 fprintf (stderr, "unable to exec ");
1289 (void) pidXwait (child_id, NULLCP);
1296 (void) unlink (tmpfil);
1301 static char *hlpmsg[] = {
1302 "The %s program emulates many of the commands found in the Rand MH",
1303 "system. Instead of operating on MH folders, commands to %s concern",
1306 "To see the list of commands available, just type a ``?'' followed by",
1307 "the RETURN key. To find out what switches each command takes, type",
1308 "the name of the command followed by ``-help''. To leave %s, use the",
1309 "``quit'' command.",
1311 "Although a lot of MH commands are found in %s, not all are fully",
1312 "implemented. %s will always recognize all legal switches for a",
1313 "given command though, and will let you know when you ask for an",
1314 "option that it is unable to perform.",
1316 "Running %s is fun, but using MH from your shell is far superior.",
1317 "After you have familiarized yourself with the MH style by using %s,",
1318 "you should try using MH from the shell. You can still use %s for",
1319 "message files that aren't in MH format, such as BBoard files.",
1331 for (i = 0; hlpmsg[i]; i++) {
1332 printf (hlpmsg[i], invo_name);
1333 (void) putchar ('\n');
1339 static struct swit markswit[] = {
1383 while (cp = *args++) {
1385 switch (smatch (++cp, markswit)) {
1387 ambigsw (cp, markswit);
1390 fprintf (stderr, "-%s unknown\n", cp);
1393 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
1394 help (buf, markswit);
1399 deletesw = listsw = 0;
1407 addsw = deletesw = 0;
1411 if (!(cp = *args++) || *cp == '-') {
1412 advise (NULLCP, "missing argument to %s", args[-2]);
1418 advise (NULLCP, "only %d sequences allowed!", NATTRS);
1423 case MPUBSW: /* not implemented */
1438 if (*cp == '+' || *cp == '@') {
1439 advise (NULLCP, "sorry, no folders allowed!");
1446 if (!addsw && !deletesw && !listsw)
1453 seqs[seqp++] = "unseen";
1457 msgs[msgp++] = "all";
1461 msgs[msgp++] = listsw ? "all" :"cur";
1462 for (msgnum = 0; msgnum < msgp; msgnum++)
1463 if (!m_convert (mp, msgs[msgnum]))
1467 printf ("invo_name=%s mypath=%s defpath=%s\n",
1468 invo_name, mypath, defpath);
1469 printf ("ctxpath=%s context flags=%s\n",
1470 ctxpath, sprintb (buf, (unsigned) ctxflags, DBITS));
1471 printf ("foldpath=%s flags=%s\n",
1473 sprintb (buf, (unsigned) mp -> msgflags, FBITS));
1474 printf ("hghmsg=%d lowmsg=%d nummsg=%d curmsg=%d\n",
1475 mp -> hghmsg, mp -> lowmsg, mp -> nummsg, mp -> curmsg);
1476 printf ("lowsel=%d hghsel=%d numsel=%d\n",
1477 mp -> lowsel, mp -> hghsel, mp -> numsel);
1479 printf ("lowoff=%d hghoff=%d\n",
1480 mp -> lowoff, mp -> hghoff);
1482 printf ("lowoff=%d hghoff=%d msgbase=0x%x msgstats=0x%x\n",
1483 mp -> lowoff, mp -> hghoff, mp -> msgbase, mp -> msgstats);
1487 if (seqp == 0 && (addsw || deletesw)) {
1488 advise (NULLCP, "-%s requires at least one -sequence argument",
1489 addsw ? "add" : "delete");
1495 for (seqp = 0; seqs[seqp]; seqp++) {
1496 if (zerosw && !m_seqnew (mp, seqs[seqp], 0))
1498 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
1499 if (mp -> msgstats[msgnum] & SELECTED)
1500 if (!m_seqadd (mp, seqs[seqp], msgnum, 0))
1505 for (seqp = 0; seqs[seqp]; seqp++) {
1507 for (msgnum = mp -> lowmsg; msgnum <= mp -> hghmsg; msgnum++)
1508 if (mp -> msgstats[msgnum] & EXISTS)
1509 if (!m_seqadd (mp, seqs[seqp], msgnum, 0))
1511 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
1512 if (mp -> msgstats[msgnum] & SELECTED)
1513 if (!m_seqdel (mp, seqs[seqp], msgnum))
1518 int bits = FFATTRSLOT;
1520 #define empty(s) ((s) ? (s) : "")
1522 for (i = 0; mp -> msgattrs[i]; i++)
1523 printf ("%s%s: %s\n", mp -> msgattrs[i],
1524 mp -> attrstats & (1 << (bits + i))
1525 ? " (private)" : "",
1526 empty(m_seq (mp, mp -> msgattrs[i])));
1528 for (seqp = 0; seqs[seqp]; seqp++)
1529 printf ("%s%s: %s\n", seqs[seqp],
1530 empty(m_seq (mp, seqs[seqp])));
1535 for (msgnum = mp -> lowsel;
1536 msgnum <= mp -> hghsel && !interrupted;
1538 if (mp -> msgstats[msgnum] & SELECTED) {
1539 printf ("%*d: id=%d top=%d start=%ld stop=%ld %s\n",
1541 Msgs[msgnum].m_bboard_id, Msgs[msgnum].m_top,
1542 Msgs[msgnum].m_start, Msgs[msgnum].m_stop,
1543 sprintb (buf, (unsigned) mp -> msgstats[msgnum],
1545 if (Msgs[msgnum].m_scanl)
1546 printf ("%s", Msgs[msgnum].m_scanl);
1554 static struct swit mhnswit[] = {
1557 #define MHNNAUTOSW 1
1559 #define MHNDEBUGSW 2
1561 #define MHNEBCDICSW 3
1563 #define MHNNEBCDICSW 4
1569 #define MHNNHEADSW 7
1573 #define MHNNLISTSW 9
1575 #define MHNPARTSW 10
1577 #define MHNSIZESW 11
1579 #define MHNNSIZESW 12
1581 #define MHNRFC934SW 13
1583 #define MHNNRFC934SW 14
1585 #define MHNSERIALSW 15
1587 #define MHNNSERIALSW 16
1589 #define MHNSHOWSW 17
1591 #define MHNNSHOWSW 18
1593 #define MHNSTORESW 19
1595 #define MHNNSTORESW 20
1597 #define MHNTYPESW 21
1599 #define MHNVERBSW 22
1601 #define MHNNVERBSW 23
1603 #define MHNHELPSW 24
1605 #define MHNPROGSW 25
1606 "moreproc program", -4,
1607 #define MHNNPROGSW 26
1612 "width columns", -4,
1632 forkcmd (args, cmd_name);
1636 while (cp = *args++) {
1638 switch (smatch (++cp, mhnswit)) {
1640 ambigsw (cp, mhnswit);
1643 fprintf (stderr, "-%s unknown\n", cp);
1646 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
1647 help (buf, mhnswit);
1682 if (!(cp = *args++) || *cp == '-') {
1683 advise (NULLCP, "missing argument to %s", args[-2]);
1689 if (*cp == '+' || *cp == '@') {
1690 advise (NULLCP, "sorry, no folders allowed!");
1698 vec[vecp++] = "-file";
1701 msgs[msgp++] = "cur";
1702 for (msgnum = 0; msgnum < msgp; msgnum++)
1703 if (!m_convert (mp, msgs[msgnum]))
1708 for (msgnum = mp -> lowsel;
1709 msgnum <= mp -> hghsel && !interrupted;
1711 if (mp -> msgstats[msgnum] & SELECTED)
1712 if (process (msgnum, cmd_name, vecp, vec)) {
1713 mp -> msgstats[msgnum] &= ~SELECTED;
1717 m_setcur (mp, mp -> hghsel);
1723 static struct swit packswit[] = {
1748 forkcmd (args, cmd_name);
1752 while (cp = *args++) {
1754 switch (smatch (++cp, packswit)) {
1756 ambigsw (cp, packswit);
1759 fprintf (stderr, "-%s unknown\n", cp);
1762 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
1763 help (buf, packswit);
1767 if (!(file = *args++) || *file == '-') {
1768 advise (NULLCP, "missing argument to %s", args[-2]);
1773 if (*cp == '+' || *cp == '@') {
1774 advise (NULLCP, "sorry, no folders allowed!");
1783 file = path (file, TFILE);
1784 if (stat (file, &st) == NOTOK) {
1785 if (errno != ENOENT) {
1786 advise (file, "error on file");
1789 md = getanswer (cp = concat ("Create file \"", file, "\"? ", NULLCP));
1796 msgs[msgp++] = "all";
1797 for (msgnum = 0; msgnum < msgp; msgnum++)
1798 if (!m_convert (mp, msgs[msgnum]))
1802 if ((md = mbx_open (file, getuid (), getgid (), m_gmprot ())) == NOTOK) {
1803 advise (file, "unable to open");
1806 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
1807 if (mp -> msgstats[msgnum] & SELECTED)
1808 if (pack (file, md, msgnum) == NOTOK)
1810 (void) mbx_close (file, md);
1812 if (mp -> hghsel != mp -> curmsg)
1813 m_setcur (mp, mp -> lowsel);
1821 int pack (mailbox, md, msgnum)
1828 if (Msgs[msgnum].m_bboard_id == 0)
1829 (void) readid (msgnum);
1831 zp = msh_ready (msgnum, 1);
1832 return mbx_write (mailbox, md, zp, Msgs[msgnum].m_bboard_id,
1833 0L, ftell (zp), Msgs[msgnum].m_stop, 1, 1);
1845 while (cp = *args++) {
1847 switch (smatch (++cp, packswit)) {
1854 if (!(file = *args++) || *file == '-')
1858 if (*cp == '+' || *cp == '@')
1862 file = path (file ? file : "./msgbox", TFILE);
1863 result = access (file, 0) == NOTOK ? OK : NOTOK;
1871 static struct swit pickswit[] = {
1890 "search pattern", 0,
1892 "subject pattern", 0,
1896 "-othercomponent pattern", 15,
1902 "datefield field", 5,
1942 while (cp = *args++) {
1948 switch (smatch (cp, pickswit)) {
1950 ambigsw (cp, pickswit);
1953 fprintf (stderr, "-%s unknown\n", cp);
1956 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
1957 help (buf, pickswit);
1971 if (!(cp = *args++)) {/* allow -xyz arguments */
1972 advise (NULLCP, "missing argument to %s", args[-2]);
1978 advise (NULLCP, "internal error!");
1989 if (!(cp = *args++) || *cp == '-') {
1990 advise (NULLCP, "missing argument to %s", args[-2]);
1996 advise (NULLCP, "only %d sequences allowed!", NATTRS);
2007 case PIPUSW: /* not implemented */
2014 if (*cp == '+' || *cp == '@') {
2015 advise (NULLCP, "sorry, no folders allowed!");
2024 msgs[msgp++] = "all";
2025 for (msgnum = 0; msgnum < msgp; msgnum++)
2026 if (!m_convert (mp, msgs[msgnum]))
2031 if (!pcompile (vec, NULLCP))
2037 for (msgnum = mp -> lowsel;
2038 msgnum <= mp -> hghsel && !interrupted;
2040 if (mp -> msgstats[msgnum] & SELECTED) {
2041 zp = msh_ready (msgnum, 1);
2042 if (pmatches (zp, msgnum, fmsh ? 0L : Msgs[msgnum].m_start,
2043 fmsh ? 0L : Msgs[msgnum].m_stop)) {
2050 mp -> msgstats[msgnum] &= ~SELECTED;
2061 if (mp -> numsel <= 0) {
2062 advise (NULLCP, "no messages match specification");
2067 for (seqp = 0; seqs[seqp]; seqp++) {
2068 if (zerosw && !m_seqnew (mp, seqs[seqp], 0))
2070 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
2071 if (mp -> msgstats[msgnum] & SELECTED)
2072 if (!m_seqadd (mp, seqs[seqp], msgnum, 0))
2076 printf ("%d hit%s\n", mp -> numsel, mp -> numsel == 1 ? "" : "s");
2081 static struct swit replswit[] = {
2091 "draftfolder +folder", 0,
2093 "draftmessage msg", 0,
2103 "filter filterfile", 0,
2115 "whatnowproc program", 0,
2138 forkcmd (args, cmd_name);
2142 while (cp = *args++) {
2144 switch (smatch (++cp, replswit)) {
2146 ambigsw (cp, replswit);
2149 fprintf (stderr, "-%s unknown\n", cp);
2152 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
2153 help (buf, replswit);
2156 case REANSW: /* not implemented */
2181 if (!(cp = *args++) || *cp == '-') {
2182 advise (NULLCP, "missing argument to %s", args[-2]);
2188 if (*cp == '+' || *cp == '@') {
2189 advise (NULLCP, "sorry, no folders allowed!");
2194 advise (NULLCP, "only one message at a time!");
2202 vec[vecp++] = "-file";
2206 if (!m_convert (mp, msg))
2210 if (mp -> numsel > 1) {
2211 advise (NULLCP, "only one message at a time!");
2214 (void) process (mp -> hghsel, cmd_name, vecp, vec);
2215 m_setcur (mp, mp -> hghsel);
2220 static struct swit rmmswit[] = {
2238 while (cp = *args++) {
2240 switch (smatch (++cp, rmmswit)) {
2242 ambigsw (cp, rmmswit);
2245 fprintf (stderr, "-%s unknown\n", cp);
2248 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
2249 help (buf, rmmswit);
2252 if (*cp == '+' || *cp == '@') {
2253 advise (NULLCP, "sorry, no folders allowed!");
2261 msgs[msgp++] = "cur";
2262 for (msgnum = 0; msgnum < msgp; msgnum++)
2263 if (!m_convert (mp, msgs[msgnum]))
2273 register int msgnum,
2276 char buffer[BUFSIZ],
2281 if (mp -> numsel > MAXARGS - 1) {
2282 advise (NULLCP, "more than %d messages for %s exec",
2283 MAXARGS - 1, rmmproc);
2287 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
2288 if (mp -> msgstats[msgnum] & SELECTED)
2289 vec[vecp++] = getcpy (m_name (msgnum));
2291 forkcmd (vec, rmmproc);
2292 for (vecp = 0; vec[vecp]; vecp++)
2296 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
2297 if (mp -> msgstats[msgnum] & SELECTED) {
2298 (void) strcpy (buffer, m_backup (cp = m_name (msgnum)));
2299 if (rename (cp, buffer) == NOTOK)
2300 admonish (buffer, "unable to rename %s to", cp);
2304 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
2305 if (mp -> msgstats[msgnum] & SELECTED) {
2306 mp -> msgstats[msgnum] |= DELETED;
2307 mp -> msgstats[msgnum] &= ~EXISTS;
2310 if (pmsh && pop_dele (msgnum) != OK)
2311 fprintf (stderr, "%s", response);
2316 if ((mp -> nummsg -= mp -> numsel) <= 0) {
2318 admonish (NULLCP, "no messages remaining in +%s", fmsh);
2320 admonish (NULLCP, "no messages remaining in %s", mp -> foldpath);
2321 mp -> lowmsg = mp -> hghmsg = mp -> nummsg = 0;
2323 if (mp -> lowsel == mp -> lowmsg) {
2324 for (msgnum = mp -> lowmsg + 1; msgnum <= mp -> hghmsg; msgnum++)
2325 if (mp -> msgstats[msgnum] & EXISTS)
2327 mp -> lowmsg = msgnum;
2329 if (mp -> hghsel == mp -> hghmsg) {
2330 for (msgnum = mp -> hghmsg - 1; msgnum >= mp -> lowmsg; msgnum--)
2331 if (mp -> msgstats[msgnum] & EXISTS)
2333 mp -> hghmsg = msgnum;
2336 mp -> msgflags |= MODIFIED;
2342 static struct swit scanswit[] = {
2348 "form formatfile", 0,
2368 #define equiv(a,b) (a ? b && !strcmp (a, b) : !b)
2386 static int p_optim = 0;
2389 static int s_optim = 0;
2390 static char *s_form = NULL,
2393 while (cp = *args++) {
2395 switch (smatch (++cp, scanswit)) {
2397 ambigsw (cp, scanswit);
2400 fprintf (stderr, "-%s unknown\n", cp);
2403 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
2404 help (buf, scanswit);
2420 if (!(form = *args++) || *form == '-') {
2421 advise (NULLCP, "missing argument to %s", args[-2]);
2427 if (!(format = *args++) || *format == '-') {
2428 advise (NULLCP, "missing argument to %s", args[-2]);
2434 if (!(cp = *args++) || *cp == '-') {
2435 advise (NULLCP, "missing argument to %s", args[-2]);
2441 if (*cp == '+' || *cp == '@') {
2442 advise (NULLCP, "sorry, no folders allowed!");
2450 msgs[msgp++] = "all";
2451 for (msgnum = 0; msgnum < msgp; msgnum++)
2452 if (!m_convert (mp, msgs[msgnum]))
2456 nfs = new_fs (form, format, FORMAT);
2457 if (scanl) { /* force scansbr to (re)compile format */
2458 (void) free (scanl);
2463 s_optim = optim = 1;
2464 s_form = form ? getcpy (form) : NULL;
2465 s_format = format ? getcpy (format) : NULL;
2476 width = sc_width ();
2478 for (dp = nfs, i = 0; *dp; dp++, i++)
2479 if (*dp == '\\' || *dp == '"' || *dp == '\n')
2482 if ((ep = malloc ((unsigned) i)) == NULL)
2483 adios (NULLCP, "out of memory");
2484 for (dp = nfs, fp = ep; *dp; dp++) {
2486 *fp++ = '\\', *fp++ = 'n';
2489 if (*dp == '"' || *dp == '\\')
2495 if (pop_command ("XTND SCAN %d \"%s\"", width, ep) == OK)
2504 optim = equiv (s_form, form) && equiv (s_format, format);
2508 if (p_optim && optim) {
2509 for (msgnum = mp -> lowmsg; msgnum <= mp -> hghmsg; msgnum++)
2510 if (!(mp -> msgstats[msgnum] & SELECTED) || Msgs[msgnum].m_scanl)
2512 if (msgnum > mp -> hghmsg && pop_command ("LIST") == OK) {
2513 fprintf (stderr, "Stand-by...");
2519 switch (pop_multiline ()) {
2521 fprintf (stderr, "%s", response);
2524 fprintf (stderr,"\n");
2528 if (sscanf (response, "%d %d", &msgnum, &size) == 2
2529 && mp -> lowmsg <= msgnum
2530 && msgnum <= mp -> hghmsg
2531 && (cp = index (response, '#'))
2533 Msgs[msgnum].m_scanl = concat (cp, "\n", NULLCP);
2544 for (msgnum = mp -> lowsel;
2545 msgnum <= mp -> hghsel && !interrupted;
2547 if (mp -> msgstats[msgnum] & SELECTED) {
2548 if (optim && Msgs[msgnum].m_scanl)
2549 printf ("%s", Msgs[msgnum].m_scanl);
2555 && (mp -> msgstats[msgnum] & VIRTUAL)
2556 && pop_command ("LIST %d", msgnum) == OK
2557 && (cp = index (response, '#'))
2559 Msgs[msgnum].m_scanl = concat (cp, "\n", NULLCP);
2560 printf ("%s", Msgs[msgnum].m_scanl);
2566 zp = msh_ready (msgnum, 0);
2567 switch (state = scan (zp, msgnum, 0, nfs, width,
2568 msgnum == mp -> curmsg,
2569 mp -> msgstats[msgnum] & UNSEEN, /* ?? */
2570 headersw, fmsh ? fmsh : mp -> foldpath,
2571 fmsh ? 0L : (long) (Msgs[msgnum].m_stop - Msgs[msgnum].m_start),
2577 Msgs[msgnum].m_scanl = getcpy (scanl);
2581 advise (NULLCP, "scan() botch (%d)", state);
2585 printf ("%*d empty\n", DMAXFOLDER, msgnum);
2598 static struct swit showswit[] = {
2604 "moreproc program", 4,
2612 "showproc program", 4,
2645 if (uleq (cmd_name, "next"))
2648 if (uleq (cmd_name, "prev"))
2650 while (cp = *args++) {
2652 switch (i = smatch (++cp, showswit)) {
2654 ambigsw (cp, showswit);
2661 (void) sprintf (buf,
2662 "%s %s[switches] [switches for showproc]",
2663 cmd_name, mode ? NULL : "[msgs] ");
2664 help (buf, showswit);
2672 if (!(cp = *args++) || *cp == '-') {
2673 advise (NULLCP, "missing argument to %s", args[-2]);
2685 if (!(proc = *args++) || *proc == '-') {
2686 advise (NULLCP, "missing argument to %s", args[-2]);
2696 advise (NULLCP, "sorry, -%s not allowed!", showswit[i].sw);
2699 if (*cp == '+' || *cp == '@') {
2700 advise (NULLCP, "sorry, no folders allowed!");
2706 "usage: %s [switches] [switches for showproc]\n",
2716 msgs[msgp++] = mode > 0 ? "next" : mode < 0 ? "prev" : "cur";
2717 for (msgnum = 0; msgnum < msgp; msgnum++)
2718 if (!m_convert (mp, msgs[msgnum]))
2723 if (!nshow && !getenv ("NOMHNPROC"))
2724 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
2725 if ((mp -> msgstats[msgnum] & SELECTED) && nontext (msgnum)) {
2726 proc = (cp = m_find ("mhnproc")) ? cp : "mhn";
2727 vec[vecp++] = "-show";
2728 vec[vecp++] = "-file";
2737 if (strcmp (showproc, "mhl") == 0) {
2743 seen = m_seqflag (mp, "unseen");
2744 vec[0] = r1bindex (proc, '/');
2747 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++)
2748 if (mp -> msgstats[msgnum] & SELECTED) {
2749 vec[vecp++] = getcpy (m_name (msgnum));
2751 (void) m_seqdel (mp, "unseen", msgnum);
2754 if (mp -> numsel == 1 && headersw)
2755 show (mp -> lowsel);
2756 (void) mhlsbr (vecp, vec, mhl_action);
2757 m_eomsbr ((int (*)()) 0);
2763 for (msgnum = mp -> lowsel;
2764 msgnum <= mp -> hghsel && !interrupted;
2766 if (mp -> msgstats[msgnum] & SELECTED) {
2767 switch (ask (msgnum)) {
2768 case NOTOK: /* QUIT */
2775 if (mp -> numsel == 1 && headersw)
2778 copy_message (msgnum, stdout);
2780 (void) process (msgnum, proc, vecp, vec);
2783 (void) m_seqdel (mp, "unseen", msgnum);
2790 m_setcur (mp, mp -> hghsel);
2795 static show (msgnum)
2798 if (Msgs[msgnum].m_bboard_id == 0)
2799 (void) readid (msgnum);
2801 printf ("(Message %d", msgnum);
2802 if (Msgs[msgnum].m_bboard_id > 0)
2803 printf (", %s: %d", BBoard_ID, Msgs[msgnum].m_bboard_id);
2810 static int eom_action (c)
2813 return (ftell (mhlfp) >= Msgs[mhlnum].m_stop);
2817 static FP mhl_action (name)
2822 if ((msgnum = m_atoi (name)) < mp -> lowmsg
2823 || msgnum > mp -> hghmsg
2824 || !(mp -> msgstats[msgnum] & EXISTS))
2828 mhlfp = msh_ready (msgnum, 1);
2830 m_eomsbr (eom_action);
2843 if (mp -> numsel == 1 || !interactive || redirected)
2846 if (SOprintf ("Press <return> to list \"%d\"...", msgnum)) {
2847 if (mp -> lowsel != msgnum)
2849 printf ("Press <return> to list \"%d\"...", msgnum);
2851 (void) fflush (stdout);
2854 (void) read (fileno (stdout), buf, sizeof buf);
2856 switch (setjmp (sigenv)) {
2859 (void) read (fileno (stdout), buf, sizeof buf);/* fall... */
2866 if (index (buf, '\n') == NULL)
2867 (void) putchar ('\n');
2870 told_to_quit = interrupted = 0;
2884 #include "../h/mhn.h"
2887 static int nontext (msgnum)
2900 if (Msgs[msgnum].m_flags & MHNCHK)
2901 return (Msgs[msgnum].m_flags & MHNYES);
2902 Msgs[msgnum].m_flags |= MHNCHK;
2904 fp = msh_ready (msgnum, 1);
2906 if (!(chset = getenv ("MM_CHARSET")))
2910 switch (state = m_getfld (state, name, buf, sizeof buf, fp)) {
2914 if (uleq (name, TYPE_FIELD)) {
2918 cp = add (buf, NULLCP);
2919 while (state == FLDPLUS) {
2920 state = m_getfld (state, name, buf, sizeof buf, fp);
2927 for (; isspace (*bp); bp++)
2932 for (bp++, i = 0;;) {
2962 for (dp = bp; istoken (*dp); dp++)
2964 c = *dp, *dp = NULL;
2968 if (result = !uleq (bp, "plain"))
2971 for (dp++; isspace (*dp); dp++)
2973 if (result = !uprf (dp, "charset"))
2975 dp += sizeof "charset" - 1;
2976 while (isspace (*dp))
2980 while (isspace (*dp))
2983 if (bp = index (++dp, '"'))
2987 for (bp = dp; *bp; bp++)
2988 if (isspace (*bp)) {
2992 if ((result = !uleq (dp, chset))
2993 && uleq (dp, "us-ascii")
2994 && uleq (chset, "iso-8859-1"))
2998 if (!(result = !uleq (bp, "text"))) {
3009 Msgs[msgnum].m_flags |= MHNYES;
3014 if (uleq (name, ENCODING_FIELD)) {
3015 cp = add (buf, NULLCP);
3016 while (state == FLDPLUS) {
3017 state = m_getfld (state, name, buf, sizeof buf, fp);
3020 for (bp = cp; isspace (*bp); bp++)
3022 for (dp = bp; istoken (*dp); dp++)
3025 result = !uleq (bp, "7bit")
3026 && !uleq (bp, "8bit")
3027 && !uleq (bp, "binary");
3031 Msgs[msgnum].m_flags |= MHNYES;
3036 while (state == FLDPLUS)
3037 state = m_getfld (state, name, buf, sizeof buf, fp);
3048 static struct swit sortswit[] = {
3050 "datefield field", 0,
3052 "textfield field", 0,
3085 forkcmd (args, cmd_name);
3089 while (cp = *args++) {
3091 switch (smatch (++cp, sortswit)) {
3093 ambigsw (cp, sortswit);
3096 fprintf (stderr, "-%s unknown\n", cp);
3099 (void) sprintf (buf, "%s [msgs] [switches]", cmd_name);
3100 help (buf, sortswit);
3105 advise (NULLCP, "only one date field at a time!");
3108 if (!(datesw = *args++) || *datesw == '-') {
3109 advise (NULLCP, "missing argument to %s", args[-2]);
3116 advise (NULLCP, "only one text field at a time!");
3119 if (!(subjsw = *args++) || *subjsw == '-') {
3120 advise (NULLCP, "missing argument to %s", args[-2]);
3128 case SOLIMT: /* too hard */
3129 if (!(cp = *args++) || *cp == '-') {
3130 advise (NULLCP, "missing argument to %s", args[-2]);
3134 case SOVERB: /* not implemented */
3138 if (*cp == '+' || *cp == '@') {
3139 advise (NULLCP, "sorry, no folders allowed!");
3147 msgs[msgp++] = "all";
3150 for (msgnum = 0; msgnum < msgp; msgnum++)
3151 if (!m_convert (mp, msgs[msgnum]))
3155 twscopy (&tb, dtwstime ());
3157 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) {
3158 if (Msgs[msgnum].m_scanl) {
3159 free (Msgs[msgnum].m_scanl);
3160 Msgs[msgnum].m_scanl = NULL;
3162 if (mp -> msgstats[msgnum] & SELECTED) {
3163 if (getws (datesw, subjsw, msgnum, &Msgs[msgnum]))
3164 twscopy (&Msgs[msgnum].m_tb,
3165 msgnum != mp -> lowsel ? &Msgs[msgnum - 1].m_tb : &tb);
3167 else /* m_scaln is already NULL */
3168 twscopy (&Msgs[msgnum].m_tb, &tb);
3169 Msgs[msgnum].m_stats = mp -> msgstats[msgnum];
3170 if (mp -> curmsg == msgnum)
3171 Msgs[msgnum].m_stats |= CUR;
3174 qsort ((char *) &Msgs[mp -> lowsel], mp -> hghsel - mp -> lowsel + 1,
3175 sizeof (struct Msg),
3176 subjsw ? subsort : msgsort);
3178 for (msgnum = mp -> lowsel; msgnum <= mp -> hghsel; msgnum++) {
3179 if (subjsw && Msgs[msgnum].m_scanl) {
3180 free (Msgs[msgnum].m_scanl); /* from subjsort */
3181 Msgs[msgnum].m_scanl = NULL;
3183 mp -> msgstats[msgnum] = Msgs[msgnum].m_stats & ~CUR;
3184 if (Msgs[msgnum].m_stats & CUR)
3185 m_setcur (mp, msgnum);
3188 mp -> msgflags |= MODIFIED;
3195 * getws - parse message, and get date and subject if needed. We'll use
3196 * the msgp->m_tb tws struct for the date, and overload the msgp->m_scanl
3197 * field with our subject string.
3199 static int getws (datesw, subjsw, msgnum, msgp)
3210 struct tws *tw = (struct tws *)0;
3213 zp = msh_ready (msgnum, 0);
3214 for (state = FLD;;) {
3215 switch (state = m_getfld (state, name, buf, sizeof buf, zp)) {
3219 if (uleq (name, datesw)) {
3221 while (state == FLDPLUS) {
3222 state = m_getfld (state, name, buf, sizeof buf, zp);
3225 if ((tw = dparsetime (bp)) == NULL)
3227 "unable to parse %s field in message %d",
3230 twscopy (&(msgp->m_tb), tw);
3232 if (!subjsw) /* not using this, or already done */
3233 break; /* all done! */
3236 else if (subjsw && uleq(name, subjsw)) {
3238 while (state == FLDPLUS) {
3239 state = m_getfld (state, name, buf, sizeof buf, zp);
3242 msgp->m_scanl = sosmash(subjsw, bp);
3244 break; /* date done so we're done */
3246 subjsw = (char *)0;/* subject done, need date */
3248 while (state == FLDPLUS) /* flush this one */
3249 state = m_getfld (state, name, buf, sizeof buf, zp);
3260 admonish (NULLCP, "format error in message %d", msgnum);
3261 if (msgp->m_scanl) { /* this might need free'd */
3262 free (msgp->m_scanl); /* probably can't use subj anyway */
3263 msgp->m_scanl = NULL;
3268 adios (NULLCP, "internal error -- you lose");
3273 return OK; /* not an error if subj not found */
3275 admonish (NULLCP, "no %s field in message %d", datesw, msgnum);
3276 return NOTOK; /* NOTOK means use some other date */
3281 static int msgsort (a, b)
3285 return twsort (&a -> m_tb, &b -> m_tb);
3288 static int subsort (a, b)
3294 if (a->m_scanl && b->m_scanl)
3295 if (i = strcmp (a->m_scanl, b->m_scanl))
3298 return twsort (&a -> m_tb, &b -> m_tb);
3302 * try to make the subject "canonical": delete leading "re:", everything
3303 * but letters & smash letters to lower case.
3315 dp = s; /* dst pointer */
3316 if (uleq (subj, "subject"))
3323 *dp++ = isupper(c) ? tolower(c) : c;
3331 *dp++ = isupper(c) ? tolower(c) : c;
3341 static int process (msgnum, proc, vecp, vec)
3353 (void) strcpy (tmpfil, m_name (msgnum));
3354 (void) m_delete (pfolder);
3355 m_replace (pfolder, fmsh);
3361 (void) strcpy (tmpfil, m_scratch ("", invo_name));
3362 if ((out = fopen (tmpfil, "w")) == NULL) {
3368 (void) strcpy (newfil, m_tmpfil (invo_name));
3369 if ((out = fopen (newfil, "w")) == NULL) {
3371 advise (tmpfil, "unable to create temporary file");
3375 (void) strcpy (tmpfil, newfil);
3377 copy_message (msgnum, out);
3378 (void) fclose (out);
3381 (void) fflush (stdout);
3382 switch (child_id = fork ()) {
3384 advise ("fork", "unable to");
3390 (void) signal (SIGINT, istat);
3391 (void) signal (SIGQUIT, qstat);
3393 vec[vecp++] = tmpfil;
3397 fprintf (stderr, "unable to exec ");
3402 status = pidXwait (child_id, NULLCP);
3407 (void) unlink (tmpfil);
3413 static copy_message (msgnum, out)
3418 static char buffer[BUFSIZ];
3421 zp = msh_ready (msgnum, 1);
3423 while (fgets (buffer, sizeof buffer, zp) != NULL) {
3424 fputs (buffer, out);
3425 if (interrupted && out == stdout)
3431 while (fgets (buffer, sizeof buffer, zp) != NULL
3432 && pos < Msgs[msgnum].m_stop) {
3433 fputs (buffer, out);
3434 pos += (long) strlen (buffer);
3435 if (interrupted && out == stdout)
3442 static copy_digest (msgnum, out)
3448 static char buffer[BUFSIZ];
3452 zp = msh_ready (msgnum, 1);
3455 while (fgets (buffer, sizeof buffer, zp) != NULL
3456 && !fmsh && pos < Msgs[msgnum].m_stop) {
3457 if (c == '\n' && *buffer == '-')
3458 (void) fputc (' ', out);
3459 fputs (buffer, out);
3460 c = buffer[strlen (buffer) - 1];
3462 pos += (long) strlen (buffer);
3463 if (interrupted && out == stdout)