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-79-g987ec1d


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, stream-cleanup, updated. rel-2_1-79-g987ec1d
Date: Fri, 30 Apr 2010 22:37:06 +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=987ec1d4f1fda22924fc84531e76f02fe6a288b9

The branch, stream-cleanup has been updated
       via  987ec1d4f1fda22924fc84531e76f02fe6a288b9 (commit)
       via  2076b7637d834f9fcb26144037f6985fee9bbe9b (commit)
       via  fc9d0ad4a67789490761459c6334bbf4dc689ce0 (commit)
       via  57168a550fc55eba4bed74721a042ec1de99c2e3 (commit)
      from  0ee00fd5861514e757aa73b1e62ca9896b2461ff (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 987ec1d4f1fda22924fc84531e76f02fe6a288b9
Author: Sergey Poznyakoff <address@hidden>
Date:   Sat May 1 01:33:49 2010 +0300

    Fix compilation of libmu_scm.
    
    * libmu_scm/mu_body.c (mu_scm_body_free): Unref the stream.
    Return 0.
    (mu-body-read-line, mu-body-write): Use stringrefs.
    * libmu_scm/mu_mailbox.c (mu-mailbox-get-port): Use stringrefs.
    * libmu_scm/mu_message.c (mu-message-copy): Use stringrefs.
    Use mu_stream_copy instead of manually copying stream contents.
    (mu-message-get-port): Use stringrefs.
    * libmu_scm/mu_port.c (mu_port_free): Unref the stream.

commit 2076b7637d834f9fcb26144037f6985fee9bbe9b
Author: Sergey Poznyakoff <address@hidden>
Date:   Sat May 1 01:31:16 2010 +0300

    Fix compilation of several example programs.
    
    * examples/header.c: Use streamrefs.
    * examples/mimetest.c: Likewise.
    * examples/mta.c: Likewise.
    * examples/nntpclient.c: Remove an unused variable.

commit fc9d0ad4a67789490761459c6334bbf4dc689ce0
Author: Sergey Poznyakoff <address@hidden>
Date:   Sat May 1 01:29:39 2010 +0300

    Fix compilation of mimeview.
    
    * mimeview/mimeview.c (mimeview_fp): Restore the variable.

commit 57168a550fc55eba4bed74721a042ec1de99c2e3
Author: Sergey Poznyakoff <address@hidden>
Date:   Sat May 1 01:28:47 2010 +0300

    Fix UNIX mbox driver and mail utility.
    
    The `mail' and `frm' utilities pass tests.
    
    * include/mailutils/stream.h (mu_stream_err): New proto.
    * libproto/mbox/mbox.c (_msg_stream_setup)
    (_msg_body_setup): Fix stream abridgement.
    (mbox_envelope_date, mbox_envelope_sender): Fix seek position.
    (uid_to_stream): Fix invocation of mu_stream_printf.
    (append_message_to_stream): Likewise.
    (mbox_expunge_unlocked): Rewind tempstr before copying its
    contents back to the mailbox.
    (mbox_expunge0): Open tempstr.
    * libproto/mbox/mbox0.h (_mbox_message)<header_from>: Rename to
    envel_from.
    <header_from_end>: Rename to envel_from_end. All uses changed.
    * libproto/mbox/mboxscan.c: Minor changes.
    
    * mail/decode.c: Use streamrefs.
    * mail/escape.c: Likewise.
    * mail/msgset.y: Likewise.
    * mail/pipe.c: Likewise.
    * mail/print.c: Likewise.
    * mail/top.c: Likewise.
    * mail/write.c: Likewise.
    
    * mail/send.c: Use streamrefs.
    (mail_send0): Reset env->header after assigning it to
    the message.
    
    * mailbox/body.c (_body_seek): Fix a typo which produced
    a recursive call.
    * mailbox/file_stream.c (fd_truncate): New function.
    (_mu_file_stream_create): Initialize str->stream.truncate.
    
    * mailbox/header.c (header_parse): Fix parsing of blurbs lacking
    terminating empty line.
    (header_seek): Fix boundary checks.
    Return new position in presult.
    * mailbox/message.c (string_find_eoh): Rewrite to handle \n\n
    split between two successive invocations.
    (_header_fill): Update the invocation of string_find_eoh.
    
    * mailbox/stream.c (mu_stream_destroy): Call mu_stream_close.
    (mu_stream_get_flags, mu_stream_set_flags)
    (mu_stream_clr_flags): Ignore internal
    bits.
    (mu_stream_err): New function.
    (mu_stream_close): Close the stream only if it is not used by anyone else.
    * mailbox/streamref.c (_streamref_read): Clear transport error if
    ESPIPE is returned.
    (_streamref_size): Take into account sp->end and sp->start.
    (mu_streamref_create_abridged): Set pointer to 0.

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

Summary of changes:
 examples/header.c          |    7 ++-
 examples/mimetest.c        |    4 +-
 examples/mta.c             |    5 +-
 examples/nntpclient.c      |    1 -
 include/mailutils/stream.h |    1 +
 libmu_scm/mu_body.c        |    7 ++-
 libmu_scm/mu_mailbox.c     |    2 +-
 libmu_scm/mu_message.c     |   28 +++++--------
 libmu_scm/mu_port.c        |    2 +
 libproto/mbox/mbox.c       |   98 ++++++++++++++++++++++++++------------------
 libproto/mbox/mbox0.h      |    4 +-
 libproto/mbox/mboxscan.c   |    9 ++--
 mail/decode.c              |   38 ++++++-----------
 mail/escape.c              |   19 +++++----
 mail/msgset.y              |    5 +-
 mail/pipe.c                |    5 +-
 mail/print.c               |   14 +++++-
 mail/send.c                |   27 +++++++-----
 mail/top.c                 |    5 +-
 mail/write.c               |    7 ++-
 mailbox/body.c             |    2 +-
 mailbox/file_stream.c      |   10 ++++
 mailbox/header.c           |   20 +++------
 mailbox/message.c          |   42 +++++++++++++------
 mailbox/stream.c           |   18 ++++++--
 mailbox/streamref.c        |   23 ++++++++--
 mimeview/mimeview.c        |   10 ++--
 27 files changed, 240 insertions(+), 173 deletions(-)

diff --git a/examples/header.c b/examples/header.c
index 742bc2b..90cce65 100644
--- a/examples/header.c
+++ b/examples/header.c
@@ -173,7 +173,7 @@ cmd_dump (int argc, char **argv)
   if (argc == 2)
     off = strtoul (argv[1], NULL, 0);
 
-  status = mu_header_get_stream (header, &stream);
+  status = mu_header_get_streamref (header, &stream);
   if (status)
     {
       mu_error ("%u: cannot get stream: %s", line_num, mu_strerror (status));
@@ -183,6 +183,7 @@ cmd_dump (int argc, char **argv)
   status = mu_stream_seek (stream, off, SEEK_SET, NULL);
   if (status)
     {
+      mu_stream_destroy (&stream);
       mu_error ("%u: cannot seek: %s", line_num, mu_strerror (status));
       return;
     }
@@ -192,6 +193,7 @@ cmd_dump (int argc, char **argv)
     {
       fwrite (buf, 1, n, stdout);
     }
+  mu_stream_destroy (&stream);
 }  
 
 void
@@ -272,7 +274,7 @@ cmd_write (int argc, char **argv)
   if (check_args (argv[0], argc, 1, 1))
     return;
 
-  status = mu_header_get_stream (header, &str);
+  status = mu_header_get_streamref (header, &str);
   if (status)
     {
       mu_error ("%u: cannot get stream: %s", line_num, mu_strerror (status));
@@ -286,6 +288,7 @@ cmd_write (int argc, char **argv)
       if (buf[0] == '\n')
        break;
     }
+  mu_stream_destroy (&str);
 }
 
 void
