summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-04-08 23:13:38 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2010-04-08 23:13:38 +0300
commit787121995cef1f77d279df9b70a9eb1f4fb35325 (patch)
tree795ae383ac877b97091d738ea6d4b9a50a5b80b8
parentd02e8bf4ee35f5b1f81208b56b545e1f2d6ac2a9 (diff)
downloadmailutils-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.c59
-rw-r--r--include/mailutils/message.h28
-rw-r--r--include/mailutils/types.hin1
-rw-r--r--mailbox/attachment.c203
-rw-r--r--mailbox/mimehdr.c6
-rw-r--r--mailbox/testsuite/Mime20
-rw-r--r--mh/mh_getopt.h3
-rw-r--r--mh/mhn.c31
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,
diff --git a/mh/mhn.c b/mh/mhn.c
index db100f6f5..f37d63d0d 100644
--- a/mh/mhn.c
+++ b/mh/mhn.c
@@ -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)

Return to:

Send suggestions and report system problems to the System administrator.