commit-mailutils
[Top][All Lists]
Advanced

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

[SCM] GNU Mailutils branch, master, updated. release-2.2-61-g906499d


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. release-2.2-61-g906499d
Date: Thu, 09 Sep 2010 20:40:17 +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=906499db53aea7333a11a87955c5c41ccbe45310

The branch, master has been updated
       via  906499db53aea7333a11a87955c5c41ccbe45310 (commit)
       via  1c398929444c1c64561c06f856fb0b744a74f25b (commit)
      from  6cf8cbbb057216f37008287a83d1c61908e21737 (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 906499db53aea7333a11a87955c5c41ccbe45310
Author: Sergey Poznyakoff <address@hidden>
Date:   Thu Sep 9 23:18:40 2010 +0300

    Optimize I/O bufferization.
    
    New ioctls MU_IOCTL_GET_TRANSPORT_BUFFER and
    MU_IOCTL_SET_TRANSPORT_BUFFER return and modify bufferization
    mode in the lowest level transport stream.  Both server and
    client programs use this to switch to full buffering before
    sending large amounts of data. This has a particular impact
    on the output speed and CPU usage when TLS is in use.
    
    * include/mailutils/stream.h (MU_IOCTL_GET_TRANSPORT_BUFFER)
    (MU_IOCTL_SET_TRANSPORT_BUFFER): New ioctls.
    (MU_TRANSPORT_INPUT, MU_TRANSPORT_OUTPUT): New constants.
    (MU_TRANSPORT_VALID_TYPE): New macro.
    (mu_buffer_query): New struct.
    (mu_stream_get_buffer): New proto.
    
    * libmu_auth/tls.c (_tls_io_ioctl): Return ENOSYS
    if op is not supported.
    (_tls_ioctl): Support MU_IOCTL_[GS]ET_TRANSPORT_BUFFER.
    * mailbox/file_stream.c (fd_ioctl): Support 
MU_IOCTL_[GS]ET_TRANSPORT_BUFFER.
    Return ENOSYS if op is not supported.
    * mailbox/filter_iconv.c (_icvt_ioctl): Likewise.
    * mailbox/iostream.c (_iostream_ctl): Likewise.
    * mailbox/mapfile_stream.c (_mapfile_ioctl): Likewise.
    * mailbox/memory_stream.c (_memory_ioctl): Likewise.
    * mailbox/rdcache_stream.c (rdcache_ioctl): Likewise.
    * mailbox/xscript-stream.c (_xscript_ctl): Likewise.
    * mailbox/prog_stream.c (_prog_ioctl): Return ENOSYS if op is not
    supported.
    * mailbox/tcp.c (_tcp_ioctl): Likewise.
    
    * mailbox/stream.c (mu_stream_default_buffer_size): New global.
    (mu_stream_seek): Do not call seek method if the requested offset
    is the same as the current one.
    (mu_stream_set_buffer): Size==0 means use the default value.
    (mu_stream_get_buffer): New function.
    (mu_stream_truncate): Flush the buffer before truncating.
    
    * mailbox/mime.c (mime_reset_state): New function.
    (_mime_body_stream_seek): Rewrite using mime_reset_state.
    (_mime_body_stream_ioctl): Return ENOSYS if op is not
    supported.
    (create_mime_body_stream): Reset mime state (_mime_body_stream_seek
    may not be called due to the optimization in mu_stream_seek.
    
    * mailbox/header.c (header_parse): Exit correctly if the buffer is
    not terminated with a \n.
    
    * libproto/mbox/mbox.c (mbox_open): Enforce full buffering on the
    mailbox stream.
    * libproto/pop/mbox.c (pop_header_fill): Minor fix.
    * libproto/pop/pop3_stream.c (_POP3F_DONE)
    (_POP3F_CHBUF): New constants.
    (mu_pop3_stream)<done>: Remove. Replaced with flags.
    <oldbuf>: New member.
    (_pop3_event_cb): If _POP3F_CHBUF flag is set, restore
    the initial buffering mode on the transport stream.
    (mu_pop3_filter_create): Save away current buffering mode
    and enforce full buffering while transferring bulk data.
    
    * mail/from.c (hdr_from): Check return value from mu_message_get_header.
    * mail/mail.c (main): Allow for MAILRC having empty value.
    Always close the mailbox before exiting.
    
    * pop3d/pop3d.c (pop3d_cfg_param): New statement output-buffer-size.
    * pop3d/pop3d.h (pop3d_output_bufsize): New global.
    * pop3d/retr.c (pop3d_send_payload): New function.
    (pop3d_retr): Rewrite using pop3d_send_payload. Save away
    current buffering mode and enforce full buffering while
    transferring bulk data.
    * pop3d/top.c (pop3d_top_: Likewise.

commit 1c398929444c1c64561c06f856fb0b744a74f25b
Author: Sergey Poznyakoff <address@hidden>
Date:   Thu Sep 9 18:19:28 2010 +0300

    Bugfix
    
    * mailbox/url.c (ACCESSOR(is_same,field)): Fix coredump if one
    of the accessors returned MU_ERR_NOENT.

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

Summary of changes:
 include/mailutils/stream.h |   19 +++++++++++++++++++
 libmu_auth/tls.c           |   43 ++++++++++++++++++++++++++++++++++++-------
 libproto/mbox/mbox.c       |    3 ++-
 libproto/pop/mbox.c        |   18 ++++++++++++------
 libproto/pop/pop3_stream.c |   43 +++++++++++++++++++++++++++++++++++++------
 mail/from.c                |    3 ++-
 mail/mail.c                |   32 ++++++++++++++++++++------------
 mailbox/file_stream.c      |   14 +++++++++++++-
 mailbox/filter_iconv.c     |    4 +++-
 mailbox/header.c           |    8 ++++++--
 mailbox/iostream.c         |   14 +++++++++++++-
 mailbox/mapfile_stream.c   |   14 +++++++++++++-
 mailbox/memory_stream.c    |   14 +++++++++++++-
 mailbox/mime.c             |   23 ++++++++++++++---------
 mailbox/prog_stream.c      |    2 +-
 mailbox/rdcache_stream.c   |   14 +++++++++++++-
 mailbox/stream.c           |   22 +++++++++++++++++++---
 mailbox/tcp.c              |    2 +-
 mailbox/url.c              |    4 ++--
 mailbox/xscript-stream.c   |    9 +++++++++
 pop3d/pop3d.c              |    2 ++
 pop3d/pop3d.h              |    1 +
 pop3d/retr.c               |   36 ++++++++++++++++++++++++++++--------
 pop3d/top.c                |   12 ++++++++++++
 24 files changed, 291 insertions(+), 65 deletions(-)

diff --git a/include/mailutils/stream.h b/include/mailutils/stream.h
index 0d50602..d8567ac 100644
--- a/include/mailutils/stream.h
+++ b/include/mailutils/stream.h
@@ -65,6 +65,23 @@ enum mu_buffer_type
 
 #define MU_IOCTL_LEVEL           8
 
+#define MU_IOCTL_GET_TRANSPORT_BUFFER 9
+#define MU_IOCTL_SET_TRANSPORT_BUFFER 10
+
+#define MU_TRANSPORT_INPUT  0
+#define MU_TRANSPORT_OUTPUT 1
+#define MU_TRANSPORT_VALID_TYPE(n) \
+  ((n) == MU_TRANSPORT_INPUT || (n) == MU_TRANSPORT_OUTPUT)
+
+struct mu_buffer_query
+{
+  int type;                     /* One of MU_TRANSPORT_ defines */
+  enum mu_buffer_type buftype;  /* Buffer type */
+  size_t bufsize;               /* Buffer size */
+};
+
+#define MU_STREAM_DEFBUFSIZ 8192
+extern size_t mu_stream_default_buffer_size;
 
 void mu_stream_ref (mu_stream_t stream);
 void mu_stream_unref (mu_stream_t stream);
@@ -84,6 +101,8 @@ int mu_stream_skip_input_bytes (mu_stream_t stream, mu_off_t 
count,
 
 int mu_stream_set_buffer (mu_stream_t stream, enum mu_buffer_type type,
                          size_t size);
+int mu_stream_get_buffer (mu_stream_t stream,
+                         struct mu_buffer_query *qry);
 int mu_stream_read (mu_stream_t stream, void *buf, size_t size, size_t *pread);
 int mu_stream_readdelim (mu_stream_t stream, char *buf, size_t size,
                         int delim, size_t *pread);
diff --git a/libmu_auth/tls.c b/libmu_auth/tls.c
index 2d3bd81..7199715 100644
--- a/libmu_auth/tls.c
+++ b/libmu_auth/tls.c
@@ -279,7 +279,7 @@ _tls_io_ioctl (struct _mu_stream *stream, int op, void *arg)
       break;
 
     default:
-      return EINVAL;
+      return ENOSYS;
     }
   return 0;
 }
@@ -507,20 +507,49 @@ static int
 _tls_ioctl (struct _mu_stream *stream, int op, void *arg)
 {
   struct _mu_tls_stream *sp = (struct _mu_tls_stream *) stream;
-  mu_transport_t *ptrans, trans[2];
 
   switch (op)
     {
     case MU_IOCTL_GET_TRANSPORT:
       if (!arg)
        return EINVAL;
-      ptrans = arg;
-      mu_stream_ioctl (sp->transport[0], MU_IOCTL_GET_TRANSPORT, trans);
-      ptrans[0] = trans[0];
-      mu_stream_ioctl (sp->transport[1], MU_IOCTL_GET_TRANSPORT, trans);
-      ptrans[1] = trans[0];
+      else
+       {
+         mu_transport_t *ptrans, trans[2];
+
+         ptrans = arg;
+         mu_stream_ioctl (sp->transport[0], MU_IOCTL_GET_TRANSPORT, trans);
+         ptrans[0] = trans[0];
+         mu_stream_ioctl (sp->transport[1], MU_IOCTL_GET_TRANSPORT, trans);
+         ptrans[1] = trans[0];
+       }
       break;
 
+    case MU_IOCTL_GET_TRANSPORT_BUFFER:
+      if (!arg)
+       return EINVAL;
+      else
+       {
+         struct mu_buffer_query *qp = arg;
+         if (!MU_TRANSPORT_VALID_TYPE (qp->type) ||
+             !sp->transport[qp->type])
+           return EINVAL;
+         return mu_stream_get_buffer (sp->transport[qp->type], qp);
+       }
+      
+    case MU_IOCTL_SET_TRANSPORT_BUFFER:
+      if (!arg)
+       return EINVAL;
+      else
+       {
+         struct mu_buffer_query *qp = arg;
+         if (!MU_TRANSPORT_VALID_TYPE (qp->type) ||
+             !sp->transport[qp->type])
+           return EINVAL;
+         return mu_stream_set_buffer (sp->transport[qp->type],
+                                      qp->buftype, qp->bufsize);
+       }
+      
     default:
       return EINVAL;
     }
diff --git a/libproto/mbox/mbox.c b/libproto/mbox/mbox.c
index 7b14817..9963c2f 100644
--- a/libproto/mbox/mbox.c
+++ b/libproto/mbox/mbox.c
@@ -99,7 +99,8 @@ mbox_open (mu_mailbox_t mailbox, int flags)
 
       if (status)
        return status;
-
+      mu_stream_set_buffer (mailbox->stream, mu_buffer_full, 0);
+      
       status = mu_stream_open (mailbox->stream);
       if (status)
        {
diff --git a/libproto/pop/mbox.c b/libproto/pop/mbox.c
index f513295..b1403f7 100644
--- a/libproto/pop/mbox.c
+++ b/libproto/pop/mbox.c
@@ -568,24 +568,30 @@ pop_header_fill (void *data, char **pbuf, size_t *plen)
   int status;
 
   if (mpm->flags & _POP3_MSG_SCANNED)
-    status = _pop_message_get_stream (mpm, &stream);
+    {
+      status = _pop_message_get_stream (mpm, &stream);
+      if (status == 0)
+       {
+         status = pop_header_blurb (stream, mpm->header_lines, pbuf, plen);
+         mu_stream_destroy (&stream);
+       }
+    }
   else
     {
       status = mu_pop3_top (mpd->pop3, mpm->num, 0, &stream);
+      if (status)
+       status = _pop_message_get_stream (mpm, &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);
+      return status;
     }
 
-  status = pop_header_blurb (stream, mpm->header_lines, pbuf, plen);
-  mu_stream_destroy (&stream);
   return status;
 }
 
diff --git a/libproto/pop/pop3_stream.c b/libproto/pop/pop3_stream.c
index 25fdba6..0a02d25 100644
--- a/libproto/pop/pop3_stream.c
+++ b/libproto/pop/pop3_stream.c
@@ -29,11 +29,16 @@
 #include <mailutils/sys/pop3.h>
 
 /* Implementation of the stream for TOP and RETR.  */
+
+#define _POP3F_DONE  0x01
+#define _POP3F_CHBUF 0x02
+
 struct mu_pop3_stream
 {
   struct _mu_stream stream;
   mu_pop3_t pop3;
-  int done;
+  int flags;
+  struct mu_buffer_query oldbuf;
 };
 
 enum pop3_decode_state
@@ -187,6 +192,13 @@ _pop3_event_cb (mu_stream_t str, int ev, int flags)
          struct mu_pop3_stream *sp = (struct mu_pop3_stream *) trans[0];
          _mu_pop3_xscript_level (sp->pop3, MU_XSCRIPT_NORMAL);
          sp->pop3->state = MU_POP3_NO_STATE;
+
+         if (sp->flags & _POP3F_CHBUF)
+           {
+             mu_stream_ioctl (str, MU_IOCTL_SET_TRANSPORT_BUFFER,
+                              &sp->oldbuf);
+             sp->flags = _POP3F_DONE;
+           }
        }
     }
 }
