mhn: compatibility fixes in show mode.
* mh/mhn.c (OPT_PAUSE): Remove define. (pause_option): New variable. (opt_handler): -pause/-nopause sets pause_option. If stdin is not a tty, set pause_option to 0. (check_type): New function. (mhn_show_command): If mhn-show-<type>[/<subtype>] is not set, use %pmoreproc '%F' for text/plain and message/rfc822 parts. If content type is application/octet-stream and type=tar, use tar to list the archive. Otherwise, complain and return NULL. (MHN_CONFIRM): Rename to MHN_PAUSE. (mhn_pause): New function. (show_handler): The value of pause_option controls the %p escape. Rewrite the MHN_PAUSE handling to avoid the use of the fixed-size buffer. Implement C-c handling, as in other mhns. If mhn_show_command returns NULL, do not attempt to show the content. Remove dubious usage of mu_transport_t. (mhn_store_command): handle application/octet-stream with type=tar. * mh/tests/mhn.at: Add a test for show mode.
Showing
3 changed files
with
221 additions
and
86 deletions
... | @@ -27,7 +27,7 @@ State Nice Utility Comments | ... | @@ -27,7 +27,7 @@ State Nice Utility Comments |
27 | * -20 refile --link copies messages | 27 | * -20 refile --link copies messages |
28 | + -20 rmm | 28 | + -20 rmm |
29 | + -15 folder(s) | 29 | + -15 folder(s) |
30 | + -15 mhn | 30 | * -15 mhn -[rw]?cache, -type |
31 | + -10 rmf | 31 | + -10 rmf |
32 | + 0 install-mh | 32 | + 0 install-mh |
33 | * 4 mhl Following format variables are ignored: | 33 | * 4 mhl Following format variables are ignored: | ... | ... |
... | @@ -23,6 +23,7 @@ | ... | @@ -23,6 +23,7 @@ |
23 | #define obstack_chunk_alloc xmalloc | 23 | #define obstack_chunk_alloc xmalloc |
24 | #define obstack_chunk_free free | 24 | #define obstack_chunk_free free |
25 | #include <obstack.h> | 25 | #include <obstack.h> |
26 | #include <setjmp.h> | ||
26 | 27 | ||
27 | static char doc[] = N_("GNU MH mhn")"\v" | 28 | static char doc[] = N_("GNU MH mhn")"\v" |
28 | N_("Options marked with `*' are not yet implemented.\n\ | 29 | N_("Options marked with `*' are not yet implemented.\n\ |
... | @@ -141,13 +142,13 @@ static enum mhn_mode mode = mode_compose; | ... | @@ -141,13 +142,13 @@ static enum mhn_mode mode = mode_compose; |
141 | 142 | ||
142 | #define OPT_HEADERS 001 | 143 | #define OPT_HEADERS 001 |
143 | #define OPT_REALSIZE 002 | 144 | #define OPT_REALSIZE 002 |
144 | #define OPT_PAUSE 004 | 145 | #define OPT_AUTO 004 |
145 | #define OPT_AUTO 010 | 146 | #define OPT_SERIALONLY 010 |
146 | #define OPT_SERIALONLY 020 | 147 | #define OPT_VERBOSE 020 |
147 | #define OPT_VERBOSE 040 | 148 | #define OPT_QUIET 040 |
148 | #define OPT_QUIET 100 | ||
149 | 149 | ||
150 | static int mode_options = OPT_HEADERS; | 150 | static int mode_options = OPT_HEADERS; |
151 | static int pause_option = -1; /* -pause option. -1 means "not given" */ | ||
151 | static char *formfile; | 152 | static char *formfile; |
152 | static char *content_type; | 153 | static char *content_type; |
153 | static char *content_subtype; | 154 | static char *content_subtype; |
... | @@ -165,7 +166,7 @@ static msg_part_t req_part; | ... | @@ -165,7 +166,7 @@ static msg_part_t req_part; |
165 | #define MHN_EXCLUSIVE_EXEC 001 | 166 | #define MHN_EXCLUSIVE_EXEC 001 |
166 | #define MHN_STDIN 002 | 167 | #define MHN_STDIN 002 |
167 | #define MHN_LISTING 004 | 168 | #define MHN_LISTING 004 |
168 | #define MHN_CONFIRM 010 | 169 | #define MHN_PAUSE 010 |
169 | 170 | ||
170 | void | 171 | void |
171 | sfree (char **ptr) | 172 | sfree (char **ptr) |
... | @@ -199,6 +200,30 @@ split_content (const char *content, char **type, char **subtype) | ... | @@ -199,6 +200,30 @@ split_content (const char *content, char **type, char **subtype) |
199 | } | 200 | } |
200 | } | 201 | } |
201 | 202 | ||
203 | static void | ||
204 | split_args (const char *argstr, size_t len, int *pargc, char ***pargv) | ||
205 | { | ||
206 | struct mu_wordsplit ws; | ||
207 | |||
208 | ws.ws_delim = ";"; | ||
209 | if (mu_wordsplit_len (argstr, len, &ws, | ||
210 | MU_WRDSF_DEFFLAGS | MU_WRDSF_DELIM | MU_WRDSF_WS)) | ||
211 | { | ||
212 | mu_error (_("cannot split line `%s': %s"), argstr, | ||
213 | mu_wordsplit_strerror (&ws)); | ||
214 | *pargc = 0; | ||
215 | *pargv = NULL; | ||
216 | } | ||
217 | else | ||
218 | { | ||
219 | *pargc = ws.ws_wordc; | ||
220 | *pargv = ws.ws_wordv; | ||
221 | ws.ws_wordc = 0; | ||
222 | ws.ws_wordv = NULL; | ||
223 | mu_wordsplit_free (&ws); | ||
224 | } | ||
225 | } | ||
226 | |||
202 | int | 227 | int |
203 | _get_content_type (mu_header_t hdr, char **value, char **rest) | 228 | _get_content_type (mu_header_t hdr, char **value, char **rest) |
204 | { | 229 | { |
... | @@ -340,14 +365,11 @@ opt_handler (int key, char *arg, struct argp_state *state) | ... | @@ -340,14 +365,11 @@ opt_handler (int key, char *arg, struct argp_state *state) |
340 | break; | 365 | break; |
341 | 366 | ||
342 | case ARG_PAUSE: | 367 | case ARG_PAUSE: |
343 | if (is_true (arg)) | 368 | pause_option = is_true (arg); |
344 | { | ||
345 | mode_options |= OPT_PAUSE; | ||
346 | break; | 369 | break; |
347 | } | 370 | |
348 | /*FALLTHRU*/ | ||
349 | case ARG_NOPAUSE: | 371 | case ARG_NOPAUSE: |
350 | mode_options &= ~OPT_PAUSE; | 372 | pause_option = 0; |
351 | break; | 373 | break; |
352 | 374 | ||
353 | /* Store options */ | 375 | /* Store options */ |
... | @@ -399,6 +421,8 @@ opt_handler (int key, char *arg, struct argp_state *state) | ... | @@ -399,6 +421,8 @@ opt_handler (int key, char *arg, struct argp_state *state) |
399 | case ARGP_KEY_FINI: | 421 | case ARGP_KEY_FINI: |
400 | if (!formfile) | 422 | if (!formfile) |
401 | mh_find_file ("mhl.headers", &formfile); | 423 | mh_find_file ("mhl.headers", &formfile); |
424 | if (!isatty (0)) | ||
425 | pause_option = 0; | ||
402 | break; | 426 | break; |
403 | 427 | ||
404 | default: | 428 | default: |
... | @@ -695,6 +719,32 @@ mhn_tempfile_name (char **tempfile, const char *type, const char *subtype) | ... | @@ -695,6 +719,32 @@ mhn_tempfile_name (char **tempfile, const char *type, const char *subtype) |
695 | } | 719 | } |
696 | } | 720 | } |
697 | 721 | ||
722 | static int | ||
723 | check_type (const char *typeargs, const char *typeval) | ||
724 | { | ||
725 | int rc = 1; | ||
726 | |||
727 | if (typeargs) | ||
728 | { | ||
729 | int i, argc; | ||
730 | char **argv; | ||
731 | |||
732 | split_args (typeargs, strlen (typeargs), &argc, &argv); | ||
733 | for (i = 0; i < argc; i++) | ||
734 | { | ||
735 | if (strlen (argv[i]) > 5 | ||
736 | && memcmp (argv[i], "type=", 5) == 0 | ||
737 | && mu_c_strcasecmp (argv[i] + 5, typeval) == 0) | ||
738 | { | ||
739 | rc = 0; | ||
740 | break; | ||
741 | } | ||
742 | } | ||
743 | mu_argcv_free (argc, argv); | ||
744 | } | ||
745 | return rc; | ||
746 | } | ||
747 | |||
698 | char * | 748 | char * |
699 | mhn_show_command (mu_message_t msg, msg_part_t part, int *flags, | 749 | mhn_show_command (mu_message_t msg, msg_part_t part, int *flags, |
700 | char **tempfile) | 750 | char **tempfile) |
... | @@ -703,13 +753,51 @@ mhn_show_command (mu_message_t msg, msg_part_t part, int *flags, | ... | @@ -703,13 +753,51 @@ mhn_show_command (mu_message_t msg, msg_part_t part, int *flags, |
703 | char *typestr, *type, *subtype, *typeargs; | 753 | char *typestr, *type, *subtype, *typeargs; |
704 | struct obstack stk; | 754 | struct obstack stk; |
705 | mu_header_t hdr; | 755 | mu_header_t hdr; |
756 | char *temp_cmd = NULL; | ||
706 | 757 | ||
707 | mu_message_get_header (msg, &hdr); | 758 | mu_message_get_header (msg, &hdr); |
708 | _get_content_type (hdr, &typestr, &typeargs); | 759 | _get_content_type (hdr, &typestr, &typeargs); |
709 | split_content (typestr, &type, &subtype); | 760 | split_content (typestr, &type, &subtype); |
710 | str = _mhn_profile_get ("show", type, subtype, NULL); | 761 | str = _mhn_profile_get ("show", type, subtype, NULL); |
711 | if (!str) /* FIXME */ | 762 | if (!str) |
763 | { | ||
764 | if (mu_c_strcasecmp (typestr, "text/plain") == 0 | ||
765 | /* FIXME: The following one should produce | ||
766 | %pshow -file '%F' */ | ||
767 | || mu_c_strcasecmp (typestr, "message/rfc822") == 0) | ||
768 | { | ||
769 | int rc; | ||
770 | const char *moreproc = mh_global_profile_get ("moreproc", | ||
771 | getenv ("PAGER")); | ||
772 | if (!moreproc) | ||
773 | return NULL; | ||
774 | rc = mu_asprintf (&temp_cmd, "%%p%s '%%F'", moreproc); | ||
775 | if (rc) | ||
776 | { | ||
777 | mu_diag_funcall (MU_DIAG_ERROR, "mu_asprintf", NULL, rc); | ||
778 | return NULL; | ||
779 | } | ||
780 | str = temp_cmd; | ||
781 | } | ||
782 | else if (mu_c_strcasecmp (typestr, "application/octet-stream") == 0 && | ||
783 | check_type (typeargs, "tar") == 0) | ||
784 | /* Use temporary file to get tar a chance to select appropriate | ||
785 | decompressor, if the archive is compressed. */ | ||
786 | str = "tar tvf '%F'"; | ||
787 | else | ||
788 | { | ||
789 | char *parts = msg_part_format (part); | ||
790 | |||
791 | /* FIXME: This message should in fact occupy two lines (exactly | ||
792 | as split below), but mu_error malfunctions if a \n appears | ||
793 | within the format string */ | ||
794 | mu_error (_("don't know how to display content" | ||
795 | " (content %s in message %lu, part %s)"), | ||
796 | typestr, (unsigned long)part->part[0], parts); | ||
797 | free (parts); | ||
712 | return NULL; | 798 | return NULL; |
799 | } | ||
800 | } | ||
713 | 801 | ||
714 | /* Expand macro-notations: | 802 | /* Expand macro-notations: |
715 | %a additional arguments | 803 | %a additional arguments |
... | @@ -765,7 +853,7 @@ mhn_show_command (mu_message_t msg, msg_part_t part, int *flags, | ... | @@ -765,7 +853,7 @@ mhn_show_command (mu_message_t msg, msg_part_t part, int *flags, |
765 | 853 | ||
766 | case 'p': | 854 | case 'p': |
767 | /* %l, and ask for confirmation */ | 855 | /* %l, and ask for confirmation */ |
768 | *flags |= MHN_LISTING|MHN_CONFIRM; | 856 | *flags |= MHN_LISTING|MHN_PAUSE; |
769 | break; | 857 | break; |
770 | 858 | ||
771 | case 's': | 859 | case 's': |
... | @@ -793,6 +881,7 @@ mhn_show_command (mu_message_t msg, msg_part_t part, int *flags, | ... | @@ -793,6 +881,7 @@ mhn_show_command (mu_message_t msg, msg_part_t part, int *flags, |
793 | free (typestr); | 881 | free (typestr); |
794 | free (type); | 882 | free (type); |
795 | free (subtype); | 883 | free (subtype); |
884 | free (temp_cmd); | ||
796 | 885 | ||
797 | str = obstack_finish (&stk); | 886 | str = obstack_finish (&stk); |
798 | p = mu_str_skip_class (str, MU_CTYPE_SPACE); | 887 | p = mu_str_skip_class (str, MU_CTYPE_SPACE); |
... | @@ -831,12 +920,6 @@ mhn_store_command (mu_message_t msg, msg_part_t part, const char *name, | ... | @@ -831,12 +920,6 @@ mhn_store_command (mu_message_t msg, msg_part_t part, const char *name, |
831 | 920 | ||
832 | if (!str) | 921 | if (!str) |
833 | { | 922 | { |
834 | /* FIXME: | ||
835 | [If the mhn-store component] isn't found, mhn will check to see if | ||
836 | the content is application/octet-stream with parameter "type=tar". | ||
837 | If so, mhn will choose an appropriate filename. | ||
838 | */ | ||
839 | |||
840 | if (mu_c_strcasecmp (type, "message") == 0) | 923 | if (mu_c_strcasecmp (type, "message") == 0) |
841 | { | 924 | { |
842 | /* If the content is not application/octet-stream, then mhn | 925 | /* If the content is not application/octet-stream, then mhn |
... | @@ -845,6 +928,12 @@ mhn_store_command (mu_message_t msg, msg_part_t part, const char *name, | ... | @@ -845,6 +928,12 @@ mhn_store_command (mu_message_t msg, msg_part_t part, const char *name, |
845 | *return_string = xstrdup (mh_current_folder ()); | 928 | *return_string = xstrdup (mh_current_folder ()); |
846 | return store_to_folder_msg; | 929 | return store_to_folder_msg; |
847 | } | 930 | } |
931 | else if (mu_c_strcasecmp (typestr, "application/octet-stream") == 0 && | ||
932 | check_type (typeargs, "tar") == 0) | ||
933 | /* [If the mhn-store component] isn't found, mhn will check to see if | ||
934 | the content is application/octet-stream with parameter "type=tar". | ||
935 | If so, mhn will choose an appropriate filename. */ | ||
936 | str = "%m%P.tar"; | ||
848 | else | 937 | else |
849 | str = "%m%P.%s"; | 938 | str = "%m%P.%s"; |
850 | } | 939 | } |
... | @@ -948,30 +1037,6 @@ mhn_store_command (mu_message_t msg, msg_part_t part, const char *name, | ... | @@ -948,30 +1037,6 @@ mhn_store_command (mu_message_t msg, msg_part_t part, const char *name, |
948 | 1037 | ||
949 | /* ************************* Auxiliary functions ************************** */ | 1038 | /* ************************* Auxiliary functions ************************** */ |
950 | 1039 | ||
951 | static void | ||
952 | split_args (const char *argstr, size_t len, int *pargc, char ***pargv) | ||
953 | { | ||
954 | struct mu_wordsplit ws; | ||
955 | |||
956 | ws.ws_delim = ";"; | ||
957 | if (mu_wordsplit_len (argstr, len, &ws, | ||
958 | MU_WRDSF_DEFFLAGS | MU_WRDSF_DELIM | MU_WRDSF_WS)) | ||
959 | { | ||
960 | mu_error (_("cannot split line `%s': %s"), argstr, | ||
961 | mu_wordsplit_strerror (&ws)); | ||
962 | *pargc = 0; | ||
963 | *pargv = NULL; | ||
964 | } | ||
965 | else | ||
966 | { | ||
967 | *pargc = ws.ws_wordc; | ||
968 | *pargv = ws.ws_wordv; | ||
969 | ws.ws_wordc = 0; | ||
970 | ws.ws_wordv = NULL; | ||
971 | mu_wordsplit_free (&ws); | ||
972 | } | ||
973 | } | ||
974 | |||
975 | int | 1040 | int |
976 | _message_is_external_body (mu_message_t msg, char ***env) | 1041 | _message_is_external_body (mu_message_t msg, char ***env) |
977 | { | 1042 | { |
... | @@ -1310,7 +1375,8 @@ mhn_list () | ... | @@ -1310,7 +1375,8 @@ mhn_list () |
1310 | static mu_list_t mhl_format; | 1375 | static mu_list_t mhl_format; |
1311 | 1376 | ||
1312 | int | 1377 | int |
1313 | show_internal (mu_message_t msg, msg_part_t part, char *encoding, mu_stream_t out) | 1378 | show_internal (mu_message_t msg, msg_part_t part, char *encoding, |
1379 | mu_stream_t out) | ||
1314 | { | 1380 | { |
1315 | int rc; | 1381 | int rc; |
1316 | mu_body_t body = NULL; | 1382 | mu_body_t body = NULL; |
... | @@ -1407,6 +1473,41 @@ mhn_run_command (mu_message_t msg, msg_part_t part, | ... | @@ -1407,6 +1473,41 @@ mhn_run_command (mu_message_t msg, msg_part_t part, |
1407 | return rc; | 1473 | return rc; |
1408 | } | 1474 | } |
1409 | 1475 | ||
1476 | static RETSIGTYPE | ||
1477 | sigint (int sig) | ||
1478 | { | ||
1479 | /* nothing */ | ||
1480 | } | ||
1481 | |||
1482 | static int | ||
1483 | mhn_pause () | ||
1484 | { | ||
1485 | int c; | ||
1486 | int rc = 0; | ||
1487 | RETSIGTYPE (*saved_sig) (int) = signal (SIGINT, sigint); | ||
1488 | printf (_("Press <return> to show content...")); | ||
1489 | fflush (stdout); | ||
1490 | do | ||
1491 | { | ||
1492 | fd_set set; | ||
1493 | int res; | ||
1494 | |||
1495 | FD_ZERO (&set); | ||
1496 | FD_SET (0, &set); | ||
1497 | res = select (1, &set, NULL, NULL, NULL); | ||
1498 | if (res != 1 | ||
1499 | || read (0, &c, 1) != 1) | ||
1500 | { | ||
1501 | putchar ('\n'); | ||
1502 | rc = 1; | ||
1503 | break; | ||
1504 | } | ||
1505 | } | ||
1506 | while (c != '\n'); | ||
1507 | signal (SIGINT, saved_sig); | ||
1508 | return rc; | ||
1509 | } | ||
1510 | |||
1410 | int | 1511 | int |
1411 | show_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding, | 1512 | show_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding, |
1412 | void *data) | 1513 | void *data) |
... | @@ -1414,65 +1515,45 @@ show_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding, | ... | @@ -1414,65 +1515,45 @@ show_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding, |
1414 | mu_stream_t out = data; | 1515 | mu_stream_t out = data; |
1415 | char *cmd; | 1516 | char *cmd; |
1416 | int flags = 0; | 1517 | int flags = 0; |
1417 | int fd = 1; | ||
1418 | char *tempfile = NULL; | 1518 | char *tempfile = NULL; |
1419 | int ismime; | 1519 | int ismime; |
1420 | mu_transport_t trans[2]; | ||
1421 | 1520 | ||
1422 | if (mu_message_is_multipart (msg, &ismime) == 0 && ismime) | 1521 | if (mu_message_is_multipart (msg, &ismime) == 0 && ismime) |
1423 | return 0; | 1522 | return 0; |
1424 | 1523 | ||
1425 | mu_stream_ioctl (out, MU_IOCTL_GET_TRANSPORT, trans); | ||
1426 | fd = (int) trans[0]; /* FIXME */ | ||
1427 | |||
1428 | if (mode_options & OPT_PAUSE) | ||
1429 | flags |= MHN_CONFIRM; | ||
1430 | cmd = mhn_show_command (msg, part, &flags, &tempfile); | 1524 | cmd = mhn_show_command (msg, part, &flags, &tempfile); |
1431 | if (!cmd) | 1525 | if (!cmd) |
1432 | flags |= MHN_LISTING; | 1526 | return 0; |
1527 | if (pause_option == 0) | ||
1528 | flags &= ~MHN_PAUSE; | ||
1529 | else if (pause_option > 0) | ||
1530 | flags |= MHN_PAUSE; | ||
1531 | |||
1433 | if (flags & MHN_LISTING) | 1532 | if (flags & MHN_LISTING) |
1434 | { | 1533 | { |
1435 | char *str; | 1534 | mu_header_t hdr = NULL; |
1436 | const char *p; | 1535 | char *parts; |
1536 | const char *descr; | ||
1437 | mu_off_t size = 0; | 1537 | mu_off_t size = 0; |
1438 | 1538 | ||
1439 | str = (char*) _("part "); | ||
1440 | mu_stream_write (out, str, strlen (str), NULL); | ||
1441 | str = msg_part_format (part); | ||
1442 | mu_stream_write (out, str, strlen (str), NULL); | ||
1443 | free (str); | ||
1444 | mu_stream_write (out, " ", 1, NULL); | ||
1445 | mu_stream_write (out, type, strlen (type), NULL); | ||
1446 | mhn_message_size (msg, &size); | 1539 | mhn_message_size (msg, &size); |
1447 | p = mu_umaxtostr (0, size); | 1540 | parts = msg_part_format (part); |
1448 | mu_stream_write (out, p, strlen (p), NULL); | 1541 | mu_stream_printf (out, _("part %5s %-24.24s %lu"), parts, type, |
1542 | (unsigned long) size); | ||
1543 | free (parts); | ||
1544 | if (mu_message_get_header (msg, &hdr) == 0 && | ||
1545 | mu_header_sget_value (hdr, MU_HEADER_CONTENT_DESCRIPTION, | ||
1546 | &descr) == 0) | ||
1547 | mu_stream_printf (out, " %s", descr); | ||
1449 | mu_stream_write (out, "\n", 1, NULL); | 1548 | mu_stream_write (out, "\n", 1, NULL); |
1450 | mu_stream_flush (out); | 1549 | mu_stream_flush (out); |
1451 | } | 1550 | } |
1452 | 1551 | ||
1453 | if (flags & MHN_CONFIRM) | 1552 | if (!((flags & MHN_PAUSE) && mhn_pause ())) |
1454 | { | ||
1455 | if (isatty (fd) && isatty (0)) | ||
1456 | { | ||
1457 | char buf[64]; | ||
1458 | printf (_("Press <return> to show content...")); | ||
1459 | if (!fgets (buf, sizeof buf, stdin) || buf[0] != '\n') | ||
1460 | return 0; | ||
1461 | } | ||
1462 | } | ||
1463 | |||
1464 | if (!cmd) | ||
1465 | { | ||
1466 | const char *pager = mh_global_profile_get ("moreproc", getenv ("PAGER")); | ||
1467 | if (pager) | ||
1468 | exec_internal (msg, part, encoding, pager, 0); | ||
1469 | else | ||
1470 | show_internal (msg, part, encoding, out); | ||
1471 | } | ||
1472 | else | ||
1473 | { | ||
1474 | mhn_run_command (msg, part, encoding, cmd, flags, tempfile); | 1553 | mhn_run_command (msg, part, encoding, cmd, flags, tempfile); |
1475 | free (cmd); | 1554 | free (cmd); |
1555 | if (tempfile) | ||
1556 | { | ||
1476 | unlink (tempfile); | 1557 | unlink (tempfile); |
1477 | free (tempfile); | 1558 | free (tempfile); |
1478 | } | 1559 | } | ... | ... |
... | @@ -266,5 +266,59 @@ Why, I do it again and again.' | ... | @@ -266,5 +266,59 @@ Why, I do it again and again.' |
266 | storing msg 4 part 1 using command /home/gray/gnu/mailutils/mh/tests/mhed - | 266 | storing msg 4 part 1 using command /home/gray/gnu/mailutils/mh/tests/mhed - |
267 | ]) | 267 | ]) |
268 | 268 | ||
269 | dnl ------------------------------------------------------------------- | ||
270 | dnl 3. Show mode | ||
271 | dnl ------------------------------------------------------------------- | ||
272 | MH_CHECK([mhn-show msg1],[mhn12 mhn-show-msg1],[ | ||
273 | MUT_MBCOPY($abs_top_srcdir/testsuite/mh/mbox1,[Mail/inbox]) | ||
274 | mhn -show 1 | sed /^X-IMAPbase/d | ||
275 | ], | ||
276 | [0], | ||
277 | [Date: Fri, 28 Dec 2001 22:18:08 +0200 | ||
278 | To: Bar <bar@dontmailme.org> | ||
279 | From: Foo Bar <foobar@nonexistent.net> | ||
280 | Subject: Jabberwocky | ||
281 | |||
282 | X-Envelope-Date: Fri Dec 28 22:18:09 2001 | ||
283 | X-Envelope-Sender: foobar@nonexistent.net | ||
284 | |||
285 | part text/plain 937 | ||
286 | `Twas brillig, and the slithy toves | ||
287 | Did gyre and gimble in the wabe; | ||
288 | All mimsy were the borogoves, | ||
289 | And the mome raths outgrabe. | ||
290 | |||
291 | `Beware the Jabberwock, my son! | ||
292 | The jaws that bite, the claws that catch! | ||
293 | Beware the Jujub bird, and shun | ||
294 | The frumious Bandersnatch!' | ||
295 | |||
296 | He took his vorpal sword in hand: | ||
297 | Long time the manxome foe he sought -- | ||
298 | So rested he by the Tumtum gree, | ||
299 | And stood awhile in thought. | ||
300 | |||
301 | And as in uffish thought he stood, | ||
302 | The Jabberwock, with eyes of flame, | ||
303 | Came whiffling through the tulgey wook, | ||
304 | And burbled as it came! | ||
305 | |||
306 | One, two! One, two! And through and through | ||
307 | The vorpal blade went snicker-snack! | ||
308 | He left it dead, and with its head | ||
309 | He went galumphing back. | ||
310 | |||
311 | `And has thou slain the Jabberwock? | ||
312 | Come to my arms, my beamish boy! | ||
313 | O frabjous day! Calloh! Callay! | ||
314 | He chortled in his joy. | ||
315 | |||
316 | `Twas brillig, and the slithy toves | ||
317 | Did gyre and gimble in the wabe; | ||
318 | All mimsy were the borogoves, | ||
319 | And the mome raths outgrabe. | ||
320 | |||
321 | ]) | ||
322 | |||
269 | m4_popdef[MH_KEYWORDS]) | 323 | m4_popdef[MH_KEYWORDS]) |
270 | # End of mhn.at | 324 | # End of mhn.at | ... | ... |
-
Please register or sign in to post a comment