Commit 59740431 597404315ba308889ea2776c56c184d1eb9b02fc by Sergey Poznyakoff

mh: improve component reading (profile, context and whom).

* libmailutils/filter/header.c: New file.
* libmailutils/filter/Makefile.am (libfilter_la_SOURCES): Add header.c.
* libmailutils/filter/filter.c (mu_filter_get_list): Register
mu_header_filter.
* libmailutils/filter/inline-comment.c: (ilcmt_ws)
(ilcmt_rollback): New states.
(ILCMT_REMOVE_EMPTY_LINES,ILCMT_SQUEEZE_WS): New flags.
(ilcmt_data)<buf,size,level,replay>: New members.
(ilcmt_action): New enum
(new_ilcmt_state): Return enum ilcmt_action.
(_ilcmt_decoder): Optionally remove
empty lines and squeeze leading white space.
* libmailutils/property/mhprop.c (_mh_prop_read_stream): Remove
empty lines from the input.

* libmailutils/tests/Makefile.am (TESTSUITE_AT): Add hdrflt.at
and inline-comment.at.
* libmailutils/tests/testsuite.at: Include hdrflt.at and inline-comment.at.
* libmailutils/tests/fltst.c: Pass optional arguments to the
filter creation procedure.

* mh/mh_whom.c (read_header): New function.
(mh_whom): Rewrite using headers.

