commit-mailutils
[Top][All Lists]
Advanced

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

[SCM] GNU Mailutils branch, stream-cleanup, updated. rel-2_1-129-g817286


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, stream-cleanup, updated. rel-2_1-129-g8172866
Date: Tue, 07 Sep 2010 11:08:40 +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=817286698ccc3f262cd0003401becef6c11050ae

The branch, stream-cleanup has been updated
       via  817286698ccc3f262cd0003401becef6c11050ae (commit)
      from  bfb29ced5d88dbe449347d5b8b86e6ee887c450b (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 817286698ccc3f262cd0003401becef6c11050ae
Author: Sergey Poznyakoff <address@hidden>
Date:   Tue Sep 7 13:57:30 2010 +0300

    Finish pop3 mailbox implementation.
    
    * mailbox/msgscan.c: New file.
    * mailbox/Makefile.am (libmailutils_la_SOURCES): Add it.
    
    * include/mailutils/body.h (mu_body_set_get_stream): New prototype.
    * include/mailutils/message.h (MU_SCAN_SEEK, MU_SCAN_SIZE): New
    defines.
    (mu_message_scan): New structure.
    (mu_stream_scan_message): New prototype.
    (mu_message_set_get_stream): New prototype.
    * include/mailutils/stream.h (mu_stream_copy): Change signature: takes
    4 arguments now.
    * include/mailutils/sys/body.h (_mu_body) <_get_stream>: New method.
    * include/mailutils/sys/message.h (_mu_message) <_get_stream>: New method.
    * mailbox/body.c (_body_get_stream): Call _get_stream, if provided.
    * mailbox/message.c (_message_get_stream): Call _get_stream, if provided.
    
    * mailbox/stream.c (_stream_flush_buffer): Avoid infinite recursion:
    call stream->seek directly.
    * mailbox/streamcpy.c (mu_stream_copy): Return the number of bytes
    actually copied in the fourth argument. All uses updated.
    * mailbox/streamref.c (streamref_return): Do not propagate internal
    flags.
    (_streamref_readdelim): Ensure there is enough buffer space for the
    mu_stream_readdelim call.
    
    * libproto/pop/mbox.c: Finish client implementation.
    
    * mail/print.c (mail_print_msg): Close pager before returning on
    error.

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

Summary of changes:
 examples/base64.c                 |    2 +-
 examples/mucat.c                  |    4 +-
 imap4d/io.c                       |    2 +-
 include/mailutils/body.h          |    5 +-
 include/mailutils/message.h       |   24 +++-
 include/mailutils/stream.h        |    3 +-
 include/mailutils/sys/body.h      |    1 +
 include/mailutils/sys/message.h   |    1 +
 libmu_scm/mu_message.c            |    2 +-
 libmu_sieve/actions.c             |    2 +-
 libmu_sieve/extensions/pipe.c     |    2 +-
 libmu_sieve/extensions/spamd.c    |    2 +-
 libmu_sieve/extensions/vacation.c |    2 +-
 libproto/mbox/mbox.c              |    8 +-
 libproto/pop/mbox.c               |  385 +++++++++++++++++++++++++++++++------
 mail/decode.c                     |    2 +-
 mail/print.c                      |    2 +
 mailbox/Makefile.am               |    1 +
 mailbox/body.c                    |   84 +++++---
 mailbox/message.c                 |   59 ++++--
 mailbox/msgscan.c                 |  106 ++++++++++
 mailbox/rdcache_stream.c          |    2 +-
 mailbox/stream.c                  |   10 +-
 mailbox/streamcpy.c               |   18 +-
 mailbox/streamref.c               |   18 +-
 mh/burst.c                        |    2 +-
 mh/comp.c                         |    2 +-
 mh/mhn.c                          |   10 +-
 pop3d/retr.c                      |    2 +-
 pop3d/top.c                       |    2 +-
 30 files changed, 611 insertions(+), 154 deletions(-)
 create mode 100644 mailbox/msgscan.c

diff --git a/examples/base64.c b/examples/base64.c
index 226cde9..aa6bdeb 100644
--- a/examples/base64.c
+++ b/examples/base64.c
@@ -55,7 +55,7 @@ c_copy (mu_stream_t out, mu_stream_t in)
        }
     }
   else
-    MU_ASSERT (mu_stream_copy (out, in, 0));
+    MU_ASSERT (mu_stream_copy (out, in, 0, NULL));
   mu_stream_write (out, "\n", 1, NULL);
   mu_stream_close (out);
   mu_stream_close (in);
diff --git a/examples/mucat.c b/examples/mucat.c
index b8cb314..92f55eb 100644
--- a/examples/mucat.c
+++ b/examples/mucat.c
@@ -69,14 +69,14 @@ main (int argc, char * argv [])
       MU_ASSERT (mu_stream_seek (in, skip_off, MU_SEEK_SET, NULL));
     }
   
-  MU_ASSERT (mu_stream_copy (out, in, 0));
+  MU_ASSERT (mu_stream_copy (out, in, 0, NULL));
 
   if (reread_option)
     {
       mu_stream_printf (out, "rereading from %lu:\n",
                        (unsigned long) reread_off);
       MU_ASSERT (mu_stream_seek (in, reread_off, MU_SEEK_SET, NULL));
-      MU_ASSERT (mu_stream_copy (out, in, 0));
+      MU_ASSERT (mu_stream_copy (out, in, 0, NULL));
     }
   
   mu_stream_close (in);
diff --git a/imap4d/io.c b/imap4d/io.c
index 05645ae..a8b6cb0 100644
--- a/imap4d/io.c
+++ b/imap4d/io.c
@@ -152,7 +152,7 @@ sc2string (int rc)
 int
 io_copy_out (mu_stream_t str, size_t size)
 {
-  return mu_stream_copy (iostream, str, size);
+  return mu_stream_copy (iostream, str, size, NULL);
 }
 
 int
diff --git a/include/mailutils/body.h b/include/mailutils/body.h
index 5fc25b7..d935d00 100644
--- a/include/mailutils/body.h
+++ b/include/mailutils/body.h
@@ -36,7 +36,10 @@ extern int mu_body_get_stream     (mu_body_t, mu_stream_t *)
                                       __attribute__ ((deprecated));
 extern int mu_body_get_streamref  (mu_body_t body, mu_stream_t *pstream);
 extern int mu_body_set_stream     (mu_body_t, mu_stream_t, void *owner);
-
+extern int mu_body_set_get_stream (mu_body_t,
+                                  int (*) (mu_body_t, mu_stream_t *),
+                                  void *owner);
+  
 extern int mu_body_get_filename   (mu_body_t, char *, size_t, size_t *);
 
 extern int mu_body_size           (mu_body_t, size_t *);