diff --git a/examples/mimetest.c b/examples/mimetest.c
index ed527ba..8e38ca9 100644
--- a/examples/mimetest.c
+++ b/examples/mimetest.c
@@ -250,12 +250,12 @@ message_display_parts (mu_message_t msg, int indent)
          printf ("%*.*sText Message\n", indent, indent, "");
           printf ("%*.*sBegin\n", indent, indent, "");
           mu_message_get_body (part, &body);
-          mu_body_get_stream (body, &str);
+          mu_body_get_streamref (body, &str);
           /* Make sure the original body stream is not closed when
              str gets destroyed */
           mu_filter_create (&str, str, encoding, MU_FILTER_DECODE,
                            MU_STREAM_READ | MU_STREAM_NO_CLOSE);
-
+         
          while (mu_stream_readline (str, buf, sizeof (buf), &nbytes) == 0
                 && nbytes)
             {
diff --git a/examples/mta.c b/examples/mta.c
index 6d10480..1604955 100644
--- a/examples/mta.c
+++ b/examples/mta.c
@@ -19,7 +19,7 @@
 
 /* This is a "fake" mta designed for testing purposes. It imitates
    sendmail sending and daemon modes. It does not actually send anything,
-   instead it just outputs the transcript of what would have been done.
+   instead it just outputs a transcript of what would have been done.
 
    Invocation:
    
@@ -326,7 +326,7 @@ mta_send (mu_message_t msg)
   fprintf (diag, "ENVELOPE TO: %s\n", value);
   free (value);
 
-  mu_message_get_stream (msg, &stream);
+  mu_message_get_streamref (msg, &stream);
   line = 0;
   fprintf (diag, "%4lu: ", (unsigned long) line);
   while (mu_stream_read (stream, buffer, sizeof buffer - 1, &n) == 0
@@ -344,6 +344,7 @@ mta_send (mu_message_t msg)
            }
        }
     }
+  mu_stream_destroy (&stream);
   fprintf (diag, "\nEND OF MESSAGE\n");
   fflush (diag);
   return 0;
diff --git a/examples/nntpclient.c b/examples/nntpclient.c
index 2c652f1..4fac953 100644
--- a/examples/nntpclient.c
+++ b/examples/nntpclient.c
@@ -423,7 +423,6 @@ com_body (char *arg)
 
    if (status == 0 && stream != NULL)
     {
-      size_t n = 0;
       char buf[128];
       while (mu_stream_readline (stream, buf, sizeof buf, 0) == 0)
         printf ("%s", buf);
diff --git a/include/mailutils/stream.h b/include/mailutils/stream.h
index e6b2f5e..0197fcd 100644
--- a/include/mailutils/stream.h
+++ b/include/mailutils/stream.h
@@ -65,6 +65,7 @@ void mu_stream_unref (mu_stream_t stream);
 void mu_stream_destroy (mu_stream_t *pstream);
 int mu_stream_open (mu_stream_t stream);
 const char *mu_stream_strerror (mu_stream_t stream, int rc);
+int mu_stream_err (mu_stream_t stream);
 int mu_stream_last_error (mu_stream_t stream);
 void mu_stream_clearerr (mu_stream_t stream);
 int mu_stream_eof (mu_stream_t stream);
diff --git a/libmu_scm/mu_body.c b/libmu_scm/mu_body.c
index 3a5db3f..a5c5cf5 100644
--- a/libmu_scm/mu_body.c
+++ b/libmu_scm/mu_body.c
@@ -47,8 +47,9 @@ mu_scm_body_free (SCM body_smob)
   struct mu_body *mbp = (struct mu_body *) SCM_CDR (body_smob);
   if (mbp->buffer)
     free (mbp->buffer);
+  mu_stream_unref (mbp->stream);
   free (mbp);
-  return sizeof (struct mu_body);
+  return 0;
 }
 
 static int
@@ -114,7 +115,7 @@ SCM_DEFINE_PUBLIC (scm_mu_body_read_line, 
"mu-body-read-line", 1, 0, 0,
 
   if (!mbp->stream)
     {
-      status = mu_body_get_stream (mbp->body, &mbp->stream);
+      status = mu_body_get_streamref (mbp->body, &mbp->stream);
       if (status)
        mu_scm_error (FUNC_NAME, status,
                      "Cannot get body stream",
@@ -158,7 +159,7 @@ SCM_DEFINE_PUBLIC (scm_mu_body_write, "mu-body-write", 2, 
0, 0,
   
   if (!mbp->stream)
     {
-      status = mu_body_get_stream (mbp->body, &mbp->stream);
+      status = mu_body_get_streamref (mbp->body, &mbp->stream);
       if (status)
        mu_scm_error (FUNC_NAME, status,
                      "Cannot get body stream", SCM_BOOL_F);
diff --git a/libmu_scm/mu_mailbox.c b/libmu_scm/mu_mailbox.c
index dce05e8..4dec046 100644
--- a/libmu_scm/mu_mailbox.c
+++ b/libmu_scm/mu_mailbox.c
@@ -316,7 +316,7 @@ SCM_DEFINE_PUBLIC (scm_mu_mailbox_get_port, 
"mu-mailbox-get-port", 2, 0, 0,
   SCM_ASSERT (mu_scm_is_mailbox (mbox), mbox, SCM_ARG1, FUNC_NAME);
   SCM_ASSERT (scm_is_string (mode), mode, SCM_ARG2, FUNC_NAME);
   mum = (struct mu_mailbox *) SCM_CDR (mbox);
-  status = mu_mailbox_get_stream (mum->mbox, &stream);
+  status = mu_mailbox_get_streamref (mum->mbox, &stream);
   if (status)
     mu_scm_error (FUNC_NAME, status,
                  "Cannot get mailbox stream",
diff --git a/libmu_scm/mu_message.c b/libmu_scm/mu_message.c
index 127cfe7..ffcf9e3 100644
--- a/libmu_scm/mu_message.c
+++ b/libmu_scm/mu_message.c
@@ -195,14 +195,12 @@ SCM_DEFINE_PUBLIC (scm_mu_message_copy, 
"mu-message-copy", 1, 0, 0,
 {
   mu_message_t msg, newmsg;
   mu_stream_t in = NULL, out = NULL;
-  char buffer[512];
-  size_t n;
   int status;
   
   SCM_ASSERT (mu_scm_is_message (mesg), mesg, SCM_ARG1, FUNC_NAME);
   msg = mu_scm_message_get (mesg);
 
-  status = mu_message_get_stream (msg, &in);
+  status = mu_message_get_streamref (msg, &in);
   if (status)
     mu_scm_error (FUNC_NAME, status,
                  "Cannot get input stream from message ~A",
@@ -213,7 +211,7 @@ SCM_DEFINE_PUBLIC (scm_mu_message_copy, "mu-message-copy", 
1, 0, 0,
     mu_scm_error (FUNC_NAME, status,
                  "Cannot create message", SCM_BOOL_F);
   
-  status = mu_message_get_stream (newmsg, &out);
+  status = mu_message_get_streamref (newmsg, &out);
   if (status)
     {
       mu_message_destroy (&newmsg, NULL);
@@ -221,18 +219,14 @@ SCM_DEFINE_PUBLIC (scm_mu_message_copy, 
"mu-message-copy", 1, 0, 0,
                    "Cannot get output stream", SCM_BOOL_F);
     }
 
-  mu_stream_seek (in, 0, MU_SEEK_SET, NULL);
-  while ((status = mu_stream_read (in, buffer, sizeof (buffer) - 1, &n))
-        == 0
-        && n != 0)
+  status = mu_stream_copy (out, in, 0);
+  mu_stream_destroy (&in);
+  mu_stream_destroy (&out);
+  if (status)
     {
-      status = mu_stream_write (out, buffer, n, NULL);
-      if (status)
-       {
-         mu_message_destroy (&newmsg, NULL);
-         mu_scm_error (FUNC_NAME, status,
-                       "Error writing to stream", SCM_BOOL_F);
-       }
+      mu_message_destroy (&newmsg, NULL);
+      mu_scm_error (FUNC_NAME, status,
+                   "Error writing to stream", SCM_BOOL_F);
     }
   
   return mu_scm_message_create (SCM_BOOL_F, newmsg);
@@ -905,7 +899,7 @@ SCM_DEFINE_PUBLIC (scm_mu_message_get_port, 
"mu-message-get-port", 2, 1, 0,
       SCM_ASSERT (scm_is_bool (full), full, SCM_ARG3, FUNC_NAME);
       if (full == SCM_BOOL_T)
        {
-         status = mu_message_get_stream (msg, &stream);
+         status = mu_message_get_streamref (msg, &stream);
          if (status)
            mu_scm_error (FUNC_NAME, status, "Cannot get message stream",
                          SCM_BOOL_F);
@@ -920,7 +914,7 @@ SCM_DEFINE_PUBLIC (scm_mu_message_get_port, 
"mu-message-get-port", 2, 1, 0,
       if (status)
        mu_scm_error (FUNC_NAME, status, "Cannot get message body",
                      SCM_BOOL_F);
-      status = mu_body_get_stream (body, &stream);
+      status = mu_body_get_streamref (body, &stream);
       if (status)
        mu_scm_error (FUNC_NAME, status, "Cannot get message body stream",
                      SCM_BOOL_F);
diff --git a/libmu_scm/mu_port.c b/libmu_scm/mu_port.c
index 2214dd3..0efa5e7 100644
--- a/libmu_scm/mu_port.c
+++ b/libmu_scm/mu_port.c
@@ -151,6 +151,8 @@ mu_port_close (SCM port)
 static scm_sizet
 mu_port_free (SCM port)
 {
+  struct mu_port *mp = MU_PORT (port);
+  mu_stream_unref (mp->stream);
   mu_port_close (port);
   return 0;
 }
diff --git a/libproto/mbox/mbox.c b/libproto/mbox/mbox.c
index 7e16f4f..5bb043c 100644
--- a/libproto/mbox/mbox.c
+++ b/libproto/mbox/mbox.c
@@ -259,7 +259,7 @@ static int
 mbox_message_qid (mu_message_t msg, mu_message_qid_t *pqid)
 {
   mbox_message_t mum = mu_message_get_owner (msg);
-  return mu_asprintf (pqid, "%lu", (unsigned long) mum->header_from);
+  return mu_asprintf (pqid, "%lu", (unsigned long) mum->envel_from);
 }
 
 
@@ -297,8 +297,8 @@ _msg_stream_setup (mu_message_t msg, mbox_message_t mum)
   
   status = mu_streamref_create_abridged (&stream,
                                         mum->mud->mailbox->stream,
-                                        mum->header_from_end + 1,
-                                        mum->body);
+                                        mum->envel_from_end,
+                                        mum->body_end);
   if (status == 0)
     status = mu_message_set_stream (msg, stream, mum);
   return status;
@@ -343,7 +343,7 @@ _msg_body_setup (mu_message_t msg, mbox_message_t mum)
   status = mu_streamref_create_abridged (&stream,
                                         mum->mud->mailbox->stream,
                                         mum->body,
-                                        mum->body_end);
+                                        mum->body_end - 1);
   if (status)
     mu_body_destroy (&body, msg);
   else
@@ -373,7 +373,7 @@ mbox_envelope_date (mu_envelope_t envelope, char *buf, 
size_t len,
     return EINVAL;
 
   status = mu_stream_seek (mum->mud->mailbox->stream,
-                          mum->header_from, MU_SEEK_SET,
+                          mum->envel_from, MU_SEEK_SET,
                           NULL);
   if (status)
     return status;
@@ -419,7 +419,7 @@ mbox_envelope_sender (mu_envelope_t envelope, char *buf, 
size_t len,
     return EINVAL;
 
   status = mu_stream_seek (mum->mud->mailbox->stream,
-                          mum->header_from, MU_SEEK_SET,
+                          mum->envel_from, MU_SEEK_SET,
                           NULL);
   if (status)
     return status;
@@ -1022,8 +1022,10 @@ uid_to_stream (mu_stream_t ostr, mu_message_t msg, 
mbox_data_t mud, int flags)
   else
     uid = mud->uidnext++;
   
-  return mu_stream_printf (ostr, "%s: %u\n", MU_HEADER_X_UID,
-                          (unsigned) uid);
+  mu_stream_printf (ostr, "%s: %u\n", MU_HEADER_X_UID, (unsigned) uid);
+  if (mu_stream_err (ostr))
+    return mu_stream_last_error (ostr);
+  return 0;
 }
 
 /* Append MSG to stream OSTR in its current position */
@@ -1048,12 +1050,14 @@ append_message_to_stream (mu_stream_t ostr, 
mu_message_t msg,
 
       if (flags & MBOX_FIRSTMSG)
        {
-         status = mu_stream_printf (ostr, "%s: %lu %u\n",
-                                    MU_HEADER_X_IMAPBASE,
-                                    (unsigned long) mud->uidvalidity,
-                                    (unsigned) mud->uidnext);
-         if (status)
-           return status;
+         /* FIXME: Perhaps printf should return error code,
+            like the rest of stream functions. */
+         mu_stream_printf (ostr, "%s: %lu %u\n",
+                           MU_HEADER_X_IMAPBASE,
+                           (unsigned long) mud->uidvalidity,
+                           (unsigned) mud->uidnext);
+         if (mu_stream_err (ostr))
+           return mu_stream_last_error (ostr);
        }
 
       status = msg_attr_to_stream (ostr, msg);
@@ -1165,7 +1169,7 @@ mbox_reset (mu_mailbox_t mailbox, size_t dirty, int 
remove_deleted)
          else
            memset (mum, 0, sizeof (*mum));
        }
-      mum->header_from = mum->header_from_end = 0;
+      mum->envel_from = mum->envel_from_end = 0;
       mum->body = mum->body_end = 0;
       mum->header_lines = mum->body_lines = 0;
     }
