commit-mailutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SCM] GNU Mailutils branch, master, updated. release-2.2-183-g50bf64d


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. release-2.2-183-g50bf64d
Date: Wed, 10 Nov 2010 13:56:45 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU Mailutils".

http://git.savannah.gnu.org/cgit/mailutils.git/commit/?id=50bf64db74ffa1d1cf1c5ebbda55cabdb530b8f5

The branch, master has been updated
       via  50bf64db74ffa1d1cf1c5ebbda55cabdb530b8f5 (commit)
       via  e9580ebf7bd77a9d1c456c2138d38258275b454c (commit)
       via  90af346ddc4f730f2dd8b26fda528750af006b76 (commit)
      from  64b00582e8b3b08cbf1b6e530583b1757a8bdf77 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 50bf64db74ffa1d1cf1c5ebbda55cabdb530b8f5
Author: Sergey Poznyakoff <address@hidden>
Date:   Wed Nov 10 15:52:51 2010 +0200

    mhn: optimize using new API.
    
    * mh/mhn.c (_get_hdr_value): Remove.  All callers modified to use
    mu_header_aget_value_unfold instead.
    (mhn_message_size): Type of 2nd arg is mu_off_t *.
    Use null stream & stream stats in realsize mode.
    (list_handler): Fix rounding of the message size.
    (copy_header): Use mu_header_sget* to avoid unnecessary
    memory allocations.

commit e9580ebf7bd77a9d1c456c2138d38258275b454c
Author: Sergey Poznyakoff <address@hidden>
Date:   Wed Nov 10 14:11:09 2010 +0200

    Improve stream statistics interface. Introduce "null stream".
    
    * include/mailutils/stream.h (MU_IOCTL_NULLSTREAM_SET_PATTERN)
    (MU_IOCTL_NULLSTREAM_SET_PATCLASS)
    (MU_IOCTL_NULLSTREAM_SETSIZE)
    (MU_IOCTL_NULLSTREAM_CLRSIZE): New ioctl opcodes.
    (mu_nullstream_pattern): New struct.
    (MU_STREAM_STAT_IN,MU_STREAM_STAT_OUT)
    (MU_STREAM_STAT_READS,MU_STREAM_STAT_WRITES)
    (MU_STREAM_STAT_SEEKS,_MU_STREAM_STAT_MAX): New defines.
    (MU_STREAM_STAT_MASK): New macro.
    (MU_STREAM_STAT_MASK_ALL): New define.
    (mu_stream_stat_buffer): New typedef.
    (mu_stream_set_stat, mu_stream_get_stat)
    (mu_nullstream_create): New protos.
    (mu_stream_bytes_in, mu_stream_bytes_out): Remove protos.
    
    * include/mailutils/sys/nullstream.h: New file.
    * include/mailutils/sys/stream.h (_mu_stream) <bytes_in>,
    <bytes_out>: Remove.
    <statmask,statbuf>: New members.
    * include/mailutils/sys/Makefile.am (sysinclude_HEADERS): Add nullstream.h.
    
    * libmailutils/stream/nullstream.c: New file.
    * libmailutils/stream/stream.c (_stream_read, _stream_write)
    (_stream_seek, _stream_stat_incr): New macros.
    (_stream_fill_buffer, mu_stream_seek)
    (_stream_read_unbuffered)
    (_stream_write_unbuffered): Use _stream_read, _stream_write
    and _stream_seek instead of calling the corresponding methods directly.
    (mu_stream_bytes_in, mu_stream_bytes_out): Remove.
    (mu_stream_unref): Clear statbuf, if provided.
    (mu_stream_set_stat, mu_stream_get_stat): New functions.
    
    * libmailutils/stream/Makefile.am (libstream_la_SOURCES): Add nullstream.c.
    
    * libmailutils/stream/fltstream.c (filter_wr_close): Check for fs->eof.
    
    * examples/base64.c (c_copy): Use new statistics interface.
    * libmailutils/tests/fltst.c: Likewise.

commit 90af346ddc4f730f2dd8b26fda528750af006b76
Author: Sergey Poznyakoff <address@hidden>
Date:   Wed Nov 10 10:59:25 2010 +0200

    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.

-----------------------------------------------------------------------

Summary of changes:
 doc/texinfo/mu-mh.texi                             |    2 +-
 examples/base64.c                                  |   36 +++-
 include/mailutils/header.h                         |    8 +-
 include/mailutils/message.h                        |    3 -
 include/mailutils/stream.h                         |   45 ++++-
 include/mailutils/sys/Makefile.am                  |    1 +
 .../mailutils/sys/{streamref.h => nullstream.h}    |   20 +-
 include/mailutils/sys/stream.h                     |    4 +-
 libmailutils/mime/attachment.c                     |  151 ++++-----------
 libmailutils/stream/Makefile.am                    |    1 +
 libmailutils/stream/fltstream.c                    |    2 +-
 libmailutils/stream/nullstream.c                   |  204 ++++++++++++++++++++
 libmailutils/stream/stream.c                       |   73 +++++---
 libmailutils/tests/fltst.c                         |   39 ++++-
 mh/mhn.c                                           |   81 ++++-----
 15 files changed, 459 insertions(+), 211 deletions(-)
 copy include/mailutils/sys/{streamref.h => nullstream.h} (62%)
 create mode 100644 libmailutils/stream/nullstream.c

diff --git a/doc/texinfo/mu-mh.texi b/doc/texinfo/mu-mh.texi
index 4f8d336..f25f625 100644
--- a/doc/texinfo/mu-mh.texi
+++ b/doc/texinfo/mu-mh.texi
@@ -4,7 +4,7 @@
 @comment *******************************************************************
 
 The primary aim of this implementation is to provide an interface
-between Mailutils and Emacs using mh-e module. 
+between Mailutils and Emacs using mh-e module.
 
 To use Mailutils MH with Emacs, add the following line to your
 site-start.el or .emacs file:
diff --git a/examples/base64.c b/examples/base64.c
index deadfd2..2e80a60 100644
--- a/examples/base64.c
+++ b/examples/base64.c
@@ -33,6 +33,22 @@ int printable = 0;
 static void
 c_copy (mu_stream_t out, mu_stream_t in)
 {
+  mu_stream_stat_buffer instat, outstat;
+
+  if (verbose)
+    {
+      mu_stream_set_stat (in,
+                         MU_STREAM_STAT_MASK (MU_STREAM_STAT_IN) |
+                         MU_STREAM_STAT_MASK (MU_STREAM_STAT_READS) |
+                         MU_STREAM_STAT_MASK (MU_STREAM_STAT_SEEKS),
+                         instat);
+      mu_stream_set_stat (out,
+                         MU_STREAM_STAT_MASK (MU_STREAM_STAT_OUT) |
+                         MU_STREAM_STAT_MASK (MU_STREAM_STAT_WRITES) |
+                         MU_STREAM_STAT_MASK (MU_STREAM_STAT_SEEKS),
+                         outstat);
+    }
+
   if (printable)
     {
       char c;
@@ -58,9 +74,23 @@ c_copy (mu_stream_t out, mu_stream_t in)
   mu_stream_close (out);
   mu_stream_close (in);
   if (verbose)
-    fprintf (stderr, "\ntotal: %lu/%lu bytes\n",
-            (unsigned long) mu_stream_bytes_in (in),
-            (unsigned long) mu_stream_bytes_out (out));
+    {
+      fprintf (stderr, "\nInput stats:\n");
+      fprintf (stderr, "Bytes in: %lu\n",
+              (unsigned long) instat[MU_STREAM_STAT_IN]);
+      fprintf (stderr, "Reads: %lu\n",
+              (unsigned long) instat[MU_STREAM_STAT_READS]);
+      fprintf (stderr, "Seeks: %lu\n",
+              (unsigned long) instat[MU_STREAM_STAT_SEEKS]);
+
+      fprintf (stderr, "\nOutput stats:\n");
+      fprintf (stderr, "Bytes out: %lu\n",
+              (unsigned long) outstat[MU_STREAM_STAT_OUT]);
+      fprintf (stderr, "Writes: %lu\n",
+              (unsigned long) outstat[MU_STREAM_STAT_WRITES]);
+      fprintf (stderr, "Seeks: %lu\n",
+              (unsigned long) outstat[MU_STREAM_STAT_SEEKS]);
+    }
 }
 
 /* Set the maximum line length for the filter NAME to LENGTH.
diff --git a/include/mailutils/header.h b/include/mailutils/header.h
index 0a73d52..c326c5c 100644
--- a/include/mailutils/header.h
+++ b/include/mailutils/header.h
@@ -35,7 +35,7 @@ extern "C" {
 #define MU_HEADER_RESENT_FROM               "Resent-From"
 #define MU_HEADER_SUBJECT                   "Subject"
 #define MU_HEADER_SENDER                    "Sender"
-#define MU_HEADER_RESENT_SENDER             "Resent-SENDER"
+#define MU_HEADER_RESENT_SENDER             "Resent-Sender"
 #define MU_HEADER_TO                        "To"
 #define MU_HEADER_RESENT_TO                 "Resent-To"
 #define MU_HEADER_CC                        "Cc"
@@ -54,7 +54,7 @@ extern "C" {
 #define MU_HEADER_STATUS                    "Status"
 #define MU_HEADER_CONTENT_LENGTH            "Content-Length"
 #define MU_HEADER_CONTENT_LANGUAGE          "Content-Language"
-#define MU_HEADER_CONTENT_TRANSFER_ENCODING "Content-transfer-encoding"
+#define MU_HEADER_CONTENT_TRANSFER_ENCODING "Content-Transfer-Encoding"
 #define MU_HEADER_CONTENT_ID                "Content-ID"
 #define MU_HEADER_CONTENT_TYPE              "Content-Type"
 #define MU_HEADER_CONTENT_DESCRIPTION       "Content-Description"
@@ -68,8 +68,8 @@ extern "C" {
 #define MU_HEADER_ENV_SENDER                "X-Envelope-Sender"
 #define MU_HEADER_ENV_DATE                  "X-Envelope-Date"
 #define MU_HEADER_FCC                       "Fcc"
-#define MU_HEADER_DELIVERY_DATE             "Delivery-date"
-#define MU_HEADER_ENVELOPE_TO               "Envelope-to"
+#define MU_HEADER_DELIVERY_DATE             "Delivery-Date"
+#define MU_HEADER_ENVELOPE_TO               "Envelope-To"
 #define MU_HEADER_X_EXPIRE_TIMESTAMP        "X-Expire-Timestamp"
   
 #define MU_HEADER_REPLACE 0x01
diff --git a/include/mailutils/message.h b/include/mailutils/message.h
index 09c7c9e..7208ee6 100644
--- a/include/mailutils/message.h
+++ b/include/mailutils/message.h
@@ -148,9 +148,6 @@ extern int mu_message_unencapsulate (mu_message_t msg, 
mu_message_t *newmsg,
 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,
diff --git a/include/mailutils/stream.h b/include/mailutils/stream.h
index bb14186..444733e 100644
--- a/include/mailutils/stream.h
+++ b/include/mailutils/stream.h
@@ -76,12 +76,31 @@ enum mu_buffer_type
 
 #define MU_IOCTL_GET_ECHO        12     
 #define MU_IOCTL_SET_ECHO        13  
+
+/* The following ioctls are for nullstreams only: */  
+#define MU_IOCTL_NULLSTREAM_SET_PATTERN 14
+  /* Set read pattern.
+     Argument: struct mu_nullstream_pattern *pat.
+     If pat==NULL, any reads from that stream will return EOF. */
+#define MU_IOCTL_NULLSTREAM_SET_PATCLASS 15
+  /* Set pattern class for reads:  Argument int *pclass (a class mask
+     from mailutils/cctype.h */
+#define MU_IOCTL_NULLSTREAM_SETSIZE 16
+  /* Limit stream size.  Argument: mu_off_t *psize; */
+#define MU_IOCTL_NULLSTREAM_CLRSIZE 17
+  /* Lift the size limit.  Argument: NULL */
   
 #define MU_TRANSPORT_INPUT  0
 #define MU_TRANSPORT_OUTPUT 1
 #define MU_TRANSPORT_VALID_TYPE(n) \
   ((n) == MU_TRANSPORT_INPUT || (n) == MU_TRANSPORT_OUTPUT)
 
+struct mu_nullstream_pattern
+{
+  char *pattern;
+  size_t size;
+};
+  
 struct mu_buffer_query
 {
   int type;                     /* One of MU_TRANSPORT_ defines */
@@ -89,6 +108,28 @@ struct mu_buffer_query
   size_t bufsize;               /* Buffer size */
 };
 
+/* Statistics */  
+#define MU_STREAM_STAT_IN       0
+#define MU_STREAM_STAT_OUT      1
+#define MU_STREAM_STAT_READS    2 
+#define MU_STREAM_STAT_WRITES   3
+#define MU_STREAM_STAT_SEEKS    4
+#define _MU_STREAM_STAT_MAX     5   
+
+#define MU_STREAM_STAT_MASK(n)  (1U<<(n+1))
+#define MU_STREAM_STAT_MASK_ALL  \
+  (MU_STREAM_STAT_MASK (MU_STREAM_STAT_IN) | \
+   MU_STREAM_STAT_MASK (MU_STREAM_STAT_OUT) |   \
+   MU_STREAM_STAT_MASK (MU_STREAM_STAT_READS) | \
+   MU_STREAM_STAT_MASK (MU_STREAM_STAT_WRITES) | \
+   MU_STREAM_STAT_MASK (MU_STREAM_STAT_SEEKS))
+
+typedef mu_off_t mu_stream_stat_buffer[_MU_STREAM_STAT_MAX];
+int mu_stream_set_stat (mu_stream_t stream, int statmask,
+                       mu_stream_stat_buffer statbuf);
+int mu_stream_get_stat (mu_stream_t stream, int *pstatmask,
+                       mu_off_t **pstatbuf);
+  
 #define MU_STREAM_DEFBUFSIZ 8192
 extern size_t mu_stream_default_buffer_size;
 
@@ -127,8 +168,6 @@ int mu_stream_writeline (mu_stream_t stream, const char 
*buf, size_t size);
 int mu_stream_flush (mu_stream_t stream);
 int mu_stream_close (mu_stream_t stream);
 int mu_stream_size (mu_stream_t stream, mu_off_t *psize);
-mu_off_t mu_stream_bytes_in (mu_stream_t stream);
-mu_off_t mu_stream_bytes_out (mu_stream_t stream);
 int mu_stream_ioctl (mu_stream_t stream, int code, void *ptr);
 int mu_stream_truncate (mu_stream_t stream, mu_off_t);
 int mu_stream_shutdown (mu_stream_t stream, int how);
@@ -202,6 +241,8 @@ int mu_dbgstream_create(mu_stream_t *pref, mu_debug_t debug,
 int mu_rdcache_stream_create (mu_stream_t *pstream, mu_stream_t transport,
                              int flags);
 
+int mu_nullstream_create (mu_stream_t *pref, int flags);
+  
 #ifdef __cplusplus
 }
 #endif
diff --git a/include/mailutils/sys/Makefile.am 
b/include/mailutils/sys/Makefile.am
index 90610cd..0ef9f33 100644
--- a/include/mailutils/sys/Makefile.am
+++ b/include/mailutils/sys/Makefile.am
@@ -42,6 +42,7 @@ sysinclude_HEADERS = \
  mime.h\
  monitor.h\
  nntp.h\
+ nullstream.h\
  observer.h\
  pop3.h\
  prog_stream.h\
diff --git a/include/mailutils/sys/streamref.h 
b/include/mailutils/sys/nullstream.h
similarity index 62%
copy from include/mailutils/sys/streamref.h
copy to include/mailutils/sys/nullstream.h
index 35f035e..0e906fe 100644
--- a/include/mailutils/sys/streamref.h
+++ b/include/mailutils/sys/nullstream.h
@@ -14,20 +14,22 @@
    You should have received a copy of the GNU Lesser General Public License
    along with GNU Mailutils.  If not, see <http://www.gnu.org/licenses/>. */
 
-#ifndef _MAILUTILS_SYS_STREAMREF_H
-#define _MAILUTILS_SYS_STREAMREF_H
+#ifndef _MAILUTILS_SYS_NULLSTREAM_H
+#define _MAILUTILS_SYS_NULLSTREAM_H
 
 #include <mailutils/types.h>
 #include <mailutils/sys/stream.h>
 
-struct _mu_streamref
+#define MU_NULLSTREAM_SIZE     0x0001 /* Stream has a limited size */
+#define MU_NULLSTREAM_PATSTAT  0x0002 /* Pattern is allocated statically */
+
+struct _mu_nullstream
 {
-  struct _mu_stream stream;      /* Superclass */
-  mu_stream_t transport;         /* Transport stream */
-  mu_off_t offset;               /* Offset in transport stream */
-                            /* For abridged stream references: */
-  mu_off_t start;                /* Start offset */
-  mu_off_t end;                  /* End offset */
+  struct _mu_stream base;        /* Superclass */
+  int mode;                      /* Stream mode */
+  mu_off_t size;                 /* Stream size */
+  char *pattern;                 /* Fill pattern */
+  size_t patsize;                /* Size of pattern */
 };
 
 #endif
diff --git a/include/mailutils/sys/stream.h b/include/mailutils/sys/stream.h
index aa95f7e..2fe18ae 100644
--- a/include/mailutils/sys/stream.h
+++ b/include/mailutils/sys/stream.h
@@ -45,7 +45,9 @@ struct _mu_stream
 
   int flags;
   mu_off_t offset;
-  mu_off_t bytes_in, bytes_out;
+  
+  int statmask;
+  mu_off_t *statbuf;
   
   int last_err;
 
diff --git a/libmailutils/mime/attachment.c b/libmailutils/mime/attachment.c
index e4a09e3..7bd7a80 100644
--- a/libmailutils/mime/attachment.c
+++ b/libmailutils/mime/attachment.c
@@ -43,14 +43,11 @@
 #include <mailutils/stream.h>
 #include <mailutils/errno.h>
 #include <mailutils/util.h>
-
-#define BUF_SIZE       2048
+#include <mailutils/io.h>
 
 struct _mu_mime_io_buffer
 {
   unsigned int refcnt;
-  char *buf;
-  size_t bufsize;
   char *charset;
   mu_header_t hdr;
   mu_message_t msg;
@@ -58,8 +55,6 @@ struct _mu_mime_io_buffer
   mu_stream_t fstream; /* output file stream for saving attachment */
 };
 
-#define MSG_HDR "Content-Type: %s; name=%s\nContent-Transfer-Encoding: 
%s\nContent-Disposition: attachment; filename=%s\n\n"
-
 int
 mu_message_create_attachment (const char *content_type, const char *encoding,
                              const char *filename, mu_message_t *newmsg)
@@ -88,35 +83,34 @@ mu_message_create_attachment (const char *content_type, 
const char *encoding,
            name++;
          else
            name = fname;
-         if ((header =
-              malloc (strlen (MSG_HDR) + strlen (content_type) +
-                      strlen (name) * 2 + strlen (encoding) + 1)) == NULL)
-           ret = ENOMEM;
-         else
+         ret = mu_asprintf (&header,
+                            "Content-Type: %s; name=%s\n"
+                            "Content-Transfer-Encoding: %s\n"
+                            "Content-Disposition: attachment; filename=%s\n\n",
+                            content_type, name, encoding, name);
+         if (ret)
            {
-             sprintf (header, MSG_HDR, content_type, name, encoding, name);
-             if ((ret = mu_header_create (&hdr, header, strlen (header)))
-                 == 0)
+             if ((ret = mu_header_create (&hdr, header,
+                                          strlen (header))) == 0)
                {
                  mu_message_get_body (*newmsg, &body);
-                 if ((ret =
-                      mu_file_stream_create (&fstream, filename,
-                                             MU_STREAM_READ)) == 0)
+                 if ((ret = mu_file_stream_create (&fstream, filename,
+                                                   MU_STREAM_READ)) == 0)
                    {
-                     if ((ret =
-                          mu_filter_create (&tstream, fstream, encoding,
-                                            MU_FILTER_ENCODE,
-                                            MU_STREAM_READ)) == 0)
+                     if ((ret = mu_filter_create (&tstream, fstream, encoding,
+                                                  MU_FILTER_ENCODE,
+                                                  MU_STREAM_READ)) == 0)
                        {
                          mu_body_set_stream (body, tstream, *newmsg);
                          mu_message_set_header (*newmsg, hdr, NULL);
                        }
                    }
+                 free (header);
                }
-             free (header);
            }
        }
     }