diff --git a/include/mailutils/message.h b/include/mailutils/message.h
index 8a2416f..14df6f6 100644
--- a/include/mailutils/message.h
+++ b/include/mailutils/message.h
@@ -26,6 +26,25 @@
 extern "C" {
 #endif
 
+#define MU_SCAN_SEEK  0x01
+#define MU_SCAN_SIZE  0x02
+
+struct mu_message_scan
+{
+  int flags;
+  mu_off_t message_start;
+  mu_off_t message_size;
+
+  mu_off_t body_start;
+  mu_off_t body_end;
+  size_t header_lines;
+  size_t body_lines;
+  int attr_flags;
+  unsigned long uidvalidity;
+};
+
+int mu_stream_scan_message (mu_stream_t stream, struct mu_message_scan *sp);
+  
 /* A message is considered to be a container for:
   mu_header_t, mu_body_t, and its mu_attribute_t.  */
 
@@ -34,7 +53,7 @@ extern void mu_message_destroy (mu_message_t *, void *owner);
 
 extern int mu_message_create_copy (mu_message_t *to, mu_message_t from);
 
-extern void * mu_message_get_owner (mu_message_t);
+extern void *mu_message_get_owner (mu_message_t);
 extern int mu_message_is_modified (mu_message_t);
 extern int mu_message_clear_modified (mu_message_t);
 extern int mu_message_get_mailbox (mu_message_t, mu_mailbox_t *);
@@ -64,6 +83,9 @@ extern int mu_message_set_attribute (mu_message_t, 
mu_attribute_t, void *);
 
 extern int mu_message_get_observable (mu_message_t, mu_observable_t *);
 
+extern int mu_message_set_get_stream (mu_message_t,
+                                     int (*) (mu_message_t, mu_stream_t *),
+                                     void *);
 extern int mu_message_is_multipart (mu_message_t, int *);
 extern int mu_message_set_is_multipart (mu_message_t, 
                                        int (*_is_multipart) (mu_message_t,
diff --git a/include/mailutils/stream.h b/include/mailutils/stream.h
index f2af9b3..e7d04ea 100644
--- a/include/mailutils/stream.h
+++ b/include/mailutils/stream.h
@@ -115,7 +115,8 @@ int mu_stream_clr_flags (mu_stream_t stream, int fl);
 int mu_stream_vprintf (mu_stream_t str, const char *fmt, va_list ap);
 int mu_stream_printf (mu_stream_t stream, const char *fmt, ...);
 
-int mu_stream_copy (mu_stream_t dst, mu_stream_t src, size_t size);
+int mu_stream_copy (mu_stream_t dst, mu_stream_t src, mu_off_t size,
+                   mu_off_t *pcsz);
 
 
 int mu_file_stream_create (mu_stream_t *pstream, const char *filename, int 
flags);
diff --git a/include/mailutils/sys/body.h b/include/mailutils/sys/body.h
index 9c82a2a..7ec58e3 100644
--- a/include/mailutils/sys/body.h
+++ b/include/mailutils/sys/body.h
@@ -40,6 +40,7 @@ struct _mu_body
 
   int (*_size)  (mu_body_t, size_t*);
   int (*_lines) (mu_body_t, size_t*);
+  int (*_get_stream) (mu_body_t, mu_stream_t *);
 };
 
 #ifdef __cplusplus
diff --git a/include/mailutils/sys/message.h b/include/mailutils/sys/message.h
index ec91372..5e96d85 100644
--- a/include/mailutils/sys/message.h
+++ b/include/mailutils/sys/message.h
@@ -52,6 +52,7 @@ struct _mu_message
   /* Reference count.  */
   int ref;
 
+  int (*_get_stream)     (mu_message_t, mu_stream_t *);
   int (*_get_uidl)       (mu_message_t, char *, size_t, size_t *);
   int (*_get_uid)        (mu_message_t, size_t *);
   int (*_get_qid)        (mu_message_t,        mu_message_qid_t *);
diff --git a/libmu_scm/mu_message.c b/libmu_scm/mu_message.c
index ffcf9e3..1cb06c0 100644
--- a/libmu_scm/mu_message.c
+++ b/libmu_scm/mu_message.c
@@ -219,7 +219,7 @@ SCM_DEFINE_PUBLIC (scm_mu_message_copy, "mu-message-copy", 
1, 0, 0,
                    "Cannot get output stream", SCM_BOOL_F);
     }
 
-  status = mu_stream_copy (out, in, 0);
+  status = mu_stream_copy (out, in, 0, NULL);
   mu_stream_destroy (&in);
   mu_stream_destroy (&out);
   if (status)
diff --git a/libmu_sieve/actions.c b/libmu_sieve/actions.c
index 940b691..952626a 100644
--- a/libmu_sieve/actions.c
+++ b/libmu_sieve/actions.c
@@ -252,7 +252,7 @@ mime_create_quote (mu_mime_t mime, mu_message_t msg)
   mu_body_get_streamref (body, &ostream);
   mu_message_get_streamref (msg, &istream);
 
-  rc = mu_stream_copy (ostream, istream, 0);
+  rc = mu_stream_copy (ostream, istream, 0, NULL);
 
   mu_stream_destroy (&istream);
   mu_stream_close (ostream);
diff --git a/libmu_sieve/extensions/pipe.c b/libmu_sieve/extensions/pipe.c
index 717706a..1378461 100644
--- a/libmu_sieve/extensions/pipe.c
+++ b/libmu_sieve/extensions/pipe.c
@@ -118,7 +118,7 @@ sieve_action_pipe (mu_sieve_machine_t mach, mu_list_t args, 
mu_list_t tags)
          ONERR (rc, _("stream write failed"), NULL);
        }
 
-      rc = mu_stream_copy (pstr, mstr, 0);
+      rc = mu_stream_copy (pstr, mstr, 0, NULL);
       ONERR (rc, _("command failed"), cmd);
     }
   while (0);
diff --git a/libmu_sieve/extensions/spamd.c b/libmu_sieve/extensions/spamd.c
index 26640d4..e620e58 100644
--- a/libmu_sieve/extensions/spamd.c
+++ b/libmu_sieve/extensions/spamd.c
@@ -117,7 +117,7 @@ spamd_send_message (mu_stream_t stream, mu_message_t msg)
       return rc;
     }
 
-  rc = mu_stream_copy (stream, flt, 0);
+  rc = mu_stream_copy (stream, flt, 0, NULL);
 
   mu_stream_destroy (&mstr);
   mu_stream_destroy (&flt);