@@ -1187,7 +1191,7 @@ mbox_expunge_unlocked (mu_mailbox_t mailbox, size_t 
dirty, int remove_deleted,
   mu_off_t size;
 
   /* Set the marker position.  */
-  start_off = mud->umessages[dirty]->header_from;
+  start_off = mud->umessages[dirty]->envel_from;
 
   for (i = dirty; i < mud->messages_count; i++)
     {
@@ -1226,8 +1230,8 @@ mbox_expunge_unlocked (mu_mailbox_t mailbox, size_t 
dirty, int remove_deleted,
              status = mbox_get_message (mailbox, i + 1, &msg);
              if (status != 0)
                {
-                 mu_error (_("error expunging:%d: %s"), __LINE__,
-                           mu_strerror (status));
+                 mu_error (_("%s:%d: error expunging: %s"),            
+                           __FILE__, __LINE__, mu_strerror (status));  
                  return status;
                }
            }
@@ -1235,8 +1239,8 @@ mbox_expunge_unlocked (mu_mailbox_t mailbox, size_t 
dirty, int remove_deleted,
                                             flags);
          if (status != 0)
            {
-             mu_error (_("error expunging:%d: %s"), __LINE__,
-                       mu_strerror (status));
+             mu_error (_("%s:%d: error expunging: %s"),                
+                       __FILE__, __LINE__, mu_strerror (status));      
              return status;
            }
          /* Clear the dirty bits.  */
@@ -1247,7 +1251,7 @@ mbox_expunge_unlocked (mu_mailbox_t mailbox, size_t 
dirty, int remove_deleted,
        {
          /* Otherwise, copy bits from mailbox->stream as is. */
          
-         status = mu_stream_seek (mailbox->stream, mum->header_from,
+         status = mu_stream_seek (mailbox->stream, mum->envel_from,
                                   MU_SEEK_SET, NULL);
          if (status)
            {
@@ -1257,7 +1261,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->header_from);
+                                  mum->body_end - mum->envel_from);
          if (status)
            {
              mu_error (_("%s:%d: error copying: %s"),
@@ -1336,10 +1340,19 @@ mbox_expunge_unlocked (mu_mailbox_t mailbox, size_t 
dirty, int remove_deleted,
       return status;
     }
   
+  status = mu_stream_seek (tempstr, 0, MU_SEEK_SET, NULL);
+  if (status)
+    {
+      mu_error (_("%s:%d: seek error: %s"),
+               __FILE__, __LINE__,
+               mu_stream_strerror (mailbox->stream, status));
+      return status;
+    }
+
   status = mu_stream_copy (mailbox->stream, tempstr, size);
   if (status)
     {
-      mu_error (_("%s:%d: error writing to temporary stream: %s"),
+      mu_error (_("%s:%d: copying from the temporary stream: %s"),
                __FILE__, __LINE__,
                mu_strerror (status));
       return status;
@@ -1395,30 +1408,35 @@ mbox_expunge0 (mu_mailbox_t mailbox, int remove_deleted)
   status = mu_temp_file_stream_create (&tempstr, NULL);
   if (status == 0)
     {
-      sigset_t signalset;
+      status = mu_stream_open (tempstr);
+      if (status == 0)
+       {
+         sigset_t signalset;
 #ifdef WITH_PTHREAD
-      int state;
-      pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &state);
+         int state;
+         pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, &state);
 #endif
-      sigemptyset (&signalset);
-      sigaddset (&signalset, SIGTERM);
-      sigaddset (&signalset, SIGHUP);
-      sigaddset (&signalset, SIGTSTP);
-      sigaddset (&signalset, SIGINT);
-      sigaddset (&signalset, SIGWINCH);
-      sigprocmask (SIG_BLOCK, &signalset, 0);
-
-      status = mbox_expunge_unlocked (mailbox, dirty, remove_deleted, tempstr);
+         sigemptyset (&signalset);
+         sigaddset (&signalset, SIGTERM);
+         sigaddset (&signalset, SIGHUP);
+         sigaddset (&signalset, SIGTSTP);
+         sigaddset (&signalset, SIGINT);
+         sigaddset (&signalset, SIGWINCH);
+         sigprocmask (SIG_BLOCK, &signalset, 0);
+         
+         status = mbox_expunge_unlocked (mailbox, dirty, remove_deleted,
+                                         tempstr);
 
 #ifdef WITH_PTHREAD
-      pthread_setcancelstate (state, &state);
+         pthread_setcancelstate (state, &state);
 #endif
-      sigprocmask (SIG_UNBLOCK, &signalset, 0);
+         sigprocmask (SIG_UNBLOCK, &signalset, 0);
       
-      mu_stream_destroy (&tempstr);
+         mu_stream_destroy (&tempstr);
 
-      if (status == 0)
-       mbox_reset (mailbox, dirty, remove_deleted);
+         if (status == 0)
+           mbox_reset (mailbox, dirty, remove_deleted);
+       }
     }
   mu_locker_unlock (mailbox->locker);
   return status;
diff --git a/libproto/mbox/mbox0.h b/libproto/mbox/mbox0.h
index 4e1f201..b53aa65 100644
--- a/libproto/mbox/mbox0.h
+++ b/libproto/mbox/mbox0.h
@@ -71,8 +71,8 @@ typedef struct _mbox_message *mbox_message_t;
 struct _mbox_message
 {
   /* Offset of the messages in the mailbox.  */
-  mu_off_t header_from;        /* Start of envelope (^From ) */
-  mu_off_t header_from_end;    /* End of envelope (terminating \n) */
+  mu_off_t envel_from;         /* Start of envelope (^From ) */
+  mu_off_t envel_from_end;     /* End of envelope (terminating \n) */
   mu_off_t body;               /* Start of body */
   mu_off_t body_end;           /* End of body */
 
diff --git a/libproto/mbox/mboxscan.c b/libproto/mbox/mboxscan.c
index 127a360..db8a099 100644
--- a/libproto/mbox/mboxscan.c
+++ b/libproto/mbox/mboxscan.c
@@ -359,11 +359,10 @@ mbox_scan_internal (mu_mailbox_t mailbox, mbox_message_t 
mum,
                }
              /* Allocate_msgs will initialize mum.  */
              ALLOCATE_MSGS (mailbox, mud);
-             mud->messages_count++;
-             mum = mud->umessages[mud->messages_count - 1];
+             mum = mud->umessages[mud->messages_count++];
              mum->mud = mud;
-              mum->header_from = total - n;
-              mum->header_from_end = total;
+              mum->envel_from = total - n;
+              mum->envel_from_end = total;
              mum->body_end = mum->body = 0;
              mum->attr_flags = 0;
              lines = 0;
@@ -467,7 +466,7 @@ mbox_scan0 (mu_mailbox_t mailbox, size_t msgno, size_t 
*pcount, int do_notif)
     {
       mum = mud->umessages[msgno - 1];
       if (mum)
-       total = mum->header_from;
+       total = mum->envel_from;
       mud->messages_count = msgno - 1;
     }
   else
diff --git a/mail/decode.c b/mail/decode.c
index 3c4fe46..f0212cd 100644
--- a/mail/decode.c
+++ b/mail/decode.c
@@ -116,8 +116,11 @@ display_headers (FILE *out, mu_message_t mesg,
     {
       mu_stream_t stream = NULL;
       if (mu_message_get_header (mesg, &hdr) == 0
-         && mu_header_get_stream (hdr, &stream) == 0)
-       print_stream (stream, out);
+         && mu_header_get_streamref (hdr, &stream) == 0)
+       {
+         print_stream (stream, out);
+         mu_stream_destroy (&stream);
+       }
     }
 }
 
@@ -254,12 +257,12 @@ display_submessage (struct mime_descend_closure *closure, 
void *data)
       
       mu_message_get_body (closure->message, &body);
       mu_message_get_header (closure->message, &hdr);
-      mu_body_get_stream (body, &b_stream);
+      mu_body_get_streamref (body, &b_stream);
 
       /* Can we decode.  */
-      if (mu_filter_create(&d_stream, b_stream, closure->encoding,
-                          MU_FILTER_DECODE, 
-                          MU_STREAM_READ|MU_STREAM_NO_CLOSE) == 0)
+      if (mu_filter_create (&d_stream, b_stream, closure->encoding,
+                           MU_FILTER_DECODE, 
+                           MU_STREAM_READ|MU_STREAM_NO_CLOSE) == 0)
        stream = d_stream;
       else
        stream = b_stream;
@@ -303,13 +306,13 @@ display_submessage (struct mime_descend_closure *closure, 
void *data)
          if (out != ofile)
            pclose (out);
        }
-      if (d_stream)
-       mu_stream_destroy (&d_stream);
+      mu_stream_destroy (&stream);
     }
   
   return 0;
 }
 
+/* FIXME: Try to use mu_stream_copy instead */
 static int
 print_stream (mu_stream_t stream, FILE *out)
 {
@@ -317,12 +320,6 @@ print_stream (mu_stream_t stream, FILE *out)
   size_t n = 0;
   int rc;
   
-  rc = mu_stream_seek (stream, 0, MU_SEEK_SET, NULL);
-  if (rc)
-    {
-      util_error (_("seek error: %s"), mu_stream_strerror (stream, rc));
-      return rc;
-    }
   while (mu_stream_read (stream, buffer, sizeof (buffer) - 1, &n) == 0
         && n != 0)
     {
@@ -397,20 +394,18 @@ run_metamail (const char *mailcap_cmd, mu_message_t mesg)
     {
       /* Child process */
       int status;
-      mu_stream_t stream;
+      mu_stream_t stream = NULL;
 
       do /* Fake loop to avoid gotos */
        {
          mu_stream_t pstr;
-         char buffer[512];
-         size_t n;
          char *no_ask;
          
          setenv ("METAMAIL_PAGER", getenv ("PAGER"), 0);
          if (mailvar_get (&no_ask, "mimenoask", mailvar_type_string, 0))
            setenv ("MM_NOASK", no_ask, 1);
          
-         status = mu_message_get_stream (mesg, &stream);
+         status = mu_message_get_streamref (mesg, &stream);
          if (status)
            {
              mu_error ("mu_message_get_stream: %s", mu_strerror (status));
@@ -430,12 +425,7 @@ run_metamail (const char *mailcap_cmd, mu_message_t mesg)
              mu_error ("mu_stream_open: %s", mu_strerror (status));
              break;
            }
-         mu_stream_seek (stream, 0, MU_SEEK_SET, NULL);
-         while (mu_stream_read (stream, buffer, sizeof buffer - 1,
-                                &n) == 0
-                && n > 0)
-           mu_stream_write (pstr, buffer, n, NULL);
-
+         mu_stream_copy (pstr, stream, 0);
          mu_stream_close (pstr);
          mu_stream_destroy (&pstr);
          exit (0);
diff --git a/mail/escape.c b/mail/escape.c
index c874514..0f3f57e 100644
--- a/mail/escape.c
+++ b/mail/escape.c
@@ -30,19 +30,21 @@ dump_headers (FILE *fp, compose_env_t *env)
   size_t n;
   int rc;
   
-  mu_header_get_stream (env->header, &stream);
-  rc = mu_stream_seek (stream, 0, MU_SEEK_SET, NULL);
+  rc = mu_header_get_streamref (env->header, &stream);
   if (rc)
     {
-      util_error (_("seek error: %s"), mu_stream_strerror (stream, rc));
+      util_error ("mu_header_get_streamref: %s",
+                 mu_stream_strerror (stream, rc));
       return;
     }
+  /* FIXME: Use mu_stream_copy */
   while (mu_stream_read (stream, buffer, sizeof buffer - 1, &n) == 0
         && n != 0)
     {
       buffer[n] = 0;
       fprintf (fp, "%s", buffer);
     }
+  mu_stream_destroy (&stream);
 }
 
 #define STATE_INIT 0
@@ -478,24 +480,25 @@ quote0 (msgset_t *mspec, mu_message_t mesg, void *data)
        }
       fprintf (ofile, "%s\n", prefix);
       mu_message_get_body (mesg, &body);
-      mu_body_get_stream (body, &stream);
+      rc = mu_body_get_streamref (body, &stream);
     }
   else
-    mu_message_get_stream (mesg, &stream);
+    rc = mu_message_get_streamref (mesg, &stream);
 
-  rc = mu_stream_seek (stream, 0, MU_SEEK_SET, NULL);
   if (rc)
     {
-      util_error (_("seek error: %s"), mu_stream_strerror (stream, rc));
+      util_error (_("get_streamref error: %s"), mu_strerror (rc));
       return rc;
     }
-  
+
+  /* FIXME: Use mu_stream_copy? */
   while (mu_stream_readline (stream, buffer, sizeof buffer - 1, &n) == 0
         && n != 0)
     {
       buffer[n] = '\0';
       fprintf (ofile, "%s%s", prefix, buffer);
     }
+  mu_stream_destroy (&stream);
   return 0;
 }
 
diff --git a/mail/msgset.y b/mail/msgset.y
index a076473..f2c2a52 100644
--- a/mail/msgset.y
+++ b/mail/msgset.y
@@ -629,8 +629,7 @@ select_body (mu_message_t msg, void *closure)
   mu_message_get_body (msg, &body);
   mu_body_size (body, &size);
   mu_body_lines (body, &lines);
-  mu_body_get_stream (body, &stream);
-  status = mu_stream_seek (stream, 0, MU_SEEK_SET, NULL);
+  status = mu_body_get_streamref (body, &stream);
   while (status == 0
         && mu_stream_readline (stream, buffer, sizeof(buffer)-1, &n) == 0
         && n > 0)
@@ -643,7 +642,7 @@ select_body (mu_message_t msg, void *closure)
       else
        status = regexec (&re, buffer, 0, NULL, 0);
     }
-
+  mu_stream_destroy (&stream);
   if (!noregex)
     regfree (&re);
 
diff --git a/mail/pipe.c b/mail/pipe.c
index 681e405..bb7ab0a 100644
--- a/mail/pipe.c
+++ b/mail/pipe.c
@@ -49,14 +49,15 @@ mail_pipe (int argc, char **argv)
     {
       if (util_get_message (mbox, mp->msg_part[0], &msg) == 0)
        {
-         mu_message_get_stream (msg, &stream);
-         mu_stream_seek (stream, 0, MU_SEEK_SET, NULL);
+         mu_message_get_streamref (msg, &stream);
+         /* FIXME: Use mu_stream_copy */
          while (mu_stream_read (stream, buffer, sizeof (buffer) - 1, &n) == 0
                 && n != 0)
            {
              buffer[n] = '\0';
              fprintf (tube, "%s", buffer);
            }
+         mu_stream_destroy (&stream);
          if (mailvar_get (NULL, "page", mailvar_type_boolean, 0) == 0)
            fprintf (tube, "\f\n");
        }
diff --git a/mail/print.c b/mail/print.c
index c804e26..9f0e409 100644
--- a/mail/print.c
+++ b/mail/print.c
@@ -36,6 +36,7 @@ mail_print_msg (msgset_t *mspec, mu_message_t mesg, void 
*data)
   size_t n = 0, lines = 0;
   FILE *out = ofile;
   int pagelines = util_get_crt ();
+  int status;
   
   mu_message_lines (mesg, &lines);
   if (mailvar_get (NULL, "showenvelope", mailvar_type_boolean, 0) == 0)
@@ -89,12 +90,18 @@ mail_print_msg (msgset_t *mspec, mu_message_t mesg, void 
*data)
        }
       fprintf (out, "\n");
       mu_message_get_body (mesg, &body);
-      mu_body_get_stream (body, &stream);
+      status = mu_body_get_streamref (body, &stream);
     }
   else
-    mu_message_get_stream (mesg, &stream);
+    status = mu_message_get_streamref (mesg, &stream);
 
-  mu_stream_seek (stream, 0, MU_SEEK_SET, NULL);
+  if (status)
+    {
+      mu_error (_("get_stream error: %s"), mu_strerror (status));
+      return 0;
+    }
+
+  /* FIXME: Use mu_stream_copy instead? */
   while (mu_stream_read (stream, buffer, sizeof buffer - 1, &n) == 0
         && n != 0)
     {
@@ -106,6 +113,7 @@ mail_print_msg (msgset_t *mspec, mu_message_t mesg, void 
*data)
       buffer[n] = '\0';
       fprintf (out, "%s", buffer);
     }
+  mu_stream_destroy (&stream);
   if (out != ofile)
     pclose (out);
   
diff --git a/mail/send.c b/mail/send.c
index 07a7b1a..88c358e 100644
--- a/mail/send.c
+++ b/mail/send.c
@@ -293,36 +293,37 @@ compose_header_get (compose_env_t * env, char *name, char 
*defval)
 }
 
 void
