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.
Showing
14 changed files
with
552 additions
and
35 deletions
... | @@ -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 | { | ... | ... |
... | @@ -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; | ... | ... |
libmailutils/filter/header.c
0 → 100644
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,11 +104,47 @@ new_ilcmt_state (struct ilcmt_data *pd, int c) | ... | @@ -61,11 +104,47 @@ 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; |
65 | } | 108 | } |
66 | else | 109 | else if (c == '\n') |
67 | pd->state = ilcmt_copy; | 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 | } | ||
127 | } | ||
128 | pd->state = ilcmt_copy; | ||
68 | break; | 129 | break; |
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; | ||
69 | 148 | ||
70 | case ilcmt_copy: | 149 | case ilcmt_copy: |
71 | if (c == '\n') | 150 | if (c == '\n') |
... | @@ -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) | 255 | pd->cstart = ';'; |
133 | pd->cstart = argv[1][0]; | 256 | pd->flags = 0; |
134 | else | 257 | pd->buf = NULL; |
135 | pd->cstart = ';'; | 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: | ... | ... |
... | @@ -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,9 +152,17 @@ main (int argc, char * argv []) | ... | @@ -152,9 +152,17 @@ 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 | } |
163 | |||
164 | argc -= i; | ||
165 | argv += i; | ||
158 | 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)); |
... | @@ -164,17 +172,21 @@ main (int argc, char * argv []) | ... | @@ -164,17 +172,21 @@ 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, |
168 | MU_STREAM_READ|MU_STREAM_SEEK| | 176 | argc, (const char **)argv, |
169 | MU_STREAM_AUTOCLOSE)); | 177 | mode, |
178 | MU_STREAM_READ|MU_STREAM_SEEK| | ||
179 | MU_STREAM_AUTOCLOSE)); | ||
170 | if (shift) | 180 | if (shift) |
171 | MU_ASSERT (mu_stream_seek (flt, shift, MU_SEEK_SET, NULL)); | 181 | MU_ASSERT (mu_stream_seek (flt, shift, MU_SEEK_SET, NULL)); |
172 | c_copy (out, flt); | 182 | c_copy (out, flt); |
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, |
177 | MU_STREAM_WRITE)); | 187 | argc, (const char **)argv, |
188 | mode, | ||
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)); |
180 | c_copy (flt, in); | 192 | c_copy (flt, in); | ... | ... |
libmailutils/tests/hdrflt.at
0 → 100644
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 |
libmailutils/tests/inline-comment.at
0 → 100644
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 | ... | ... |
... | @@ -197,7 +197,65 @@ _print_local_recipient (void *item, void *data) | ... | @@ -197,7 +197,65 @@ _print_local_recipient (void *item, void *data) |
197 | (*count)++; | 197 | (*count)++; |
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; |
215 | 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); | ||
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); | ... | ... |
-
Please register or sign in to post a comment