* include/mailutils/filter.h: Fix a typo.
* libmailutils/stream/fltstream.c: Likewise.
* libmu_auth/gsasl.c: Likewise.
1 parent 72beac0a
...@@ -56,7 +56,7 @@ enum mu_filter_command ...@@ -56,7 +56,7 @@ enum mu_filter_command
56 enum mu_filter_result 56 enum mu_filter_result
57 { 57 {
58 mu_filter_ok, 58 mu_filter_ok,
59 mu_filter_falure, 59 mu_filter_failure,
60 mu_filter_moreinput, 60 mu_filter_moreinput,
61 mu_filter_moreoutput, 61 mu_filter_moreoutput,
62 mu_filter_again 62 mu_filter_again
...@@ -109,6 +109,7 @@ extern mu_filter_record_t mu_rfc_2047_Q_filter; ...@@ -109,6 +109,7 @@ extern mu_filter_record_t mu_rfc_2047_Q_filter;
109 extern mu_filter_record_t mu_rfc_2047_B_filter; 109 extern mu_filter_record_t mu_rfc_2047_B_filter;
110 extern mu_filter_record_t mu_from_filter; 110 extern mu_filter_record_t mu_from_filter;
111 extern mu_filter_record_t mu_inline_comment_filter; 111 extern mu_filter_record_t mu_inline_comment_filter;
112 extern mu_filter_record_t mu_header_filter;
112 113
113 enum mu_iconv_fallback_mode 114 enum mu_iconv_fallback_mode
114 { 115 {
......
...@@ -27,6 +27,7 @@ libfilter_la_SOURCES =\ ...@@ -27,6 +27,7 @@ libfilter_la_SOURCES =\
27 filter.c\ 27 filter.c\
28 filter_iconv.c\ 28 filter_iconv.c\
29 fromflt.c\ 29 fromflt.c\
30 header.c\
30 inline-comment.c\ 31 inline-comment.c\
31 linelenflt.c\ 32 linelenflt.c\
32 qpflt.c 33 qpflt.c
......
...@@ -79,6 +79,7 @@ mu_filter_get_list (mu_list_t *plist) ...@@ -79,6 +79,7 @@ mu_filter_get_list (mu_list_t *plist)
79 mu_list_append (filter_list, mu_rfc_2047_B_filter); 79 mu_list_append (filter_list, mu_rfc_2047_B_filter);
80 mu_list_append (filter_list, mu_from_filter); 80 mu_list_append (filter_list, mu_from_filter);
81 mu_list_append (filter_list, mu_inline_comment_filter); 81 mu_list_append (filter_list, mu_inline_comment_filter);
82 mu_list_append (filter_list, mu_header_filter);
82 /* FIXME: add the default encodings? */ 83 /* FIXME: add the default encodings? */
83 } 84 }
84 *plist = filter_list; 85 *plist = filter_list;
......
1 /* Message header filter for GNU Mailutils.
2 Copyright (C) 2010 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 /* This filter reads the input data up to the first empty line (i.e. \n\n).
18 It is suitable to extract headers from RFC822 messages.
19 */
20
21 #ifdef HAVE_CONFIG_H
22 # include <config.h>
23 #endif
24 #include <stdlib.h>
25 #include <string.h>
26 #include <mailutils/errno.h>
27 #include <mailutils/filter.h>
28 #include <mailutils/cctype.h>
29
30 enum hflt_state
31 {
32 hflt_initial,
33 hflt_newline,
34 hflt_copy
35 };
36
37 static int
38 new_state (int *pd, unsigned c)
39 {
40 switch (*pd)
41 {
42 case hflt_initial:
43 case hflt_copy:
44 *pd = (c == '\n') ? hflt_newline : hflt_copy;
45 break;
46
47 case hflt_newline:
48 if (c == '\n')
49 return 1;
50 *pd = hflt_copy;
51 break;
52 }
53 return 0;
54 }
55
56 static enum mu_filter_result
57 _hflt_decoder (void *xd, enum mu_filter_command cmd,
58 struct mu_filter_io *iobuf)
59 {
60 int *pd = xd;
61 size_t i, j;
62 const unsigned char *iptr;
63 size_t isize;
64 char *optr;
65 size_t osize;
66
67 switch (cmd)
68 {
69 case mu_filter_init:
70 *pd = hflt_initial;
71 return mu_filter_ok;
72
73 case mu_filter_done:
74 return mu_filter_ok;
75
76 default:
77 break;
78 }
79
80 iptr = (const unsigned char *) iobuf->input;
81 isize = iobuf->isize;
82 optr = iobuf->output;
83 osize = iobuf->osize;
84
85 for (i = j = 0; i < isize && j < osize; i++)
86 {
87 unsigned char c = *iptr++;
88 if (new_state (pd, c))
89 {
90 iobuf->eof = 1;
91 break;
92 }
93 optr[j++] = c;
94 }
95
96 iobuf->isize = i;
97 iobuf->osize = j;
98 return mu_filter_ok;
99 }
100
101 static int
102 alloc_state (void **pret, int mode MU_ARG_UNUSED,
103 int argc MU_ARG_UNUSED, const char **argv MU_ARG_UNUSED)
104 {
105 int *pd = malloc (sizeof (*pd));
106
107 if (!pd)
108 return ENOMEM;
109 *pret = pd;
110 return 0;
111 }
112
113 static struct _mu_filter_record _header_filter = {
114 "HEADER",
115 0,
116 alloc_state,
117 NULL,
118 _hflt_decoder
119 };
120
121 mu_filter_record_t mu_header_filter = &_header_filter;
...@@ -36,22 +36,65 @@ ...@@ -36,22 +36,65 @@
36 #include <string.h> 36 #include <string.h>
37 #include <mailutils/errno.h> 37 #include <mailutils/errno.h>
38 #include <mailutils/filter.h> 38 #include <mailutils/filter.h>
39 #include <mailutils/cctype.h>
39 40
40 enum ilcmt_state 41 enum ilcmt_state
41 { 42 {
42 ilcmt_initial, 43 ilcmt_initial,
43 ilcmt_newline, 44 ilcmt_newline,
44 ilcmt_copy, 45 ilcmt_copy,
45 ilcmt_comment 46 ilcmt_comment,
47 ilcmt_ws,
48 ilcmt_rollback
46 }; 49 };
47 50
51 #define ILCMT_REMOVE_EMPTY_LINES 0x01
52 #define ILCMT_SQUEEZE_WS 0x02
53
48 struct ilcmt_data 54 struct ilcmt_data
49 { 55 {
50 enum ilcmt_state state; 56 enum ilcmt_state state;
51 int cstart; 57 int cstart;
58 int flags;
59 char *buf;
60 size_t size;
61 size_t level;
62 size_t replay;
52 }; 63 };
53 64
65 enum ilcmt_action
66 {
67 action_echo,
68 action_noecho,
69 action_error
70 };
71
72 #define ILCMT_BUF_INIT 80
73 #define ILCMT_BUF_INCR 16
74
54 static int 75 static int
76 ilcmt_save (struct ilcmt_data *pd, int c)
77 {
78 if (pd->level == pd->size)
79 {
80 size_t nsz;
81 char *np;
82
83 if (pd->size == 0)
84 nsz = ILCMT_BUF_INIT;
85 else
86 nsz = pd->size + ILCMT_BUF_INCR;
87 np = realloc (pd->buf, nsz);
88 if (!np)
89 return 1;
90 pd->buf = np;
91 pd->size = nsz;
92 }
93 pd->buf[pd->level++] = c;
94 return 0;
95 }
96
97 static enum ilcmt_action
55 new_ilcmt_state (struct ilcmt_data *pd, int c) 98 new_ilcmt_state (struct ilcmt_data *pd, int c)
56 { 99 {
57 switch (pd->state) 100 switch (pd->state)
...@@ -61,12 +104,48 @@ new_ilcmt_state (struct ilcmt_data *pd, int c) ...@@ -61,12 +104,48 @@ new_ilcmt_state (struct ilcmt_data *pd, int c)
61 if (c == pd->cstart) 104 if (c == pd->cstart)
62 { 105 {
63 pd->state = ilcmt_comment; 106 pd->state = ilcmt_comment;
64 return 0; 107 return action_noecho;
108 }
109 else if (c == '\n')
110 {
111 if (pd->flags & ILCMT_REMOVE_EMPTY_LINES)
112 return action_noecho;
113 }
114 else if (mu_isspace (c))
115 {
116 if (pd->flags & ILCMT_REMOVE_EMPTY_LINES)
117 {
118 pd->state = ilcmt_ws;
119 pd->level = 0;
120 if (!(pd->flags & ILCMT_SQUEEZE_WS))
121 {
122 if (ilcmt_save (pd, c))
123 return action_error;
124 }
125 return action_noecho;
126 }
65 } 127 }
66 else
67 pd->state = ilcmt_copy; 128 pd->state = ilcmt_copy;
68 break; 129 break;
69 130
131 case ilcmt_ws:
132 if (c == '\n')
133 pd->state = ilcmt_newline;
134 else if (mu_isspace (c))
135 {
136 if (!(pd->flags & ILCMT_SQUEEZE_WS))
137 {
138 if (ilcmt_save (pd, c))
139 return action_error;
140 }
141 }
142 else
143 {
144 pd->replay = 0;
145 pd->state = ilcmt_rollback;
146 }
147 return action_noecho;
148
70 case ilcmt_copy: 149 case ilcmt_copy:
71 if (c == '\n') 150 if (c == '\n')
72 pd->state = ilcmt_newline; 151 pd->state = ilcmt_newline;
...@@ -75,9 +154,13 @@ new_ilcmt_state (struct ilcmt_data *pd, int c) ...@@ -75,9 +154,13 @@ new_ilcmt_state (struct ilcmt_data *pd, int c)
75 case ilcmt_comment: 154 case ilcmt_comment:
76 if (c == '\n') 155 if (c == '\n')
77 pd->state = ilcmt_newline; 156 pd->state = ilcmt_newline;
78 return 0; 157 return action_noecho;
158
159 default:
160 /* should not happen */
161 break;
79 } 162 }
80 return 1; 163 return action_echo;
81 } 164 }
82 165
83 static enum mu_filter_result 166 static enum mu_filter_result
...@@ -109,11 +192,50 @@ _ilcmt_decoder (void *xd, enum mu_filter_command cmd, ...@@ -109,11 +192,50 @@ _ilcmt_decoder (void *xd, enum mu_filter_command cmd,
109 optr = iobuf->output; 192 optr = iobuf->output;
110 osize = iobuf->osize; 193 osize = iobuf->osize;
111 194
112 for (i = j = 0; i < isize && j < osize; i++) 195 i = j = 0;
196 if (pd->state == ilcmt_rollback)
197 {
198 if (pd->flags & ILCMT_SQUEEZE_WS)
199 {
200 if (j == osize)
201 {
202 iobuf->osize = 1;
203 return mu_filter_moreoutput;
204 }
205 optr[j++] = ' ';
206 pd->state = ilcmt_copy;
207 }
208 else
209 while (j < osize)
210 {
211 if (pd->replay == pd->level)
212 {
213 pd->state = ilcmt_copy;
214 break;
215 }
216 optr[j++] = pd->buf[pd->replay++];
217 }
218
219 if (pd->state == ilcmt_copy)
220 {
221 /* Clear the buffer state. */
222 pd->level = pd->replay = 0;
223 }
224 }
225
226 for (; i < isize && j < osize; i++)
113 { 227 {
114 unsigned char c = *iptr++; 228 unsigned char c = *iptr++;
115 if (new_ilcmt_state (pd, c)) 229 enum ilcmt_action action = new_ilcmt_state (pd, c);
230 if (action == action_echo)
116 optr[j++] = c; 231 optr[j++] = c;
232 else if (action == action_noecho)
233 {
234 if (pd->state == ilcmt_rollback)
235 break;
236 }
237 else
238 return mu_filter_failure;
117 } 239 }
118 240
119 iobuf->isize = i; 241 iobuf->isize = i;
...@@ -125,14 +247,39 @@ static int ...@@ -125,14 +247,39 @@ static int
125 alloc_state (void **pret, int mode MU_ARG_UNUSED, int argc, const char **argv) 247 alloc_state (void **pret, int mode MU_ARG_UNUSED, int argc, const char **argv)
126 { 248 {
127 struct ilcmt_data *pd = malloc (sizeof (*pd)); 249 struct ilcmt_data *pd = malloc (sizeof (*pd));
250 int i;
128 251
129 if (!pd) 252 if (!pd)
130 return ENOMEM; 253 return ENOMEM;
131 254
132 if (argc == 2)
133 pd->cstart = argv[1][0];
134 else
135 pd->cstart = ';'; 255 pd->cstart = ';';
256 pd->flags = 0;
257 pd->buf = NULL;
258 pd->size = pd->level = pd->replay = 0;
259
260 for (i = 1; i < argc; i++)
261 {
262 if (argv[i][1] == 0)
263 pd->cstart = argv[i][0];
264 else if (argv[i][0] == '-')
265 {
266 switch (argv[i][1])
267 {
268 case 'r':
269 pd->flags |= ILCMT_REMOVE_EMPTY_LINES;
270 break;
271
272 case 's':
273 pd->flags |= ILCMT_SQUEEZE_WS;
274 break;
275
276 default:
277 free (pd);
278 return MU_ERR_PARSE;
279 }
280 }
281 }
282
136 *pret = pd; 283 *pret = pd;
137 284
138 return 0; 285 return 0;
......
...@@ -100,7 +100,7 @@ _mh_prop_read_stream (mu_header_t *phdr, mu_stream_t stream) ...@@ -100,7 +100,7 @@ _mh_prop_read_stream (mu_header_t *phdr, mu_stream_t stream)
100 { 100 {
101 int rc; 101 int rc;
102 mu_stream_t flt; 102 mu_stream_t flt;
103 const char *argv[3]; 103 const char *argv[4];
104 mu_off_t size; 104 mu_off_t size;
105 size_t total; 105 size_t total;
106 char *blurb; 106 char *blurb;
...@@ -111,7 +111,8 @@ _mh_prop_read_stream (mu_header_t *phdr, mu_stream_t stream) ...@@ -111,7 +111,8 @@ _mh_prop_read_stream (mu_header_t *phdr, mu_stream_t stream)
111 111
112 argv[0] = "INLINE-COMMENT"; 112 argv[0] = "INLINE-COMMENT";
113 argv[1] = "#"; 113 argv[1] = "#";
114 argv[2] = NULL; 114 argv[2] = "-r";
115 argv[3] = NULL;
115 rc = mu_filter_create_args (&flt, stream, argv[0], 2, argv, 116 rc = mu_filter_create_args (&flt, stream, argv[0], 2, argv,
116 MU_FILTER_DECODE, MU_STREAM_READ); 117 MU_FILTER_DECODE, MU_STREAM_READ);
117 if (rc) 118 if (rc)
......
...@@ -60,7 +60,7 @@ filter_stream_init (struct _mu_filter_stream *fs) ...@@ -60,7 +60,7 @@ filter_stream_init (struct _mu_filter_stream *fs)
60 { 60 {
61 struct mu_filter_io iobuf; 61 struct mu_filter_io iobuf;
62 memset (&iobuf, 0, sizeof (iobuf)); 62 memset (&iobuf, 0, sizeof (iobuf));
63 if (fs->xcode (fs->xdata, mu_filter_init, &iobuf) == mu_filter_falure) 63 if (fs->xcode (fs->xdata, mu_filter_init, &iobuf) == mu_filter_failure)
64 return iobuf.errcode; 64 return iobuf.errcode;
65 } 65 }
66 return 0; 66 return 0;
...@@ -182,7 +182,7 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret) ...@@ -182,7 +182,7 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret)
182 } 182 }
183 break; 183 break;
184 184
185 case mu_filter_falure: 185 case mu_filter_failure:
186 return iobuf.errcode; 186 return iobuf.errcode;
187 187
188 case mu_filter_moreinput: 188 case mu_filter_moreinput:
...@@ -288,7 +288,7 @@ filter_write_internal (mu_stream_t stream, enum mu_filter_command cmd, ...@@ -288,7 +288,7 @@ filter_write_internal (mu_stream_t stream, enum mu_filter_command cmd,
288 } 288 }
289 break; 289 break;
290 290
291 case mu_filter_falure: 291 case mu_filter_failure:
292 return iobuf.errcode; 292 return iobuf.errcode;
293 293
294 case mu_filter_moreinput: 294 case mu_filter_moreinput:
......
...@@ -68,6 +68,8 @@ TESTSUITE_AT = \ ...@@ -68,6 +68,8 @@ TESTSUITE_AT = \
68 decode2047.at\ 68 decode2047.at\
69 encode2047.at\ 69 encode2047.at\
70 fromflt.at\ 70 fromflt.at\
71 hdrflt.at\
72 inline-comment.at\
71 list.at\ 73 list.at\
72 mailcap.at\ 74 mailcap.at\
73 prop.at\ 75 prop.at\
......
...@@ -99,7 +99,7 @@ usage (const char *diag) ...@@ -99,7 +99,7 @@ usage (const char *diag)
99 fp = stdout; 99 fp = stdout;
100 100
101 fprintf (fp, "%s", 101 fprintf (fp, "%s",
102 "usage: fltst FILTER {encode|decode} {read|write} [shift=N] [linelen=N] [verbose] [printable] [nl]\n"); 102 "usage: fltst FILTER {encode|decode} {read|write} [shift=N] [linelen=N] [verbose] [printable] [nl] [-- args]\n");
103 exit (diag ? 1 : 0); 103 exit (diag ? 1 : 0);
104 } 104 }
105 105
...@@ -152,10 +152,18 @@ main (int argc, char * argv []) ...@@ -152,10 +152,18 @@ main (int argc, char * argv [])
152 printable++; 152 printable++;
153 else if (strcmp (argv[i], "nl") == 0) 153 else if (strcmp (argv[i], "nl") == 0)
154 newline_option++; 154 newline_option++;
155 else if (strcmp (argv[i], "--") == 0)
156 {
157 argv[i] = fltname;
158 break;
159 }
155 else 160 else
156 usage ("wrong option"); 161 usage ("wrong option");
157 } 162 }
158 163
164 argc -= i;
165 argv += i;
166
159 MU_ASSERT (mu_stdio_stream_create (&in, MU_STDIN_FD, 0)); 167 MU_ASSERT (mu_stdio_stream_create (&in, MU_STDIN_FD, 0));
160 MU_ASSERT (mu_stdio_stream_create (&out, MU_STDOUT_FD, 0)); 168 MU_ASSERT (mu_stdio_stream_create (&out, MU_STDOUT_FD, 0));
161 169
...@@ -164,7 +172,9 @@ main (int argc, char * argv []) ...@@ -164,7 +172,9 @@ main (int argc, char * argv [])
164 172
165 if (flags == MU_STREAM_READ) 173 if (flags == MU_STREAM_READ)
166 { 174 {
167 MU_ASSERT (mu_filter_create (&flt, in, fltname, mode, 175 MU_ASSERT (mu_filter_create_args (&flt, in, fltname,
176 argc, (const char **)argv,
177 mode,
168 MU_STREAM_READ|MU_STREAM_SEEK| 178 MU_STREAM_READ|MU_STREAM_SEEK|
169 MU_STREAM_AUTOCLOSE)); 179 MU_STREAM_AUTOCLOSE));
170 if (shift) 180 if (shift)
...@@ -173,7 +183,9 @@ main (int argc, char * argv []) ...@@ -173,7 +183,9 @@ main (int argc, char * argv [])
173 } 183 }
174 else 184 else
175 { 185 {
176 MU_ASSERT (mu_filter_create (&flt, out, fltname, mode, 186 MU_ASSERT (mu_filter_create_args (&flt, out, fltname,
187 argc, (const char **)argv,
188 mode,
177 MU_STREAM_WRITE)); 189 MU_STREAM_WRITE));
178 if (shift) 190 if (shift)
179 MU_ASSERT (mu_stream_seek (in, shift, MU_SEEK_SET, NULL)); 191 MU_ASSERT (mu_stream_seek (in, shift, MU_SEEK_SET, NULL));
......
1 # This file is part of GNU Mailutils. -*- Autotest -*-
2 # Copyright (C) 2010 Free Software Foundation, Inc.
3 #
4 # GNU Mailutils is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License as
6 # published by the Free Software Foundation; either version 3, or (at
7 # your option) any later version.
8 #
9 # GNU Mailutils is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # 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 AT_SETUP([header filter])
18 AT_KEYWORDS([header-filter hdrflt])
19
20 AT_DATA([input],
21 [From: gray@gnu.org
22 To: root@example.com
23 Subject: test
24
25 Mon beau pays par l'hiver soumis
26 Quand reverrons-nous l'hirondelle
27 Noire et blanche, noire et blanche
28 Quand reverrons-nous l'hirondelle
29 Blanche au ventre et noire aux ailes
30 ])
31
32 AT_DATA([expout],[dnl
33 From: gray@gnu.org
34 To: root@example.com
35 Subject: test
36 ])
37
38
39 AT_CHECK([fltst header decode read < input],[0],[expout])
40 AT_CHECK([fltst header decode write < input],[0],[expout])
41
42 AT_CLEANUP
...\ No newline at end of file ...\ No newline at end of file
1 # This file is part of GNU Mailutils. -*- Autotest -*-
2 # Copyright (C) 2010 Free Software Foundation, Inc.
3 #
4 # GNU Mailutils is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License as
6 # published by the Free Software Foundation; either version 3, or (at
7 # your option) any later version.
8 #
9 # GNU Mailutils is distributed in the hope that it will be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 # 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 dnl -------------------------------------------------------------------
18 dnl INLINECOM(NAME, [KW = `'], [OPTS = `'], [TEXT], [OUTPUT = `'])
19 dnl -------------------------------------------------------------------
20 m4_pushdef([INLINECOM],[
21 AT_SETUP([inline-comment: $1])
22 AT_KEYWORDS([filter inline-comment icmt $2])
23 sed 's/\$.*//' > input <<EOT
24 $4
25 EOT
26 sed 's/\$.*//' > expout <<EOT
27 $5
28 EOT
29
30 AT_CHECK([fltst inline-comment decode read $3 < input],
31 [0],
32 [expout])
33 AT_CHECK([fltst inline-comment decode write $3 < input],
34 [0],
35 [expout])
36 AT_CLEANUP
37 ])
38
39 dnl -------------------------------------------------------------------
40
41 INLINECOM([default], [icmt00], [],
42 [; comment 1
43 text 1
44 ; comment 2
45 text 2
46
47 text 3
48 ; comment 3
49 ],
50 [text 1
51 text 2
52
53 text 3
54 ])
55
56 INLINECOM([change comment starter], [icmt02], [-- %],
57 [% comment 1
58 text 1
59 % comment 2
60 text 2
61
62 text 3
63 % comment 3
64 ],
65 [text 1
66 text 2
67
68 text 3
69 ])
70
71 INLINECOM([remove empty lines],[icmt03],[-- -r],
72 [; comment 1
73 text 1
74 ; comment 2
75 ; comment 3
76 text 2
77
78 text 3
79
80 $
81 text 4
82 text 5
83 ],
84 [text 1
85 text 2
86 text 3
87 text 4
88 text 5[]dnl
89 ])
90
91 INLINECOM([remove empty lines/squeeze whitespace],[icmt04],[-- -r -s],
92 [; comment 1
93 text 1
94 ; comment 2
95 ; comment 3
96 text 2
97
98 text 3
99
100 $
101 text 4
102 text 5
103 ],
104 [text 1
105 text 2
106 text 3
107 text 4
108 text 5[]dnl
109 ])
110
111
112 m4_popdef([INLINECOM])
113 # End of inline-comment.at
...@@ -66,4 +66,6 @@ m4_include([encode2047.at]) ...@@ -66,4 +66,6 @@ m4_include([encode2047.at])
66 m4_include([fromflt.at]) 66 m4_include([fromflt.at])
67 m4_include([wicket.at]) 67 m4_include([wicket.at])
68 m4_include([prop.at]) 68 m4_include([prop.at])
69 m4_include([inline-comment.at])
70 m4_include([hdrflt.at])
69 71
......
...@@ -82,7 +82,7 @@ _gsasl_encoder (void *xdata, ...@@ -82,7 +82,7 @@ _gsasl_encoder (void *xdata,
82 if (status) 82 if (status)
83 { 83 {
84 flt->gsasl_err = status; 84 flt->gsasl_err = status;
85 return mu_filter_falure; 85 return mu_filter_failure;
86 } 86 }
87 } 87 }
88 88
...@@ -141,7 +141,7 @@ _gsasl_decoder (void *xdata, ...@@ -141,7 +141,7 @@ _gsasl_decoder (void *xdata,
141 141
142 default: 142 default:
143 flt->gsasl_err = status; 143 flt->gsasl_err = status;
144 return mu_filter_falure; 144 return mu_filter_failure;
145 } 145 }
146 } 146 }
147 147
......
...@@ -198,6 +198,64 @@ _print_local_recipient (void *item, void *data) ...@@ -198,6 +198,64 @@ _print_local_recipient (void *item, void *data)
198 return 0; 198 return 0;
199 } 199 }
200 200
201 static mu_header_t
202 read_header (mu_stream_t stream)
203 {
204 int rc;
205 mu_stream_t flt;
206 mu_off_t size;
207 size_t total;
208 char *blurb;
209 mu_header_t hdr;
210
211 rc = mu_stream_size (stream, &size);
212 if (rc)
213 {
214 mu_error (_("cannot get stream size: %s"), mu_strerror (rc));
215 exit (1);
216 }
217
218 rc = mu_filter_create (&flt, stream, "HEADER",
219 MU_FILTER_DECODE, MU_STREAM_READ);
220 if (rc)
221 {
222 mu_error (_("cannot open filter stream: %s"), mu_strerror (rc));
223 exit (1);
224 }
225
226 blurb = xmalloc (size + 1);
227
228 total = 0;
229 while (1)
230 {
231 size_t n;
232
233 rc = mu_stream_read (flt, blurb + total, size - total, &n);
234 if (rc)
235 break;
236 if (n == 0)
237 break;
238 total += n;
239 }
240
241 mu_stream_destroy (&flt);
242 if (rc)
243 {
244 free (blurb);
245 mu_error (_("read error: %s"), mu_strerror (rc));
246 exit (1);
247 }
248
249 rc = mu_header_create (&hdr, blurb, total);
250 free (blurb);
251 if (rc)
252 {
253 mu_diag_funcall (MU_DIAG_ERROR, "mu_header_create", NULL, rc);
254 exit (1);
255 }
256 return hdr;
257 }
258
201 int 259 int
202 mh_whom (const char *filename, int check) 260 mh_whom (const char *filename, int check)
203 { 261 {
...@@ -205,19 +263,35 @@ mh_whom (const char *filename, int check) ...@@ -205,19 +263,35 @@ mh_whom (const char *filename, int check)
205 263
206 if (access (filename, R_OK)) 264 if (access (filename, R_OK))
207 { 265 {
208 mu_error ("%s: %s", filename, mu_strerror (rc)); 266 mu_error ("%s: %s", filename, mu_strerror (errno));
209 rc = -1; 267 rc = -1;
210 } 268 }
211 else 269 else
212 { 270 {
213 size_t count = 0; 271 size_t count = 0;
214 mu_property_t prop; 272 mu_header_t hdr;
273 mu_stream_t str;
274 int rc;
275 const char *val;
276
277 rc = mu_file_stream_create (&str, filename, MU_STREAM_READ);
278 if (rc)
279 {
280 mu_diag_funcall (MU_DIAG_ERROR, "mu_file_stream_create",
281 filename, rc);
282 exit (1);
283 }
284 hdr = read_header (str);
285 mu_stream_unref (str);
215 286
216 mh_read_aliases (); 287 mh_read_aliases ();
217 prop = mh_read_property_file (xstrdup (filename), 1); 288
218 scan_addrs (mu_mhprop_get_value (prop, MU_HEADER_TO, NULL), 0); 289 if (mu_header_sget_value (hdr, MU_HEADER_TO, &val) == 0)
219 scan_addrs (mu_mhprop_get_value (prop, MU_HEADER_CC, NULL), 0); 290 scan_addrs (val, 0);
220 scan_addrs (mu_mhprop_get_value (prop, MU_HEADER_BCC, NULL), 1); 291 if (mu_header_sget_value (hdr, MU_HEADER_CC, &val) == 0)
292 scan_addrs (val, 0);
293 if (mu_header_sget_value (hdr, MU_HEADER_BCC, &val) == 0)
294 scan_addrs (val, 1);
221 295
222 if (local_rcp) 296 if (local_rcp)
223 { 297 {
...@@ -236,7 +310,7 @@ mh_whom (const char *filename, int check) ...@@ -236,7 +310,7 @@ mh_whom (const char *filename, int check)
236 mu_error(_("no recipients")); 310 mu_error(_("no recipients"));
237 rc = -1; 311 rc = -1;
238 } 312 }
239 mu_property_destroy (&prop); 313 mu_header_destroy (&hdr);
240 } 314 }
241 destroy_addrs (&network_rcp); 315 destroy_addrs (&network_rcp);
242 destroy_addrs (&local_rcp); 316 destroy_addrs (&local_rcp);
......