-compose_destroy (compose_env_t * env)
+compose_destroy (compose_env_t *env)
 {
   mu_header_destroy (&env->header);
   free (env->outfiles);
 }
 
+/* FIXME: Can we use mu_stream_t instead of FILE? If so,
+   replace the loop with a call to mu_stream_copy. */
 static int
 fill_body (mu_message_t msg, FILE *file)
 {
   mu_body_t body = NULL;
   mu_stream_t stream = NULL;
-  off_t offset = 0;
   char *buf = NULL;
   size_t n = 0;
   mu_message_get_body (msg, &body);
-  mu_body_get_stream (body, &stream);
-
-  mu_stream_seek (stream, 0, MU_SEEK_SET, NULL);
-  offset = 0;
+  mu_body_get_streamref (body, &stream);
+  int nullbody = 1;
+  
   while (getline (&buf, &n, file) >= 0)
     {
       size_t len = strlen (buf);
+      if (len)
+       nullbody = 0;
       mu_stream_write (stream, buf, len, NULL);
-      offset += len;
     }
-           
+  mu_stream_destroy (&stream);
   if (buf)
     free (buf);
 
-  if (offset == 0)
+  if (nullbody)
     {
       if (mailvar_get (NULL, "nullbody", mailvar_type_boolean, 0) == 0)
        {
@@ -525,7 +526,6 @@ mail_send0 (compose_env_t * env, int save_to)
          int rc;
          
          mu_message_create (&msg, NULL);
-         mu_message_set_header (msg, env->header, NULL);
 
          /* Fill the body.  */
          rc = fill_body (msg, file);
@@ -599,6 +599,8 @@ mail_send0 (compose_env_t * env, int save_to)
                  if (mailvar_get (&sendmail, "sendmail",
                                   mailvar_type_string, 0) == 0)
                    {
+                     mu_message_set_header (msg, env->header, NULL);
+                     env->header = NULL;
                      if (sendmail[0] == '/')
                        msg_to_pipe (sendmail, msg);
                      else
@@ -669,14 +671,15 @@ msg_to_pipe (const char *cmd, mu_message_t msg)
       mu_stream_t stream = NULL;
       char buffer[512];
       size_t n = 0;
-      mu_message_get_stream (msg, &stream);
-      mu_stream_seek (stream, 0, MU_SEEK_SET, NULL);
+      /* FIXME: Use mu_stream_copy */
+      mu_message_get_streamref (msg, &stream);
       while (mu_stream_read (stream, buffer, sizeof buffer - 1, &n) == 0
             && n != 0)
        {
          buffer[n] = '\0';
          fprintf (fp, "%s", buffer);
        }
+      mu_stream_destroy (&stream);
       pclose (fp);
     }
   else
diff --git a/mail/top.c b/mail/top.c
index d287156..de030af 100644
--- a/mail/top.c
+++ b/mail/top.c
@@ -35,8 +35,8 @@ top0 (msgset_t *mspec, mu_message_t msg, void *data)
       || lines < 0)
     return 1;
 
-  mu_message_get_stream (msg, &stream);
-  mu_stream_seek (stream, 0, MU_SEEK_SET, NULL);
+  /* FIXME: Use mu_stream_copy */
+  mu_message_get_streamref (msg, &stream);
   for (; lines > 0; lines--)
     {
       int status = mu_stream_readline (stream, buf, sizeof (buf), &n);
@@ -44,6 +44,7 @@ top0 (msgset_t *mspec, mu_message_t msg, void *data)
        break;
       fprintf (ofile, "%s", buf);
     }
+  mu_stream_destroy (&stream);
   set_cursor (mspec->msg_part[0]);
 
   util_mark_read (msg);
diff --git a/mail/write.c b/mail/write.c
index eb7c1ff..ffaa44f 100644
--- a/mail/write.c
+++ b/mail/write.c
@@ -98,8 +98,8 @@ mail_write (int argc, char **argv)
       mu_body_lines (bod, &size);
       total_lines += size;
 
-      mu_body_get_stream (bod, &stream);
-      mu_stream_seek (stream, 0, MU_SEEK_SET, NULL);
+      /* FIXME: Use mu_stream_copy */
+      mu_body_get_streamref (bod, &stream);
       /* should there be a separator? */
       while (mu_stream_read (stream, buffer, sizeof (buffer) - 1, &n) == 0
             && n != 0)
@@ -107,7 +107,8 @@ mail_write (int argc, char **argv)
          buffer[n] = '\0';
          fprintf (output, "%s", buffer);
        }
-
+      mu_stream_destroy (&stream);
+      
       /* mark as saved. */
 
       mu_message_get_attribute (msg, &attr);
diff --git a/mailbox/body.c b/mailbox/body.c
index 17e616a..01f14f0 100644
--- a/mailbox/body.c
+++ b/mailbox/body.c
@@ -285,7 +285,7 @@ _body_seek (mu_stream_t stream, mu_off_t off, int whence, 
mu_off_t *presult)
 {
   struct _mu_body_stream *str = (struct _mu_body_stream*) stream;
   mu_body_t body = str->body;
-  return mu_stream_seek (body->stream, off, whence, presult);
+  return mu_stream_seek (body->fstream, off, whence, presult);
 }
 
 static const char *
diff --git a/mailbox/file_stream.c b/mailbox/file_stream.c
index 977004d..abf63ac 100644
--- a/mailbox/file_stream.c
+++ b/mailbox/file_stream.c
@@ -221,6 +221,15 @@ fd_wait (mu_stream_t stream, int *pflags, struct timeval 
*tvp)
 }
 
 int