diff --git a/libmu_sieve/extensions/vacation.c 
b/libmu_sieve/extensions/vacation.c
index f22e0e6..6b220df 100644
--- a/libmu_sieve/extensions/vacation.c
+++ b/libmu_sieve/extensions/vacation.c
@@ -111,7 +111,7 @@ build_mime (mu_sieve_machine_t mach, mu_list_t tags, 
mu_mime_t *pmime,
     }
 
   mu_stream_seek (input, 0, MU_SEEK_SET, NULL);
-  rc = mu_stream_copy (stream, input, 0);
+  rc = mu_stream_copy (stream, input, 0, NULL);
   if (rc)
     {
       mu_sieve_error (mach,
diff --git a/libproto/mbox/mbox.c b/libproto/mbox/mbox.c
index 51da14e..7b14817 100644
--- a/libproto/mbox/mbox.c
+++ b/libproto/mbox/mbox.c
@@ -1086,7 +1086,7 @@ append_message_to_stream (mu_stream_t ostr, mu_message_t 
msg,
       if (status)
        return status;
     }
-  status = mu_stream_copy (ostr, istr, 0);
+  status = mu_stream_copy (ostr, istr, 0, NULL);
   mu_stream_destroy (&istr);
   if (status == 0)
     status = mu_stream_write (ostr, "\n", 1, NULL);
@@ -1264,7 +1264,7 @@ mbox_expunge_unlocked (mu_mailbox_t mailbox, size_t 
dirty, int remove_deleted,
              return status;
            }
          status = mu_stream_copy (tempstr, mailbox->stream,
-                                  mum->body_end - mum->envel_from);
+                                  mum->body_end - mum->envel_from, NULL);
          if (status)
            {
              mu_error (_("%s:%d: error copying: %s"),
@@ -1295,7 +1295,7 @@ mbox_expunge_unlocked (mu_mailbox_t mailbox, size_t 
dirty, int remove_deleted,
              return status;
            }
   
-         status = mu_stream_copy (tempstr, mailbox->stream, len);
+         status = mu_stream_copy (tempstr, mailbox->stream, len, NULL);
          if (status)
            {
              mu_error (_("%s:%d: error writing to temporary stream: %s"),
@@ -1342,7 +1342,7 @@ mbox_expunge_unlocked (mu_mailbox_t mailbox, size_t 
dirty, int remove_deleted,
       return status;
     }
 
-  status = mu_stream_copy (mailbox->stream, tempstr, size);
+  status = mu_stream_copy (mailbox->stream, tempstr, size, NULL);
   if (status)
     {
       mu_error (_("%s:%d: copying from the temporary stream: %s"),
diff --git a/libproto/pop/mbox.c b/libproto/pop/mbox.c
index 3b538a0..ced5126 100644
--- a/libproto/pop/mbox.c
+++ b/libproto/pop/mbox.c
@@ -41,6 +41,7 @@
 #include <mailutils/observer.h>
 #include <mailutils/property.h>
 #include <mailutils/stream.h>
+#include <mailutils/filter.h>
 #include <mailutils/url.h>
 #include <mailutils/secret.h>
 #include <mailutils/tls.h>
@@ -56,22 +57,24 @@
 #include <mailutils/sys/registrar.h>
 #include <mailutils/sys/url.h>
 
-#define _POP3_MSG_INBODY  0x01
-#define _POP3_MSG_SKIPHDR 0x02
-#define _POP3_MSG_SKIPBDY 0x04
+#define _POP3_MSG_CACHED  0x01      /* Message is already cached */
+#define _POP3_MSG_SIZE    0x02      /* Message size obtained */
+#define _POP3_MSG_SCANNED 0x04      /* Message has been scanned */
+#define _POP3_MSG_ATTRSET 0x08      /* Attributes has been set */
 
 struct _pop3_message
 {
   int flags;
-  size_t body_size;
-  size_t header_size;
-  size_t body_lines;
-  size_t header_lines;
-  size_t message_size;
-  size_t num;
-  char *uidl; /* Cache the uidl string.  */
-  int attr_flags;
-  mu_message_t message;
+  mu_off_t offset;          /* Offset in the message cache stream */
+  mu_off_t body_start;      /* Start of message, relative to offset */
+  mu_off_t body_end;        /* End of message, relative to offset */  
+  size_t header_lines;      /* Number of lines in the header */
+  size_t body_lines;        /* Number of lines in the body */
+  int attr_flags;           /* Message attributes */
+  size_t message_size;      /* Message size */ 
+  size_t num;               /* Message number */
+  char *uidl;               /* Cached uidl string.  */
+  mu_message_t message;     /* Pointer to the message structure */ 
   struct _pop3_mailbox *mpd; /* Back pointer.  */
 };
   
@@ -87,10 +90,16 @@ struct _pop3_mailbox
   size_t msg_max;             /* Actual size of the array */  
   mu_mailbox_t mbox;          /* MU mailbox corresponding to this one. */
 
-  char *user;     /* Temporary holders for user and passwd.  */
+  mu_stream_t cache;          /* Message cache stream */
+   /* Temporary holders for user and passwd: */
+  char *user;    
   mu_secret_t secret;
 };
 
+
+/* ------------------------------------------------------------------------- */
+/* Basic operations */
+
 static int
 pop_open (mu_mailbox_t mbox, int flags)
 {
@@ -193,6 +202,7 @@ pop_close (mu_mailbox_t mbox)
   if (status)
     mu_error ("mu_pop3_disconnect failed: %s", mu_strerror (status));
   mu_pop3_destroy (&mpd->pop3);
+  mu_stream_destroy (&mpd->cache);
   return 0;
 }
 
@@ -220,6 +230,7 @@ pop_destroy (mu_mailbox_t mbox)
        free (mpd->user);
       if (mpd->secret)
        mu_secret_unref (mpd->secret);
+      mu_stream_destroy (&mpd->cache);
    }
 }
 
@@ -319,6 +330,156 @@ pop_get_size (mu_mailbox_t mbox, mu_off_t *psize)
 }
 
 
+/* ------------------------------------------------------------------------- */
+/* POP3 message streams */
+
+static void
+pop_stream_drain (mu_stream_t str)
+{
+  char buf[2048];
+  size_t size;
+
+  while (mu_stream_read (str, buf, sizeof buf, &size) == 0 && size)
+    ;
+}
+     
+static int
+_pop_message_get_stream (struct _pop3_message *mpm, mu_stream_t *pstr)
+{
+  int status;
+  struct _pop3_mailbox *mpd = mpm->mpd;
+  
+  if (!(mpm->flags & _POP3_MSG_CACHED))
+    {
+      mu_stream_t stream;
+      mu_off_t size;
+      
+      status = mu_pop3_retr (mpd->pop3, mpm->num, &stream);
+      if (status)
+       return status;
+
+      do
+       {
+         mu_stream_t flt;
+         
+         if (!mpd->cache)
+           {
+             status = mu_temp_file_stream_create (&mpd->cache, NULL);
+             if (status)
+               /* FIXME: Try to recover first */
+               break;
+
+             status = mu_stream_open (mpd->cache);
+             if (status)
+               {
+                 mu_stream_destroy (&mpd->cache);
+                 break;
+               }
+             mu_stream_set_buffer (mpd->cache, mu_buffer_full, 8192);
+           }
+
+         status = mu_stream_size (mpd->cache, &mpm->offset);
+         if (status)
+           break;
+
+         status = mu_filter_create (&flt, stream, "CRLF", MU_FILTER_DECODE,
+                                    MU_STREAM_READ);
+         if (status)
+           break;
+
+         status = mu_stream_copy (mpd->cache, flt, 0, &size);
+
+         mu_stream_destroy (&flt);
+       }
+      while (0);
+
+      if (status)
+       {
+         pop_stream_drain (stream);
+         mu_stream_unref (stream);
+         return status;
+       }
+
+      mu_stream_unref (stream);
+
+      mpm->message_size = size; /* FIXME: Possible overflow. */
+
+      mpm->flags |= _POP3_MSG_CACHED | _POP3_MSG_SIZE;
+    }
+  return mu_streamref_create_abridged (pstr, mpd->cache,
+                                      mpm->offset,
+                                      mpm->offset + mpm->message_size - 1);
+}
+
+static int
+pop_message_get_stream (mu_message_t msg, mu_stream_t *pstr)
+{
+  struct _pop3_message *mpm = mu_message_get_owner (msg);
+  return _pop_message_get_stream (mpm, pstr);
+}
+        
+static int
+pop_scan_message (struct _pop3_message *mpm)
+{
+  int status;
+  mu_stream_t stream;
+  struct mu_message_scan scan;
+
+  if (mpm->flags & _POP3_MSG_SCANNED)
+    return 0;
+  
+  status = _pop_message_get_stream (mpm, &stream);
+  if (status)
+    return status;
+      
+  scan.flags = MU_SCAN_SEEK | MU_SCAN_SIZE;
+  scan.message_start = 0;
+  scan.message_size = mpm->message_size;
+  status = mu_stream_scan_message (stream, &scan);
+  mu_stream_unref (stream);
+
+  if (status == 0)
+    {
+      mpm->body_start = scan.body_start;
+      mpm->body_end = scan.body_end;
+      mpm->header_lines = scan.header_lines;
+      mpm->body_lines = scan.body_lines;
+      if (!(mpm->flags & _POP3_MSG_ATTRSET))
+       {
+         mpm->attr_flags = scan.attr_flags;
+         mpm->flags |= _POP3_MSG_ATTRSET;
+       }
+
+      mpm->flags |= _POP3_MSG_SCANNED;
+    }
+  
+  return status;
+}
+
+
+static int
+pop_message_size (mu_message_t msg, size_t *psize)
+{
+  struct _pop3_message *mpm = mu_message_get_owner (msg);
+  struct _pop3_mailbox *mpd = mpm->mpd;
+
+  if (mpm == NULL)
+    return EINVAL;
+
+  if (!(mpm->flags & _POP3_MSG_SIZE))
+    {
+      /* FIXME: The size obtained this way may differ from the actual one
+        by the number of lines in the message. */
+      int status = mu_pop3_list (mpd->pop3, mpm->num, &mpm->message_size);
+      if (status)
+       return status;
+      mpm->flags |= _POP3_MSG_SIZE;
+    }
+  if (psize)
+    *psize = mpm->message_size;
+  return 0;
+}
+
 static int
 pop_create_message (struct _pop3_message *mpm, struct _pop3_mailbox *mpd)
 {
@@ -328,7 +489,9 @@ pop_create_message (struct _pop3_message *mpm, struct 
_pop3_mailbox *mpd)
   status = mu_message_create (&msg, mpm);
   if (status)
     return status;
-  // FIXME...
+
+  mu_message_set_get_stream (msg, pop_message_get_stream, mpm);
+  mu_message_set_size (msg, pop_message_size, mpm);
   mpm->message = msg;
   return 0;
 }
@@ -337,46 +500,34 @@ pop_create_message (struct _pop3_message *mpm, struct 
_pop3_mailbox *mpd)
 /* ------------------------------------------------------------------------- */
 /* Header */
 
-static int
-pop_header_fill (void *data, char **pbuf, size_t *plen)
+int
+pop_header_blurb (mu_stream_t stream, size_t maxlines,
+                 char **pbuf, size_t *plen)
 {
-  struct _pop3_message *mpm = data;
-  struct _pop3_mailbox *mpd = mpm->mpd;
-  mu_stream_t stream;
-  mu_opool_t opool;
   int status;
+  mu_opool_t opool;
+  size_t size = 0;
+  char *buf = NULL;
+  size_t n;
+  size_t nlines = 0;
   
   status = mu_opool_create (&opool, 0);
   if (status)
     return status;
-  
-  if (mu_pop3_capa_test (mpd->pop3, "TOP", NULL) == 0)
-    status = mu_pop3_top (mpd->pop3, mpm->num, 0, &stream);
-  else
-    status = mu_pop3_retr (mpd->pop3, mpm->num, &stream);
-
+      
+  while ((status = mu_stream_getline (stream, &buf, &size, &n)) == 0 && n > 0)
+    {
+      size_t len = mu_rtrim_cset (buf, "\r\n");
+      if (len == 0)
+       break;
+      mu_opool_append (opool, buf, len);
+      mu_opool_append_char (opool, '\n');
+      if (maxlines && ++nlines >= maxlines)
+       break;
+    }
+      
   if (status == 0)
     {
-      size_t size = 0;
-      char *buf = NULL;
-      size_t n;
-
-      while (mu_stream_getline (stream, &buf, &size, &n) == 0
-            && n > 0)
-       {
-         size_t len = mu_rtrim_cset (buf, "\r\n");
-         if (len == 0)
-           break;
-         mu_opool_append (opool, buf, len);
-         mu_opool_append_char (opool, '\n');
-       }
-
-      if (!mu_stream_eof (stream))
-       /* Drain the stream. */
-       while (mu_stream_getline (stream, &buf, &size, &n) == 0
-              && n > 0);
-      mu_stream_destroy (&stream);
-
       n = mu_opool_size (opool);
       if (n > size)
        {
@@ -384,19 +535,53 @@ pop_header_fill (void *data, char **pbuf, size_t *plen)
          if (!p)
            {
              free (buf);
-             mu_opool_destroy (&opool);
-             return ENOMEM;
+             status = ENOMEM;
            }
-         buf = p;
+         else
+           buf = p;
        }
+    }
 
+  if (status == 0)
+    {
       mu_opool_copy (opool, buf, n);
       *pbuf = buf;
       *plen = n;
-      status = 0;
     }
+  else
+    free (buf);
   mu_opool_destroy (&opool);
-  
+
+  return 0;
+}
+
+static int
+pop_header_fill (void *data, char **pbuf, size_t *plen)
+{
+  struct _pop3_message *mpm = data;
+  struct _pop3_mailbox *mpd = mpm->mpd;
+  mu_stream_t stream;
+  int status;
+
+  if (mpm->flags & _POP3_MSG_SCANNED)
+    status = _pop_message_get_stream (mpm, &stream);
+  else
+    {
+      status = mu_pop3_top (mpd->pop3, mpm->num, 0, &stream);
+      if (status == 0)
+       {
+         status = pop_header_blurb (stream, 0, pbuf, plen);
+         if (!mu_stream_eof (stream))
+           pop_stream_drain (stream);
+         mu_stream_destroy (&stream);
+         return status;
+       }
+      else
+       status = _pop_message_get_stream (mpm, &stream);
+    }
+
+  status = pop_header_blurb (stream, mpm->header_lines, pbuf, plen);
+  mu_stream_destroy (&stream);
   return status;
 }
 
@@ -437,7 +622,7 @@ pop_get_attribute (mu_attribute_t attr, int *pflags)
 
   if (mpm == NULL || pflags == NULL)
     return EINVAL;
-  if (mpm->attr_flags == 0)
+  if (!(mpm->flags & _POP3_MSG_ATTRSET))
     {
       hdr_status[0] = '\0';
 
@@ -458,6 +643,7 @@ pop_set_attribute (mu_attribute_t attr, int flags)
   if (mpm == NULL)
     return EINVAL;
   mpm->attr_flags |= flags;
+  mpm->flags |= _POP3_MSG_ATTRSET;
   return 0;
 }
 
@@ -469,6 +655,7 @@ pop_unset_attribute (mu_attribute_t attr, int flags)
   if (mpm == NULL)
     return EINVAL;
   mpm->attr_flags &= ~flags;
+  mpm->flags |= _POP3_MSG_ATTRSET;
   return 0;
 }
 
@@ -492,11 +679,58 @@ pop_create_attribute (struct _pop3_message *mpm)
 /* ------------------------------------------------------------------------- */
 /* Body */
 
+int
+pop_body_get_stream (mu_body_t body, mu_stream_t *pstr)
+{
+  struct _pop3_message *mpm = mu_body_get_owner (body);
+  struct _pop3_mailbox *mpd = mpm->mpd;
+  int status = pop_scan_message (mpm);
+  if (status)
+    return status;
+  return mu_streamref_create_abridged (pstr, mpd->cache,
+                                      mpm->offset + mpm->body_start,
+                                      mpm->offset + mpm->body_end - 1);
+}
+
+static int
+pop_body_size (mu_body_t body, size_t *psize)
+{
+  struct _pop3_message *mpm = mu_body_get_owner (body);
+  int status = pop_scan_message (mpm);
+  if (status)
+    return status;
+  *psize = mpm->body_end - mpm->body_start;
+  return 0;
+}
+
+static int
+pop_body_lines (mu_body_t body, size_t *plines)
+{
+  struct _pop3_message *mpm = mu_body_get_owner (body);
+  int status = pop_scan_message (mpm);
+  if (status)
+    return status;
+  *plines = mpm->body_lines;
+  return 0;
+}
+
 static int
 pop_create_body (struct _pop3_message *mpm)
 {
-  /* FIXME */
-  return ENOSYS;
+  int status;
+  mu_body_t body = NULL;
+
+  status = mu_body_create (&body, mpm);
+  if (status)
+    return status;
+
+  mu_body_set_get_stream (body, pop_body_get_stream, mpm);
+  mu_body_set_size (body, pop_body_size, mpm);
+  mu_body_set_lines (body, pop_body_lines, mpm);
+
+  mu_message_set_body (mpm->message, body, mpm);
+
+  return 0;
 }
 
 
@@ -568,9 +802,9 @@ pop_get_message (mu_mailbox_t mbox, size_t msgno, 
mu_message_t *pmsg)
       if (!mpd->msg)
        return ENOMEM;
     }
-  if (mpd->msg[msgno])
+  if (mpd->msg[msgno - 1])
     {
-      *pmsg = mpd->msg[msgno]->message;
+      *pmsg = mpd->msg[msgno - 1]->message;
       return 0;
     }
 
@@ -613,13 +847,45 @@ pop_get_message (mu_mailbox_t mbox, size_t msgno, 
mu_message_t *pmsg)
 
   mu_message_set_uid (mpm->message, pop_uid, mpm);
 
-  mpd->msg[msgno] = mpm;
+  mpd->msg[msgno - 1] = mpm;
   mu_message_set_mailbox (mpm->message, mbox, mpm);
   *pmsg = mpm->message;
   return 0;
 }
 
 static int