+  
   if (ret)
     {
       if (*newmsg)
@@ -139,23 +133,10 @@ mu_mime_io_buffer_create (mu_mime_io_buffer_t *pinfo)
   if ((info = calloc (1, sizeof (*info))) == NULL)
     return ENOMEM;
   info->refcnt = 1;
-  info->bufsize = BUF_SIZE;
   *pinfo = info;
   return 0;
 }
 
-void
-mu_mime_io_buffer_set_size (mu_mime_io_buffer_t info, size_t size)
-{
-  info->bufsize = size;
-}
-
-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)
 {
@@ -189,7 +170,6 @@ mu_mime_io_buffer_destroy (mu_mime_io_buffer_t *pinfo)
     {
       mu_mime_io_buffer_t info = *pinfo;
       free (info->charset);
-      free (info->buf);
       free (info);
       *pinfo = NULL;
     }
@@ -212,7 +192,6 @@ _attachment_free (struct _mu_mime_io_buffer *info, int 
free_message)
   if (--info->refcnt == 0)
     {
       free (info->charset);
-      free (info->buf);
       free (info);
     }
 }
@@ -245,11 +224,6 @@ _attachment_setup (mu_mime_io_buffer_t *pinfo, 
mu_message_t msg,
        return ret;
     }
   
-  if (!info->buf && ((info->buf = malloc (info->bufsize)) == NULL))
-    {
-      _attachment_free (info, 0);
-      return ENOMEM;
-    }
   info->msg = msg;
   *pinfo = info;
   return 0;