+fd_truncate (mu_stream_t stream, mu_off_t size)
+{
+  struct _mu_file_stream *fstr = (struct _mu_file_stream *) stream;
+  if (ftruncate (fstr->fd, size))
+    return errno;
+  return 0;
+}
+
+int
 _mu_file_stream_create (mu_stream_t *pstream, size_t size,
                        char *filename, int flags)
 {
@@ -239,6 +248,7 @@ _mu_file_stream_create (mu_stream_t *pstream, size_t size,
   str->stream.size = fd_size;
   str->stream.ctl = fd_ioctl;
   str->stream.wait = fd_wait;
+  str->stream.truncate = fd_truncate;
   str->stream.error_string = fd_error_string;
 
   str->filename = filename;
diff --git a/mailbox/header.c b/mailbox/header.c
index 50ff83f..224915f 100644
--- a/mailbox/header.c
+++ b/mailbox/header.c
@@ -329,7 +329,7 @@ header_parse (mu_header_t header, const char *blurb, int 
len)
        *[ (' ' | '\t') field-value '\r' '\n' ]
   */
   /* First loop goes through the blurb */
-  for (header_start = blurb;  ; header_start = ++header_end)
+  for (header_start = blurb; len > 0; header_start = ++header_end)
     {
       const char *fn, *fn_end, *fv, *fv_end;
       struct mu_hdrent *ent;
@@ -340,7 +340,7 @@ header_parse (mu_header_t header, const char *blurb, int 
len)
        break;
 
       /* Second loop extract one header field. */
-      for (header_start2 = header_start;  ;header_start2 = ++header_end)
+      for (header_start2 = header_start; len; header_start2 = ++header_end)
        {
          header_end = memchr (header_start2, '\n', len);
          if (header_end == NULL)
@@ -348,21 +348,14 @@ header_parse (mu_header_t header, const char *blurb, int 
len)
          else
            {
              len -= (header_end - header_start2 + 1);
-             if (len < 0)
-               {
-                 header_end = NULL;
-                 break;
-               }
-             if (header_end[1] != ' '
-                 && header_end[1] != '\t')
+             if (!len
+                 || (header_end[1] != ' '
+                     && header_end[1] != '\t'))
                break; /* New header break the inner for. */
            }
          /* *header_end = ' ';  smash LF ? NO */
        }
 
-      if (header_end == NULL)
-       break; /* FIXME: Bail out.  */
-      
       /* Now save the header in the data structure.  */
 
       /* Treats unix "From " specially.  FIXME: Should we? */
@@ -956,9 +949,10 @@ header_seek (mu_stream_t str, mu_off_t off, int whence, 
mu_off_t *presult)
       break;
     }
 
-  if (off < 0 || off >= hstr->hdr->size)
+  if (off < 0 || off > hstr->hdr->size)
     return ESPIPE;
   hstr->off = off;
+  *presult = off;
   return 0;
 }
 
diff --git a/mailbox/message.c b/mailbox/message.c
index 5d9a505..d23677c 100644
--- a/mailbox/message.c
+++ b/mailbox/message.c
@@ -270,21 +270,35 @@ _message_stream_create (mu_stream_t *pmsg, mu_message_t 
msg, int flags)
 }
 
 
