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-632-ga7a174d


From: Sergey Poznyakoff
Subject: [SCM] GNU Mailutils branch, master, updated. release-2.2-632-ga7a174d
Date: Wed, 08 Aug 2012 12:17:15 +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=a7a174d51ca7845f9eda854709258d64e5d0077e

The branch, master has been updated
       via  a7a174d51ca7845f9eda854709258d64e5d0077e (commit)
      from  b9f10525a3fb6167b0588c988f0aec4507c2c0f0 (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 a7a174d51ca7845f9eda854709258d64e5d0077e
Author: Sergey Poznyakoff <address@hidden>
Date:   Wed Aug 8 14:46:54 2012 +0300

    Improve header stream write method.
    
    * libmailutils/mailbox/header.c (HEADER_STREAMMOD): New flag.
    (mu_header_fill): Read data back from mstream if it was
    modified.
    (mu_header_destroy): Destroy mstream.
    (header_write): Rewrite from scratch. Allow for writing at
    arbitrary offsets.
    * examples/header.c: New commands: "overwrite" and "append",
    for testing the new functionality.

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

Summary of changes:
 examples/header.c             |   71 ++++++++++++++++++++++++-
 libmailutils/mailbox/header.c |  115 ++++++++++++++++++++++------------------
 2 files changed, 132 insertions(+), 54 deletions(-)

diff --git a/examples/header.c b/examples/header.c
index f25d5df..bde8b82 100644
--- a/examples/header.c
+++ b/examples/header.c
@@ -283,7 +283,7 @@ cmd_write (int argc, char **argv)
       mu_error ("%u: cannot get stream: %s", line_num, mu_strerror (status));
       return;
     }
-  printf("[reading headers; end with an empty line]\n");
+  printf ("[reading headers; end with an empty line]\n");
   mu_stream_seek (str, 0, SEEK_SET, NULL);
   while (prompt (1), fgets(buf, sizeof buf, stdin))
     {
@@ -296,6 +296,71 @@ cmd_write (int argc, char **argv)
 }
 
 void