+pop_expunge (mu_mailbox_t mbox)
+{
+  struct _pop3_mailbox *mpd = mbox->data;
+  int status = 0;
+  size_t i;
+  
+  if (mpd == NULL)
+    return EINVAL;
+
+  if (!mpd->msg)
+    return 0;
+  
+  for (i = 0; i < mpd->msg_count; i++)
+    {
+      struct _pop3_message *mpm = mpd->msg[i];
+
+      if (mpm &&
+         (mpm->flags & _POP3_MSG_ATTRSET) &&
+         (mpm->attr_flags & MU_ATTRIBUTE_DELETED))
+       {
+         status = mu_pop3_dele (mpd->pop3, mpm->num);
+         if (status)
+           break;
+       }
+    }
+  return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+/* Initialization */
+
+static int
 _pop3_mailbox_init (mu_mailbox_t mbox, int pops)
 {
   struct _pop3_mailbox *mpd;
@@ -649,13 +915,10 @@ _pop3_mailbox_init (mu_mailbox_t mbox, int pops)
   mbox->_message_unseen = pop_message_unseen;
   mbox->_get_size = pop_get_size;
   
-#if 0 //FIXME
   /* Messages.  */
   mbox->_get_message = pop_get_message;
   mbox->_expunge = pop_expunge;
 
-
-
   /* Set our properties.  */
   {
     mu_property_t property = NULL;
@@ -663,7 +926,6 @@ _pop3_mailbox_init (mu_mailbox_t mbox, int pops)
     mu_property_set_value (property, "TYPE", "POP3", 1);
   }
 
-#endif
   /* Hack! POP does not really have a folder.  */
   mbox->folder->data = mbox;
   return status;
@@ -682,6 +944,7 @@ _mailbox_pops_init (mu_mailbox_t mbox)
 }
 
 
+/* ------------------------------------------------------------------------- */
 /* Authentication */
 
 /* Extract the User from the URL or the ticket.  */
diff --git a/mail/decode.c b/mail/decode.c
index 1a2f369..cd1d159 100644
--- a/mail/decode.c
+++ b/mail/decode.c
@@ -424,7 +424,7 @@ run_metamail (const char *mailcap_cmd, mu_message_t mesg)
              mu_error ("mu_stream_open: %s", mu_strerror (status));
              break;
            }
