Commit f8fc2081 f8fc2081dffd950ab1c6082e4a32f0096bd7415d by Sergey Poznyakoff

mail: implement struct command.

* NEWS, doc/texinfo/programs.texi: Document struct command.
* mail/struct.c: New file.
* mail/Makefile.am (mail_SOURCES): Add struct.c
* mail/decode.c (fprint_msgset, mime_descend): New functions.
Rewrite the rest using mime_descend.
* mail/mail.h (mail_struct): New function.
(MDHINT_SELECTED_HEADERS): New define.
(struct mime_descend_closure, mime_descend_fn): New types.
(mime_descend): New proto.
(util_get_content_type): Get two arguments.
* mail/table.c (mail_command_table): Add st[ruct].
* mail/util.c (util_get_content_type): Get two arguments.
All callers updated.
(util_get_hdr_value): use mu_header_aget_value_unfold and
mu_rtrim_class.
1 parent 0517ca03
1 GNU mailutils NEWS -- history of user-visible changes. 2009-07-12 1 GNU mailutils NEWS -- history of user-visible changes. 2009-07-13
2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2 Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007,
3 2008, 2009 Free Software Foundation, Inc. 3 2008, 2009 Free Software Foundation, Inc.
4 See the end of file for copying conditions. 4 See the end of file for copying conditions.
...@@ -53,6 +53,15 @@ is also allowed. ...@@ -53,6 +53,15 @@ is also allowed.
53 The -F option (record outgoing messages in a file named after the 53 The -F option (record outgoing messages in a file named after the
54 first recipient) is implemented. 54 first recipient) is implemented.
55 55
56 ** struct command
57
58 The st[ruct] command allows to list message MIME structures, e.g.:
59
60 & struct 2
61 2[1] text/plain 513
62 2[2] application/octal-stream 247K
63 2[3] text/x-diff 31K
64
56 ** error locations 65 ** error locations
57 66
58 Diagnostic messages issued while processing `source' command 67 Diagnostic messages issued while processing `source' command
......
...@@ -2878,6 +2878,7 @@ Displays current mailbox summary. E.g.: ...@@ -2878,6 +2878,7 @@ Displays current mailbox summary. E.g.:
2878 @kyindex Print, mail command 2878 @kyindex Print, mail command
2879 @kyindex Type, mail command 2879 @kyindex Type, mail command
2880 @kyindex decode, mail command 2880 @kyindex decode, mail command
2881 @kyindex struct, mail command
2881 @kyindex top, mail command 2882 @kyindex top, mail command
2882 @kyindex pipe, mail command 2883 @kyindex pipe, mail command
2883 @kyindex |, mail command 2884 @kyindex |, mail command
...@@ -2926,6 +2927,21 @@ defaults to five. ...@@ -2926,6 +2927,21 @@ defaults to five.
2926 Pipe the contents of specified messages through @var{shell-command}. If 2927 Pipe the contents of specified messages through @var{shell-command}. If
2927 @var{shell-command} is empty but the string variable @code{cmd} is set, 2928 @var{shell-command} is empty but the string variable @code{cmd} is set,
2928 the value of this variable is used as a command name. 2929 the value of this variable is used as a command name.
2930 @item struct [@var{msglist}]
2931 Prints the @acronym{MIME} structure of each message from
2932 @var{msglist}. Empty @var{msglist} means current message.
2933
2934 Example:
2935
2936 @smallexample
2937 @cartouche
2938 & struct 2
2939 2 multipart/mixed 14k
2940 2[1] text/plain 296
2941 2[2] application/octet-stream 5k
2942 2[3] text/x-diff 31k
2943 @end cartouche
2944 @end smallexample
2929 @end table 2945 @end table
2930 2946
2931 @node Marking Messages 2947 @node Marking Messages
......
...@@ -84,6 +84,7 @@ mail_SOURCES = \ ...@@ -84,6 +84,7 @@ mail_SOURCES = \
84 shell.c\ 84 shell.c\
85 size.c\ 85 size.c\
86 source.c\ 86 source.c\
87 struct.c\
87 summary.c\ 88 summary.c\
88 table.c\ 89 table.c\
89 tag.c\ 90 tag.c\
......
...@@ -33,7 +33,8 @@ struct decode_closure ...@@ -33,7 +33,8 @@ struct decode_closure
33 33
34 static int print_stream (mu_stream_t, FILE *); 34 static int print_stream (mu_stream_t, FILE *);
35 static int display_message (mu_message_t, msgset_t *msgset, void *closure); 35 static int display_message (mu_message_t, msgset_t *msgset, void *closure);
36 static int display_message0 (mu_message_t, const msgset_t *, int); 36 static int display_submessage (struct mime_descend_closure *closure,
37 void *data);
37 static int get_content_encoding (mu_header_t hdr, char **value); 38 static int get_content_encoding (mu_header_t hdr, char **value);
38 static void run_metamail (const char *mailcap, mu_message_t mesg); 39 static void run_metamail (const char *mailcap, mu_message_t mesg);
39 40
...@@ -59,12 +60,20 @@ display_message (mu_message_t mesg, msgset_t *msgset, void *arg) ...@@ -59,12 +60,20 @@ display_message (mu_message_t mesg, msgset_t *msgset, void *arg)
59 { 60 {
60 struct decode_closure *closure = arg; 61 struct decode_closure *closure = arg;
61 mu_attribute_t attr = NULL; 62 mu_attribute_t attr = NULL;
62 63 struct mime_descend_closure mclos;
64
63 mu_message_get_attribute (mesg, &attr); 65 mu_message_get_attribute (mesg, &attr);
64 if (mu_attribute_is_deleted (attr)) 66 if (mu_attribute_is_deleted (attr))
65 return 1; 67 return 1;
66 68
67 display_message0 (mesg, msgset, closure->select_hdr); 69 mclos.hints = closure->select_hdr ? MDHINT_SELECTED_HEADERS : 0;
70 mclos.msgset = msgset;
71 mclos.message = mesg;
72 mclos.type = NULL;
73 mclos.encoding = NULL;
74 mclos.parent = NULL;
75
76 mime_descend (&mclos, display_submessage, NULL);
68 77
69 /* Mark enclosing message as read */ 78 /* Mark enclosing message as read */
70 if (mu_mailbox_get_message (mbox, msgset->msg_part[0], &mesg) == 0) 79 if (mu_mailbox_get_message (mbox, msgset->msg_part[0], &mesg) == 0)
...@@ -112,9 +121,23 @@ display_headers (FILE *out, mu_message_t mesg, ...@@ -112,9 +121,23 @@ display_headers (FILE *out, mu_message_t mesg,
112 } 121 }
113 } 122 }
114 123
124 size_t
125 fprint_msgset (FILE *fp, const msgset_t *msgset)
126 {
127 int i;
128 size_t n = 0;
129
130 n = fprintf (fp, "%d", msgset->msg_part[0]);
131 for (i = 1; i < msgset->npart; i++)
132 n += fprintf (fp, "[%d", msgset->msg_part[i]);
133 for (i = 1; i < msgset->npart; i++)
134 n += fprintf (fp, "]");
135 return n;
136 }
137
115 static void 138 static void
116 display_part_header (FILE *out, const msgset_t *msgset, 139 display_part_header (FILE *out, const msgset_t *msgset,
117 char *type, char *encoding) 140 const char *type, const char *encoding)
118 { 141 {
119 int size = util_screen_columns () - 3; 142 int size = util_screen_columns () - 3;
120 unsigned int i; 143 unsigned int i;
...@@ -124,11 +147,8 @@ display_part_header (FILE *out, const msgset_t *msgset, ...@@ -124,11 +147,8 @@ display_part_header (FILE *out, const msgset_t *msgset,
124 fputc ('-', out); 147 fputc ('-', out);
125 fputc ('+', out); 148 fputc ('+', out);
126 fputc ('\n', out); 149 fputc ('\n', out);
127 fprintf (out, _("| Message=%d"), msgset->msg_part[0]); 150 fprintf (out, "%s", _("| Message="));
128 for (i = 1; i < msgset->npart; i++) 151 fprint_msgset (out, msgset);
129 fprintf (out, "[%d", msgset->msg_part[i]);
130 for (i = 1; i < msgset->npart; i++)
131 fprintf (out, "]");
132 fprintf (out, "\n"); 152 fprintf (out, "\n");
133 153
134 fprintf (out, _("| Type=%s\n"), type); 154 fprintf (out, _("| Type=%s\n"), type);
...@@ -140,38 +160,49 @@ display_part_header (FILE *out, const msgset_t *msgset, ...@@ -140,38 +160,49 @@ display_part_header (FILE *out, const msgset_t *msgset,
140 fputc ('\n', out); 160 fputc ('\n', out);
141 } 161 }
142 162
143 static int 163 int
144 display_message0 (mu_message_t mesg, const msgset_t *msgset, 164 mime_descend (struct mime_descend_closure *closure,
145 int select_hdr) 165 mime_descend_fn fun, void *data)
146 { 166 {
167 int status = 0;
147 size_t nparts = 0; 168 size_t nparts = 0;
148 mu_header_t hdr = NULL; 169 mu_header_t hdr = NULL;
149 char *type; 170 char *type;
150 char *encoding; 171 char *encoding;
151 int ismime = 0; 172 int ismime = 0;
152 char *tmp; 173 struct mime_descend_closure subclosure;
153 174
154 mu_message_get_header (mesg, &hdr); 175 mu_message_get_header (closure->message, &hdr);
155 util_get_content_type (hdr, &type); 176 util_get_content_type (hdr, &type, NULL);
156 get_content_encoding (hdr, &encoding); 177 get_content_encoding (hdr, &encoding);
157 178
158 mu_message_is_multipart (mesg, &ismime); 179 closure->type = type;
180 closure->encoding = encoding;
181
182 subclosure.hints = 0;
183 subclosure.parent = closure;
184
185 mu_message_is_multipart (closure->message, &ismime);
159 if (ismime) 186 if (ismime)
160 { 187 {
161 unsigned int j; 188 unsigned int j;
162 189
163 mu_message_get_num_parts (mesg, &nparts); 190 mu_message_get_num_parts (closure->message, &nparts);
164 191
165 for (j = 1; j <= nparts; j++) 192 for (j = 1; j <= nparts; j++)
166 { 193 {
167 mu_message_t message = NULL; 194 mu_message_t message = NULL;
168 195
169 if (mu_message_get_part (mesg, j, &message) == 0) 196 if (mu_message_get_part (closure->message, j, &message) == 0)
170 { 197 {
171 msgset_t *set = msgset_expand (msgset_dup (msgset), 198 msgset_t *set = msgset_expand (msgset_dup (closure->msgset),
172 msgset_make_1 (j)); 199 msgset_make_1 (j));
173 display_message0 (message, set, 0); 200 subclosure.msgset = set;
201 subclosure.message = message;
202 status = mime_descend (&subclosure, fun, data);
174 msgset_free (set); 203 msgset_free (set);
204 if (status)
205 break;
175 } 206 }
176 } 207 }
177 } 208 }
...@@ -179,14 +210,36 @@ display_message0 (mu_message_t mesg, const msgset_t *msgset, ...@@ -179,14 +210,36 @@ display_message0 (mu_message_t mesg, const msgset_t *msgset,
179 { 210 {
180 mu_message_t submsg = NULL; 211 mu_message_t submsg = NULL;
181 212
182 if (mu_message_unencapsulate (mesg, &submsg, NULL) == 0) 213 if (mu_message_unencapsulate (closure->message, &submsg, NULL) == 0)
183 display_message0 (submsg, msgset, select_hdr); 214 {
215 subclosure.hints = MDHINT_SELECTED_HEADERS;
216 subclosure.msgset = closure->msgset;
217 subclosure.message = submsg;
218 status = mime_descend (&subclosure, fun, data);
219 }
184 } 220 }
185 else if (mailvar_get (&tmp, "metamail", mailvar_type_string, 0) == 0) 221 else
222 status = fun (closure, data);
223
224 closure->type = NULL;
225 closure->encoding = NULL;
226
227 free (type);
228 free (encoding);
229
230 return status;
231 }
232
233 static int
234 display_submessage (struct mime_descend_closure *closure, void *data)
235 {
236 char *tmp;
237
238 if (mailvar_get (&tmp, "metamail", mailvar_type_string, 0) == 0)
186 { 239 {
187 /* If `metamail' is set to a string, treat it as command line 240 /* If `metamail' is set to a string, treat it as command line
188 of external metamail program. */ 241 of external metamail program. */
189 run_metamail (tmp, mesg); 242 run_metamail (tmp, closure->message);
190 } 243 }
191 else 244 else
192 { 245 {
...@@ -197,19 +250,20 @@ display_message0 (mu_message_t mesg, const msgset_t *msgset, ...@@ -197,19 +250,20 @@ display_message0 (mu_message_t mesg, const msgset_t *msgset,
197 mu_stream_t stream = NULL; 250 mu_stream_t stream = NULL;
198 mu_header_t hdr = NULL; 251 mu_header_t hdr = NULL;
199 252
200 mu_message_get_body (mesg, &body); 253 mu_message_get_body (closure->message, &body);
201 mu_message_get_header (mesg, &hdr); 254 mu_message_get_header (closure->message, &hdr);
202 mu_body_get_stream (body, &b_stream); 255 mu_body_get_stream (body, &b_stream);
203 256
204 /* Can we decode. */ 257 /* Can we decode. */
205 if (mu_filter_create(&d_stream, b_stream, encoding, 258 if (mu_filter_create(&d_stream, b_stream, closure->encoding,
206 MU_FILTER_DECODE, MU_STREAM_READ) == 0) 259 MU_FILTER_DECODE, MU_STREAM_READ) == 0)
207 stream = d_stream; 260 stream = d_stream;
208 else 261 else
209 stream = b_stream; 262 stream = b_stream;
210 263
211 display_part_header (ofile, msgset, type, encoding); 264 display_part_header (ofile, closure->msgset,
212 265 closure->type, closure->encoding);
266
213 /* If `metamail' is set to true, enable internal mailcap 267 /* If `metamail' is set to true, enable internal mailcap
214 support */ 268 support */
215 if (mailvar_get (NULL, "metamail", mailvar_type_boolean, 0) == 0) 269 if (mailvar_get (NULL, "metamail", mailvar_type_boolean, 0) == 0)
...@@ -225,33 +279,31 @@ display_message0 (mu_message_t mesg, const msgset_t *msgset, ...@@ -225,33 +279,31 @@ display_message0 (mu_message_t mesg, const msgset_t *msgset,
225 builtin_display = display_stream_mailcap (NULL, stream, hdr, no_ask, 279 builtin_display = display_stream_mailcap (NULL, stream, hdr, no_ask,
226 interactive, 0, debug); 280 interactive, 0, debug);
227 } 281 }
228 282
229 if (builtin_display) 283 if (builtin_display)
230 { 284 {
231 size_t lines = 0; 285 size_t lines = 0;
232 int pagelines = util_get_crt (); 286 int pagelines = util_get_crt ();
233 FILE *out; 287 FILE *out;
234 288
235 mu_message_lines (mesg, &lines); 289 mu_message_lines (closure->message, &lines);
236 if (pagelines && lines > pagelines) 290 if (pagelines && lines > pagelines)
237 out = popen (getenv ("PAGER"), "w"); 291 out = popen (getenv ("PAGER"), "w");
238 else 292 else
239 out = ofile; 293 out = ofile;
240 294
241 display_headers (out, mesg, msgset, select_hdr); 295 display_headers (out, closure->message, closure->msgset,
242 296 closure->hints & MDHINT_SELECTED_HEADERS);
297
243 print_stream (stream, out); 298 print_stream (stream, out);
244 299
245 if (out != ofile) 300 if (out != ofile)
246 pclose (out); 301 pclose (out);
247 } 302 }
248 if (d_stream) 303 if (d_stream)
249 mu_stream_destroy (&d_stream, NULL); 304 mu_stream_destroy (&d_stream, NULL);
250 } 305 }
251 306
252 free (type);
253 free (encoding);
254
255 return 0; 307 return 0;
256 } 308 }
257 309
......
...@@ -242,6 +242,7 @@ extern int mail_eq (int argc, char **argv); /* command = */ ...@@ -242,6 +242,7 @@ extern int mail_eq (int argc, char **argv); /* command = */
242 extern int mail_setenv (int argc, char **argv); 242 extern int mail_setenv (int argc, char **argv);
243 extern int mail_envelope (int argc, char **argv); 243 extern int mail_envelope (int argc, char **argv);
244 extern int print_envelope (msgset_t *mspec, mu_message_t msg, void *data); 244 extern int print_envelope (msgset_t *mspec, mu_message_t msg, void *data);
245 extern int mail_struct (int argc, char **argv);
245 246
246 extern int if_cond (void); 247 extern int if_cond (void);
247 248
...@@ -307,6 +308,27 @@ extern int msgset_member (msgset_t *set, size_t n); ...@@ -307,6 +308,27 @@ extern int msgset_member (msgset_t *set, size_t n);
307 extern msgset_t *msgset_negate (msgset_t *set); 308 extern msgset_t *msgset_negate (msgset_t *set);
308 extern size_t msgset_count (msgset_t *set); 309 extern size_t msgset_count (msgset_t *set);
309 310
311
312 #define MDHINT_SELECTED_HEADERS 0x1
313
314 struct mime_descend_closure
315 {
316 int hints;
317 const msgset_t *msgset;
318 mu_message_t message;
319 const char *type;
320 const char *encoding;
321 const struct mime_descend_closure *parent;
322 };
323
324 typedef int (*mime_descend_fn) (struct mime_descend_closure *closure,
325 void *data);
326
327 extern int mime_descend (struct mime_descend_closure *closure,
328 mime_descend_fn fun, void *data);
329
330
331
310 extern int util_do_command (const char *cmd, ...) MU_PRINTFLIKE(1,2); 332 extern int util_do_command (const char *cmd, ...) MU_PRINTFLIKE(1,2);
311 333
312 extern int util_foreach_msg (int argc, char **argv, int flags, 334 extern int util_foreach_msg (int argc, char **argv, int flags,
...@@ -369,7 +391,7 @@ extern int util_tempfile (char **namep); ...@@ -369,7 +391,7 @@ extern int util_tempfile (char **namep);
369 extern void util_msgset_iterate (msgset_t *msgset, 391 extern void util_msgset_iterate (msgset_t *msgset,
370 int (*fun) (mu_message_t, msgset_t *, void *), 392 int (*fun) (mu_message_t, msgset_t *, void *),
371 void *closure); 393 void *closure);
372 extern int util_get_content_type (mu_header_t hdr, char **value); 394 extern int util_get_content_type (mu_header_t hdr, char **value, char **args);
373 extern int util_get_hdr_value (mu_header_t hdr, const char *name, char **value); 395 extern int util_get_hdr_value (mu_header_t hdr, const char *name, char **value);
374 extern int util_merge_addresses (char **addr_str, const char *value); 396 extern int util_merge_addresses (char **addr_str, const char *value);
375 extern int util_header_expand (mu_header_t *hdr); 397 extern int util_header_expand (mu_header_t *hdr);
...@@ -383,6 +405,8 @@ void util_mark_read (mu_message_t msg); ...@@ -383,6 +405,8 @@ void util_mark_read (mu_message_t msg);
383 405
384 const char *util_url_to_string (mu_url_t url); 406 const char *util_url_to_string (mu_url_t url);
385 407
408 size_t fprint_msgset (FILE *fp, const msgset_t *msgset);
409
386 int is_address_field (const char *name); 410 int is_address_field (const char *name);
387 411
388 extern int ml_got_interrupt (void); 412 extern int ml_got_interrupt (void);
......
1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2009 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 #include "mail.h"
18
19 #define PART_WIDTH 8
20
21 static int
22 show_part (struct mime_descend_closure *closure, void *data)
23 {
24 size_t width;
25 size_t size = 0;
26
27 width = fprint_msgset (ofile, closure->msgset);
28 for (; width < 5; width++)
29 fputc (' ', ofile);
30
31 fprintf (ofile, " %-25s", closure->type);
32
33 mu_message_size (closure->message, &size);
34 if (size < 1024)
35 fprintf (ofile, " %4lu", (unsigned long) size);
36 else if (size < 1024*1024)
37 fprintf (ofile, "%4luK", (unsigned long) size / 1024);
38 else
39 fprintf (ofile, "%4luM", (unsigned long) size / 1024 / 1024);
40
41 fprintf (ofile, "\n");
42 return 0;
43 }
44
45 static int
46 show_struct (msgset_t *msgset, mu_message_t msg, void *data)
47 {
48 struct mime_descend_closure mclos;
49
50 mclos.hints = 0;
51 mclos.msgset = msgset;
52 mclos.message = msg;
53 mclos.type = NULL;
54 mclos.encoding = NULL;
55 mclos.parent = NULL;
56
57 mime_descend (&mclos, show_part, NULL);
58
59 /* Mark enclosing message as read */
60 if (mu_mailbox_get_message (mbox, msgset->msg_part[0], &msg) == 0)
61 util_mark_read (msg);
62
63 return 0;
64 }
65
66 int
67 mail_struct (int argc, char **argv)
68 {
69 return util_foreach_msg (argc, argv, MSG_NODELETED|MSG_SILENT,
70 show_struct, NULL);
71 }
...@@ -136,6 +136,8 @@ static const struct mail_command_entry mail_command_table[] = { ...@@ -136,6 +136,8 @@ static const struct mail_command_entry mail_command_table[] = {
136 mail_size, msglist_compl }, 136 mail_size, msglist_compl },
137 { "so", "source", "so[urce] file", 0, 137 { "so", "source", "so[urce] file", 0,
138 mail_source, NULL }, 138 mail_source, NULL },
139 { "st", "struct", "st[ruct] [msglist]", 0,
140 mail_struct, NULL },
139 { "su", "summary", "su[mmary]", 0, 141 { "su", "summary", "su[mmary]", 0,
140 mail_summary, no_compl }, 142 mail_summary, no_compl },
141 { "T", "Type", "T[ype] [msglist]", 0, 143 { "T", "Type", "T[ype] [msglist]", 0,
......
...@@ -793,7 +793,7 @@ util_descend_subparts (mu_message_t mesg, msgset_t *msgset, mu_message_t *part) ...@@ -793,7 +793,7 @@ util_descend_subparts (mu_message_t mesg, msgset_t *msgset, mu_message_t *part)
793 mu_header_t hdr = NULL; 793 mu_header_t hdr = NULL;
794 794
795 mu_message_get_header (mesg, &hdr); 795 mu_message_get_header (mesg, &hdr);
796 util_get_content_type (hdr, &type); 796 util_get_content_type (hdr, &type, NULL);
797 if (mu_c_strncasecmp (type, "message/rfc822", strlen (type)) == 0) 797 if (mu_c_strncasecmp (type, "message/rfc822", strlen (type)) == 0)
798 { 798 {
799 if (mu_message_unencapsulate (mesg, &submsg, NULL)) 799 if (mu_message_unencapsulate (mesg, &submsg, NULL))
...@@ -839,12 +839,12 @@ util_msgset_iterate (msgset_t *msgset, ...@@ -839,12 +839,12 @@ util_msgset_iterate (msgset_t *msgset,
839 return; 839 return;
840 840
841 if (util_descend_subparts (mesg, msgset, &mesg) == 0) 841 if (util_descend_subparts (mesg, msgset, &mesg) == 0)
842 (*fun)(mesg, msgset, closure); 842 (*fun) (mesg, msgset, closure);
843 } 843 }
844 } 844 }
845 845
846 int 846 int
847 util_get_content_type (mu_header_t hdr, char **value) 847 util_get_content_type (mu_header_t hdr, char **value, char **args)
848 { 848 {
849 char *type = NULL; 849 char *type = NULL;
850 util_get_hdr_value (hdr, MU_HEADER_CONTENT_TYPE, &type); 850 util_get_hdr_value (hdr, MU_HEADER_CONTENT_TYPE, &type);
...@@ -854,6 +854,17 @@ util_get_content_type (mu_header_t hdr, char **value) ...@@ -854,6 +854,17 @@ util_get_content_type (mu_header_t hdr, char **value)
854 free (type); 854 free (type);
855 type = strdup ("text/plain"); /* Default. */ 855 type = strdup ("text/plain"); /* Default. */
856 } 856 }
857 else
858 {
859 char *p;
860 p = strchr (type, ';');
861 if (p)
862 {
863 *p++ = 0;
864 if (args)
865 *args = p;
866 }
867 }
857 *value = type; 868 *value = type;
858 return 0; 869 return 0;
859 } 870 }
...@@ -861,16 +872,9 @@ util_get_content_type (mu_header_t hdr, char **value) ...@@ -861,16 +872,9 @@ util_get_content_type (mu_header_t hdr, char **value)
861 int 872 int
862 util_get_hdr_value (mu_header_t hdr, const char *name, char **value) 873 util_get_hdr_value (mu_header_t hdr, const char *name, char **value)
863 { 874 {
864 int status = mu_header_aget_value (hdr, name, value); 875 int status = mu_header_aget_value_unfold (hdr, name, value);
865 if (status == 0) 876 if (status == 0)
866 { 877 mu_rtrim_class (*value, MU_CTYPE_SPACE);
867 /* Remove the newlines. */
868 char *nl;
869 while ((nl = strchr (*value, '\n')) != NULL)
870 {
871 *nl = ' ';
872 }
873 }
874 return status; 878 return status;
875 } 879 }
876 880
......