+cmd_overwrite (int argc, char **argv)
+{
+  char buf[512];
+  mu_stream_t str;
+  int status;
+  mu_off_t off;
+  
+  if (check_args (argv[0], argc, 2, 2))
+    return;
+
+  off = strtoul (argv[1], NULL, 0);
+  
+  status = mu_header_get_streamref (header, &str);
+  if (status)
+    {
+      mu_error ("%u: cannot get stream: %s", line_num, mu_strerror (status));
+      return;
+    }
+  status = mu_stream_seek (str, off, SEEK_SET, NULL);
+  if (status)
+    {
+      mu_error ("seek error: %s", mu_strerror (status));
+      return;
+    }
+
+  printf ("[reading headers; end with an empty line]\n");
+  while (prompt (1), fgets(buf, sizeof buf, stdin))
+    {
+      if (buf[0] == '\n')
+       break;
+      mu_stream_write (str, buf, strlen (buf), NULL);
+    }
+  mu_stream_destroy (&str);
+  mu_stream_destroy (&hstream);
+}
+
+void
+cmd_append (int argc, char **argv)
+{
+  char buf[512];
+  mu_stream_t str;
+  int status;
+  
+  if (check_args (argv[0], argc, 1, 1))
+    return;
+
+  status = mu_header_get_streamref (header, &str);
+  if (status)
+    {
+      mu_error ("%u: cannot get stream: %s", line_num, mu_strerror (status));
+      return;
+    }
+  printf ("[reading headers; end with an empty line]\n");
+  mu_stream_seek (str, 0, SEEK_END, NULL);
+  while (prompt (1), fgets(buf, sizeof buf, stdin))
+    {
+      mu_stream_write (str, buf, strlen (buf), NULL);
+      if (buf[0] == '\n')
+       break;
+    }
+  mu_stream_destroy (&str);
+  mu_stream_destroy (&hstream);
+}
+
+void
 cmd_iterate (int argc, char **argv)
 {
   if (check_args (argv[0], argc, 1, 2))
@@ -379,7 +444,7 @@ static struct cmdtab cmdtab[] = {
   { "free", cmd_free, NULL, "discard all headers" },
   { "print", cmd_print, "NAME [N]",
     "find and print the Nth (by default, 1st) instance of header named NAME" },
-  { "dump", cmd_dump, NULL, "dump all headers on screen" },
+  { "dump", cmd_dump, "[OFF]", "dump all headers on screen" },
   { "itr", cmd_iterate, "[first|1|next|n]", "iterate over headers" },
   { "readline", cmd_readline, "[SIZE]", "read line" },
   { "remove", cmd_remove, "NAME [N]",
@@ -387,6 +452,8 @@ static struct cmdtab cmdtab[] = {
   { "insert", cmd_insert, "NAME VALUE [REF [NUM] [before|after] [replace]]",
     "insert new header" },
   { "write", cmd_write, NULL, "accept headers from raw stream" },
+  { "overwrite", cmd_overwrite, "OFF", "overwrite raw data from offset OFF" },
+  { "append", cmd_append, NULL, "append raw data" },
   { "help", cmd_help, "[COMMAND]", "print short usage message" },
   { NULL }
 };
diff --git a/libmailutils/mailbox/header.c b/libmailutils/mailbox/header.c
index f889b4c..1c76421 100644
--- a/libmailutils/mailbox/header.c
+++ b/libmailutils/mailbox/header.c
@@ -50,6 +50,7 @@
 
 #define HEADER_MODIFIED   0x01
 #define HEADER_INVALIDATE 0x02
+#define HEADER_STREAMMOD  0x04
 
 #define HEADER_SET_MODIFIED(h) \
   ((h)->flags |= (HEADER_MODIFIED|HEADER_INVALIDATE))
@@ -412,6 +413,33 @@ mu_header_fill (mu_header_t header)
   size_t blurb_len = 0;
   char *blurb = NULL;
   
+  if (header->mstream && header->flags & HEADER_STREAMMOD)
+    {
+      mu_off_t end;
+
+      mu_header_invalidate (header);
+      status = mu_stream_size (header->mstream, &end);
+      if (status)
+       return status;
+      status = mu_stream_seek (header->mstream, 0, MU_SEEK_SET, NULL);
+      if (status)
+       return status;      
+      blurb_len = end;
+      blurb = malloc (blurb_len + 1);
+      if (!blurb)
+       return ENOMEM;
+      status = mu_stream_read (header->mstream, blurb, blurb_len, NULL);
+      if (status)
+       {
+         free (blurb);
+         return status;
+       }
+      status = header_parse (header, blurb, blurb_len);
+      free (blurb);
+      if (status == 0)
+       header->flags &= ~HEADER_STREAMMOD;
+      return status;
+    }
   if (header->spool_used)
     return 0;
   
@@ -452,6 +480,7 @@ mu_header_destroy (mu_header_t *ph)
     {  
       mu_header_t header = *ph;
 
+      mu_stream_destroy (&header->mstream);
       mu_stream_destroy (&header->stream);
       mu_hdrent_free_list (header);
       free (header->spool);
@@ -1091,68 +1120,50 @@ _header_readline (mu_stream_t is, char *buffer, size_t 
buflen, size_t *pnread)
 static int
 header_write (mu_stream_t os, const char *buf, size_t buflen, size_t *pnwrite)
 {
-  struct _mu_header_stream *hstr;
+  struct _mu_header_stream *hstr = (struct _mu_header_stream *) os;
   mu_header_t header;
-  int status;
-  mu_off_t mstream_size;
+  int rc;
   
-  if (!os || !buf)
+  if (os == NULL)
     return EINVAL;
-
-  hstr = (struct _mu_header_stream *) os;
   header = hstr->hdr;
-  if (header == NULL)
-    return EINVAL;
-  
-  /* Skip the obvious.  */
-  if (*buf == '\0' || buflen == 0)
-    {
-      if (pnwrite)
-        *pnwrite = 0;
-      return 0;
-    }
-
-  if (!header->mstream)
+  if (!(header->flags & HEADER_STREAMMOD))
     {
-      status = mu_memory_stream_create (&header->mstream, MU_STREAM_RDWR);
-      if (status)
-       return status;
-    }
-
-  status = mu_stream_write (header->mstream, buf, buflen, NULL);
-  if (status)
-    {
-      mu_stream_destroy (&header->mstream);
-      return status;
-    }
-
-  status = mu_stream_size (header->mstream, &mstream_size);
-  if (status == 0 && mstream_size > 1)
-    {
-      char nlbuf[2];
+      struct mu_hdrent *ent;
+       
+      rc = mu_header_fill (header);
+      if (rc)
+       return rc;
 
-      status = mu_stream_seek (header->mstream, -2, MU_SEEK_END, NULL);
-      if (status == 0)
-       status = mu_stream_read (header->mstream, nlbuf, 2, NULL);
-      if (status == 0 && memcmp (nlbuf, "\n\n", 2) == 0)
+      if (!header->mstream)
        {
-         char *blurb;
-
-         blurb = calloc (1, mstream_size + 1);
-         if (blurb)
-           {
-             mu_stream_read (header->mstream, blurb, mstream_size, NULL);
-             status = header_parse (header, blurb, mstream_size);
-           }
-         free (blurb);
-         mu_stream_destroy (&header->mstream);
+         rc = mu_memory_stream_create (&header->mstream, MU_STREAM_RDWR);
+         if (rc)
+           return rc;
        }
+      mu_stream_seek (header->mstream, 0, MU_SEEK_SET, NULL);
+      if (header->spool_used)
+       {
+         for (ent = header->head; ent; ent = ent->next)
+           mu_hdrent_fixup (header, ent);
+         rc = mu_stream_write (header->mstream, header->spool,
+                               header->spool_used, NULL);
+         for (ent = header->head; ent; ent = ent->next)
+           mu_hdrent_unroll_fixup (header, ent);
+         if (rc)
+           return rc;
+         mu_stream_truncate (header->mstream, header->spool_used);
+         if (hstr->off > header->spool_used)
+           hstr->off = header->spool_used;
+       }
+      header->flags |= HEADER_STREAMMOD;
     }
+
+  rc = mu_stream_seek (header->mstream, hstr->off, MU_SEEK_SET, NULL);
+  if (rc)
+    return rc;
   
-  if (pnwrite)
-    *pnwrite = buflen;
-  
-  return status;
+  return mu_stream_write (header->mstream, buf, buflen, pnwrite);
 }
 
 static int


hooks/post-receive
-- 
GNU Mailutils



reply via email to

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