-         mu_stream_copy (pstr, stream, 0);
+         mu_stream_copy (pstr, stream, 0, NULL);
          mu_stream_close (pstr);
          mu_stream_destroy (&pstr);
          exit (0);
diff --git a/mail/print.c b/mail/print.c
index 9f0e409..89542f6 100644
--- a/mail/print.c
+++ b/mail/print.c
@@ -98,6 +98,8 @@ mail_print_msg (msgset_t *mspec, mu_message_t mesg, void 
*data)
   if (status)
     {
       mu_error (_("get_stream error: %s"), mu_strerror (status));
+      if (out != ofile)
+       pclose (out);
       return 0;
     }
 
diff --git a/mailbox/Makefile.am b/mailbox/Makefile.am
index 7a82437..c24c257 100644
--- a/mailbox/Makefile.am
+++ b/mailbox/Makefile.am
@@ -108,6 +108,7 @@ libmailutils_la_SOURCES = \
  mimehdr.c\
  mkfilename.c\
  monitor.c\
+ msgscan.c\
  msrv.c\
  mu_auth.c\
  muctype.c\
diff --git a/mailbox/body.c b/mailbox/body.c
index 038d29a..513ad01 100644
--- a/mailbox/body.c
+++ b/mailbox/body.c
@@ -161,36 +161,46 @@ _body_get_stream (mu_body_t body, mu_stream_t *pstream, 
int ref)
 
   if (body->stream == NULL)
     {
-      int status;
-      struct _mu_body_stream *str =
-       (struct _mu_body_stream *)
-          _mu_stream_create (sizeof (*str),
-                             MU_STREAM_RDWR|MU_STREAM_SEEK);
-      if (!str)
-       return ENOMEM;
-      
-      /* Create the temporary file.  */
-      body->filename = mu_tempname (NULL);
-      status = mu_file_stream_create (&body->fstream, 
-                                     body->filename, MU_STREAM_RDWR);
-      if (status != 0)
-       return status;
-      status = mu_stream_open (body->fstream);
-      if (status != 0)
-       return status;
-      str->stream.ctl = _body_ioctl;
-      str->stream.read = _body_read;
-      str->stream.write = _body_write;
-      str->stream.truncate = _body_truncate;
-      str->stream.size = _body_size;
-      str->stream.seek = _body_seek;
-      str->stream.flush = _body_flush;
-      str->body = body;
-      body->stream = (mu_stream_t) str;
-      /* Override the defaults.  */
-      body->_lines = _body_get_lines;
-      body->_size = _body_get_size;
+      if (body->_get_stream)
+       {
+         int status = body->_get_stream (body, &body->stream);
+         if (status)
+           return status;
+       }
+      else
+       {
+         int status;
+         struct _mu_body_stream *str =
+           (struct _mu_body_stream *)
+           _mu_stream_create (sizeof (*str),
+                              MU_STREAM_RDWR|MU_STREAM_SEEK);
+         if (!str)
+           return ENOMEM;
+         
+         /* Create the temporary file.  */
+         body->filename = mu_tempname (NULL);
+         status = mu_file_stream_create (&body->fstream, 
+                                         body->filename, MU_STREAM_RDWR);
+         if (status != 0)
+           return status;
+         status = mu_stream_open (body->fstream);
+         if (status != 0)
+           return status;
+         str->stream.ctl = _body_ioctl;
+         str->stream.read = _body_read;
+         str->stream.write = _body_write;
+         str->stream.truncate = _body_truncate;
+         str->stream.size = _body_size;
+         str->stream.seek = _body_seek;
+         str->stream.flush = _body_flush;
+         str->body = body;
+         body->stream = (mu_stream_t) str;
+         /* Override the defaults.  */
+         body->_lines = _body_get_lines;
+         body->_size = _body_get_size;
+       }
     }