@@ -205,8 +217,27 @@ mu_pop3_filter_create (mu_stream_t *pstream, mu_stream_t 
stream)
   if (rc == 0)
     {
       mu_stream_t str = *pstream;
+      mu_transport_t trans[2];
+      
       str->event_cb = _pop3_event_cb;
       str->event_mask = _MU_STR_EOF;
+
+      if (mu_stream_ioctl (str, MU_IOCTL_GET_TRANSPORT, trans) == 0)
+       {
+         struct mu_pop3_stream *sp = (struct mu_pop3_stream *) trans[0];
+         if (mu_stream_ioctl (stream, MU_IOCTL_GET_TRANSPORT_BUFFER,
+                              &sp->oldbuf) == 0)
+           {
+             struct mu_buffer_query newbuf;
+
+             sp->flags |= _POP3F_CHBUF;
+             newbuf.type = MU_TRANSPORT_OUTPUT;
+             newbuf.buftype = mu_buffer_full;
+             newbuf.bufsize = 64*1024;
+             mu_stream_ioctl (str, MU_IOCTL_SET_TRANSPORT_BUFFER,
+                              &newbuf);
+           }
+       }
     }
   return rc;
 }
@@ -221,7 +252,7 @@ _mu_pop3_read (struct _mu_stream *str, char *buf, size_t 
bufsize,
   size_t nread;
   int status = 0;
 
-  if (sp->done)
+  if (sp->flags & _POP3F_DONE)
     nread = 0;
   else
     {
@@ -229,7 +260,7 @@ _mu_pop3_read (struct _mu_stream *str, char *buf, size_t 
bufsize,
       if (status == 0 && nread == 0)
        {
          pop3->state = MU_POP3_NO_STATE;
-         sp->done = 1;
+         sp->flags |= _POP3F_DONE;
        }
     }
   *pnread = nread;
@@ -245,7 +276,7 @@ _mu_pop3_readdelim (struct _mu_stream *str, char *buf, 
size_t bufsize,
   size_t nread;
   int status = 0;
   
-  if (sp->done)
+  if (sp->flags & _POP3F_DONE)
     nread = 0;
   else
     {
@@ -254,7 +285,7 @@ _mu_pop3_readdelim (struct _mu_stream *str, char *buf, 
size_t bufsize,
       if (status == 0 && nread == 0)
        {
          pop3->state = MU_POP3_NO_STATE;
-         sp->done = 1;
+         sp->flags |= _POP3F_DONE;
        }
     }
   *pnread = nread;
@@ -294,7 +325,7 @@ mu_pop3_stream_create (mu_pop3_t pop3, mu_stream_t *pstream)
   sp->stream.wait = _mu_pop3_wait;
   
   sp->pop3 = pop3;
-  sp->done = 0;
+  sp->flags = 0;
   str = (mu_stream_t) sp;
   mu_stream_set_buffer (str, mu_buffer_line, 1024);
 
diff --git a/mail/from.c b/mail/from.c
index 7af3cb7..e624252 100644
--- a/mail/from.c
+++ b/mail/from.c
@@ -231,7 +231,8 @@ hdr_from (struct header_call_args *args, void *data)
     {  
       mu_header_t hdr;
       
-      mu_message_get_header (args->msg, &hdr);
+      if (mu_message_get_header (args->msg, &hdr))
+       abort ();
       if (mu_header_aget_value_unfold (hdr, MU_HEADER_FROM, &from) == 0)
        {
          mu_address_t address = NULL;
diff --git a/mail/mail.c b/mail/mail.c
index dba26a2..8a43b76 100644
--- a/mail/mail.c
+++ b/mail/mail.c
@@ -321,10 +321,18 @@ mail_diag_stderr_printer (void *data, mu_log_level_t 
level, const char *buf)
   return 0;
 }
 
+static void
+do_and_quit (const char *command)
+{
+  int rc = util_do_command (command);
+  mu_mailbox_close (mbox);
+  exit (rc != 0);
+}
+
 int
 main (int argc, char **argv)
 {
-  char *mode = NULL, *prompt = NULL;
+  char *mode = NULL, *prompt = NULL, *p;
   struct arguments args;
   int i, rc;
   
@@ -376,13 +384,9 @@ main (int argc, char **argv)
   util_do_command ("set columns=%d", util_getcols ());
   
   /* Set the default mailer to sendmail.  */
-  {
-    char *mailer_name = alloca (strlen ("sendmail:")
-                               + strlen (PATH_SENDMAIL) + 1);
-    sprintf (mailer_name, "sendmail:%s", PATH_SENDMAIL);
-    mailvar_set ("sendmail", mailer_name, mailvar_type_string,
-                MOPTF_OVERWRITE);
-  }
+  mailvar_set ("sendmail",
+              xstrdup ("sendmail:" PATH_SENDMAIL), mailvar_type_string,
+              MOPTF_OVERWRITE);
 
   args.argc = 0;
   args.argv = NULL;
@@ -401,7 +405,8 @@ main (int argc, char **argv)
   /* read system-wide mail.rc and user's .mailrc */
   if (mailvar_get (NULL, "rc", mailvar_type_boolean, 0) == 0)
     util_do_command ("source %s", SITE_MAIL_RC);
-  util_do_command ("source %s", getenv ("MAILRC"));
+  if ((p = getenv ("MAILRC")) && *p)
+    util_do_command ("source %s", getenv ("MAILRC"));
 
   util_run_cached_commands (&command_list);
 
@@ -476,11 +481,14 @@ main (int argc, char **argv)
            }
 
          if (strcmp (mode, "exist") == 0)
-           return (total < 1) ? 1 : 0;
+           {
+             mu_mailbox_close (mbox);
+             return (total < 1) ? 1 : 0;
+           }
          else if (strcmp (mode, "print") == 0)
-           return util_do_command ("print *");
+           do_and_quit ("print *");
          else if (strcmp (mode, "headers") == 0)
-           return util_do_command ("from *");
+           do_and_quit ("from *");
          else if (strcmp (mode, "read"))
            {
              util_error (_("Unknown mode `%s'"), mode);
diff --git a/mailbox/file_stream.c b/mailbox/file_stream.c
index 7ffde02..0df1254 100644
--- a/mailbox/file_stream.c
+++ b/mailbox/file_stream.c
@@ -217,8 +217,20 @@ fd_ioctl (struct _mu_stream *str, int code, void *ptr)
       fstr->fd = (int) ptrans[0];
       break;
       
+    case MU_IOCTL_GET_TRANSPORT_BUFFER:
+      {
+        struct mu_buffer_query *qp = ptr;
+       return mu_stream_get_buffer (str, qp);
+      }
+      
+    case MU_IOCTL_SET_TRANSPORT_BUFFER:
+      {
+        struct mu_buffer_query *qp = ptr;
+       return mu_stream_set_buffer (str, qp->buftype, qp->bufsize);
+      }
+      
     default:
-      return EINVAL;
+      return ENOSYS;
     }
   return 0;
 }
diff --git a/mailbox/filter_iconv.c b/mailbox/filter_iconv.c
index 93b9cb4..88c397d 100644
--- a/mailbox/filter_iconv.c
+++ b/mailbox/filter_iconv.c
@@ -401,10 +401,12 @@ _icvt_ioctl (mu_stream_t stream, int code, void *ptr)
       break;
 
     case MU_IOCTL_SWAP_STREAM:
+    case MU_IOCTL_GET_TRANSPORT_BUFFER:
+    case MU_IOCTL_SET_TRANSPORT_BUFFER:
       return mu_stream_ioctl (s->transport, code, ptr);
       
     default:
-      return EINVAL;
+      return ENOSYS;
     }
   return 0;
 }
diff --git a/mailbox/header.c b/mailbox/header.c
index f49ea86..2861c67 100644
--- a/mailbox/header.c
+++ b/mailbox/header.c
@@ -344,7 +344,11 @@ header_parse (mu_header_t header, const char *blurb, int 
len)
        {
          header_end = memchr (header_start2, '\n', len);
          if (header_end == NULL)
-           break;
+           {
+             header_end = header_start2 + len;
+             len = 0;
+             break;
+           }
          else
            {
              len -= (header_end - header_start2 + 1);
@@ -431,7 +435,7 @@ mu_header_create (mu_header_t *ph, const char *blurb, 
size_t len)
 {
   mu_header_t header;
   int status = 0;
-  
+
   header = calloc (1, sizeof (*header));
   if (header == NULL)
     return ENOMEM;
diff --git a/mailbox/iostream.c b/mailbox/iostream.c
index 4267a81..ca2f36b 100644
--- a/mailbox/iostream.c
+++ b/mailbox/iostream.c
@@ -153,9 +153,21 @@ _iostream_ctl (struct _mu_stream *str, int op, void *arg)
       if (!arg)
        return EINVAL;
       return _mu_stream_swap_streams (str, sp->transport, arg, 0);
+
+    case MU_IOCTL_GET_TRANSPORT_BUFFER:
+    case MU_IOCTL_SET_TRANSPORT_BUFFER:
+      if (!arg)
+       return EINVAL;
+      else
+       {
+         struct mu_buffer_query *qp = arg;
+         if (!MU_TRANSPORT_VALID_TYPE (qp->type) || !sp->transport[qp->type])
+           return EINVAL;
+         return mu_stream_ioctl (sp->transport[qp->type], op, arg);
+       }
       
     default:
-      return EINVAL;
+      return ENOSYS;
     }
   return 0;
 }
diff --git a/mailbox/mapfile_stream.c b/mailbox/mapfile_stream.c
index aeb85e5..8733622 100644
--- a/mailbox/mapfile_stream.c
+++ b/mailbox/mapfile_stream.c
@@ -218,8 +218,20 @@ _mapfile_ioctl (struct _mu_stream *str, int code, void 
*ptr)
       ptrans[1] = NULL;
       break;
 
+    case MU_IOCTL_GET_TRANSPORT_BUFFER:
+      {
+        struct mu_buffer_query *qp = ptr;
+       return mu_stream_get_buffer (str, qp);
+      }
+      
+    case MU_IOCTL_SET_TRANSPORT_BUFFER:
+      {
+        struct mu_buffer_query *qp = ptr;
+       return mu_stream_set_buffer (str, qp->buftype, qp->bufsize);
+      }
+
     default:
-      return EINVAL;
+      return ENOSYS;
     }
   return 0;
 }
diff --git a/mailbox/memory_stream.c b/mailbox/memory_stream.c
index 19d4590..98db753 100644
--- a/mailbox/memory_stream.c
+++ b/mailbox/memory_stream.c
@@ -159,8 +159,20 @@ _memory_ioctl (struct _mu_stream *stream, int code, void 
*ptr)
       ptrans[1] = NULL;
       break;
 
+    case MU_IOCTL_GET_TRANSPORT_BUFFER:
+      {
+        struct mu_buffer_query *qp = ptr;
+       return mu_stream_get_buffer (stream, qp);
+      }
+      
+    case MU_IOCTL_SET_TRANSPORT_BUFFER:
+      {
+        struct mu_buffer_query *qp = ptr;
+       return mu_stream_set_buffer (stream, qp->buftype, qp->bufsize);
+      }
+      
     default:
-      return EINVAL;
+      return ENOSYS;
     }
   return 0;
 }
