attachment.c: redesign/simplify using the new API.
* libmailutils/mime/attachment.c (BUF_SIZE): Remove. (_mu_mime_io_buffer)<buf, bufsize>: Remove members. (MSG_HDR): Remove. (mu_message_create_attachment): Use mu_asprintf instead of manually crafting the string. (mu_mime_io_buffer_set_size) (mu_mime_io_buffer_get_size): Remove. (mu_message_save_attachment) (mu_message_encapsulate) (mu_message_unencapsulate): Use mu_header_sget to avoid unnecessary memory allocations. Use mu_stream_copy instead of (ineffective) loops. * include/mailutils/message.h (mu_mime_io_buffer_set_size) (mu_mime_io_buffer_get_size): Remove prototypes. * include/mailutils/header.h (MU_HEADER_RESENT_SENDER) (MU_HEADER_CONTENT_TRANSFER_ENCODING) (MU_HEADER_DELIVERY_DATE) (MU_HEADER_ENVELOPE_TO): Normalize spelling.
Showing
3 changed files
with
36 additions
and
114 deletions
... | @@ -35,7 +35,7 @@ extern "C" { | ... | @@ -35,7 +35,7 @@ extern "C" { |
35 | #define MU_HEADER_RESENT_FROM "Resent-From" | 35 | #define MU_HEADER_RESENT_FROM "Resent-From" |
36 | #define MU_HEADER_SUBJECT "Subject" | 36 | #define MU_HEADER_SUBJECT "Subject" |
37 | #define MU_HEADER_SENDER "Sender" | 37 | #define MU_HEADER_SENDER "Sender" |
38 | #define MU_HEADER_RESENT_SENDER "Resent-SENDER" | 38 | #define MU_HEADER_RESENT_SENDER "Resent-Sender" |
39 | #define MU_HEADER_TO "To" | 39 | #define MU_HEADER_TO "To" |
40 | #define MU_HEADER_RESENT_TO "Resent-To" | 40 | #define MU_HEADER_RESENT_TO "Resent-To" |
41 | #define MU_HEADER_CC "Cc" | 41 | #define MU_HEADER_CC "Cc" |
... | @@ -54,7 +54,7 @@ extern "C" { | ... | @@ -54,7 +54,7 @@ extern "C" { |
54 | #define MU_HEADER_STATUS "Status" | 54 | #define MU_HEADER_STATUS "Status" |
55 | #define MU_HEADER_CONTENT_LENGTH "Content-Length" | 55 | #define MU_HEADER_CONTENT_LENGTH "Content-Length" |
56 | #define MU_HEADER_CONTENT_LANGUAGE "Content-Language" | 56 | #define MU_HEADER_CONTENT_LANGUAGE "Content-Language" |
57 | #define MU_HEADER_CONTENT_TRANSFER_ENCODING "Content-transfer-encoding" | 57 | #define MU_HEADER_CONTENT_TRANSFER_ENCODING "Content-Transfer-Encoding" |
58 | #define MU_HEADER_CONTENT_ID "Content-ID" | 58 | #define MU_HEADER_CONTENT_ID "Content-ID" |
59 | #define MU_HEADER_CONTENT_TYPE "Content-Type" | 59 | #define MU_HEADER_CONTENT_TYPE "Content-Type" |
60 | #define MU_HEADER_CONTENT_DESCRIPTION "Content-Description" | 60 | #define MU_HEADER_CONTENT_DESCRIPTION "Content-Description" |
... | @@ -68,8 +68,8 @@ extern "C" { | ... | @@ -68,8 +68,8 @@ extern "C" { |
68 | #define MU_HEADER_ENV_SENDER "X-Envelope-Sender" | 68 | #define MU_HEADER_ENV_SENDER "X-Envelope-Sender" |
69 | #define MU_HEADER_ENV_DATE "X-Envelope-Date" | 69 | #define MU_HEADER_ENV_DATE "X-Envelope-Date" |
70 | #define MU_HEADER_FCC "Fcc" | 70 | #define MU_HEADER_FCC "Fcc" |
71 | #define MU_HEADER_DELIVERY_DATE "Delivery-date" | 71 | #define MU_HEADER_DELIVERY_DATE "Delivery-Date" |
72 | #define MU_HEADER_ENVELOPE_TO "Envelope-to" | 72 | #define MU_HEADER_ENVELOPE_TO "Envelope-To" |
73 | #define MU_HEADER_X_EXPIRE_TIMESTAMP "X-Expire-Timestamp" | 73 | #define MU_HEADER_X_EXPIRE_TIMESTAMP "X-Expire-Timestamp" |
74 | 74 | ||
75 | #define MU_HEADER_REPLACE 0x01 | 75 | #define MU_HEADER_REPLACE 0x01 | ... | ... |
... | @@ -148,9 +148,6 @@ extern int mu_message_unencapsulate (mu_message_t msg, mu_message_t *newmsg, | ... | @@ -148,9 +148,6 @@ extern int mu_message_unencapsulate (mu_message_t msg, mu_message_t *newmsg, |
148 | extern int mu_mime_io_buffer_create (mu_mime_io_buffer_t *pinfo); | 148 | extern int mu_mime_io_buffer_create (mu_mime_io_buffer_t *pinfo); |
149 | extern void mu_mime_io_buffer_destroy (mu_mime_io_buffer_t *pinfo); | 149 | extern void mu_mime_io_buffer_destroy (mu_mime_io_buffer_t *pinfo); |
150 | 150 | ||
151 | extern void mu_mime_io_buffer_set_size (mu_mime_io_buffer_t info, size_t size); | ||
152 | extern void mu_mime_io_buffer_get_size (mu_mime_io_buffer_t info, | ||
153 | size_t *psize); | ||
154 | extern int mu_mime_io_buffer_set_charset (mu_mime_io_buffer_t info, | 151 | extern int mu_mime_io_buffer_set_charset (mu_mime_io_buffer_t info, |
155 | const char *charset); | 152 | const char *charset); |
156 | extern void mu_mime_io_buffer_sget_charset (mu_mime_io_buffer_t info, | 153 | extern void mu_mime_io_buffer_sget_charset (mu_mime_io_buffer_t info, | ... | ... |
... | @@ -43,14 +43,11 @@ | ... | @@ -43,14 +43,11 @@ |
43 | #include <mailutils/stream.h> | 43 | #include <mailutils/stream.h> |
44 | #include <mailutils/errno.h> | 44 | #include <mailutils/errno.h> |
45 | #include <mailutils/util.h> | 45 | #include <mailutils/util.h> |
46 | 46 | #include <mailutils/io.h> | |
47 | #define BUF_SIZE 2048 | ||
48 | 47 | ||
49 | struct _mu_mime_io_buffer | 48 | struct _mu_mime_io_buffer |
50 | { | 49 | { |
51 | unsigned int refcnt; | 50 | unsigned int refcnt; |
52 | char *buf; | ||
53 | size_t bufsize; | ||
54 | char *charset; | 51 | char *charset; |
55 | mu_header_t hdr; | 52 | mu_header_t hdr; |
56 | mu_message_t msg; | 53 | mu_message_t msg; |
... | @@ -58,8 +55,6 @@ struct _mu_mime_io_buffer | ... | @@ -58,8 +55,6 @@ struct _mu_mime_io_buffer |
58 | mu_stream_t fstream; /* output file stream for saving attachment */ | 55 | mu_stream_t fstream; /* output file stream for saving attachment */ |
59 | }; | 56 | }; |
60 | 57 | ||
61 | #define MSG_HDR "Content-Type: %s; name=%s\nContent-Transfer-Encoding: %s\nContent-Disposition: attachment; filename=%s\n\n" | ||
62 | |||
63 | int | 58 | int |
64 | mu_message_create_attachment (const char *content_type, const char *encoding, | 59 | mu_message_create_attachment (const char *content_type, const char *encoding, |
65 | const char *filename, mu_message_t *newmsg) | 60 | const char *filename, mu_message_t *newmsg) |
... | @@ -88,23 +83,21 @@ mu_message_create_attachment (const char *content_type, const char *encoding, | ... | @@ -88,23 +83,21 @@ mu_message_create_attachment (const char *content_type, const char *encoding, |
88 | name++; | 83 | name++; |
89 | else | 84 | else |
90 | name = fname; | 85 | name = fname; |
91 | if ((header = | 86 | ret = mu_asprintf (&header, |
92 | malloc (strlen (MSG_HDR) + strlen (content_type) + | 87 | "Content-Type: %s; name=%s\n" |
93 | strlen (name) * 2 + strlen (encoding) + 1)) == NULL) | 88 | "Content-Transfer-Encoding: %s\n" |
94 | ret = ENOMEM; | 89 | "Content-Disposition: attachment; filename=%s\n\n", |
95 | else | 90 | content_type, name, encoding, name); |
91 | if (ret) | ||
96 | { | 92 | { |
97 | sprintf (header, MSG_HDR, content_type, name, encoding, name); | 93 | if ((ret = mu_header_create (&hdr, header, |
98 | if ((ret = mu_header_create (&hdr, header, strlen (header))) | 94 | strlen (header))) == 0) |
99 | == 0) | ||
100 | { | 95 | { |
101 | mu_message_get_body (*newmsg, &body); | 96 | mu_message_get_body (*newmsg, &body); |
102 | if ((ret = | 97 | if ((ret = mu_file_stream_create (&fstream, filename, |
103 | mu_file_stream_create (&fstream, filename, | ||
104 | MU_STREAM_READ)) == 0) | 98 | MU_STREAM_READ)) == 0) |
105 | { | 99 | { |
106 | if ((ret = | 100 | if ((ret = mu_filter_create (&tstream, fstream, encoding, |
107 | mu_filter_create (&tstream, fstream, encoding, | ||
108 | MU_FILTER_ENCODE, | 101 | MU_FILTER_ENCODE, |
109 | MU_STREAM_READ)) == 0) | 102 | MU_STREAM_READ)) == 0) |
110 | { | 103 | { |
... | @@ -112,11 +105,12 @@ mu_message_create_attachment (const char *content_type, const char *encoding, | ... | @@ -112,11 +105,12 @@ mu_message_create_attachment (const char *content_type, const char *encoding, |
112 | mu_message_set_header (*newmsg, hdr, NULL); | 105 | mu_message_set_header (*newmsg, hdr, NULL); |
113 | } | 106 | } |
114 | } | 107 | } |
115 | } | ||
116 | free (header); | 108 | free (header); |
117 | } | 109 | } |
118 | } | 110 | } |
119 | } | 111 | } |
112 | } | ||
113 | |||
120 | if (ret) | 114 | if (ret) |
121 | { | 115 | { |
122 | if (*newmsg) | 116 | if (*newmsg) |
... | @@ -139,23 +133,10 @@ mu_mime_io_buffer_create (mu_mime_io_buffer_t *pinfo) | ... | @@ -139,23 +133,10 @@ mu_mime_io_buffer_create (mu_mime_io_buffer_t *pinfo) |
139 | if ((info = calloc (1, sizeof (*info))) == NULL) | 133 | if ((info = calloc (1, sizeof (*info))) == NULL) |
140 | return ENOMEM; | 134 | return ENOMEM; |
141 | info->refcnt = 1; | 135 | info->refcnt = 1; |
142 | info->bufsize = BUF_SIZE; | ||
143 | *pinfo = info; | 136 | *pinfo = info; |
144 | return 0; | 137 | return 0; |
145 | } | 138 | } |
146 | 139 | ||
147 | void | ||
148 | mu_mime_io_buffer_set_size (mu_mime_io_buffer_t info, size_t size) | ||
149 | { | ||
150 | info->bufsize = size; | ||
151 | } | ||
152 | |||
153 | void | ||
154 | mu_mime_io_buffer_get_size (mu_mime_io_buffer_t info, size_t *psize) | ||
155 | { | ||
156 | *psize = info->bufsize; | ||
157 | } | ||
158 | |||
159 | int | 140 | int |
160 | mu_mime_io_buffer_set_charset (mu_mime_io_buffer_t info, const char *charset) | 141 | mu_mime_io_buffer_set_charset (mu_mime_io_buffer_t info, const char *charset) |
161 | { | 142 | { |
... | @@ -189,7 +170,6 @@ mu_mime_io_buffer_destroy (mu_mime_io_buffer_t *pinfo) | ... | @@ -189,7 +170,6 @@ mu_mime_io_buffer_destroy (mu_mime_io_buffer_t *pinfo) |
189 | { | 170 | { |
190 | mu_mime_io_buffer_t info = *pinfo; | 171 | mu_mime_io_buffer_t info = *pinfo; |
191 | free (info->charset); | 172 | free (info->charset); |
192 | free (info->buf); | ||
193 | free (info); | 173 | free (info); |
194 | *pinfo = NULL; | 174 | *pinfo = NULL; |
195 | } | 175 | } |
... | @@ -212,7 +192,6 @@ _attachment_free (struct _mu_mime_io_buffer *info, int free_message) | ... | @@ -212,7 +192,6 @@ _attachment_free (struct _mu_mime_io_buffer *info, int free_message) |
212 | if (--info->refcnt == 0) | 192 | if (--info->refcnt == 0) |
213 | { | 193 | { |
214 | free (info->charset); | 194 | free (info->charset); |
215 | free (info->buf); | ||
216 | free (info); | 195 | free (info); |
217 | } | 196 | } |
218 | } | 197 | } |
... | @@ -245,11 +224,6 @@ _attachment_setup (mu_mime_io_buffer_t *pinfo, mu_message_t msg, | ... | @@ -245,11 +224,6 @@ _attachment_setup (mu_mime_io_buffer_t *pinfo, mu_message_t msg, |
245 | return ret; | 224 | return ret; |
246 | } | 225 | } |
247 | 226 | ||
248 | if (!info->buf && ((info->buf = malloc (info->bufsize)) == NULL)) | ||
249 | { | ||
250 | _attachment_free (info, 0); | ||
251 | return ENOMEM; | ||
252 | } | ||
253 | info->msg = msg; | 227 | info->msg = msg; |
254 | *pinfo = info; | 228 | *pinfo = info; |
255 | return 0; | 229 | return 0; |
... | @@ -261,8 +235,6 @@ mu_message_save_attachment (mu_message_t msg, const char *filename, | ... | @@ -261,8 +235,6 @@ mu_message_save_attachment (mu_message_t msg, const char *filename, |
261 | { | 235 | { |
262 | mu_stream_t istream; | 236 | mu_stream_t istream; |
263 | int ret; | 237 | int ret; |
264 | size_t size; | ||
265 | size_t nbytes; | ||
266 | mu_header_t hdr; | 238 | mu_header_t hdr; |
267 | const char *fname = NULL; | 239 | const char *fname = NULL; |
268 | char *partname = NULL; | 240 | char *partname = NULL; |
... | @@ -285,44 +257,22 @@ mu_message_save_attachment (mu_message_t msg, const char *filename, | ... | @@ -285,44 +257,22 @@ mu_message_save_attachment (mu_message_t msg, const char *filename, |
285 | else | 257 | else |
286 | fname = filename; | 258 | fname = filename; |
287 | if (fname | 259 | if (fname |
288 | && (ret = | 260 | && (ret = mu_file_stream_create (&info->fstream, fname, |
289 | mu_file_stream_create (&info->fstream, fname, | ||
290 | MU_STREAM_WRITE | MU_STREAM_CREAT)) == 0) | 261 | MU_STREAM_WRITE | MU_STREAM_CREAT)) == 0) |
291 | { | 262 | { |
292 | char *content_encoding; | 263 | const char *content_encoding; |
293 | char *content_encoding_mem = NULL; | ||
294 | 264 | ||
295 | mu_header_get_value (hdr, "Content-Transfer-Encoding", NULL, 0, | 265 | if (mu_header_sget_value (hdr, MU_HEADER_CONTENT_TRANSFER_ENCODING, |
296 | &size); | 266 | &content_encoding)) |
297 | if (size) | ||
298 | { | ||
299 | content_encoding_mem = malloc (size + 1); | ||
300 | if (content_encoding_mem == NULL) | ||
301 | ret = ENOMEM; | ||
302 | content_encoding = content_encoding_mem; | ||
303 | mu_header_get_value (hdr, "Content-Transfer-Encoding", | ||
304 | content_encoding, size + 1, 0); | ||
305 | } | ||
306 | else | ||
307 | content_encoding = "7bit"; | 267 | content_encoding = "7bit"; |
308 | ret = | 268 | ret = mu_filter_create (&info->stream, istream, content_encoding, |
309 | mu_filter_create (&info->stream, istream, content_encoding, | ||
310 | MU_FILTER_DECODE, | 269 | MU_FILTER_DECODE, |
311 | MU_STREAM_READ); | 270 | MU_STREAM_READ); |
312 | free (content_encoding_mem); | ||
313 | } | 271 | } |
314 | } | 272 | } |
315 | if (info->stream && istream) | 273 | if (info->stream && istream) |
316 | { | 274 | ret = mu_stream_copy (info->fstream, info->stream, 0, NULL); |
317 | while (((ret = | 275 | |
318 | mu_stream_read (info->stream, info->buf, BUF_SIZE, | ||
319 | &nbytes)) == 0 && nbytes)) | ||
320 | { | ||
321 | if ((ret = | ||
322 | mu_stream_write (info->fstream, info->buf, nbytes, NULL)) != 0) | ||
323 | break; | ||
324 | } | ||
325 | } | ||
326 | if (ret != EAGAIN && info) | 276 | if (ret != EAGAIN && info) |
327 | { | 277 | { |
328 | mu_stream_close (info->fstream); | 278 | mu_stream_close (info->fstream); |
... | @@ -345,9 +295,7 @@ mu_message_encapsulate (mu_message_t msg, mu_message_t *newmsg, | ... | @@ -345,9 +295,7 @@ mu_message_encapsulate (mu_message_t msg, mu_message_t *newmsg, |
345 | mu_mime_io_buffer_t info) | 295 | mu_mime_io_buffer_t info) |
346 | { | 296 | { |
347 | mu_stream_t istream, ostream; | 297 | mu_stream_t istream, ostream; |
348 | const char *header; | ||
349 | int ret = 0; | 298 | int ret = 0; |
350 | size_t nbytes; | ||
351 | mu_message_t tmsg = NULL; | 299 | mu_message_t tmsg = NULL; |
352 | 300 | ||
353 | if (newmsg == NULL) | 301 | if (newmsg == NULL) |
... | @@ -361,11 +309,13 @@ mu_message_encapsulate (mu_message_t msg, mu_message_t *newmsg, | ... | @@ -361,11 +309,13 @@ mu_message_encapsulate (mu_message_t msg, mu_message_t *newmsg, |
361 | if (ret) | 309 | if (ret) |
362 | return ret; | 310 | return ret; |
363 | msg = tmsg; | 311 | msg = tmsg; |
364 | header = | 312 | #define MSG822_HEADER "Content-Type: message/rfc822\n" \ |
365 | "Content-Type: message/rfc822\nContent-Transfer-Encoding: 7bit\n\n"; | 313 | "Content-Transfer-Encoding: 7bit\n\n" |
366 | if ((ret = | 314 | if ((ret = mu_header_create (&hdr, |
367 | mu_header_create (&hdr, header, strlen (header))) == 0) | 315 | MSG822_HEADER, |
316 | sizeof (MSG822_HEADER) - 1)) == 0) | ||
368 | ret = mu_message_set_header (msg, hdr, NULL); | 317 | ret = mu_message_set_header (msg, hdr, NULL); |
318 | #undef MSG822_HEADER | ||
369 | if (ret) | 319 | if (ret) |
370 | { | 320 | { |
371 | mu_message_destroy (&msg, NULL); | 321 | mu_message_destroy (&msg, NULL); |
... | @@ -382,13 +332,7 @@ mu_message_encapsulate (mu_message_t msg, mu_message_t *newmsg, | ... | @@ -382,13 +332,7 @@ mu_message_encapsulate (mu_message_t msg, mu_message_t *newmsg, |
382 | if (ret == 0 && (ret = mu_message_get_streamref (msg, &istream)) == 0) | 332 | if (ret == 0 && (ret = mu_message_get_streamref (msg, &istream)) == 0) |
383 | { | 333 | { |
384 | mu_stream_seek (istream, 0, MU_SEEK_SET, NULL); | 334 | mu_stream_seek (istream, 0, MU_SEEK_SET, NULL); |
385 | while (((ret = mu_stream_read (istream, info->buf, BUF_SIZE, | 335 | ret = mu_stream_copy (ostream, istream, 0, NULL); |
386 | &nbytes)) == 0 && nbytes)) | ||
387 | { | ||
388 | if ((ret = | ||
389 | mu_stream_write (ostream, info->buf, nbytes, NULL)) != 0) | ||
390 | break; | ||
391 | } | ||
392 | mu_stream_destroy (&istream); | 336 | mu_stream_destroy (&istream); |
393 | } | 337 | } |
394 | if (ret == 0) | 338 | if (ret == 0) |
... | @@ -404,7 +348,6 @@ int | ... | @@ -404,7 +348,6 @@ int |
404 | mu_message_unencapsulate (mu_message_t msg, mu_message_t *newmsg, | 348 | mu_message_unencapsulate (mu_message_t msg, mu_message_t *newmsg, |
405 | mu_mime_io_buffer_t info) | 349 | mu_mime_io_buffer_t info) |
406 | { | 350 | { |
407 | size_t size, nbytes; | ||
408 | int ret = 0; | 351 | int ret = 0; |
409 | mu_header_t hdr; | 352 | mu_header_t hdr; |
410 | mu_stream_t istream, ostream; | 353 | mu_stream_t istream, ostream; |
... | @@ -417,21 +360,10 @@ mu_message_unencapsulate (mu_message_t msg, mu_message_t *newmsg, | ... | @@ -417,21 +360,10 @@ mu_message_unencapsulate (mu_message_t msg, mu_message_t *newmsg, |
417 | if (info == NULL /* FIXME: not needed? */ | 360 | if (info == NULL /* FIXME: not needed? */ |
418 | && (ret = mu_message_get_header (msg, &hdr)) == 0) | 361 | && (ret = mu_message_get_header (msg, &hdr)) == 0) |
419 | { | 362 | { |
420 | mu_header_get_value (hdr, "Content-Type", NULL, 0, &size); | 363 | const char *s; |
421 | if (size) | 364 | if (!(mu_header_sget_value (hdr, MU_HEADER_CONTENT_TYPE, &s) == 0 && |
422 | { | 365 | mu_c_strncasecmp (s, MESSAGE_RFC822_STR, |
423 | char *content_type; | 366 | sizeof (MESSAGE_RFC822_STR) - 1) == 0)) |
424 | if ((content_type = malloc (size + 1)) == NULL) | ||
425 | return ENOMEM; | ||
426 | mu_header_get_value (hdr, "Content-Type", content_type, size + 1, | ||
427 | 0); | ||
428 | ret = mu_c_strncasecmp (content_type, MESSAGE_RFC822_STR, | ||
429 | sizeof (MESSAGE_RFC822_STR) - 1); | ||
430 | free (content_type); | ||
431 | if (ret != 0) | ||
432 | return EINVAL; | ||
433 | } | ||
434 | else | ||
435 | return EINVAL; | 367 | return EINVAL; |
436 | } | 368 | } |
437 | if ((ret = _attachment_setup (&info, msg, &istream)) != 0) | 369 | if ((ret = _attachment_setup (&info, msg, &istream)) != 0) |
... | @@ -442,14 +374,7 @@ mu_message_unencapsulate (mu_message_t msg, mu_message_t *newmsg, | ... | @@ -442,14 +374,7 @@ mu_message_unencapsulate (mu_message_t msg, mu_message_t *newmsg, |
442 | { | 374 | { |
443 | mu_message_get_streamref (info->msg, &ostream); | 375 | mu_message_get_streamref (info->msg, &ostream); |
444 | mu_stream_seek (ostream, 0, MU_SEEK_SET, NULL); | 376 | mu_stream_seek (ostream, 0, MU_SEEK_SET, NULL); |
445 | while (((ret = | 377 | ret = mu_stream_copy (ostream, istream, 0, NULL); |
446 | mu_stream_read (istream, info->buf, BUF_SIZE, | ||
447 | &nbytes)) == 0 && nbytes)) | ||
448 | { | ||
449 | if ((ret = | ||
450 | mu_stream_write (ostream, info->buf, nbytes, NULL)) != 0) | ||
451 | break; | ||
452 | } | ||
453 | mu_stream_destroy (&ostream); | 378 | mu_stream_destroy (&ostream); |
454 | } | 379 | } |
455 | if (ret == 0) | 380 | if (ret == 0) | ... | ... |
-
Please register or sign in to post a comment