Commit ec100ee6 ec100ee63e55ba60369363c72d6d2e1fbc3663a2 by Sergey Poznyakoff

Implement MH show utility.

* mh/show.c: New file.
* NEWS: Document changes.
* libmailutils/stream/message_stream.c (copy_trimmed_value): Fix
string length calculation to allow for empty lines.
* mh/.gitignore: Update.
* mh/Makefile.am: Build show.
* mh/TODO: Document show.
* mh/mh_getopt.h: Add new option codes.
* mh/mh_init.c (mh_expand_name): Change handling of the
last argument. All callers updated.
(mh_draft_name): Remove.
1 parent d7dec968
1 GNU mailutils NEWS -- history of user-visible changes. 2013-03-21 1 GNU mailutils NEWS -- history of user-visible changes. 2013-04-12
2 Copyright (C) 2002-2013 Free Software Foundation, Inc. 2 Copyright (C) 2002-2013 Free Software Foundation, Inc.
3 See the end of file for copying conditions. 3 See the end of file for copying conditions.
4 4
...@@ -176,6 +176,10 @@ input folders of type IMAP or IMAPS. A sample usage is: ...@@ -176,6 +176,10 @@ input folders of type IMAP or IMAPS. A sample usage is:
176 176
177 Note the `-truncate' option. 177 Note the `-truncate' option.
178 178
179 ** MH show and msgchk
180
181 Implemented two new programs: show and msgchk.
182
179 ** MH: multiple sources 183 ** MH: multiple sources
180 184
181 The `inc' command is able to incorporate messages from several 185 The `inc' command is able to incorporate messages from several
......
...@@ -138,7 +138,8 @@ copy_trimmed_value (const char *str) ...@@ -138,7 +138,8 @@ copy_trimmed_value (const char *str)
138 size_t len; 138 size_t len;
139 139
140 str = mu_str_skip_class (str, MU_CTYPE_SPACE); 140 str = mu_str_skip_class (str, MU_CTYPE_SPACE);
141 len = strlen (str) - 1; 141 p = mu_str_skip_class_comp (str, MU_CTYPE_ENDLN);
142 len = p - str;
142 p = malloc (len + 1); 143 p = malloc (len + 1);
143 memcpy (p, str, len); 144 memcpy (p, str, len);
144 p[len] = 0; 145 p[len] = 0;
......
...@@ -33,6 +33,7 @@ repl ...@@ -33,6 +33,7 @@ repl
33 rmf 33 rmf
34 rmm 34 rmm
35 scan 35 scan
36 show
36 send 37 send
37 sortm 38 sortm
38 whatnow 39 whatnow
......
...@@ -42,6 +42,7 @@ bin_PROGRAMS = \ ...@@ -42,6 +42,7 @@ bin_PROGRAMS = \
42 rmf\ 42 rmf\
43 rmm\ 43 rmm\
44 scan\ 44 scan\
45 show\
45 send\ 46 send\
46 sortm\ 47 sortm\
47 whatnow\ 48 whatnow\
......
...@@ -42,6 +42,7 @@ State Nice Utility Comments ...@@ -42,6 +42,7 @@ State Nice Utility Comments
42 + 20 sortm 42 + 20 sortm
43 + 20 prompter 43 + 20 prompter
44 * 20 msgchk --date functionality not implemented 44 * 20 msgchk --date functionality not implemented
45 + 20 show next, prev not implemented
45 46
46 Utilities In Alphabetical Order 47 Utilities In Alphabetical Order
47 =============================== 48 ===============================
...@@ -64,6 +65,7 @@ repl ...@@ -64,6 +65,7 @@ repl
64 rmf 65 rmf
65 rmm 66 rmm
66 send 67 send
68 show
67 sortm 69 sortm
68 whatnow 70 whatnow
69 whom 71 whom
......
...@@ -126,7 +126,7 @@ opt_handler (int key, char *arg, struct argp_state *state) ...@@ -126,7 +126,7 @@ opt_handler (int key, char *arg, struct argp_state *state)
126 break; 126 break;
127 127
128 case ARG_FILE: 128 case ARG_FILE:
129 wh_env.file = mh_expand_name (NULL, arg, 0); 129 wh_env.file = mh_expand_name (NULL, arg, NAME_ANY);
130 break; 130 break;
131 131
132 case ARG_NODRAFTFOLDER: 132 case ARG_NODRAFTFOLDER:
...@@ -218,7 +218,7 @@ main (int argc, char **argv) ...@@ -218,7 +218,7 @@ main (int argc, char **argv)
218 } 218 }
219 else if (folder_set) 219 else if (folder_set)
220 { 220 {
221 wh_env.file = mh_expand_name (NULL, "draft", 0); 221 wh_env.file = mh_expand_name (NULL, "draft", NAME_ANY);
222 } 222 }
223 else 223 else
224 { 224 {
......
...@@ -459,7 +459,7 @@ action_print () ...@@ -459,7 +459,7 @@ action_print ()
459 } 459 }
460 else 460 else
461 { 461 {
462 char *p = mh_expand_name (NULL, mh_current_folder (), 0); 462 char *p = mh_expand_name (NULL, mh_current_folder (), NAME_ANY);
463 _scan (p, 1); 463 _scan (p, 1);
464 free (p); 464 free (p);
465 } 465 }
...@@ -854,7 +854,8 @@ fixup_private (const char *name, const char *value, void *data) ...@@ -854,7 +854,8 @@ fixup_private (const char *name, const char *value, void *data)
854 int 854 int
855 action_pack () 855 action_pack ()
856 { 856 {
857 const char *folder_dir = mh_expand_name (NULL, mh_current_folder (), 0); 857 const char *folder_dir = mh_expand_name (NULL, mh_current_folder (),
858 NAME_ANY);
858 mu_mailbox_t mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR); 859 mu_mailbox_t mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
859 struct pack_tab *pack_tab; 860 struct pack_tab *pack_tab;
860 size_t i, count, start; 861 size_t i, count, start;
......
...@@ -505,7 +505,7 @@ main (int argc, char **argv) ...@@ -505,7 +505,7 @@ main (int argc, char **argv)
505 } 505 }
506 506
507 if (build_only || !draftfolder) 507 if (build_only || !draftfolder)
508 wh_env.file = mh_expand_name (NULL, "draft", 0); 508 wh_env.file = mh_expand_name (NULL, "draft", NAME_ANY);
509 else if (draftfolder) 509 else if (draftfolder)
510 { 510 {
511 if (mh_draft_message (draftfolder, draftmessage, &wh_env.file)) 511 if (mh_draft_message (draftfolder, draftmessage, &wh_env.file))
......
...@@ -306,9 +306,13 @@ size_t mh_msgset_first (mu_msgset_t msgset); ...@@ -306,9 +306,13 @@ size_t mh_msgset_first (mu_msgset_t msgset);
306 size_t mh_msgset_first_uid (mu_msgset_t msgset); 306 size_t mh_msgset_first_uid (mu_msgset_t msgset);
307 int mh_msgset_single_message (mu_msgset_t msgset); 307 int mh_msgset_single_message (mu_msgset_t msgset);
308 308
309 #define NAME_ANY 0
310 #define NAME_FOLDER 1
311 #define NAME_FILE 2
312 char *mh_expand_name (const char *base, const char *name, int what);
313
309 char *mh_get_dir (void); 314 char *mh_get_dir (void);
310 int mh_find_file (const char *name, char **resolved_name); 315 int mh_find_file (const char *name, char **resolved_name);
311 char *mh_expand_name (const char *base, const char *name, int is_folder);
312 void mh_quote (const char *in, char **out); 316 void mh_quote (const char *in, char **out);
313 void mh_expand_aliases (mu_message_t msg, mu_address_t *addr_to, 317 void mh_expand_aliases (mu_message_t msg, mu_address_t *addr_to,
314 mu_address_t *addr_cc, 318 mu_address_t *addr_cc,
......
...@@ -246,7 +246,7 @@ push_source (const char *name, int fail) ...@@ -246,7 +246,7 @@ push_source (const char *name, int fail)
246 char *filename; 246 char *filename;
247 int ex = 0; 247 int ex = 0;
248 248
249 filename = mh_expand_name (NULL, name, 0); 249 filename = mh_expand_name (NULL, name, NAME_ANY);
250 if (stat (filename, &st)) 250 if (stat (filename, &st))
251 { 251 {
252 if (fail) 252 if (fail)
......
...@@ -135,6 +135,7 @@ enum mh_arg { ...@@ -135,6 +135,7 @@ enum mh_arg {
135 ARG_NORMALIZE, 135 ARG_NORMALIZE,
136 ARG_NOSERIALONLY, 136 ARG_NOSERIALONLY,
137 ARG_NOSHOW, 137 ARG_NOSHOW,
138 ARG_NOSHOWPROC,
138 ARG_NOSTORE, 139 ARG_NOSTORE,
139 ARG_NOT, 140 ARG_NOT,
140 ARG_NOTEXTFIELD, 141 ARG_NOTEXTFIELD,
...@@ -168,6 +169,7 @@ enum mh_arg { ...@@ -168,6 +169,7 @@ enum mh_arg {
168 ARG_SEQUENCE, 169 ARG_SEQUENCE,
169 ARG_SERIALONLY, 170 ARG_SERIALONLY,
170 ARG_SHOW, 171 ARG_SHOW,
172 ARG_SHOWPROC,
171 ARG_SOURCE, 173 ARG_SOURCE,
172 ARG_SPLIT, 174 ARG_SPLIT,
173 ARG_STORE, 175 ARG_STORE,
......
...@@ -76,7 +76,7 @@ _mh_init_global_context () ...@@ -76,7 +76,7 @@ _mh_init_global_context ()
76 p = getenv ("CONTEXT"); 76 p = getenv ("CONTEXT");
77 if (!p) 77 if (!p)
78 p = MH_CONTEXT_FILE; 78 p = MH_CONTEXT_FILE;
79 ctx_name = mh_expand_name (NULL, p, 0); 79 ctx_name = mh_expand_name (NULL, p, NAME_ANY);
80 80
81 mu_mh_context = mh_read_property_file (ctx_name, 0); 81 mu_mh_context = mh_read_property_file (ctx_name, 0);
82 82
......
...@@ -437,7 +437,7 @@ mh_open_folder (const char *folder, int flags) ...@@ -437,7 +437,7 @@ mh_open_folder (const char *folder, int flags)
437 mu_mailbox_t mbox = NULL; 437 mu_mailbox_t mbox = NULL;
438 char *name; 438 char *name;
439 439
440 name = mh_expand_name (NULL, folder, 1); 440 name = mh_expand_name (NULL, folder, NAME_FOLDER);
441 if ((flags & MU_STREAM_CREAT) && mh_check_folder (name, 1)) 441 if ((flags & MU_STREAM_CREAT) && mh_check_folder (name, 1))
442 exit (0); 442 exit (0);
443 443
...@@ -482,7 +482,7 @@ mh_get_dir () ...@@ -482,7 +482,7 @@ mh_get_dir ()
482 } 482 }
483 483
484 char * 484 char *
485 mh_expand_name (const char *base, const char *name, int is_folder) 485 mh_expand_name (const char *base, const char *name, int what)
486 { 486 {
487 char *p = NULL; 487 char *p = NULL;
488 char *namep = NULL; 488 char *namep = NULL;
...@@ -495,11 +495,13 @@ mh_expand_name (const char *base, const char *name, int is_folder) ...@@ -495,11 +495,13 @@ mh_expand_name (const char *base, const char *name, int is_folder)
495 char *cwd = mu_getcwd (); 495 char *cwd = mu_getcwd ();
496 char *tmp = mh_safe_make_file_name (cwd, namep); 496 char *tmp = mh_safe_make_file_name (cwd, namep);
497 free (cwd); 497 free (cwd);
498 if (what == NAME_FILE)
499 return tmp;
498 free (namep); 500 free (namep);
499 namep = tmp; 501 namep = tmp;
500 } 502 }
501 503
502 if (is_folder) 504 if (what == NAME_FOLDER)
503 { 505 {
504 if (memcmp (namep, "mh:/", 4) == 0) 506 if (memcmp (namep, "mh:/", 4) == 0)
505 return namep; 507 return namep;
...@@ -510,7 +512,17 @@ mh_expand_name (const char *base, const char *name, int is_folder) ...@@ -510,7 +512,17 @@ mh_expand_name (const char *base, const char *name, int is_folder)
510 namep); 512 namep);
511 } 513 }
512 else if (namep[0] != '/') 514 else if (namep[0] != '/')
513 mu_asprintf (&p, "%s/%s", base ? base : mu_folder_directory (), namep); 515 {
516 if (what == NAME_FILE)
517 {
518 char *cwd = mu_getcwd ();
519 p = mh_safe_make_file_name (cwd, namep);
520 free (cwd);
521 }
522 else
523 p = mh_safe_make_file_name (base ? base : mu_folder_directory (),
524 namep);
525 }
514 else 526 else
515 return namep; 527 return namep;
516 528
...@@ -543,7 +555,7 @@ mh_find_file (const char *name, char **resolved_name) ...@@ -543,7 +555,7 @@ mh_find_file (const char *name, char **resolved_name)
543 return errno; 555 return errno;
544 } 556 }
545 557
546 s = mh_expand_name (NULL, name, 0); 558 s = mh_expand_name (NULL, name, NAME_ANY);
547 if (access (s, R_OK) == 0) 559 if (access (s, R_OK) == 0)
548 { 560 {
549 *resolved_name = s; 561 *resolved_name = s;
...@@ -554,7 +566,8 @@ mh_find_file (const char *name, char **resolved_name) ...@@ -554,7 +566,8 @@ mh_find_file (const char *name, char **resolved_name)
554 _("cannot access %s: %s"), s, mu_strerror (errno)); 566 _("cannot access %s: %s"), s, mu_strerror (errno));
555 free (s); 567 free (s);
556 568
557 s = mh_expand_name (mh_global_profile_get ("mhetcdir", MHLIBDIR), name, 0); 569 s = mh_expand_name (mh_global_profile_get ("mhetcdir", MHLIBDIR), name,
570 NAME_ANY);
558 if (access (s, R_OK) == 0) 571 if (access (s, R_OK) == 0)
559 { 572 {
560 *resolved_name = s; 573 *resolved_name = s;
...@@ -690,7 +703,7 @@ mh_file_to_message (const char *folder, const char *file_name) ...@@ -690,7 +703,7 @@ mh_file_to_message (const char *folder, const char *file_name)
690 703
691 if (folder) 704 if (folder)
692 { 705 {
693 tmp_name = mh_expand_name (folder, file_name, 0); 706 tmp_name = mh_expand_name (folder, file_name, NAME_ANY);
694 msg = _file_to_message (tmp_name); 707 msg = _file_to_message (tmp_name);
695 free (tmp_name); 708 free (tmp_name);
696 } 709 }
...@@ -853,14 +866,6 @@ mh_annotate (mu_message_t msg, const char *field, const char *text, int date) ...@@ -853,14 +866,6 @@ mh_annotate (mu_message_t msg, const char *field, const char *text, int date)
853 } 866 }
854 867
855 char * 868 char *
856 mh_draft_name ()
857 {
858 return mh_expand_name (mh_global_profile_get ("Draft-Folder",
859 mu_folder_directory ()),
860 "draft", 0);
861 }
862
863 char *
864 mh_create_message_id (int subpart) 869 mh_create_message_id (int subpart)
865 { 870 {
866 char *p; 871 char *p;
......
...@@ -22,7 +22,7 @@ static char * ...@@ -22,7 +22,7 @@ static char *
22 private_sequence_name (const char *name) 22 private_sequence_name (const char *name)
23 { 23 {
24 char *p; 24 char *p;
25 char *mbox_dir = mh_expand_name (NULL, mh_current_folder (), 0); 25 char *mbox_dir = mh_expand_name (NULL, mh_current_folder (), NAME_ANY);
26 mu_asprintf (&p, "atr-%s-%s", name, mbox_dir); 26 mu_asprintf (&p, "atr-%s-%s", name, mbox_dir);
27 free (mbox_dir); 27 free (mbox_dir);
28 return p; 28 return p;
......
...@@ -2978,7 +2978,7 @@ main (int argc, char **argv) ...@@ -2978,7 +2978,7 @@ main (int argc, char **argv)
2978 return 1; 2978 return 1;
2979 } 2979 }
2980 input_file = mh_expand_name (mu_folder_directory (), 2980 input_file = mh_expand_name (mu_folder_directory (),
2981 argc == 1 ? argv[0] : "draft", 0); 2981 argc == 1 ? argv[0] : "draft", NAME_ANY);
2982 message = mh_file_to_message (NULL, input_file); 2982 message = mh_file_to_message (NULL, input_file);
2983 if (!message) 2983 if (!message)
2984 return 1; 2984 return 1;
......
...@@ -418,14 +418,14 @@ main (int argc, char **argv) ...@@ -418,14 +418,14 @@ main (int argc, char **argv)
418 } 418 }
419 419
420 if (build_only) 420 if (build_only)
421 wh_env.file = mh_expand_name (draftfolder, "reply", 0); 421 wh_env.file = mh_expand_name (draftfolder, "reply", NAME_ANY);
422 else if (draftfolder) 422 else if (draftfolder)
423 { 423 {
424 if (mh_draft_message (draftfolder, draftmessage, &wh_env.file)) 424 if (mh_draft_message (draftfolder, draftmessage, &wh_env.file))
425 return 1; 425 return 1;
426 } 426 }
427 else 427 else
428 wh_env.file = mh_expand_name (draftfolder, "draft", 0); 428 wh_env.file = mh_expand_name (draftfolder, "draft", NAME_ANY);
429 wh_env.draftfile = wh_env.file; 429 wh_env.draftfile = wh_env.file;
430 430
431 make_draft (mbox, DISP_REPLACE, &wh_env); 431 make_draft (mbox, DISP_REPLACE, &wh_env);
......
...@@ -196,7 +196,7 @@ main (int argc, char **argv) ...@@ -196,7 +196,7 @@ main (int argc, char **argv)
196 name = cur_folder_path; 196 name = cur_folder_path;
197 } 197 }
198 else 198 else
199 name = mh_expand_name (NULL, folder_name, 0); 199 name = mh_expand_name (NULL, folder_name, NAME_ANY);
200 if (recursive) 200 if (recursive)
201 status = recrmf (name); 201 status = recrmf (name);
202 else 202 else
......
...@@ -325,7 +325,7 @@ elt_fixup (void *item, void *data) ...@@ -325,7 +325,7 @@ elt_fixup (void *item, void *data)
325 { 325 {
326 struct list_elt *elt = item; 326 struct list_elt *elt = item;
327 327
328 elt->file_name = mh_expand_name (draftfolder, elt->file_name, 0); 328 elt->file_name = mh_expand_name (draftfolder, elt->file_name, NAME_ANY);
329 if (checkdraft (elt->file_name)) 329 if (checkdraft (elt->file_name))
330 exit (1); 330 exit (1);
331 elt->msg = mh_file_to_message (NULL, elt->file_name); 331 elt->msg = mh_file_to_message (NULL, elt->file_name);
...@@ -357,7 +357,7 @@ read_mts_profile () ...@@ -357,7 +357,7 @@ read_mts_profile ()
357 { 357 {
358 mu_property_t local_profile; 358 mu_property_t local_profile;
359 359
360 name = mh_expand_name (MHLIBDIR, "mtstailor", 0); 360 name = mh_expand_name (MHLIBDIR, "mtstailor", NAME_ANY);
361 mts_profile = mh_read_property_file (name, 1); 361 mts_profile = mh_read_property_file (name, 1);
362 362
363 name = mu_tilde_expansion ("~/.mtstailor", MU_HIERARCHY_DELIMITER, NULL); 363 name = mu_tilde_expansion ("~/.mtstailor", MU_HIERARCHY_DELIMITER, NULL);
...@@ -886,7 +886,8 @@ main (int argc, char **argv) ...@@ -886,7 +886,8 @@ main (int argc, char **argv)
886 addfolder (dfolder, 0, NULL); 886 addfolder (dfolder, 0, NULL);
887 else 887 else
888 { 888 {
889 char *df = mh_expand_name (mu_folder_directory (), "draft", 0); 889 char *df = mh_expand_name (mu_folder_directory (), "draft",
890 NAME_ANY);
890 if (checkdraft (df)) 891 if (checkdraft (df))
891 exit (1); 892 exit (1);
892 if (!use_draft && !mh_usedraft (df)) 893 if (!use_draft && !mh_usedraft (df))
...@@ -906,7 +907,7 @@ main (int argc, char **argv) ...@@ -906,7 +907,7 @@ main (int argc, char **argv)
906 { 907 {
907 /* -draftfolder is supplied */ 908 /* -draftfolder is supplied */
908 draftfolder = mh_expand_name (mu_folder_directory (), 909 draftfolder = mh_expand_name (mu_folder_directory (),
909 draftfolder, 0); 910 draftfolder, NAME_ANY);
910 use_draft = 1; 911 use_draft = 1;
911 mesg_list_fixup (); 912 mesg_list_fixup ();
912 if (mu_list_is_empty (mesg_list) || argc != 0) 913 if (mu_list_is_empty (mesg_list) || argc != 0)
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2002, 2005, 2007-2012 Free Software Foundation, Inc.
3
4 GNU Mailutils is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3, or (at your option)
7 any later version.
8
9 GNU Mailutils is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
16
17 /* MH show command */
18
19 #include <mh.h>
20
21 static char doc[] = N_("GNU MH show")"\v"
22 N_("Use -help to obtain the list of traditional MH options.");
23 static char args_doc[] = N_("[+FOLDER] [MSGLIST]");
24
25 #define ARG_PASS ARG_MAX
26
27 static struct argp_option options[] = {
28 {"draft", ARG_DRAFT, NULL, 0,
29 N_("show the draft file") },
30 {"file", ARG_FILE, N_("FILE"), 0,
31 N_("show this file") },
32 {"header", ARG_HEADER, N_("BOOL"), OPTION_ARG_OPTIONAL,
33 N_("display a description of the message before the message itself") },
34 {"noheader", ARG_HEADER, NULL, OPTION_HIDDEN, "" },
35 {"showproc", ARG_SHOWPROC, N_("PROGRAM"), 0,
36 N_("use PROGRAM to show messages")},
37 {"noshowproc", ARG_NOSHOWPROC, NULL, 0,
38 N_("disable the use of the \"showproc:\" profile component") },
39
40 {"form", ARG_FORM, N_("FILE"), 0,
41 N_("read format from given file")},
42 {"moreproc", ARG_MOREPROC, N_("PROG"), 0,
43 N_("use this PROG as pager"), },
44 {"nomoreproc", ARG_NOMOREPROC, NULL, 0,
45 N_("disable the use of moreproc") },
46 {"length", ARG_LENGTH, N_("NUMBER"), 0,
47 N_("set output screen length")},
48 {"width", ARG_WIDTH, N_("NUMBER"), 0,
49 N_("set output width")},
50
51 {NULL}
52 };
53
54 /* Traditional MH options */
55 struct mh_option mh_option[] = {
56 { "draft" },
57 { "file", MH_OPT_ARG, "file" },
58 { "header", MH_OPT_BOOL },
59 { "showproc", MH_OPT_ARG, "program" },
60 { "noshowproc" },
61 { "form", MH_OPT_ARG, "formatfile"},
62 { "width", MH_OPT_ARG, "number"},
63 { "length", MH_OPT_ARG, "number"},
64 { "moreproc", MH_OPT_ARG, "program"},
65 { "nomoreproc" },
66
67 { NULL }
68 };
69
70 int use_draft;
71 int use_showproc = 1;
72 int header_option = 1;
73 char *file;
74
75 const char *showproc;
76 char **showargv;
77 size_t showargc;
78 size_t showargmax;
79
80 const char *mhnproc;
81
82 static void
83 addarg (const char *arg)
84 {
85 if (showargc == showargmax)
86 showargv = mu_2nrealloc (showargv, &showargmax, sizeof showargv[0]);
87 showargv[showargc++] = (char*) arg;
88 }
89
90 static void
91 insarg (char *arg)
92 {
93 addarg (arg);
94 if (showargc > 2)
95 {
96 char *p = showargv[showargc-1];
97 memmove (showargv + 2, showargv + 1,
98 sizeof (showargv[0]) * (showargc - 2));
99 showargv[1] = p;
100 }
101 }
102
103 static const char *
104 findopt (int key)
105 {
106 struct argp_option *p;
107
108 for (p = options; p->name; p++)
109 if (p->key == key)
110 return p->name;
111 abort ();
112 }
113
114 static error_t
115 opt_handler (int key, char *arg, struct argp_state *state)
116 {
117 switch (key)
118 {
119 case ARG_FOLDER:
120 mh_set_current_folder (arg);
121 break;
122
123 case ARG_DRAFT:
124 if (use_draft || file)
125 argp_error (state, _("only one file at a time!"));
126 use_draft = 1;
127 break;
128
129 case ARG_FILE:
130 if (use_draft || file)
131 argp_error (state, _("only one file at a time!"));
132 file = mh_expand_name (NULL, arg, NAME_FILE);
133 break;
134
135 case ARG_HEADER:
136 header_option = is_true (arg);
137 break;
138
139 case ARG_NOHEADER:
140 header_option = 0;
141 break;
142
143 case ARG_SHOWPROC:
144 showproc = arg;
145 break;
146
147 case ARG_NOSHOWPROC:
148 use_showproc = 0;
149 break;
150
151 case ARG_NOMOREPROC:
152 case ARG_FORM:
153 case ARG_MOREPROC:
154 case ARG_LENGTH:
155 case ARG_WIDTH:
156 addarg (findopt (key));
157 if (arg)
158 addarg (arg);
159 break;
160
161 default:
162 return ARGP_ERR_UNKNOWN;
163 }
164 return 0;
165 }
166
167 static int
168 resolve_mime (size_t num, mu_message_t msg, void *data)
169 {
170 int *ismime = data;
171
172 mu_message_is_multipart (msg, ismime);
173 return *ismime;
174 }
175
176 static int
177 resolve_msg (size_t num, mu_message_t msg, void *data)
178 {
179 char *path = data;
180
181 mh_message_number (msg, &num);
182 addarg (mh_safe_make_file_name (path, mu_umaxtostr (0, num)));
183
184 return 0;
185 }
186
187 static int
188 adduid (size_t num, void *data)
189 {
190 addarg (mu_umaxtostr (0, num));
191 return 0;
192 }
193
194 static int
195 printheader (size_t num, void *data)
196 {
197 mu_printf ("(Message %s:%lu)\n", (char*) data, (unsigned long)num);
198 return 1;
199 }
200
201 static void
202 checkfile (char *file)
203 {
204 int ismime = 0;
205
206 if (!showproc)
207 {
208 mu_message_t msg = mh_file_to_message (NULL, file);
209 mu_message_is_multipart (msg, &ismime);
210 mu_message_unref (msg);
211 }
212 if (ismime)
213 {
214 showproc = mhnproc;
215 insarg ("-show");
216 addarg ("-file");
217 }
218 addarg (file);
219 }
220
221 int
222 main (int argc, char **argv)
223 {
224 int index = 0;
225 mu_mailbox_t mbox;
226 mu_msgset_t msgset;
227 const char *p;
228
229 /* Native Language Support */
230 MU_APP_INIT_NLS ();
231
232 showargmax = 2;
233 showargc = 1;
234 showargv = mu_calloc (showargmax, sizeof showargv[0]);
235
236 mh_argp_init ();
237 mh_argp_parse (&argc, &argv, 0, options, mh_option, args_doc, doc,
238 opt_handler, NULL, &index);
239 mbox = mh_open_folder (mh_current_folder (), MU_STREAM_RDWR);
240
241 argc -= index;
242 argv += index;
243
244 if (use_draft || file)
245 {
246 if (argc)
247 {
248 mu_error (_("only one file at a time!"));
249 exit (1);
250 }
251 }
252 else
253 mh_msgset_parse (&msgset, mbox, argc, argv, "cur");
254
255 /* 1. If !use_showproc set showproc to /bin/cat and go to X.
256 2. If -file or -draft is given
257 2.a. If showproc is set, go to 2.c
258 2.b. If the file is a multipart one, set showproc to mhn with -file
259 and -show options and go to X
260 2.c. Add file to the argument list and go to X.
261 3. Scan all messages to see if there are MIME ones. If so, set
262 showproc to mhn with the -show option, transfer message UIDs
263 to showproc arguments, and go to X
264 4. Otherwise set showproc from the showproc variable in .mh_profile
265 X. If showproc is not set, set it to PAGER ("/usr/bin/more" by default).
266 Y. Execute showproc with the collected argument list.
267 */
268
269 if (!use_showproc)
270 showproc = "/bin/cat";
271 else
272 showproc = mh_global_profile_get ("showproc", NULL);
273
274 mhnproc = mh_global_profile_get ("mhnproc", "mhn");
275
276 if (use_draft || file)
277 {
278 if (file)
279 checkfile (file);
280 else
281 {
282 const char *dfolder = mh_global_profile_get ("Draft-Folder", NULL);
283
284 if (dfolder)
285 {
286 int ismime = 0;
287
288 mu_mailbox_close (mbox);
289 mu_mailbox_destroy (&mbox);
290 mbox = mh_open_folder (dfolder, MU_STREAM_RDWR);
291 mh_msgset_parse (&msgset, mbox, 0, NULL, "cur");
292
293 mu_msgset_foreach_message (msgset, resolve_mime, &ismime);
294 if (ismime)
295 {
296 showproc = mhnproc;
297 insarg ("-show");
298 addarg ("-file");
299 }
300 mu_msgset_foreach_message (msgset, resolve_msg,
301 (void *) dfolder);
302 }
303 else
304 checkfile (mh_expand_name (mu_folder_directory (),
305 "draft", NAME_ANY));
306 }
307 }
308 else
309 {
310 mu_url_t url;
311 size_t n;
312 int ismime = 0;
313 const char *path;
314
315 mu_mailbox_get_url (mbox, &url);
316 mu_url_sget_path (url, &path);
317
318 if (!showproc)
319 {
320 mu_msgset_foreach_message (msgset, resolve_mime, &ismime);
321 if (ismime)
322 {
323 showproc = mhnproc;
324 insarg ("-show");
325 }
326 }
327
328 if (ismime)
329 mu_msgset_foreach_msguid (msgset, adduid, NULL);
330 else
331 mu_msgset_foreach_message (msgset, resolve_msg, (void*) path);
332
333 p = mh_global_profile_get ("Unseen-Sequence", NULL);
334 if (p)
335 {
336 mh_seq_delete (mbox, p, msgset, 0);
337 mh_global_save_state ();
338 }
339
340 if (header_option && mu_msgset_count (msgset, &n) == 0 && n == 1)
341 mu_msgset_foreach_msguid (msgset, printheader, (void*) path);
342 }
343
344 mu_stream_flush (mu_strout);
345 mu_mailbox_close (mbox);
346 mu_mailbox_destroy (&mbox);
347
348 if (!showproc)
349 {
350 showproc = getenv ("PAGER");
351 if (!showproc)
352 showproc = "/usr/bin/more";
353 }
354
355 addarg (NULL);
356 p = strrchr (showproc, '/');
357 showargv[0] = (char*) (p ? p + 1 : showproc);
358 execvp (showproc, showargv);
359 mu_error (_("unable to exec %s: %s"), showargv[0], mu_strerror (errno));
360 return 1;
361 }
362
363
...@@ -108,7 +108,7 @@ main (int argc, char **argv) ...@@ -108,7 +108,7 @@ main (int argc, char **argv)
108 return 1; 108 return 1;
109 } 109 }
110 else 110 else
111 wh_env.draftfile = mh_expand_name (draftfolder, "draft", 0); 111 wh_env.draftfile = mh_expand_name (draftfolder, "draft", NAME_ANY);
112 wh_env.draftfile = wh_env.file; 112 wh_env.draftfile = wh_env.file;
113 113
114 return mh_whatnow (&wh_env, initial_edit); 114 return mh_whatnow (&wh_env, initial_edit);
......
...@@ -118,6 +118,6 @@ main (int argc, char **argv) ...@@ -118,6 +118,6 @@ main (int argc, char **argv)
118 mu_folder_directory ()); 118 mu_folder_directory ());
119 119
120 120
121 return mh_whom (mh_expand_name (draft_folder, name, 0), check_recipients) ? 121 return mh_whom (mh_expand_name (draft_folder, name, NAME_ANY),
122 1 : 0; 122 check_recipients) ? 1 : 0;
123 } 123 }
......