diff --git a/mailbox/mime.c b/mailbox/mime.c
index 2f90b64..2c923cc 100644
--- a/mailbox/mime.c
+++ b/mailbox/mime.c
@@ -579,6 +579,17 @@ _mime_body_stream_size (mu_stream_t stream, mu_off_t 
*psize)
   return rc;
 }
 
+static void
+mime_reset_state (mu_mime_t mime)
+{                              /* reset message */
+  mime->cur_offset = 0;
+  mime->cur_part = 0;
+  mime->part_offset = 0;
+  
+  if (mime->nmtp_parts > 1)
+    mime->flags |= MIME_INSERT_BOUNDARY;
+}
+
 /* FIXME: The seek method is defective */
 static int
 _mime_body_stream_seek (mu_stream_t stream, mu_off_t off, mu_off_t *presult)
@@ -587,14 +598,7 @@ _mime_body_stream_seek (mu_stream_t stream, mu_off_t off, 
mu_off_t *presult)
   mu_mime_t mime = mstr->mime;
 
   if (off == 0)
-    {                          /* reset message */
-      mime->cur_offset = 0;
-      mime->cur_part = 0;
-      mime->part_offset = 0;
-
-      if (mime->nmtp_parts > 1)
-       mime->flags |= MIME_INSERT_BOUNDARY;
-    }
+    mime_reset_state (mime);
 
   if (off != mime->cur_offset)
     return ESPIPE;