+enum eoh_state
+  {
+    eoh_no,
+    eoh_maybe,
+    eoh_yes
+  };
+
 /* Message header stuff */
-static int
-string_find_eoh (const char *str, size_t len, size_t *ppos)
+static enum eoh_state
+string_find_eoh (enum eoh_state eoh, const char *str, size_t len,
+                size_t *ppos)
 {
   size_t pos;
-  int eoh = 0;
+
+  if (eoh == eoh_maybe && *str == '\n')
+    {
+      *ppos = 0;
+      return eoh_yes;
+    }
   
-  for (pos = 0; pos < len-1; pos++)
-    if (str[pos] == '\n' && str[pos+1] == '\n')
+  for (pos = 0; pos < len - 1; pos++)
+    if (str[pos] == '\n' && str[pos + 1] == '\n')
       {
-       eoh = 1;
-       break;
+       *ppos = pos + 1;
+       return eoh_yes;
       }
+  
   *ppos = pos + 1;
-  return eoh;
+  return str[pos] == '\n' ? eoh_maybe : eoh_no;
 }
 
 #define MIN_HEADER_BUF_SIZE 2048
@@ -297,17 +311,21 @@ _header_fill (mu_stream_t stream, char **pbuf, size_t 
*plen)
   size_t bufsize = 0;
   char inbuf[MIN_HEADER_BUF_SIZE];
   size_t nread;