+  
   if (!ref)
     {
       *pstream = body->stream;
@@ -227,7 +237,21 @@ mu_body_set_stream (mu_body_t body, mu_stream_t stream, 
void *owner)
 }
 
 int
-mu_body_set_lines (mu_body_t body, int (*_lines) (mu_body_t, size_t *), void 
*owner)
+mu_body_set_get_stream (mu_body_t body,
+                       int (*_getstr) (mu_body_t, mu_stream_t *),
+                       void *owner)
+{
+  if (body == NULL)
+    return EINVAL;
+  if (body->owner != owner)
+    return EACCES;
+  body->_get_stream = _getstr;
+  return 0;
+}
+
+int
+mu_body_set_lines (mu_body_t body, int (*_lines) (mu_body_t, size_t *),
+                  void *owner)
 {
   if (body == NULL)
     return EINVAL;
diff --git a/mailbox/message.c b/mailbox/message.c
index 8ac1258..c227a09 100644
--- a/mailbox/message.c
+++ b/mailbox/message.c
@@ -586,7 +586,7 @@ mu_message_create_copy (mu_message_t *to, mu_message_t from)
       return status;
     }
 
-  status = mu_stream_copy (tmp, fromstr, 0);
+  status = mu_stream_copy (tmp, fromstr, 0, NULL);
   if (status == 0)
     {
       status = mu_message_create (to, NULL);
@@ -786,6 +786,8 @@ mu_message_set_stream (mu_message_t msg, mu_stream_t 
stream, void *owner)
 static int
 _message_get_stream (mu_message_t msg, mu_stream_t *pstream, int ref)
 {
+  int status;
+
   if (msg == NULL)
     return EINVAL;
   if (pstream == NULL)
@@ -793,25 +795,33 @@ _message_get_stream (mu_message_t msg, mu_stream_t 
*pstream, int ref)
 
   if (msg->stream == NULL)
     {
-      int status;
-      mu_header_t hdr;
-      mu_body_t body;
+      if (msg->_get_stream)
+       {
+         status = msg->_get_stream (msg, &msg->stream);
+         if (status)
+           return status;
+       }
+      else
+       {
+         mu_header_t hdr;
+         mu_body_t body;
 
-      /* FIXME: Kind of a kludge: make sure the message has header
-        and body initialized. */
-      status = mu_message_get_header (msg, &hdr);
-      if (status)
-       return status;
-      status = mu_message_get_body (msg, &body);
-      if (status)
-       return status;
-      
-      status = _message_stream_create (&msg->stream, msg, MU_STREAM_RDWR);
-      if (status)
-       return status;
-      msg->flags |= MESSAGE_INTERNAL_STREAM;
+         /* FIXME: Kind of a kludge: make sure the message has header
+            and body initialized. */
+         status = mu_message_get_header (msg, &hdr);
+         if (status)
+           return status;
+         status = mu_message_get_body (msg, &body);
+         if (status)
+           return status;
+         
+         status = _message_stream_create (&msg->stream, msg, MU_STREAM_RDWR);
+         if (status)
+           return status;
+         msg->flags |= MESSAGE_INTERNAL_STREAM;
+       }
     }
-
+  
   if (!ref)
     {
       *pstream = msg->stream;
@@ -834,6 +844,19 @@ mu_message_get_streamref (mu_message_t msg, mu_stream_t 
*pstream)
 }
 
 int
+mu_message_set_get_stream (mu_message_t msg,
+                          int (*_getstr) (mu_message_t, mu_stream_t *),
+                          void *owner)
+{
+  if (msg == NULL)
+    return EINVAL;
+  if (msg->owner != owner)
+    return EACCES;
+  msg->_get_stream = _getstr;
+  return 0;
+}
+
+int
 mu_message_set_lines (mu_message_t msg, int (*_lines)
                   (mu_message_t, size_t *), void *owner)
 {
diff --git a/mailbox/msgscan.c b/mailbox/msgscan.c
new file mode 100644
index 0000000..dbbafed
--- /dev/null
+++ b/mailbox/msgscan.c
@@ -0,0 +1,106 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+   Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+
+   GNU Mailutils is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3, or (at your option)
+   any later version.
+
+   GNU Mailutils 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 General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with GNU Mailutils.  If not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+#include <stdlib.h>
+#include <mailutils/types.h>
+#include <mailutils/stream.h>
+#include <mailutils/message.h>
+#include <mailutils/attribute.h>
+#include <mailutils/cstr.h>
+
+int
+mu_stream_scan_message (mu_stream_t stream, struct mu_message_scan *sp)
+{
+  char buf[1024];
+  mu_off_t off;
+  size_t n;
+  int status;
+  int in_header = 1;
+  size_t hlines = 0;
+  size_t blines = 0;
+  size_t body_start = 0;
+  int attr_flags = 0;
+  unsigned long uidvalidity = 0;
+  
+  if (sp->flags & MU_SCAN_SEEK)
+    {
+      status = mu_stream_seek (stream, sp->message_start, MU_SEEK_SET, NULL);
+      if (status)
+       return status;
+    }
+  
+  off = 0;
+  while (1)
+    {
+      size_t rdsize;
+      
+      status = mu_stream_readline (stream, buf, sizeof (buf), &n);
+      if (status || n == 0)
+       break;
+      
+      if (sp->flags & MU_SCAN_SIZE)
+       {
+         rdsize = sp->message_size - off;
+         if (n > rdsize)
+           n = rdsize;
+       }
+      
+      if (in_header)
+       {
+         if (buf[0] == '\n')
+           {
+             in_header = 0;
+             body_start = off + 1;
+           }
+         if (buf[n - 1] == '\n')
+           hlines++;
+           
+         /* Process particular attributes */
+         if (mu_c_strncasecmp (buf, "status:", 7) == 0)
+           mu_string_to_flags (buf, &attr_flags);
+         else if (mu_c_strncasecmp (buf, "x-imapbase:", 11) == 0)
+           {
+             char *p;
+             uidvalidity = strtoul (buf + 11, &p, 10);
+             /* second number is next uid. Ignored */
+           }
+       }
+      else
+       {
+         if (buf[n - 1] == '\n')
+           blines++;
+       }
+      off += n;
+    }
+
+  if (status == 0)
+    {
+      if (!body_start)
+       body_start = off;
+      sp->body_start = body_start;
+      sp->body_end = off;
+      sp->header_lines = hlines;
+      sp->body_lines = blines;
+      sp->attr_flags = attr_flags;
+      sp->uidvalidity = uidvalidity;
+    }
+  return status;
+}
diff --git a/mailbox/rdcache_stream.c b/mailbox/rdcache_stream.c
index 8a8afbf..0d7eed7 100644
--- a/mailbox/rdcache_stream.c
+++ b/mailbox/rdcache_stream.c
@@ -48,7 +48,7 @@ rdcache_read (struct _mu_stream *str, char *buf, size_t size, 
size_t *pnbytes)
       status = mu_stream_seek (sp->cache, 0, MU_SEEK_END, NULL);
       if (status)
        return status;
-      status = mu_stream_copy (sp->cache, sp->transport, left);
+      status = mu_stream_copy (sp->cache, sp->transport, left, NULL);
       if (status)
        return status;
       sp->size = sp->offset;
diff --git a/mailbox/stream.c b/mailbox/stream.c
index 55af4ab..1ea8b52 100644
--- a/mailbox/stream.c
+++ b/mailbox/stream.c
@@ -153,9 +153,13 @@ _stream_flush_buffer (struct _mu_stream *stream, int all)
                  
   if (stream->flags & _MU_STR_DIRTY)
     {
-      if ((stream->flags & MU_STREAM_SEEK)
-         && (rc = mu_stream_seek (stream, stream->offset, MU_SEEK_SET, NULL)))
-       return rc;
+      if ((stream->flags & MU_STREAM_SEEK) && stream->seek)
+       {
+         mu_off_t off;
+         rc = stream->seek (stream, stream->offset, &off);
+         if (rc)
+           return rc;
+       }
 
       switch (stream->buftype)
        {
diff --git a/mailbox/streamcpy.c b/mailbox/streamcpy.c
index ec56a7a..4812667 100644
--- a/mailbox/streamcpy.c
+++ b/mailbox/streamcpy.c
@@ -31,22 +31,22 @@
 /* Copy SIZE bytes from SRC to DST.  If SIZE is 0, copy everything up to
    EOF. */
 int
-mu_stream_copy (mu_stream_t dst, mu_stream_t src, size_t size)
+mu_stream_copy (mu_stream_t dst, mu_stream_t src, mu_off_t size,
+               mu_off_t *pcsz)
 {
   int status;
   size_t bufsize, n;
   char *buf;
-
+  mu_off_t total = 0;
+  
+  if (pcsz)
+    *pcsz = 0;
   if (size == 0)
     {
-      mu_off_t strsize;
-      status = mu_stream_size (src, &strsize);
+      status = mu_stream_size (src, &size);
       switch (status)
        {
        case 0:
-         size = strsize;
-         if ((mu_off_t)size != strsize)
-           return ERANGE;
          break;
 
        case ENOSYS:
@@ -105,6 +105,7 @@ mu_stream_copy (mu_stream_t dst, mu_stream_t src, size_t 
size)
        if (status)
          break;
        size -= rdsize;
+       total += rdsize;
       }
   else
     while ((status = mu_stream_read (src, buf, bufsize, &n)) == 0
@@ -113,8 +114,11 @@ mu_stream_copy (mu_stream_t dst, mu_stream_t src, size_t 
size)
        status = mu_stream_write (dst, buf, n, NULL);
        if (status)
          break;
+       total += n;
       }
 
+  if (pcsz)
+    *pcsz = total;
   free (buf);
   return status;
 }
diff --git a/mailbox/streamref.c b/mailbox/streamref.c
index 2ce35a4..b773983 100644
--- a/mailbox/streamref.c
+++ b/mailbox/streamref.c
@@ -24,13 +24,15 @@
 #include <mailutils/errno.h>
 #include <mailutils/sys/streamref.h>
 
+#define _MU_STR_ERRMASK (_MU_STR_ERR|_MU_STR_EOF)
+
 static int
 streamref_return (struct _mu_streamref *sp, int rc)
 {
   if (rc)
     sp->stream.last_err = sp->transport->last_err;
-  sp->stream.flags = (sp->stream.flags & ~_MU_STR_INTERN_MASK) |
-                   (sp->transport->flags & _MU_STR_INTERN_MASK);
+  sp->stream.flags = (sp->stream.flags & ~_MU_STR_ERRMASK) |
+                   (sp->transport->flags & _MU_STR_ERRMASK);
   return rc;
 }
 
@@ -80,15 +82,15 @@ _streamref_readdelim (struct _mu_stream *str, char *buf, 
size_t bufsize,
   rc = mu_stream_seek (sp->transport, sp->offset, MU_SEEK_SET, &off);
   if (rc == 0)
     {
-      if (sp->end)
-       {
-         size_t size = sp->end - off + 2; /* extra 1 to account for \0 */
-         if (size < bufsize)
-           bufsize = size;
-       }
       rc = mu_stream_readdelim (sp->transport, buf, bufsize, delim, &nread);
       if (rc == 0)
        {
+         if (sp->end)
+           {
+             size_t size = sp->end - off + 1;
+             if (nread > size)
+               nread = size;
+           }
          sp->offset += nread;
          *pnread = nread;
        }
diff --git a/mh/burst.c b/mh/burst.c
index 670ea79..1bd99c3 100644
--- a/mh/burst.c
+++ b/mh/burst.c
@@ -496,7 +496,7 @@ msg_copy (size_t num, const char *file)
   mu_mailbox_get_message (tmpbox, num, &msg);
   mu_message_get_streamref (msg, &istream);
   /* FIXME: Implement RFC 934 FSA? */
-  rc = mu_stream_copy (ostream, istream, 0);
+  rc = mu_stream_copy (ostream, istream, 0, NULL);
   if (rc)
     {
       mu_error (_("copy stream error: %s"), mu_strerror (rc));
diff --git a/mh/comp.c b/mh/comp.c
index 71095a6..5439562 100644
--- a/mh/comp.c
+++ b/mh/comp.c
@@ -167,7 +167,7 @@ copy_message (mu_mailbox_t mbox, size_t n, const char *file)
       return rc;
     }
 
-  rc = mu_stream_copy (out, in, 0);
+  rc = mu_stream_copy (out, in, 0, NULL);
   mu_stream_destroy (&in);
   mu_stream_close (out);
   mu_stream_destroy (&out);
diff --git a/mh/mhn.c b/mh/mhn.c
index f92c70b..8beadd9 100644
--- a/mh/mhn.c
+++ b/mh/mhn.c
@@ -1258,7 +1258,7 @@ show_internal (mu_message_t msg, msg_part_t part, char 
*encoding, mu_stream_t ou
                         MU_FILTER_DECODE, MU_STREAM_READ);
   if (rc == 0)
     bstr = dstr;
-  rc = mu_stream_copy (out, bstr, 0);
+  rc = mu_stream_copy (out, bstr, 0, NULL);
   mu_stream_destroy (&bstr);
   return rc;
 }
@@ -2003,7 +2003,7 @@ finish_text_msg (struct compose_env *env, mu_message_t 
*msg, int ascii)
                             MU_STREAM_READ);
       if (rc == 0)
        {
-         mu_stream_copy (output, fstr, 0);
+         mu_stream_copy (output, fstr, 0, NULL);
          mu_stream_destroy (&fstr);
          mu_message_unref (*msg);
          *msg = newmsg;
@@ -2063,7 +2063,7 @@ edit_extern (char *cmd, struct compose_env *env, 
mu_message_t *msg, int level)
   free (id);
 
   mu_header_get_streamref (hdr2, &in);
-  mu_stream_copy (out, in, 0);
+  mu_stream_copy (out, in, 0, NULL);
   mu_stream_destroy (&in);
   mu_stream_close (out);
   mu_stream_destroy (&out);
@@ -2294,7 +2294,7 @@ edit_mime (char *cmd, struct compose_env *env, 
mu_message_t *msg, int level)
   
   mu_message_get_body (*msg, &body);
   mu_body_get_streamref (body, &out);
-  mu_stream_copy (out, fstr, 0);
+  mu_stream_copy (out, fstr, 0, NULL);
 
   mu_stream_close (out);
   mu_stream_destroy (&out);
@@ -2659,7 +2659,7 @@ mhn_compose ()
   mhn_header (message, msg);
   copy_header_to_stream (message, stream);
   mu_message_get_streamref (msg, &in);
-  mu_stream_copy (stream, in, 0);
+  mu_stream_copy (stream, in, 0, NULL);
   mu_stream_destroy (&in);
   mu_stream_destroy (&stream);
   
diff --git a/pop3d/retr.c b/pop3d/retr.c
index 5c30643..61908c0 100644
--- a/pop3d/retr.c
+++ b/pop3d/retr.c
@@ -46,7 +46,7 @@ pop3d_retr (char *arg)
     return ERR_UNKNOWN;
   
   pop3d_outf ("+OK\n");
-  mu_stream_copy (iostream, stream, 0);
+  mu_stream_copy (iostream, stream, 0, NULL);
   mu_stream_destroy (&stream);
 
   if (!mu_attribute_is_read (attr))
diff --git a/pop3d/top.c b/pop3d/top.c
index 3716875..7e0ce5d 100644
--- a/pop3d/top.c
+++ b/pop3d/top.c
@@ -62,7 +62,7 @@ pop3d_top (char *arg)
     return ERR_UNKNOWN;
   pop3d_outf ("+OK\n");
 
-  mu_stream_copy (iostream, stream, 0);
+  mu_stream_copy (iostream, stream, 0, NULL);
   pop3d_outf ("\n");
   mu_stream_destroy (&stream);
   


hooks/post-receive
-- 
GNU Mailutils



reply via email to

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