@@ -261,8 +235,6 @@ mu_message_save_attachment (mu_message_t msg, const char 
*filename,
 {
   mu_stream_t istream;
   int ret;
-  size_t size;
-  size_t nbytes;
   mu_header_t hdr;
   const char *fname = NULL;
   char *partname = NULL;
@@ -285,44 +257,22 @@ mu_message_save_attachment (mu_message_t msg, const char 
*filename,
       else
        fname = filename;
       if (fname
-         && (ret =
-             mu_file_stream_create (&info->fstream, fname,
+         && (ret = mu_file_stream_create (&info->fstream, fname,
                                     MU_STREAM_WRITE | MU_STREAM_CREAT)) == 0)
        {
-         char *content_encoding;
-         char *content_encoding_mem = NULL;
-         
-         mu_header_get_value (hdr, "Content-Transfer-Encoding", NULL, 0,
-                              &size);
-         if (size)
-           {
-             content_encoding_mem = malloc (size + 1);
-             if (content_encoding_mem == NULL)
-               ret = ENOMEM;
-             content_encoding = content_encoding_mem;
-             mu_header_get_value (hdr, "Content-Transfer-Encoding",
-                                  content_encoding, size + 1, 0);
-           }
-         else
+         const char *content_encoding;
+
+         if (mu_header_sget_value (hdr, MU_HEADER_CONTENT_TRANSFER_ENCODING,
+                                   &content_encoding))
            content_encoding = "7bit";
-         ret =
-           mu_filter_create (&info->stream, istream, content_encoding,
-                             MU_FILTER_DECODE,
-                             MU_STREAM_READ);
-         free (content_encoding_mem);
+         ret = mu_filter_create (&info->stream, istream, content_encoding,
+                                 MU_FILTER_DECODE,
+                                 MU_STREAM_READ);
        }
     }
   if (info->stream && istream)
-    {
-      while (((ret =
-              mu_stream_read (info->stream, info->buf, BUF_SIZE, 
-                              &nbytes)) == 0 && nbytes))
-       {
-         if ((ret =
-              mu_stream_write (info->fstream, info->buf, nbytes, NULL)) != 0)
-           break;
-       }
-    }
+    ret = mu_stream_copy (info->fstream, info->stream, 0, NULL);
+
   if (ret != EAGAIN && info)
     {
       mu_stream_close (info->fstream);
@@ -345,9 +295,7 @@ 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;
   int ret = 0;
-  size_t nbytes;
   mu_message_t tmsg = NULL;
   
   if (newmsg == NULL)
@@ -361,11 +309,13 @@ mu_message_encapsulate (mu_message_t msg, mu_message_t 
*newmsg,
       if (ret)
        return ret;
       msg = tmsg;
-      header =
-       "Content-Type: message/rfc822\nContent-Transfer-Encoding: 7bit\n\n";
-      if ((ret =
-          mu_header_create (&hdr, header, strlen (header))) == 0)
+#define MSG822_HEADER "Content-Type: message/rfc822\n" \
+                     "Content-Transfer-Encoding: 7bit\n\n"
+      if ((ret = mu_header_create (&hdr,
+                                  MSG822_HEADER,
+                                  sizeof (MSG822_HEADER) - 1)) == 0)
        ret = mu_message_set_header (msg, hdr, NULL);
+#undef MSG822_HEADER
       if (ret)
        {
          mu_message_destroy (&msg, NULL);
@@ -382,13 +332,7 @@ mu_message_encapsulate (mu_message_t msg, mu_message_t 
*newmsg,
   if (ret == 0 && (ret = mu_message_get_streamref (msg, &istream)) == 0)
     {
       mu_stream_seek (istream, 0, MU_SEEK_SET, NULL);
-      while (((ret = mu_stream_read (istream, info->buf, BUF_SIZE, 
-                                    &nbytes)) == 0 && nbytes))
-       {
-         if ((ret =
-              mu_stream_write (ostream, info->buf, nbytes, NULL)) != 0)
-           break;
-       }
+      ret = mu_stream_copy (ostream, istream, 0, NULL);
       mu_stream_destroy (&istream);
     }
   if (ret == 0)
@@ -404,7 +348,6 @@ int
 mu_message_unencapsulate (mu_message_t msg, mu_message_t *newmsg,
                          mu_mime_io_buffer_t info)
 {
-  size_t size, nbytes;
   int ret = 0;
   mu_header_t hdr;
   mu_stream_t istream, ostream;
@@ -417,21 +360,10 @@ mu_message_unencapsulate (mu_message_t msg, mu_message_t 
*newmsg,
   if (info == NULL /* FIXME: not needed? */
       && (ret = mu_message_get_header (msg, &hdr)) == 0)
     {
-      mu_header_get_value (hdr, "Content-Type", NULL, 0, &size);
-      if (size)
-       {
-         char *content_type;
-         if ((content_type = malloc (size + 1)) == NULL)
-           return ENOMEM;
-         mu_header_get_value (hdr, "Content-Type", content_type, size + 1,
-                              0);
-         ret = mu_c_strncasecmp (content_type, MESSAGE_RFC822_STR,
-                                 sizeof (MESSAGE_RFC822_STR) - 1);
-         free (content_type);
-         if (ret != 0)
-           return EINVAL;
-       }
-      else
+      const char *s;
+      if (!(mu_header_sget_value (hdr, MU_HEADER_CONTENT_TYPE, &s) == 0 &&
+           mu_c_strncasecmp (s, MESSAGE_RFC822_STR,
+                             sizeof (MESSAGE_RFC822_STR) - 1) == 0))
        return EINVAL;
     }
   if ((ret = _attachment_setup (&info, msg, &istream)) != 0)
@@ -442,14 +374,7 @@ mu_message_unencapsulate (mu_message_t msg, mu_message_t 
*newmsg,
     {
       mu_message_get_streamref (info->msg, &ostream);
       mu_stream_seek (ostream, 0, MU_SEEK_SET, NULL);
-      while (((ret =
-              mu_stream_read (istream, info->buf, BUF_SIZE, 
-                              &nbytes)) == 0 && nbytes))
-       {
-         if ((ret =
-              mu_stream_write (ostream, info->buf, nbytes, NULL)) != 0)
-           break;
-       }
+      ret = mu_stream_copy (ostream, istream, 0, NULL);
       mu_stream_destroy (&ostream);
     }
   if (ret == 0)
diff --git a/libmailutils/stream/Makefile.am b/libmailutils/stream/Makefile.am
index c68e83a..82fa573 100644
--- a/libmailutils/stream/Makefile.am
+++ b/libmailutils/stream/Makefile.am
@@ -25,6 +25,7 @@ libstream_la_SOURCES = \
  mapfile_stream.c\
  memory_stream.c\
  message_stream.c\
+ nullstream.c\
  prog_stream.c\
  rdcache_stream.c\
  socket_stream.c\
diff --git a/libmailutils/stream/fltstream.c b/libmailutils/stream/fltstream.c
index a830957..ad4d0f1 100644
--- a/libmailutils/stream/fltstream.c
+++ b/libmailutils/stream/fltstream.c
@@ -407,7 +407,7 @@ static int
 filter_wr_close (mu_stream_t stream)
 {
   struct _mu_filter_stream *fs = (struct _mu_filter_stream *)stream;
-  if (!mu_stream_eof (stream))
+  if (!mu_stream_eof (stream) && !fs->eof)
     {
       size_t dummy;
       int rc = filter_write_internal (stream, mu_filter_lastbuf, NULL, 0,
diff --git a/libmailutils/stream/nullstream.c b/libmailutils/stream/nullstream.c
new file mode 100644
index 0000000..50c174f
--- /dev/null
+++ b/libmailutils/stream/nullstream.c
@@ -0,0 +1,204 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+   Copyright (C) 2010 Free Software Foundation, Inc.
+
+   This library is free software; you can redistribute it and/or modify
+   it under the terms of the GNU Lesser General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with GNU Mailutils.  If not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <mailutils/types.h>
+#include <mailutils/stream.h>
+#include <mailutils/errno.h>
+#include <mailutils/sys/nullstream.h>
+#include <mailutils/stream.h>
+#include <mailutils/cctype.h>
+
+static int
+_nullstream_read (struct _mu_stream *str, char *buf, size_t bufsize,
+                 size_t *pnread)
+{
+  struct _mu_nullstream *np = (struct _mu_nullstream *)str;
+  size_t i;
+  mu_off_t off;
+  
+  if (np->pattern == NULL)
+    {
+      *pnread = 0;
+      return 0;
+    }
+
+  off = np->base.offset + np->base.pos;
+  for (i = 0; i < bufsize; i++, off++)
+    {
+      if ((np->mode & MU_NULLSTREAM_SIZE) && off >= np->size)
+       break;
+      *buf++ = np->pattern[off % np->patsize];
+    }
+  *pnread = i;
+  return 0;
+}
+
+static int
+_nullstream_write (struct _mu_stream *str, const char *buf, size_t bufsize,
+                  size_t *pnwrite)
+{
+  *pnwrite = bufsize;
+  return 0;
+}
+
+static void
+_nullstream_free_pattern (struct _mu_nullstream *np)
+{
+  if (!(np->mode & MU_NULLSTREAM_PATSTAT))
+    {
+      free (np->pattern);
+      np->pattern = NULL;
+      np->patsize = 0;
+      np->mode &= ~MU_NULLSTREAM_PATSTAT;
+    }
+}
+
+static void
+_nullstream_done (struct _mu_stream *str)
+{
+  struct _mu_nullstream *np = (struct _mu_nullstream *)str;
+  _nullstream_free_pattern (np);
+}
+
+static int
+_nullstream_seek (struct _mu_stream *str, mu_off_t off, mu_off_t *ppos)
+{
+  struct _mu_nullstream *np = (struct _mu_nullstream *)str;
+  if ((np->mode & MU_NULLSTREAM_SIZE) && off >= np->size)
+    return ESPIPE;
+  *ppos = off;
+  return 0;
+}
+
+static int
+_nullstream_size (struct _mu_stream *str, mu_off_t *psize)
+{
+  struct _mu_nullstream *np = (struct _mu_nullstream *)str;
+  *psize = (np->mode & MU_NULLSTREAM_SIZE) ? np->size : 0;
+  return 0;
+}
+
+static int
+_nullstream_truncate (struct _mu_stream *str, mu_off_t size)
+{
+  struct _mu_nullstream *np = (struct _mu_nullstream *)str;
+  np->base.size = _nullstream_size;
+  np->size = size;
+  np->mode |= MU_NULLSTREAM_SIZE;
+  return 0;
+}
+
+static int
+_nullstream_ctl (struct _mu_stream *str, int op, void *arg)
+{
+  struct _mu_nullstream *np = (struct _mu_nullstream *)str;
+
+  switch (op)
+    {
+    case MU_IOCTL_NULLSTREAM_SET_PATTERN:
+      if (!arg)
+       _nullstream_free_pattern (np);
+      else
+       {
+         struct mu_nullstream_pattern *pat = arg;
+         char *p;
+         
+         p = malloc (pat->size);
+         if (!p)
+           return ENOMEM;
+         memcpy (p, pat->pattern, pat->size);
+         _nullstream_free_pattern (np);
+         np->pattern = p;
+         np->patsize = pat->size;
+       }
+      break;
+
+    case MU_IOCTL_NULLSTREAM_SET_PATCLASS:
+      if (!arg)
+       return EINVAL;
+      else
+       {
+         char buf[256];
+         int cnt = 0, i;
+         int class = *(int*)arg;
+         char *p;
+         
+         for (i = 0; i < 256; i++)
+           {
+             if (mu_c_is_class (i, class))
+               buf[cnt++] = i;
+           }
+
+         p = malloc (cnt);
+         if (!p)
+           return ENOMEM;
+         memcpy (p, buf, cnt);
+         _nullstream_free_pattern (np);
+         np->pattern = p;
+         np->patsize = cnt;
+       }
+      break;
+         
+    case MU_IOCTL_NULLSTREAM_SETSIZE:
+      if (!arg)
+       return EINVAL;
+      else
+       return _nullstream_truncate (str, *(mu_off_t*)arg);
+      break;
+
+    case MU_IOCTL_NULLSTREAM_CLRSIZE:
+      np->mode &= ~MU_NULLSTREAM_SIZE;
+      np->base.size = NULL;
+      break;
+      
+    default:
+      return ENOSYS;
+    }
+  return 0;
+}
+
+int
+mu_nullstream_create (mu_stream_t *pref, int flags)
+{
+  struct _mu_nullstream *np;
+
+  np = (struct _mu_nullstream *)
+         _mu_stream_create (sizeof (*np),
+                           flags | MU_STREAM_SEEK | _MU_STR_OPEN);
+  if (!np)
+    return ENOMEM;
+  np->base.read = _nullstream_read; 
+  np->base.write = _nullstream_write;
+  np->base.seek = _nullstream_seek; 
+  np->base.ctl = _nullstream_ctl;
+  np->base.truncate = _nullstream_truncate;
+  np->base.done = _nullstream_done;
+
+  np->pattern = "";
+  np->patsize = 0;
+  np->mode = MU_NULLSTREAM_PATSTAT;
+  
+  *pref = (mu_stream_t) np;
+
+  mu_stream_set_buffer (*pref, mu_buffer_full, 0);
+  return 0;
+}
diff --git a/libmailutils/stream/stream.c b/libmailutils/stream/stream.c
index 48ca32b..f8834c1 100644
--- a/libmailutils/stream/stream.c
+++ b/libmailutils/stream/stream.c
@@ -46,6 +46,19 @@ size_t mu_stream_default_buffer_size = MU_STREAM_DEFBUFSIZ;
     }                                                          \
   while (0)
 
+#define _stream_stat_incr(s, k, n) \
+  (((s)->statmask & MU_STREAM_STAT_MASK(k)) ? ((s)->statbuf[k] += n) : 0)
+
+#define _stream_read(str, buf, size, rdbytes) \
+  (_stream_stat_incr ((str), MU_STREAM_STAT_READS, 1),  \
+   (str)->read (str, buf, size, rdbytes))
+#define _stream_write(str, buf, size, wrbytes) \
+  (_stream_stat_incr ((str), MU_STREAM_STAT_WRITES, 1),  \
+   (str)->write (str, buf, size, wrbytes))
+#define _stream_seek(str, pos, poff)                   \
+  (_stream_stat_incr ((str), MU_STREAM_STAT_SEEKS, 1),         \
+   (str)->seek (str, pos, poff))
+
 static int _stream_read_unbuffered (mu_stream_t stream, void *buf, size_t size,
                                    int full_read, size_t *pnread);
 static int _stream_write_unbuffered (mu_stream_t stream,
@@ -180,7 +193,7 @@ _stream_flush_buffer (struct _mu_stream *stream, int flags)
       if ((stream->flags & MU_STREAM_SEEK) && stream->seek)
        {
          mu_off_t off;
-         rc = stream->seek (stream, stream->offset, &off);
+         rc = _stream_seek (stream, stream->offset, &off);
          if (rc)
            return rc;
        }
@@ -306,7 +319,9 @@ mu_stream_unref (mu_stream_t stream)
 static void
 _stream_init (mu_stream_t stream)
 {
-  stream->bytes_in = stream->bytes_out = 0;
+  if (stream->statmask)
+    memset (stream->statbuf, 0,
+           _MU_STREAM_STAT_MAX * sizeof (stream->statbuf[0]));
   stream->flags &= ~_MU_STR_INTERN_MASK;
   _stream_setflag (stream, _MU_STR_OPEN);
   stream->offset = 0;
@@ -431,7 +446,7 @@ mu_stream_seek (mu_stream_t stream, mu_off_t offset, int 
whence,
        return rc;
       if (stream->offset != offset)
        {
-         rc = stream->seek (stream, offset, &stream->offset);
+         rc = _stream_seek (stream, offset, &stream->offset);
          if (rc == ESPIPE)
            return rc;
          if (rc)
@@ -602,7 +617,7 @@ _stream_read_unbuffered (mu_stream_t stream, void *buf, 
size_t size,
 
       nread = 0;
       while (size > 0
-            && (rc = stream->read (stream, buf, size, &rdbytes)) == 0)
+            && (rc = _stream_read (stream, buf, size, &rdbytes)) == 0)
        {
          if (rdbytes == 0)
            {
@@ -612,19 +627,19 @@ _stream_read_unbuffered (mu_stream_t stream, void *buf, 
size_t size,
          buf += rdbytes;
          nread += rdbytes;
          size -= rdbytes;
-         stream->bytes_in += rdbytes;
+         _stream_stat_incr (stream, MU_STREAM_STAT_IN, rdbytes);
        }
       if (size && rc)
        rc = mu_stream_seterr (stream, rc, 0);
     }
   else
     {
-      rc = stream->read (stream, buf, size, &nread);
+      rc = _stream_read (stream, buf, size, &nread);
       if (rc == 0)
        {
          if (nread == 0)
            _stream_setflag (stream, _MU_STR_EOF);
-         stream->bytes_in += nread;
+         _stream_stat_incr (stream, MU_STREAM_STAT_IN, nread);
        }
       mu_stream_seterr (stream, rc, rc != 0);
     }
@@ -665,7 +680,7 @@ _stream_write_unbuffered (mu_stream_t stream,
 
       nwritten = 0;
       while (size > 0
-            && (rc = stream->write (stream, bufp, size, &wrbytes))
+            && (rc = _stream_write (stream, bufp, size, &wrbytes))
             == 0)
        {
          if (wrbytes == 0)
@@ -676,14 +691,14 @@ _stream_write_unbuffered (mu_stream_t stream,
          bufp += wrbytes;
          nwritten += wrbytes;
          size -= wrbytes;
-         stream->bytes_out += wrbytes;
+         _stream_stat_incr (stream, MU_STREAM_STAT_OUT, wrbytes);
        }
     }
   else
     {
-      rc = stream->write (stream, buf, size, &nwritten);
+      rc = _stream_write (stream, buf, size, &nwritten);
       if (rc == 0)
-       stream->bytes_out += nwritten;
+       _stream_stat_incr (stream, MU_STREAM_STAT_OUT, nwritten);
     }
   _stream_setflag (stream, _MU_STR_WRT);
   if (pnwritten)
@@ -1101,18 +1116,6 @@ mu_stream_size (mu_stream_t stream, mu_off_t *psize)
   return mu_stream_seterr (stream, rc, rc != 0);
 }
 
-mu_off_t
-mu_stream_bytes_in (mu_stream_t stream)
-{
-  return stream->bytes_in;
-}
-
-mu_off_t
-mu_stream_bytes_out (mu_stream_t stream)
-{
-  return stream->bytes_out;
-}
-
 int
 mu_stream_ioctl (mu_stream_t stream, int code, void *ptr)
 {
@@ -1215,3 +1218,27 @@ mu_stream_clr_flags (mu_stream_t stream, int fl)
   return 0;
 }
 
+int
+mu_stream_set_stat (mu_stream_t stream, int statmask,
+                   mu_stream_stat_buffer statbuf)
+{
+  if (stream == NULL)
+    return EINVAL;
+  stream->statmask = statmask;
+  stream->statbuf = statbuf;
+  memset (stream->statbuf, 0,
+         _MU_STREAM_STAT_MAX * sizeof (stream->statbuf[0]));
+  return 0;
+}
+
+int
+mu_stream_get_stat (mu_stream_t stream, int *pstatmask,
+                   mu_off_t **pstatbuf)
+{
+  if (stream == NULL)
+    return EINVAL;
+  *pstatmask = stream->statmask;
+  *pstatbuf = stream->statbuf;
+  return 0;
+}
+  
diff --git a/libmailutils/tests/fltst.c b/libmailutils/tests/fltst.c
index e5c0ae1..cc72f2d 100644
--- a/libmailutils/tests/fltst.c
+++ b/libmailutils/tests/fltst.c
@@ -29,10 +29,21 @@
 
 int verbose = 0;
 int printable = 0;
+mu_stream_stat_buffer instat, outstat;
 
 static void
 c_copy (mu_stream_t out, mu_stream_t in)
 {
+  if (verbose)
+    {
+      mu_stream_set_stat (in,
+                         MU_STREAM_STAT_MASK_ALL,
+                         instat);
+      mu_stream_set_stat (out,
+                         MU_STREAM_STAT_MASK_ALL,
+                         outstat);
+    }
+  
   if (printable)
     {
       char c;
@@ -55,11 +66,6 @@ c_copy (mu_stream_t out, mu_stream_t in)
   else
     MU_ASSERT (mu_stream_copy (out, in, 0, NULL));
 
-  if (verbose)
-    fprintf (stderr, "\ntotal: %lu/%lu bytes\n",
-            (unsigned long) mu_stream_bytes_in (in),
-            (unsigned long) mu_stream_bytes_out (out));
-  
 }
 
 /* Set the maximum line length for the filter NAME to LENGTH.
@@ -186,5 +192,28 @@ main (int argc, char * argv [])
   mu_stream_close (out);
   mu_stream_destroy (&out);
   
+  if (verbose)
+    {
+      fprintf (stderr, "\nInput stream stats:\n");
+      fprintf (stderr, "Bytes in: %lu\n",
+              (unsigned long) instat[MU_STREAM_STAT_IN]);
+      fprintf (stderr, "Bytes out: %lu\n",
+              (unsigned long) instat[MU_STREAM_STAT_OUT]);
+      fprintf (stderr, "Reads: %lu\n",
+              (unsigned long) instat[MU_STREAM_STAT_READS]);
+      fprintf (stderr, "Seeks: %lu\n",
+              (unsigned long) instat[MU_STREAM_STAT_SEEKS]);
+
+      fprintf (stderr, "\nOutput stream stats:\n");
+      fprintf (stderr, "Bytes in: %lu\n",
+              (unsigned long) outstat[MU_STREAM_STAT_IN]);
+      fprintf (stderr, "Bytes out: %lu\n",
+              (unsigned long) outstat[MU_STREAM_STAT_OUT]);
+      fprintf (stderr, "Writes: %lu\n",
+              (unsigned long) outstat[MU_STREAM_STAT_WRITES]);
+      fprintf (stderr, "Seeks: %lu\n",
+              (unsigned long) outstat[MU_STREAM_STAT_SEEKS]);
+    }
+
   return 0;
 }
diff --git a/mh/mhn.c b/mh/mhn.c
index bc240cb..238761d 100644
--- a/mh/mhn.c
+++ b/mh/mhn.c
@@ -188,24 +188,10 @@ split_content (const char *content, char **type, char 
**subtype)
 }
 
 int
-_get_hdr_value (mu_header_t hdr, const char *name, char **value)
-{
-  int status = mu_header_aget_value (hdr, name, value);
-  if (status == 0)
-    {
-      /* Remove the newlines.  */
-      char *nl;
-      while ((nl = strchr (*value, '\n')) != NULL)
-       *nl = ' ';
-    }
-  return status;
-}
-
-int
 _get_content_type (mu_header_t hdr, char **value, char **rest)
 {
   char *type = NULL;
-  _get_hdr_value (hdr, MU_HEADER_CONTENT_TYPE, &type);
+  mu_header_aget_value_unfold (hdr, MU_HEADER_CONTENT_TYPE, &type);
   if (type == NULL || *type == '\0')
     {
       if (type)
@@ -230,7 +216,8 @@ static int
 _get_content_encoding (mu_header_t hdr, char **value)
 {
   char *encoding = NULL;
-  _get_hdr_value (hdr, MU_HEADER_CONTENT_TRANSFER_ENCODING, &encoding);
+  mu_header_aget_value_unfold (hdr, MU_HEADER_CONTENT_TRANSFER_ENCODING,
+                              &encoding);
   if (encoding == NULL || *encoding == '\0')
     {
       if (encoding)
@@ -406,7 +393,8 @@ opt_handler (int key, char *arg, struct argp_state *state)
 
 /* *********************** Message part functions ************************* */
 
-struct _msg_part {
+struct _msg_part
+{
   int level;
   int maxlevel;
   size_t *part;
@@ -1094,9 +1082,12 @@ handle_message (mu_message_t msg, msg_part_t part, 
msg_handler_t fun, void *data
 }
 
 int
-mhn_message_size (mu_message_t msg, size_t *psize)
+mhn_message_size (mu_message_t msg, mu_off_t *psize)
 {
+  int rc;
+  size_t size;
   mu_body_t body;
+  
   *psize = 0;
   mu_message_get_body (msg, &body);
   if (mode_options & OPT_REALSIZE)
@@ -1107,8 +1098,6 @@ mhn_message_size (mu_message_t msg, size_t *psize)
        {
          mu_header_t hdr;
          char *encoding;
-         size_t size = 0;
-         int rc;
          
          mu_message_get_header (msg, &hdr);
          _get_content_encoding (hdr, &encoding);
@@ -1119,22 +1108,27 @@ mhn_message_size (mu_message_t msg, size_t *psize)
          free (encoding);
          if (rc == 0)
            {
-             char buf[512];
-             size_t n;
-
-             while (mu_stream_read (dstr, buf, sizeof buf, &n) == 0
-                    && n > 0)
-               size += n;
-
+             mu_stream_stat_buffer stat;
+             mu_stream_t null;
+
+             mu_nullstream_create (&null, MU_STREAM_WRITE);
+             mu_stream_set_stat (null,
+                                 MU_STREAM_STAT_MASK (MU_STREAM_STAT_OUT),
+                                 stat);
+             mu_stream_copy (null, dstr, 0, NULL);
+             mu_stream_destroy (&null);
              mu_stream_destroy (&dstr);
-             *psize = size;
+             *psize = stat[MU_STREAM_STAT_OUT];
              return 0;
            }
          mu_stream_destroy (&bstr);
        }
     }
 
-  return mu_body_size (body, psize);
+  rc = mu_body_size (body, &size);
+  if (rc == 0)
+    *psize = size;
+  return rc;
 }
 
 
@@ -1144,7 +1138,7 @@ int
 list_handler (mu_message_t msg, msg_part_t part, char *type, char *encoding,
              void *data)
 {
-  size_t size;
+  mu_off_t size;
   mu_header_t hdr;
   
   if (msg_part_level (part) == 0)
@@ -1161,9 +1155,9 @@ list_handler (mu_message_t msg, msg_part_t part, char 
*type, char *encoding,
   if (size < 1024)
     printf (" %4lu", (unsigned long) size);
   else if (size < 1024*1024)
-    printf ("%4luK", (unsigned long) size / 1024);
+    printf ("%4luK", (unsigned long) (size + 1024 - 1) / 1024);
   else
-    printf ("%4luM", (unsigned long) size / 1024 / 1024);
+    printf ("%4luM", (unsigned long) (size + 1024*1024 - 1) / 1024 / 1024);
   
   if (mu_message_get_header (msg, &hdr) == 0)
     {
@@ -1360,7 +1354,7 @@ show_handler (mu_message_t msg, msg_part_t part, char 
*type, char *encoding,
     {
       char *str;
       const char *p;
-      size_t size = 0;
+      mu_off_t size = 0;
 
       str = (char*) _("part ");
       mu_stream_write (out, str, strlen (str), NULL);
@@ -1662,7 +1656,8 @@ mhn_store ()
 
 /* ***************************** Compose Mode **************************** */
 
-struct compose_env {
+struct compose_env
+{
   mu_stream_t input;
   mu_mime_t mime;
   size_t line;
@@ -1881,20 +1876,13 @@ copy_header (mu_message_t msg, mu_header_t out)
   mu_header_get_field_count (hdr, &count);
   for (i = 1; i <= count; i++)
     {
-      char *name, *value;
+      const char *name, *value;
 
-      if (mu_header_aget_field_name (hdr, i, &name))
-        continue;
-
-      if (mu_header_aget_field_value (hdr, i, &value))
-       {
-          free (name);
-          continue;
-        }
+      if (mu_header_sget_field_name (hdr, i, &name) ||
+         mu_header_sget_field_value (hdr, i, &value))
+       continue;
 
       mu_header_set_value (out, name, value, 0);
-      free (name);
-      free (value);
     }
 }
 
@@ -2216,7 +2204,8 @@ edit_mime (char *cmd, struct compose_env *env, 
mu_message_t *msg, int level)
   
   /* Create filter */
 
-  if (_get_hdr_value (hdr, MU_HEADER_CONTENT_TRANSFER_ENCODING, &encoding))
+  if (mu_header_aget_value_unfold (hdr, MU_HEADER_CONTENT_TRANSFER_ENCODING,
+                                  &encoding))
     {
       char *typestr, *type, *subtype;
       


hooks/post-receive
-- 
GNU Mailutils



reply via email to

[Prev in Thread] Current Thread [Next in Thread]