+  enum eoh_state eoh = eoh_no;
   
   status = mu_stream_seek (stream, 0, MU_SEEK_SET, NULL);
   if (status)
     return status;
       
-  while ((status = mu_stream_read (stream, inbuf, sizeof (inbuf), &nread))
-        == 0 && nread)
+  while (eoh != eoh_yes
+        && (status = mu_stream_read (stream, inbuf, sizeof (inbuf), &nread))
+           == 0
+        && nread)
     {
       char *nbuf;
       size_t len;
-      int eoh = string_find_eoh (inbuf, nread, &len);
+
+      eoh = string_find_eoh (eoh, inbuf, nread, &len);
       
       nbuf = realloc (buffer, bufsize + len);
       if (!nbuf)
@@ -318,8 +336,6 @@ _header_fill (mu_stream_t stream, char **pbuf, size_t *plen)
       memcpy (nbuf + bufsize, inbuf, len);
       buffer = nbuf;
       bufsize += len;
-      if (eoh)
-       break;
     }
 
   if (status)
diff --git a/mailbox/stream.c b/mailbox/stream.c
index 8d9e1f9..0ea5c01 100644
--- a/mailbox/stream.c
+++ b/mailbox/stream.c
@@ -53,7 +53,7 @@ _stream_seterror (struct _mu_stream *stream, int code, int 
perm)
 #define _stream_cleareof(s) ((s)->flags &= ~_MU_STR_EOF)
 #define _stream_advance_buffer(s,n) ((s)->cur += n, (s)->level -= n)
 #define _stream_buffer_offset(s) ((s)->cur - (s)->buffer)
