diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-04-08 23:13:38 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-04-08 23:13:38 +0300 |
commit | 787121995cef1f77d279df9b70a9eb1f4fb35325 (patch) | |
tree | 795ae383ac877b97091d738ea6d4b9a50a5b80b8 | |
parent | d02e8bf4ee35f5b1f81208b56b545e1f2d6ac2a9 (diff) | |
download | mailutils-787121995cef1f77d279df9b70a9eb1f4fb35325.tar.gz mailutils-787121995cef1f77d279df9b70a9eb1f4fb35325.tar.bz2 |
Fix all FIXMEs from b2c1b1ff. Revise attachment API.
* include/mailutils/message.h (mu_message_save_attachment)
(mu_message_encapsulate, mu_message_unencapsulate): Change type
of the last argument.
(mu_mime_io_buffer_create,mu_mime_io_buffer_destroy)
(mu_mime_io_buffer_set_size,mu_mime_io_buffer_get_size)
(mu_mime_io_buffer_set_charset,mu_mime_io_buffer_sget_charset)
(mu_mime_io_buffer_aget_charset): New prototypes.
(mu_mimehdr_get_disp,mu_mimehdr_aget_disp): Remove unneeded
parameter.
* include/mailutils/types.hin (mu_mime_io_buffer_t): New type.
* mailbox/attachment.c (_msg_info): Rename structure to
_mu_mime_io_buffer.
<header_buf,header_len,mu_header_size>: Remove unreferenced members.
<refcnt,bufsize,charset>: New members.
<ioffset,ooffset>: Change type to size_t.
(mu_mime_io_buffer_create,mu_mime_io_buffer_destroy)
(mu_mime_io_buffer_set_size,mu_mime_io_buffer_get_size)
(mu_mime_io_buffer_set_charset,mu_mime_io_buffer_sget_charset)
(mu_mime_io_buffer_aget_charset): New functions.
(mu_message_save_attachment)
(mu_message_encapsulate, mu_message_unencapsulate): Take
mu_mime_io_buffer_t as the last argument.
* mailbox/mimehdr.c (mu_mimehdr_get_disp): Remove unneeded
parameter.
(mu_mimehdr_aget_disp): Remove unneeded parameter. Store
return value into pvalue.
* examples/mimetest.c (message_display_parts): Use
mu_mimehdr_aget_disp and mu_mime_io_buffer_* functions.
* mailbox/testsuite/Mime: Update.
* mh/mhn.c (options, opt_handler): New option --charset.
(store_handler): Use mu_message_aget_decoded_attachment_name.
-rw-r--r-- | examples/mimetest.c | 59 | ||||
-rw-r--r-- | include/mailutils/message.h | 28 | ||||
-rw-r--r-- | include/mailutils/types.hin | 1 | ||||
-rw-r--r-- | mailbox/attachment.c | 203 | ||||
-rw-r--r-- | mailbox/mimehdr.c | 6 | ||||
-rw-r--r-- | mailbox/testsuite/Mime | 20 | ||||
-rw-r--r-- | mh/mh_getopt.h | 3 | ||||
-rw-r--r-- | mh/mhn.c | 31 |
8 files changed, 235 insertions, 116 deletions
diff --git a/examples/mimetest.c b/examples/mimetest.c index 53ae37719..bca97af28 100644 --- a/examples/mimetest.c +++ b/examples/mimetest.c @@ -35,7 +35,7 @@ void message_display_parts(mu_message_t msg, int indent); const char *from; const char *subject; -const char *charset = "UTF-8"; +const char *charset; int print_attachments; int indent_level = 4; @@ -180,8 +180,6 @@ message_display_parts (mu_message_t msg, int indent) size_t nparts, nsubparts; mu_message_t part; mu_header_t hdr; - const char *type; - const char *encoding; mu_stream_t str; mu_body_t body; int offset, ismulti; @@ -200,24 +198,34 @@ message_display_parts (mu_message_t msg, int indent) for (j = 1; j <= nparts; j++) { int status; + const char *hvalue; + char *type = NULL; + const char *encoding = ""; + MU_ASSERT (mu_message_get_part (msg, j, &part)); MU_ASSERT (mu_message_get_header (part, &hdr)); - status = mu_header_sget_value (hdr, MU_HEADER_CONTENT_TYPE, &type); + status = mu_header_sget_value (hdr, MU_HEADER_CONTENT_TYPE, + &hvalue); if (status == MU_ERR_NOENT) - type = ""; + /* nothing */; else if (status != 0) + mu_error ("Cannot get header value: %s", mu_strerror (status)); + else { - type = ""; - mu_error ("Cannot get header value: %s", mu_strerror (status)); + status = mu_mimehdr_aget_disp (hvalue, &type); + if (status) + mu_error ("Cannot extract content type field: %s", + mu_strerror (status)); } - printf ("%*.*sType of part %d = %s\n", indent, indent, "", j, type); + printf ("%*.*sType of part %d = %s\n", indent, indent, "", + j, type ? type : ""); print_message_part_sizes (part, indent); if (mu_header_sget_value (hdr, MU_HEADER_CONTENT_TRANSFER_ENCODING, &encoding)) encoding = ""; ismulti = 0; - if ((type[0] - && mu_c_strncasecmp (type, "message/rfc822", strlen (type)) == 0) + if ((type + && mu_c_strcasecmp (type, "message/rfc822") == 0) || (mu_message_is_multipart (part, &ismulti) == 0 && ismulti)) { if (!ismulti) @@ -232,23 +240,21 @@ message_display_parts (mu_message_t msg, int indent) indent, indent, "", from, subject); printf ("%*.*sBegin\n", indent, indent, ""); MU_ASSERT (mu_message_get_num_parts (part, &nsubparts)); - message_display_parts (part, indent+indent_level); + message_display_parts (part, indent + indent_level); mu_message_destroy (&part, NULL); } - else if (type[0] == '\0' - || (mu_c_strncasecmp (type, "text/plain", strlen ("text/plain")) == - 0) - || (mu_c_strncasecmp (type, "text/html", strlen ("text/html")) == - 0)) - { - printf ("%*.*sText Message\n", indent, indent, ""); + else if (!type + || (mu_c_strcasecmp (type, "text/plain") == 0) + || (mu_c_strcasecmp (type, "text/html")) == 0) + { + printf ("%*.*sText Message\n", indent, indent, ""); printf ("%*.*sBegin\n", indent, indent, ""); mu_message_get_body (part, &body); mu_body_get_stream (body, &str); mu_filter_create (&str, str, encoding, 0, 0); offset = 0; - while (mu_stream_readline (str, buf, sizeof (buf), offset, &nbytes) == - 0 && nbytes) + while (mu_stream_readline (str, buf, sizeof (buf), + offset, &nbytes) == 0 && nbytes) { printf ("%*.*s%s", indent, indent, "", buf); offset += nbytes; @@ -268,13 +274,22 @@ message_display_parts (mu_message_t msg, int indent) printf ("%*.*sAttachment - saving [%s]\n", indent, indent, "", fname); printf ("%*.*sBegin\n", indent, indent, ""); - /*FIXME: What is the 'data' argument for? */ - mu_message_save_attachment (part, fname, NULL); + if (charset) + { + mu_mime_io_buffer_t info; + mu_mime_io_buffer_create (&info); + mu_mime_io_buffer_set_charset (info, charset); + MU_ASSERT (mu_message_save_attachment (part, NULL, info)); + mu_mime_io_buffer_destroy (&info); + } + else + MU_ASSERT (mu_message_save_attachment (part, fname, NULL)); if (print_attachments) print_file (fname, indent); free (fname); } printf ("\n%*.*sEnd\n", indent, indent, ""); + free (type); } } diff --git a/include/mailutils/message.h b/include/mailutils/message.h index 3ff25882f..9ca5703c4 100644 --- a/include/mailutils/message.h +++ b/include/mailutils/message.h @@ -113,21 +113,35 @@ extern int mu_message_create_attachment (const char *content_type, const char *filename, mu_message_t *newmsg); extern int mu_message_save_attachment (mu_message_t msg, - const char *filename, void **data); + const char *filename, + mu_mime_io_buffer_t buf); extern int mu_message_encapsulate (mu_message_t msg, mu_message_t *newmsg, - void **data); + mu_mime_io_buffer_t buf); extern int mu_message_unencapsulate (mu_message_t msg, mu_message_t *newmsg, - void **data); + mu_mime_io_buffer_t buf); +extern int mu_mime_io_buffer_create (mu_mime_io_buffer_t *pinfo); +extern void mu_mime_io_buffer_destroy (mu_mime_io_buffer_t *pinfo); + +extern void mu_mime_io_buffer_set_size (mu_mime_io_buffer_t info, size_t size); +extern void mu_mime_io_buffer_get_size (mu_mime_io_buffer_t info, + size_t *psize); +extern int mu_mime_io_buffer_set_charset (mu_mime_io_buffer_t info, + const char *charset); +extern void mu_mime_io_buffer_sget_charset (mu_mime_io_buffer_t info, + const char **charset); +extern int mu_mime_io_buffer_aget_charset (mu_mime_io_buffer_t info, + const char **charset); + + /* Bit values for *pflags in functions below */ #define MU_MIMEHDR_MULTILINE 0x01 /* Parameter was multiline */ #define MU_MIMEHDR_CSINFO 0x02 /* Parameter contains charset/language info */ -extern int mu_mimehdr_get_disp (const char *str, const char *param, - char *buf, size_t bufsz, size_t *retsz); -extern int mu_mimehdr_aget_disp (const char *str, const char *param, - char **pvalue); +extern int mu_mimehdr_get_disp (const char *str, char *buf, size_t bufsz, + size_t *retsz); +extern int mu_mimehdr_aget_disp (const char *str, char **pvalue); extern int mu_mimehdr_get_param (const char *str, const char *param, char *buf, size_t bufsz, size_t *retsz, int *pflags); diff --git a/include/mailutils/types.hin b/include/mailutils/types.hin index 8fa198379..019e66fac 100644 --- a/include/mailutils/types.hin +++ b/include/mailutils/types.hin @@ -113,6 +113,7 @@ typedef struct _mu_m_server *mu_m_server_t; typedef struct _mu_opool *mu_opool_t; typedef struct _mu_progmailer *mu_progmailer_t; typedef struct _mu_secret *mu_secret_t; +typedef struct _mu_mime_io_buffer *mu_mime_io_buffer_t; #define MU_FOLDER_ATTRIBUTE_DIRECTORY 0x001 #define MU_FOLDER_ATTRIBUTE_FILE 0x002 diff --git a/mailbox/attachment.c b/mailbox/attachment.c index 9ef1455eb..26430fc93 100644 --- a/mailbox/attachment.c +++ b/mailbox/attachment.c @@ -47,17 +47,17 @@ #define BUF_SIZE 2048 -struct _msg_info +struct _mu_mime_io_buffer { + unsigned int refcnt; char *buf; + size_t bufsize; size_t nbytes; - char *header_buf; - int header_len; - int mu_header_size; + char *charset; mu_header_t hdr; mu_message_t msg; - int ioffset; - int ooffset; + size_t ioffset; + size_t ooffset; mu_stream_t stream; /* output file/decoding stream for saving attachment */ mu_stream_t fstream; /* output file stream for saving attachment */ }; @@ -139,58 +139,131 @@ mu_message_create_attachment (const char *content_type, const char *encoding, return ret; } +int +mu_mime_io_buffer_create (mu_mime_io_buffer_t *pinfo) +{ + mu_mime_io_buffer_t info; + + if ((info = calloc (1, sizeof (*info))) == NULL) + return ENOMEM; + info->refcnt = 1; + info->bufsize = BUF_SIZE; + *pinfo = info; + return 0; +} -static int -_attachment_setup (struct _msg_info **info, mu_message_t msg, - mu_stream_t *stream, void **data) +void +mu_mime_io_buffer_set_size (mu_mime_io_buffer_t info, size_t size) { - int sfl, ret; - mu_body_t body; + info->bufsize = size; +} - if ((ret = mu_message_get_body (msg, &body)) != 0 || - (ret = mu_body_get_stream (body, stream)) != 0) - return ret; - mu_stream_get_flags (*stream, &sfl); - if (data == NULL && (sfl & MU_STREAM_NONBLOCK)) - return EINVAL; - if (data) - *info = *data; - if (*info == NULL) - { - if ((*info = calloc (1, sizeof (struct _msg_info))) == NULL) - return ENOMEM; - } - if (((*info)->buf = malloc (BUF_SIZE)) == NULL) +void +mu_mime_io_buffer_get_size (mu_mime_io_buffer_t info, size_t *psize) +{ + *psize = info->bufsize; +} + +int +mu_mime_io_buffer_set_charset (mu_mime_io_buffer_t info, const char *charset) +{ + char *cp = strdup (charset); + if (!cp) + return ENOMEM; + free (info->charset); + info->charset = cp; + return 0; +} + +void +mu_mime_io_buffer_sget_charset (mu_mime_io_buffer_t info, const char **charset) +{ + *charset = info->charset; +} + +int +mu_mime_io_buffer_aget_charset (mu_mime_io_buffer_t info, const char **charset) +{ + *charset = strdup (info->charset); + if (!charset) + return ENOMEM; + return 0; +} + +void +mu_mime_io_buffer_destroy (mu_mime_io_buffer_t *pinfo) +{ + if (pinfo && *pinfo) { - free (*info); - return ENOMEM; + mu_mime_io_buffer_t info = *pinfo; + free (info->charset); + free (info->buf); + free (info); + *pinfo = NULL; } - return 0; } static void -_attachment_free (struct _msg_info *info, int free_message) +_attachment_free (struct _mu_mime_io_buffer *info, int free_message) { - if (info->buf) - free (info->buf); - if (info->header_buf) - free (info->header_buf); if (free_message) { if (info->msg) - mu_message_destroy (&(info->msg), NULL); + mu_message_destroy (&info->msg, NULL); else if (info->hdr) - mu_header_destroy (&(info->hdr), NULL); + mu_header_destroy (&info->hdr, NULL); + } + info->msg = NULL; + info->hdr = NULL; + info->ioffset = 0; + info->ooffset = 0; + info->stream = NULL; + info->fstream = NULL; + if (--info->refcnt == 0) + { + free (info->charset); + free (info->buf); + free (info); } - free (info); +} + +static int +_attachment_setup (mu_mime_io_buffer_t *pinfo, mu_message_t msg, + mu_stream_t *stream) +{ + int ret; + mu_body_t body; + mu_mime_io_buffer_t info; + + if ((ret = mu_message_get_body (msg, &body)) != 0 || + (ret = mu_body_get_stream (body, stream)) != 0) + return ret; + if (*pinfo) + { + info = *pinfo; + info->refcnt++; + } + else + { + ret = mu_mime_io_buffer_create (&info); + if (ret) + return ret; + } + + if (!info->buf && ((info->buf = malloc (info->bufsize)) == NULL)) + { + _attachment_free (info, 0); + return ENOMEM; + } + *pinfo = info; + return 0; } int mu_message_save_attachment (mu_message_t msg, const char *filename, - void **data) + mu_mime_io_buffer_t info) { mu_stream_t istream; - struct _msg_info *info = NULL; int ret; size_t size; size_t nbytes; @@ -201,15 +274,15 @@ mu_message_save_attachment (mu_message_t msg, const char *filename, if (msg == NULL) return EINVAL; - if ((ret = _attachment_setup (&info, msg, &istream, data)) != 0) + if ((ret = _attachment_setup (&info, msg, &istream)) != 0) return ret; if (ret == 0 && (ret = mu_message_get_header (msg, &hdr)) == 0) { if (filename == NULL) { - /* FIXME: Charset info is ignored */ - ret = mu_message_aget_attachment_name (msg, &partname, NULL); + ret = mu_message_aget_decoded_attachment_name (msg, info->charset, + &partname, NULL); if (partname) fname = partname; } @@ -248,12 +321,12 @@ mu_message_save_attachment (mu_message_t msg, const char *filename, if (info->stream && istream) { if (info->nbytes) - memmove (info->buf, info->buf + (BUF_SIZE - info->nbytes), + memmove (info->buf, info->buf + (info->bufsize - info->nbytes), info->nbytes); while ((ret == 0 && info->nbytes) || ((ret = - mu_stream_read (info->stream, info->buf, BUF_SIZE, + mu_stream_read (info->stream, info->buf, info->bufsize, info->ioffset, &info->nbytes)) == 0 && info->nbytes)) { @@ -274,9 +347,10 @@ mu_message_save_attachment (mu_message_t msg, const char *filename, mu_stream_close (info->fstream); mu_stream_destroy (&info->stream, NULL); mu_stream_destroy (&info->fstream, NULL); - _attachment_free (info, ret); } + _attachment_free (info, ret); /* FIXME: or 0? */ + /* Free fname if we allocated it. */ if (partname) free (partname); @@ -285,11 +359,11 @@ mu_message_save_attachment (mu_message_t msg, const char *filename, } int -mu_message_encapsulate (mu_message_t msg, mu_message_t *newmsg, void **data) +mu_message_encapsulate (mu_message_t msg, mu_message_t *newmsg, + mu_mime_io_buffer_t info) { mu_stream_t istream, ostream; const char *header; - struct _msg_info *info = NULL; int ret = 0; size_t nbytes; mu_body_t body; @@ -299,16 +373,16 @@ mu_message_encapsulate (mu_message_t msg, mu_message_t *newmsg, void **data) if (newmsg == NULL) return MU_ERR_OUT_PTR_NULL; - if ((ret = _attachment_setup (&info, msg, &ostream, data)) != 0) + if ((ret = _attachment_setup (&info, msg, &ostream)) != 0) return ret; if (info->msg == NULL - && (ret = mu_message_create (&(info->msg), NULL)) == 0) + && (ret = mu_message_create (&info->msg, NULL)) == 0) { header = "Content-Type: message/rfc822\nContent-Transfer-Encoding: 7bit\n\n"; if ((ret = - mu_header_create (&(info->hdr), header, strlen (header), + mu_header_create (&info->hdr, header, strlen (header), msg)) == 0) ret = mu_message_set_header (info->msg, info->hdr, NULL); } @@ -318,12 +392,12 @@ mu_message_encapsulate (mu_message_t msg, mu_message_t *newmsg, void **data) (ret = mu_body_get_stream (body, &ostream)) == 0) { if (info->nbytes) - memmove (info->buf, info->buf + (BUF_SIZE - info->nbytes), + memmove (info->buf, info->buf + (info->bufsize - info->nbytes), info->nbytes); while ((ret == 0 && info->nbytes) || ((ret = - mu_stream_read (istream, info->buf, BUF_SIZE, + mu_stream_read (istream, info->buf, info->bufsize, info->ioffset, &info->nbytes)) == 0 && info->nbytes)) { @@ -342,27 +416,27 @@ mu_message_encapsulate (mu_message_t msg, mu_message_t *newmsg, void **data) } if (ret == 0) *newmsg = info->msg; - if (ret != EAGAIN && info) - _attachment_free (info, ret); + _attachment_free (info, ret && ret != EAGAIN); return ret; } +#define MESSAGE_RFC822_STR "message/rfc822" + int mu_message_unencapsulate (mu_message_t msg, mu_message_t *newmsg, - void **data) + mu_mime_io_buffer_t info) { size_t size, nbytes; int ret = 0; mu_header_t hdr; mu_stream_t istream, ostream; - struct _msg_info *info = NULL; if (msg == NULL) return EINVAL; if (newmsg == NULL) return MU_ERR_OUT_PTR_NULL; - if ((data == NULL || *data == NULL) + if (info == NULL /* FIXME: not needed? */ && (ret = mu_message_get_header (msg, &hdr)) == 0) { mu_header_get_value (hdr, "Content-Type", NULL, 0, &size); @@ -373,9 +447,8 @@ mu_message_unencapsulate (mu_message_t msg, mu_message_t *newmsg, return ENOMEM; mu_header_get_value (hdr, "Content-Type", content_type, size + 1, 0); - ret = - mu_c_strncasecmp (content_type, "message/rfc822", - strlen ("message/rfc822")); + ret = mu_c_strncasecmp (content_type, MESSAGE_RFC822_STR, + sizeof (MESSAGE_RFC822_STR) - 1); free (content_type); if (ret != 0) return EINVAL; @@ -383,20 +456,21 @@ mu_message_unencapsulate (mu_message_t msg, mu_message_t *newmsg, else return EINVAL; } - if ((ret = _attachment_setup (&info, msg, &istream, data)) != 0) + if ((ret = _attachment_setup (&info, msg, &istream)) != 0) return ret; if (info->msg == NULL) - ret = mu_message_create (&(info->msg), NULL); + ret = mu_message_create (&info->msg, NULL); if (ret == 0) { mu_message_get_stream (info->msg, &ostream); if (info->nbytes) - memmove (info->buf, info->buf + (BUF_SIZE - info->nbytes), + memmove (info->buf, info->buf + (info->bufsize - info->nbytes), info->nbytes); while ((ret == 0 && info->nbytes) || ((ret = - mu_stream_read (istream, info->buf, BUF_SIZE, info->ioffset, + mu_stream_read (istream, info->buf, + info->bufsize, info->ioffset, &info->nbytes)) == 0 && info->nbytes)) { info->ioffset += info->nbytes; @@ -413,7 +487,6 @@ mu_message_unencapsulate (mu_message_t msg, mu_message_t *newmsg, } if (ret == 0) *newmsg = info->msg; - if (ret != EAGAIN && info) - _attachment_free (info, ret); + _attachment_free (info, ret && ret != EAGAIN); return ret; } diff --git a/mailbox/mimehdr.c b/mailbox/mimehdr.c index 2e0990306..cd38332dd 100644 --- a/mailbox/mimehdr.c +++ b/mailbox/mimehdr.c @@ -332,8 +332,7 @@ _header_get_param (const char *field_body, value, and `type/subtype' part, if it is a Content-Type value. */ int -mu_mimehdr_get_disp (const char *str, const char *param, - char *buf, size_t bufsz, size_t *retsz) +mu_mimehdr_get_disp (const char *str, char *buf, size_t bufsz, size_t *retsz) { char *p = strchr (str, ';'); size_t size; @@ -350,7 +349,7 @@ mu_mimehdr_get_disp (const char *str, const char *param, /* Same as mu_mimehdr_get_disp, but allocates memory */ int -mu_mimehdr_aget_disp (const char *str, const char *param, char **pvalue) +mu_mimehdr_aget_disp (const char *str, char **pvalue) { char *p = strchr (str, ';'); size_t size; @@ -363,6 +362,7 @@ mu_mimehdr_aget_disp (const char *str, const char *param, char **pvalue) return ENOMEM; memcpy (p, str, size); p[size] = 0; + *pvalue = p; return 0; } diff --git a/mailbox/testsuite/Mime b/mailbox/testsuite/Mime index 07d046f33..39cb23834 100644 --- a/mailbox/testsuite/Mime +++ b/mailbox/testsuite/Mime @@ -83,7 +83,7 @@ From: Sergey Poznyakoff <gray@Mirddin.farlep.net> Subject: Simple MIME Number of parts in message - 2 Total message size - 1626/42 -Type of part 1 = text/plain; name="msg.1"; charset="us-ascii" +Type of part 1 = text/plain Message part size - 371/13: 141/4, 230/9 Text Message Begin @@ -98,7 +98,7 @@ And welcome little fishes in With gently smiling jaws! End -Type of part 2 = application/octet-stream; name="msg.21" +Type of part 2 = application/octet-stream Message part size - 645/11: 183/5, 462/6 Attachment - saving [msg.21] Begin @@ -119,7 +119,7 @@ From: Sergey Poznyakoff <gray@Mirddin.farlep.net> Subject: Nested MIME Number of parts in message - 2 Total message size - 3484/84 -Type of part 1 = text/plain; name="msg.21"; charset="us-ascii" +Type of part 1 = text/plain Message part size - 496/14: 155/4, 341/10 Text Message Begin @@ -135,11 +135,11 @@ Why, I do it again and again.' End -Type of part 2 = multipart/mixed; boundary="----- =_aaaaaaaaaa1" +Type of part 2 = multipart/mixed Message part size - 2378/52: 114/3, 2264/49 Encapsulated message : Begin -Type of part 1 = application/octet-stream; name="msg.22" +Type of part 1 = application/octet-stream Message part size - 663/12: 184/5, 479/7 Attachment - saving [msg.22] Begin @@ -154,11 +154,11 @@ By the use of this ointment--one shilling the box-- Allow me to sell you a couple?' End -Type of part 2 = multipart/mixed; boundary="----- =_aaaaaaaaaa2" +Type of part 2 = multipart/mixed Message part size - 1531/32: 114/3, 1417/29 Encapsulated message : Begin -Type of part 1 = application/octet-stream; name="msg.23" +Type of part 1 = application/octet-stream Message part size - 668/12: 185/5, 483/7 Attachment - saving [msg.23] Begin @@ -173,7 +173,7 @@ And the muscular strength, which it gave to my jaw, Has lasted the rest of my life.' End -Type of part 2 = application/octet-stream; name="msg.24" +Type of part 2 = application/octet-stream Message part size - 679/12: 184/5, 495/7 Attachment - saving [msg.24] Begin @@ -197,13 +197,13 @@ From: Sergey Poznyakoff <gray@Mirddin.farlep.net> Subject: Empty MIME Parts Number of parts in message - 2 Total message size - 914/27 -Type of part 1 = text/plain; name="empty"; charset="us-ascii" +Type of part 1 = text/plain Message part size - 143/4: 143/4, 0/0 Text Message Begin End -Type of part 2 = text/plain; name="single.line"; charset="us-ascii" +Type of part 2 = text/plain Message part size - 156/5: 155/4, 1/1 Text Message Begin diff --git a/mh/mh_getopt.h b/mh/mh_getopt.h index 4815b1205..bd26f832a 100644 --- a/mh/mh_getopt.h +++ b/mh/mh_getopt.h @@ -55,7 +55,8 @@ enum mh_arg { ARG_BUILD, ARG_CC, ARG_CFLAGS, - ARG_CHANGECUR, + ARG_CHANGECUR, + ARG_CHARSET, ARG_CHECK, ARG_CHUNKSIZE, ARG_CLEAR, @@ -74,16 +74,18 @@ static struct argp_option options[] = { {"auto", ARG_AUTO, N_("BOOL"), OPTION_ARG_OPTIONAL, N_("use filenames from the content headers"), 31}, {"noauto", ARG_NOAUTO, NULL, OPTION_HIDDEN, "", 31 }, - + {"charset", ARG_CHARSET, N_("NAME"), 0, + N_("use this charset to represent attachment file names"), 31}, + {N_("Other options"), 0, NULL, OPTION_DOC, NULL, 40}, {"part", ARG_PART, N_("PART"), 0, N_("limit the scope of the operation to the given part"), 41}, {"type", ARG_TYPE, N_("CONTENT"), 0, N_("operate on message part with given multipart content"), 41 }, - {"verbose", ARG_VERBOSE, N_("BOOL"), OPTION_ARG_OPTIONAL, + {"verbose", ARG_VERBOSE, N_("BOOL"), OPTION_ARG_OPTIONAL, N_("print additional information"), 41 }, - {"noverbose", ARG_NOVERBOSE, NULL, OPTION_HIDDEN, "", 41 }, - {"quiet", ARG_QUIET, 0, 0, + {"noverbose", ARG_NOVERBOSE, NULL, OPTION_HIDDEN, "", 41 }, + {"quiet", ARG_QUIET, 0, 0, N_("be quiet")}, {"license", ARG_LICENSE, 0, 0, N_("display software license"), -1}, @@ -144,6 +146,8 @@ static char *content_type; static char *content_subtype; static char *input_file; static int width = 80; +static char *charset; /* Charset for output file names. NULL means + no recoding is necessary. */ static mh_msgset_t msgset; static mu_mailbox_t mbox; @@ -397,6 +401,10 @@ opt_handler (int key, char *arg, struct argp_state *state) mh_license (argp_program_version); break; + case ARG_CHARSET: + charset = arg; + break; + default: return ARGP_ERR_UNKNOWN; } @@ -1589,14 +1597,21 @@ store_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding, if (mode_options & OPT_AUTO) { char *val; - - /* FIXME: Take into account CS/Lang info and recode the value - if necessary */ - if (mu_message_aget_attachment_name (msg, &val, NULL) == 0) + int rc = mu_message_aget_decoded_attachment_name (msg, charset, + &val, NULL); + if (rc == 0) { name = normalize_path (dir, val); free (val); } + else if (rc != MU_ERR_NOENT) + { + char *pstr = msg_part_format (part); + mu_diag_output (MU_DIAG_WARNING, + _("%s: cannot decode attachment name: %s"), + pstr, mu_strerror (rc)); + free (pstr); + } } if (!name) |