Commit 36e8269d 36e8269d52475b4e4e5869873c835ead51d82ccb by Sergey Poznyakoff

mh: fix the use of mhl.forward in forw.

* mh/mhl.forward: New file.
* mh/forw.c (mh_option): the -format option is boolean.
(mhl_filter): Rename to mhl_filter_file.
(opt_handler) <ARG_FORMAT>: Use default mhl.filter.
<ARG_NOFORMAT>: Set encap_clear.
<ARG_FILTER>: Use mh_find_file to determine filter file name.
(finish_draft): Use MHL filter file if encap == encap_mhl.
* mh/mh.h (mh_find_file): New prototype.
* mh/mh_init.c (mh_find_file): New file.
(mh_read_formfile): Use mh_find_file to locate the file.
* mh/tests/forw.at: Test forw -format.
* mh/tests/mhparam.at: Update the -all test.
* tests/testsuite.at (MH_SETUP): Set the "mhetcdir" component.
* mh/scan.c (opt_handler): Exit if mh_read_formfile failed.
1 parent 2ef58f17
...@@ -97,8 +97,9 @@ BUILT_SOURCES= \ ...@@ -97,8 +97,9 @@ BUILT_SOURCES= \
97 97
98 MAINTAINERCLEANFILES=$(BUILT_SOURCES) 98 MAINTAINERCLEANFILES=$(BUILT_SOURCES)
99 99
100 mhlib_DATA = components replcomps replgroupcomps mhl.format $(LISPSRC) 100 mhlib_DATA = components replcomps replgroupcomps mhl.format mhl.forward\
101 EXTRA_DIST = components replcomps replgroupcomps mhl.format\ 101 $(LISPSRC)
102 EXTRA_DIST = components replcomps replgroupcomps mhl.format mhl.forward\
102 mailutils-mh.eli mh_fmtgram.y pick.y mh_alias.y mh_alias.l 103 mailutils-mh.eli mh_fmtgram.y pick.y mh_alias.y mh_alias.l
103 DISTCLEANFILES = mailutils-mh.el 104 DISTCLEANFILES = mailutils-mh.el
104 105
......
...@@ -78,7 +78,7 @@ struct mh_option mh_option[] = { ...@@ -78,7 +78,7 @@ struct mh_option mh_option[] = {
78 { "build" }, 78 { "build" },
79 { "file", MH_OPT_ARG, "msgfile" }, 79 { "file", MH_OPT_ARG, "msgfile" },
80 { "form", MH_OPT_ARG, "formatfile" }, 80 { "form", MH_OPT_ARG, "formatfile" },
81 { "format", MH_OPT_ARG, "string" }, 81 { "format", MH_OPT_BOOL },
82 { "draftfolder", MH_OPT_ARG, "folder" }, 82 { "draftfolder", MH_OPT_ARG, "folder" },
83 { "nodraftfolder" }, 83 { "nodraftfolder" },
84 { "draftmessage" }, 84 { "draftmessage" },
...@@ -103,7 +103,9 @@ static char *formfile; ...@@ -103,7 +103,9 @@ static char *formfile;
103 struct mh_whatnow_env wh_env = { 0 }; 103 struct mh_whatnow_env wh_env = { 0 };
104 static int initial_edit = 1; 104 static int initial_edit = 1;
105 static const char *whatnowproc; 105 static const char *whatnowproc;
106 static char *mhl_filter = NULL; /* --filter flag */ 106
107 static char *mhl_filter_file = NULL; /* --filter flag */
108
107 static int build_only = 0; /* --build flag */ 109 static int build_only = 0; /* --build flag */
108 static int annotate = 0; /* --annotate flag */ 110 static int annotate = 0; /* --annotate flag */
109 static enum encap_type encap = encap_clear; /* controlled by --format, --form 111 static enum encap_type encap = encap_clear; /* controlled by --format, --form
...@@ -184,15 +186,18 @@ opt_handler (int key, char *arg, struct argp_state *state) ...@@ -184,15 +186,18 @@ opt_handler (int key, char *arg, struct argp_state *state)
184 if (is_true (arg)) 186 if (is_true (arg))
185 { 187 {
186 encap = encap_mhl; 188 encap = encap_mhl;
187 break; 189 mh_find_file ("mhl.forward", &mhl_filter_file);
188 } 190 }
189 /*FALLTHRU*/ 191 else
192 encap = encap_clear;
193 break;
194
190 case ARG_NOFORMAT: 195 case ARG_NOFORMAT:
191 if (encap == encap_mhl)
192 encap = encap_clear; 196 encap = encap_clear;
193 break; 197 break;
194 198
195 case ARG_FILTER: 199 case ARG_FILTER:
200 mh_find_file (arg, &mhl_filter_file);
196 encap = encap_mhl; 201 encap = encap_mhl;
197 break; 202 break;
198 203
...@@ -381,21 +386,14 @@ finish_draft () ...@@ -381,21 +386,14 @@ finish_draft ()
381 } 386 }
382 else 387 else
383 { 388 {
384 if (!mhl_filter) 389 if (encap == encap_mhl)
385 { 390 {
386 char *s = mh_expand_name (MHLIBDIR, "mhl.forward", 0); 391 if (mhl_filter_file)
387 if (access (s, R_OK) == 0)
388 mhl_filter = "mhl.forward";
389 free (s);
390 }
391
392 if (mhl_filter)
393 { 392 {
394 char *s = mh_expand_name (MHLIBDIR, mhl_filter, 0); 393 format = mhl_format_compile (mhl_filter_file);
395 format = mhl_format_compile (s);
396 if (!format) 394 if (!format)
397 exit (1); 395 exit (1);
398 free (s); 396 }
399 } 397 }
400 398
401 if (annotate) 399 if (annotate)
......
...@@ -314,6 +314,7 @@ void mh_msgset_free (mh_msgset_t *msgset); ...@@ -314,6 +314,7 @@ void mh_msgset_free (mh_msgset_t *msgset);
314 void mh_msgset_uids (mu_mailbox_t mbox, mh_msgset_t *msgset); 314 void mh_msgset_uids (mu_mailbox_t mbox, mh_msgset_t *msgset);
315 315
316 char *mh_get_dir (void); 316 char *mh_get_dir (void);
317 int mh_find_file (const char *name, char **resolved_name);
317 char *mh_expand_name (const char *base, const char *name, int is_folder); 318 char *mh_expand_name (const char *base, const char *name, int is_folder);
318 void mh_quote (const char *in, char **out); 319 void mh_quote (const char *in, char **out);
319 void mh_expand_aliases (mu_message_t msg, mu_address_t *addr_to, 320 void mh_expand_aliases (mu_message_t msg, mu_address_t *addr_to,
...@@ -366,6 +367,7 @@ void mh_annotate (mu_message_t msg, char *field, char *text, int date); ...@@ -366,6 +367,7 @@ void mh_annotate (mu_message_t msg, char *field, char *text, int date);
366 #define MHL_DISABLE_BODY 8 367 #define MHL_DISABLE_BODY 8
367 368
368 mu_list_t mhl_format_compile (char *name); 369 mu_list_t mhl_format_compile (char *name);
370
369 int mhl_format_run (mu_list_t fmt, int width, int length, int flags, 371 int mhl_format_run (mu_list_t fmt, int width, int length, int flags,
370 mu_message_t msg, mu_stream_t output); 372 mu_message_t msg, mu_stream_t output);
371 void mhl_format_destroy (mu_list_t *fmt); 373 void mhl_format_destroy (mu_list_t *fmt);
......
...@@ -77,19 +77,33 @@ mh_read_formfile (char *name, char **pformat) ...@@ -77,19 +77,33 @@ mh_read_formfile (char *name, char **pformat)
77 char *ptr; 77 char *ptr;
78 size_t off = 0; 78 size_t off = 0;
79 char *format_str; 79 char *format_str;
80 char *file_name;
81 int rc;
82
83 rc = mh_find_file (name, &file_name);
84 if (rc)
85 {
86 mu_error (_("cannot access format file %s: %s"), name, strerror (rc));
87 return -1;
88 }
80 89
81 if (stat (name, &st)) 90 if (stat (file_name, &st))
82 { 91 {
83 mu_error (_("cannot stat format file %s: %s"), name, strerror (errno)); 92 mu_error (_("cannot stat format file %s: %s"), file_name,
93 strerror (errno));
94 free (file_name);
84 return -1; 95 return -1;
85 } 96 }
86 97
87 fp = fopen (name, "r"); 98 fp = fopen (file_name, "r");
88 if (!fp) 99 if (!fp)
89 { 100 {
90 mu_error (_("cannot open format file %s: %s"), name, strerror (errno)); 101 mu_error (_("cannot open format file %s: %s"), file_name,
102 strerror (errno));
103 free (file_name);
91 return -1; 104 return -1;
92 } 105 }
106 free (file_name);
93 107
94 format_str = xmalloc (st.st_size+1); 108 format_str = xmalloc (st.st_size+1);
95 while ((ptr = fgets (format_str + off, st.st_size - off + 1, fp)) != NULL) 109 while ((ptr = fgets (format_str + off, st.st_size - off + 1, fp)) != NULL)
...@@ -520,6 +534,68 @@ mh_expand_name (const char *base, const char *name, int is_folder) ...@@ -520,6 +534,68 @@ mh_expand_name (const char *base, const char *name, int is_folder)
520 } 534 }
521 535
522 int 536 int
537 mh_find_file (const char *name, char **resolved_name)
538 {
539 char *s;
540 int rc;
541
542 if (name[0] == '/' ||
543 (name[0] == '.' && name[1] == '/') ||
544 (name[0] == '.' && name[1] == '.' && name[2] == '/'))
545 {
546 if (access (name, R_OK) == 0)
547 {
548 *resolved_name = xstrdup (name);
549 return 0;
550 }
551 return errno;
552 }
553
554 if (name[0] == '~')
555 {
556 s = mu_tilde_expansion (name, "/", NULL);
557 if (access (s, R_OK) == 0)
558 {
559 *resolved_name = s;
560 return 0;
561 }
562 return errno;
563 }
564
565 s = mh_expand_name (NULL, name, 0);
566 if (access (s, R_OK) == 0)
567 {
568 *resolved_name = s;
569 return 0;
570 }
571 if (errno != ENOENT)
572 mu_diag_output (MU_DIAG_WARNING,
573 _("cannot access %s: %s"), s, mu_strerror (errno));
574 free (s);
575
576 s = mh_expand_name (mh_global_profile_get ("mhetcdir", MHLIBDIR), name, 0);
577 if (access (s, R_OK) == 0)
578 {
579 *resolved_name = s;
580 return 0;
581 }
582 if (errno != ENOENT)
583 mu_diag_output (MU_DIAG_WARNING,
584 _("cannot access %s: %s"), s, mu_strerror (errno));
585 free (s);
586
587 *resolved_name = xstrdup (name);
588 if (access (name, R_OK) == 0)
589 return 0;
590 rc = errno;
591 if (rc != ENOENT)
592 mu_diag_output (MU_DIAG_WARNING,
593 _("cannot access %s: %s"), s, mu_strerror (rc));
594
595 return rc;
596 }
597
598 int
523 mh_iterate (mu_mailbox_t mbox, mh_msgset_t *msgset, 599 mh_iterate (mu_mailbox_t mbox, mh_msgset_t *msgset,
524 mh_iterator_fp itr, void *data) 600 mh_iterator_fp itr, void *data)
525 { 601 {
......
1 ; This is the default mhl.format file for Mailutils MH.
2 ;
3 ; GNU Mailutils -- a suite of utilities for electronic mail
4 ; Copyright (C) 2003, 2010 Free Software Foundation, Inc.
5 ; Distributed under GPLv3+. See <http://gnu.org/licenses/gpl.html>.
6 ;
7 width=80,overflowtext=,overflowoffset=10
8 leftadjust,compress,compwidth=9
9 Date:formatfield="%<(nodate{text})%{text}%|%(tws{text})%>"
10 From:
11 To:
12 cc:
13 Subject:
14 :
15 body:nocomponent,overflowoffset=0,noleftadjust,nocompress
...@@ -99,7 +99,8 @@ opt_handler (int key, char *arg, struct argp_state *state) ...@@ -99,7 +99,8 @@ opt_handler (int key, char *arg, struct argp_state *state)
99 break; 99 break;
100 100
101 case ARG_FORM: 101 case ARG_FORM:
102 mh_read_formfile (arg, &format_str); 102 if (mh_read_formfile (arg, &format_str))
103 exit (1);
103 break; 104 break;
104 105
105 case ARG_FORMAT: 106 case ARG_FORMAT:
......
...@@ -80,7 +80,68 @@ Subject: test input ...@@ -80,7 +80,68 @@ Subject: test input
80 message body 80 message body
81 ]) 81 ])
82 82
83 MH_CHECK([forw msgs],[forw01 forw-msgs],[ 83 MH_CHECK([forw -format msg],[forw01 forw-format-msg],[
84 mkdir Mail/inbox
85 AT_DATA([Mail/inbox/1],[From: gray
86 To: root
87 Subject: test input
88
89 message body
90 ])
91
92 dir=`pwd`
93 echo quit | forwcmd -format +inbox 1 | sed "s|$dir/*||;s| *$||"
94 echo == Mail/draft ==
95 cat Mail/draft
96 echo == Message ==
97 # FIXME: AMD adds this header to the first message. Find a better way.
98 # See also the same sed hacks below.
99 sed '/^X-IMAPbase/d' Mail/inbox/1
100 ],
101 [0],
102 [-- Editor invocation: Mail/draft
103 -- Input file:
104 To:
105 cc:
106 Subject:
107 --------
108
109 ------- Forwarded message
110 From: gray
111 To: root
112 Subject: test input
113
114 message body
115
116 ------- End of Forwarded message
117
118 -- Input file end
119 What now? draft left on "Mail/draft".
120 == Mail/draft ==
121 To:
122 cc:
123 Subject:
124 --------
125
126 ------- Forwarded message
127 From: gray
128 To: root
129 Subject: test input
130
131 message body
132
133 ------- End of Forwarded message
134
135 Seen by mhed
136 == Message ==
137 From: gray
138 To: root
139 Subject: test input
140
141 message body
142 ])
143
144 MH_CHECK([forw msgs],[forw02 forw-msgs],[
84 mkdir Mail/inbox 145 mkdir Mail/inbox
85 AT_DATA([Mail/inbox/1],[From: gray 146 AT_DATA([Mail/inbox/1],[From: gray
86 To: root 147 To: root
...@@ -171,7 +232,7 @@ Subject: 2nd message ...@@ -171,7 +232,7 @@ Subject: 2nd message
171 2nd message body 232 2nd message body
172 ]) 233 ])
173 234
174 MH_CHECK([forw -build msg],[forw02 forw-build-msg],[ 235 MH_CHECK([forw -build msg],[forw03 forw-build-msg],[
175 mkdir Mail/inbox 236 mkdir Mail/inbox
176 AT_DATA([Mail/inbox/1],[From: gray 237 AT_DATA([Mail/inbox/1],[From: gray
177 To: root 238 To: root
...@@ -211,7 +272,7 @@ Subject: test input ...@@ -211,7 +272,7 @@ Subject: test input
211 message body 272 message body
212 ]) 273 ])
213 274
214 MH_CHECK([forw -build -mime msgs],[forw03 forw-build-mime-msg],[ 275 MH_CHECK([forw -build -mime msgs],[forw04 forw-build-mime-msg],[
215 mkdir Mail/inbox 276 mkdir Mail/inbox
216 AT_DATA([Mail/inbox/1],[From: gray 277 AT_DATA([Mail/inbox/1],[From: gray
217 To: root 278 To: root
...@@ -257,7 +318,7 @@ Subject: 2nd message ...@@ -257,7 +318,7 @@ Subject: 2nd message
257 2nd message body 318 2nd message body
258 ]) 319 ])
259 320
260 MH_CHECK([forw -draftfolder],[forw04 forw-draftfolder draftfolder],[ 321 MH_CHECK([forw -draftfolder],[forw05 forw-draftfolder draftfolder],[
261 mkdir Mail/inbox 322 mkdir Mail/inbox
262 mkdir Mail/drafts 323 mkdir Mail/drafts
263 AT_DATA([Mail/inbox/1],[From: gray 324 AT_DATA([Mail/inbox/1],[From: gray
...@@ -316,7 +377,7 @@ Subject: test input ...@@ -316,7 +377,7 @@ Subject: test input
316 message body 377 message body
317 ]) 378 ])
318 379
319 MH_CHECK([forw -file],[forw05 forw-file],[ 380 MH_CHECK([forw -file],[forw06 forw-file],[
320 AT_DATA([infile],[From: gray 381 AT_DATA([infile],[From: gray
321 To: root 382 To: root
322 Subject: test input 383 Subject: test input
......
...@@ -22,10 +22,11 @@ Sequence-Negation: not ...@@ -22,10 +22,11 @@ Sequence-Negation: not
22 Draft-Folder: Mail/drafts 22 Draft-Folder: Mail/drafts
23 Aliasfile: .mh_aliases 23 Aliasfile: .mh_aliases
24 EOT 24 EOT
25 mhparam -all | tr '\t' ' ' | sed 's/^Path:.*/Path: Mail/;s/ */ /g' 25 mhparam -all | tr '\t' ' ' | sed 's/^Path:.*/Path: Mail/;s/^mhetcdir:.*/mhetcdir: dir/;s/ */ /g'
26 ], 26 ],
27 [0], 27 [0],
28 [Path: Mail 28 [Path: Mail
29 mhetcdir: dir
29 Sequence-Negation: not 30 Sequence-Negation: not
30 Draft-Folder: Mail/drafts 31 Draft-Folder: Mail/drafts
31 Aliasfile: .mh_aliases 32 Aliasfile: .mh_aliases
......
...@@ -21,7 +21,10 @@ test -d Mail || mkdir Mail ...@@ -21,7 +21,10 @@ test -d Mail || mkdir Mail
21 dir=`pwd` 21 dir=`pwd`
22 MH=$dir/mh_profile 22 MH=$dir/mh_profile
23 export MH 23 export MH
24 echo "Path: $dir/Mail" > $MH 24 cat > $MH <<EOT
25 Path: $dir/Mail
26 mhetcdir: $abs_top_srcdir/mh
27 EOT
25 exec <&- 28 exec <&-
26 ]) 29 ])
27 30
......