-#define _stream_orig_level(s) ((s)->level + _stream_buffer_offset(s))
+#define _stream_orig_level(s) ((s)->level + _stream_buffer_offset (s))
 
 static int
 _stream_fill_buffer (struct _mu_stream *stream)
@@ -202,6 +202,7 @@ mu_stream_destroy (mu_stream_t *pstream)
       mu_stream_t str = *pstream;
       if (str && (str->ref_count == 0 || --str->ref_count == 0))
        {
+         mu_stream_close (str);
          if (str->done)
            str->done (str);
          free (str);
@@ -213,7 +214,7 @@ mu_stream_destroy (mu_stream_t *pstream)
 void
 mu_stream_get_flags (mu_stream_t str, int *pflags)
 {
-  *pflags = str->flags;
+  *pflags = str->flags & ~_MU_STR_INTERN_MASK;
 }
   
 void
@@ -252,6 +253,12 @@ mu_stream_strerror (mu_stream_t stream, int rc)
 }
 
 int
+mu_stream_err (mu_stream_t stream)
+{
+  return stream->flags & _MU_STR_ERR;
+}
+
+int
 mu_stream_last_error (mu_stream_t stream)
 {
   return stream->last_err;
@@ -700,6 +707,9 @@ mu_stream_close (mu_stream_t stream)
   if (!stream)
     return EINVAL;
   mu_stream_flush (stream);
+  /* Do close the stream only if it is not used by anyone else */
+  if (stream->ref_count > 1)
+    return 0;
   if (stream->close)
     rc = stream->close (stream);
   return rc;
@@ -785,7 +795,7 @@ mu_stream_set_flags (mu_stream_t stream, int fl)
 {
   if (stream == NULL)
     return EINVAL;
-  stream->flags |= fl;
+  stream->flags |= (fl & ~_MU_STR_INTERN_MASK);
   return 0;
 }
 
@@ -794,7 +804,7 @@ mu_stream_clr_flags (mu_stream_t stream, int fl)
 {
   if (stream == NULL)
     return EINVAL;
-  stream->flags &= ~fl;
+  stream->flags &= ~(fl & ~_MU_STR_INTERN_MASK);
   return 0;
 }
 
diff --git a/mailbox/streamref.c b/mailbox/streamref.c
index 04c8450..7e9ff4f 100644
--- a/mailbox/streamref.c
+++ b/mailbox/streamref.c
@@ -62,7 +62,7 @@ _streamref_read (struct _mu_stream *str, char *buf, size_t 
bufsize,
   else if (rc == ESPIPE)
     {
       *pnread = 0;
-      str->flags |= _MU_STR_EOF;
+      mu_stream_clearerr (sp->transport);
       return 0;
     }
   return streamref_return (sp, rc);
@@ -170,7 +170,21 @@ static int
 _streamref_size (struct _mu_stream *str, mu_off_t *psize)
 {
   struct _mu_streamref *sp = (struct _mu_streamref *)str;
-  return streamref_return (sp, mu_stream_size (sp->transport, psize));
+  mu_off_t size;
+  int rc = 0;
+  
+  if (sp->end)
+    size = sp->end - sp->start + 1;
+  else
+    {
+      rc = mu_stream_size (sp->transport, &size);
+      if (rc)
+       return streamref_return (sp, rc);
+      size -= sp->start;
+    }
+  if (rc == 0)
+    *psize = size;
+  return rc;
 }
 
 static int
@@ -240,12 +254,11 @@ mu_streamref_create_abridged (mu_stream_t *pref, 
mu_stream_t str,
   int flags;
   struct _mu_streamref *sp;
 
-  rc = mu_stream_seek (str, 0, MU_SEEK_CUR, &off);
+  rc = mu_stream_seek (str, 0, MU_SEEK_SET, &off);
   if (rc)
     return rc;
   mu_stream_get_flags (str, &flags);
-  sp = (struct _mu_streamref *) _mu_stream_create (sizeof (*sp),
-                                                  flags | MU_STREAM_NO_CLOSE);
+  sp = (struct _mu_streamref *) _mu_stream_create (sizeof (*sp), flags);
   if (!sp)
     return ENOMEM;
   mu_stream_ref (str);
diff --git a/mimeview/mimeview.c b/mimeview/mimeview.c
index 40840d9..6192ede 100644
--- a/mimeview/mimeview.c
+++ b/mimeview/mimeview.c
@@ -69,7 +69,7 @@ static char *no_ask_types;  /* List of MIME types for which 
no questions
                               should be asked */
 static int interactive = -1; 
 char *mimeview_file;       /* Name of the file to view */
-int mimeview_fd;     /* Its descriptor */
+FILE *mimeview_fp;     /* Its descriptor */
 
 static void
 set_debug_flags (mu_debug_t debug, const char *arg)
@@ -201,8 +201,8 @@ open_file (char *name)
     }
 
   mimeview_file = name;
-  mimeview_fd = open (name, O_RDONLY);
-  if (mimeview_fd == -1)
+  mimeview_fp = fopen (name, "r");
+  if (mimeview_fp == NULL)
     {
       mu_error (_("Cannot open `%s': %s"), name, mu_strerror (errno));
       return -1;
@@ -213,7 +213,7 @@ open_file (char *name)
 void
 close_file ()
 {
-  close (mimeview_fd);
+  fclose (mimeview_fp);
 }
 
 void
@@ -258,7 +258,7 @@ display_file (const char *type)
        mu_error (_("cannot create header: %s"), mu_strerror (status));
       else
        {
-         mu_stdio_stream_create (&stream, mimeview_fd,
+         mu_stdio_stream_create (&stream, fileno (mimeview_fp),
                                  MU_STREAM_READ|
                                  MU_STREAM_SEEK|MU_STREAM_NO_CLOSE);
          mu_stream_open (stream);


hooks/post-receive
-- 
GNU Mailutils




reply via email to

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