@@ -767,7 +771,7 @@ _mime_body_stream_ioctl (mu_stream_t stream, int code, void 
*arg)
       break;
 
     default:
-      rc = EINVAL;
+      rc = ENOSYS;
     }
   return rc;
 }
@@ -785,6 +789,7 @@ create_mime_body_stream (mu_stream_t *pstr, mu_mime_t mime)
   sp->stream.ctl = _mime_body_stream_ioctl;
   sp->stream.size = _mime_body_stream_size;
   sp->mime = mime;
+  mime_reset_state (mime);
   *pstr = (mu_stream_t) sp;
   return 0;
 }
diff --git a/mailbox/prog_stream.c b/mailbox/prog_stream.c
index 8b20f96..ef35361 100644
--- a/mailbox/prog_stream.c
+++ b/mailbox/prog_stream.c
@@ -393,7 +393,7 @@ _prog_ioctl (struct _mu_stream *str, int code, void *ptr)
       break;
       
     default:
-      return EINVAL;
+      return ENOSYS;
     }
   return 0;
 }
diff --git a/mailbox/rdcache_stream.c b/mailbox/rdcache_stream.c
index 0d7eed7..4789811 100644
--- a/mailbox/rdcache_stream.c
+++ b/mailbox/rdcache_stream.c
@@ -131,8 +131,20 @@ rdcache_ioctl (struct _mu_stream *str, int op, void *arg)
       ptrans[1] = NULL;
       break;
 
+    case MU_IOCTL_GET_TRANSPORT_BUFFER:
+    case MU_IOCTL_SET_TRANSPORT_BUFFER:
+      if (!arg)
+       return EINVAL;
+      else
+       {
+         struct mu_buffer_query *qp = arg;
+         if (qp->type != MU_TRANSPORT_INPUT || !sp->transport)
+           return EINVAL;
+         return mu_stream_ioctl (sp->transport, op, arg);
+       }
+
     default:
-      return EINVAL;
+      return ENOSYS;
     }
   return 0;
 }
diff --git a/mailbox/stream.c b/mailbox/stream.c
index 1ea8b52..202601e 100644
--- a/mailbox/stream.c
+++ b/mailbox/stream.c
@@ -32,6 +32,8 @@
 #include <mailutils/stream.h>
 #include <mailutils/sys/stream.h>
 
+size_t mu_stream_default_buffer_size = MU_STREAM_DEFBUFSIZ;
+
 static void
 _stream_setflag (struct _mu_stream *stream, int flag)
 {
@@ -351,7 +353,7 @@ mu_stream_seek (mu_stream_t stream, mu_off_t offset, int 
whence,
       return mu_stream_seterr (stream, EINVAL, 1);
     }
 
-  if (stream->buftype == mu_buffer_none
+  if ((stream->buftype == mu_buffer_none && offset != stream->offset)
       || offset < stream->offset
       || offset > stream->offset + _stream_buffer_offset (stream))
     {
@@ -442,7 +444,7 @@ mu_stream_set_buffer (mu_stream_t stream, enum 
mu_buffer_type type,
                      size_t size)
 {
   if (size == 0)
-    type = mu_buffer_none;
+    size = mu_stream_default_buffer_size;
 
   if (stream->buffer)
     {
@@ -471,6 +473,14 @@ mu_stream_set_buffer (mu_stream_t stream, enum 
mu_buffer_type type,
 }
 
 int
+mu_stream_get_buffer (mu_stream_t stream, struct mu_buffer_query *qry)
+{
+  qry->buftype = stream->buftype;
+  qry->bufsize = stream->bufsize;
+  return 0;
+}
+
+int
 mu_stream_read_unbuffered (mu_stream_t stream, void *buf, size_t size,
                           int full_read,
                           size_t *pnread)
@@ -953,7 +963,13 @@ int
 mu_stream_truncate (mu_stream_t stream, mu_off_t size)
 {
   if (stream->truncate)
-    return stream->truncate (stream, size);
+    {
+      int rc;
+      
+      if ((rc = _stream_flush_buffer (stream, 1)))
+       return rc;
+      return stream->truncate (stream, size);
+    }
   return ENOSYS;
 }
 
diff --git a/mailbox/tcp.c b/mailbox/tcp.c
index 08f8fff..ba15ae8 100644
--- a/mailbox/tcp.c
+++ b/mailbox/tcp.c
@@ -209,7 +209,7 @@ _tcp_ioctl (mu_stream_t stream, int code, void *ptr)
       break;
 
     default:
-      return EINVAL;
+      return ENOSYS;
     }
   return 0;
 }
diff --git a/mailbox/url.c b/mailbox/url.c
index 92f762b..5f7379d 100644
--- a/mailbox/url.c
+++ b/mailbox/url.c
@@ -676,8 +676,8 @@ ACCESSOR(is_same,field) (mu_url_t url1, mu_url_t url2)      
                  \
   if (status2 && status2 != MU_ERR_NOENT)                                \
     return 0;                                                            \
                                                                          \
-  if (status1 && status1 == status2) /* Both fields are missing */       \
-    return 1;                                                            \
+  if (status1 || status2)                                                \
+    return status1 == status2; /* Both fields are missing */             \
   return mu_c_strcasecmp (s1, s2) == 0;                                        
  \
 }
 
diff --git a/mailbox/xscript-stream.c b/mailbox/xscript-stream.c
index 41f28ec..332f073 100644
--- a/mailbox/xscript-stream.c
+++ b/mailbox/xscript-stream.c
@@ -315,6 +315,15 @@ _xscript_ctl (struct _mu_stream *str, int op, void *arg)
        }
       break;
 
+    case MU_IOCTL_GET_TRANSPORT_BUFFER:
+    case MU_IOCTL_SET_TRANSPORT_BUFFER:
+      {
+        struct mu_transport_buffer_query *qp = arg;
+        if (!sp->transport)
+          return EINVAL;
+        return mu_stream_ioctl (sp->transport, op, arg);
+      }
+
     case MU_IOCTL_LEVEL:
       if (!arg)
        return EINVAL;
diff --git a/pop3d/pop3d.c b/pop3d/pop3d.c
index 6b70f55..83bf850 100644
--- a/pop3d/pop3d.c
+++ b/pop3d/pop3d.c
@@ -115,6 +115,8 @@ static struct mu_cfg_param pop3d_cfg_param[] = {
     N_("Set the bulletin database file name."),
     N_("file") },
 #endif
+  { "output-buffer-size", mu_cfg_size, &pop3d_output_bufsize, 0, NULL,
+    N_("Size of the output buffer.") },
   { ".server", mu_cfg_section, NULL, 0, NULL,
     N_("Server configuration.") },
   { "transcript", mu_cfg_bool, &pop3d_transcript, 0, NULL,
diff --git a/pop3d/pop3d.h b/pop3d/pop3d.h
index d831a3e..5cadccf 100644
--- a/pop3d/pop3d.h
+++ b/pop3d/pop3d.h
@@ -201,6 +201,7 @@ extern int undelete_on_startup;
 extern struct mu_auth_data *auth_data;
 extern unsigned int idle_timeout;
 extern int pop3d_transcript;
+extern size_t pop3d_output_bufsize;
 
 extern pop3d_command_handler_t pop3d_find_command (const char *name);
 
diff --git a/pop3d/retr.c b/pop3d/retr.c
index 0ffcd24..1023a71 100644
--- a/pop3d/retr.c
+++ b/pop3d/retr.c
@@ -17,6 +17,31 @@
 
 #include "pop3d.h"
 
+size_t pop3d_output_bufsize = 64 * 1024;
+
+void
+pop3d_send_payload (mu_stream_t stream)
+{
+  struct mu_buffer_query oldbuf, newbuf;
+  int xscript_level = set_xscript_level (MU_XSCRIPT_PAYLOAD);
+
+  oldbuf.type = MU_TRANSPORT_OUTPUT;
+  mu_stream_ioctl (iostream, MU_IOCTL_GET_TRANSPORT_BUFFER,
+                  &oldbuf);
+  newbuf.type = MU_TRANSPORT_OUTPUT;
+  newbuf.buftype = mu_buffer_full;
+  newbuf.bufsize = pop3d_output_bufsize;
+  mu_stream_ioctl (iostream, MU_IOCTL_SET_TRANSPORT_BUFFER,
+                  &newbuf);
+
+  mu_stream_copy (iostream, stream, 0, NULL);
+  pop3d_outf (".\n");
+
+  mu_stream_ioctl (iostream, MU_IOCTL_SET_TRANSPORT_BUFFER,
+                  &oldbuf);
+  set_xscript_level (xscript_level);
+}
+
 /* Prints out the specified message */
 
 int
@@ -26,7 +51,6 @@ pop3d_retr (char *arg)
   mu_message_t msg = NULL;
   mu_attribute_t attr = NULL;
   mu_stream_t stream;
-  int xscript_level;
   
   if ((strlen (arg) == 0) || (strchr (arg, ' ') != NULL))
     return ERR_BAD_ARGS;
@@ -47,18 +71,14 @@ pop3d_retr (char *arg)
     return ERR_UNKNOWN;
   
   pop3d_outf ("+OK\n");
-  xscript_level = set_xscript_level (MU_XSCRIPT_PAYLOAD);
-  mu_stream_copy (iostream, stream, 0, NULL);
+  pop3d_send_payload (stream);
   mu_stream_destroy (&stream);
-
+  
   if (!mu_attribute_is_read (attr))
     mu_attribute_set_read (attr);
 
   pop3d_mark_retr (attr);
 
-  pop3d_outf (".\n");
-
-  set_xscript_level (xscript_level);
-
+  
   return OK;
 }
diff --git a/pop3d/top.c b/pop3d/top.c
index 6e295bb..151dc8e 100644
--- a/pop3d/top.c
+++ b/pop3d/top.c
@@ -31,6 +31,7 @@ pop3d_top (char *arg)
   mu_stream_t stream;
   char *mesgc, *linesc, *p;
   int xscript_level;
+  struct mu_buffer_query oldbuf, newbuf;
   
   if (strlen (arg) == 0)
     return ERR_BAD_ARGS;
@@ -64,6 +65,14 @@ pop3d_top (char *arg)
   pop3d_outf ("+OK\n");
 
   xscript_level = set_xscript_level (MU_XSCRIPT_PAYLOAD);
+  oldbuf.type = MU_TRANSPORT_OUTPUT;
+  mu_stream_ioctl (iostream, MU_IOCTL_GET_TRANSPORT_BUFFER,
+                  &oldbuf);
+  newbuf.type = MU_TRANSPORT_OUTPUT;
+  newbuf.buftype = mu_buffer_full;
+  newbuf.bufsize = pop3d_output_bufsize;
+  mu_stream_ioctl (iostream, MU_IOCTL_SET_TRANSPORT_BUFFER,
+                  &newbuf);  
 
   mu_stream_copy (iostream, stream, 0, NULL);
   pop3d_outf ("\n");
@@ -88,6 +97,9 @@ pop3d_top (char *arg)
 
   pop3d_outf (".\n");
 
+  mu_stream_ioctl (iostream, MU_IOCTL_SET_TRANSPORT_BUFFER,
+                  &oldbuf);
+  
   set_xscript_level (xscript_level);
 
   return OK;


hooks/post-receive
-- 
GNU Mailutils



reply via email to

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