<<< Date Index >>>     <<< Thread Index >>>

Re: mairix + gziped mboxesa patch



Hi Ton, the patch is attached.
some info:
- mairix will "auto-detect" gziped mailbox by its ".gz" extension. I
  will improve it latter.
- mailboxes are uncompressed to _memory_, its faster a more secure but
  of course may require lots of memory if you have huge mailboxes.
- memory is allocated in 5MB blocks, if you want you can change it by
  modifying the line that says: 'size_t buf_size = 5 * 1024 * 1024;'
- I experienced some "segfaults" with mairix, they are unrelated to the
  patch, but I'll try to fix them.

bye

Ton Boelens writes:
> On Tue, Apr 05, 2005 at 11:57:59PM -0300, Felipe Gustavo de Almeida wrote:
> > Hi,
> > I've wrote a patch to mairix so it can open gzipped mboxes. If
> > anyone here have interest in this patch please let me know.

> > I'm using it to index/search archived old mail (using mutt 
> > "compressed-patch")

> Felipe,

> I use Mairix and Mutt and I like it very much. I also use archivemail
> to export old messages to zipped mailboxes. So, I am interested in
> your patch.

> I have tried to send you a direct email, but I got a NDR, that's
> why I react through this list.

> Kind regards,


> -- 
> /ton
> http://www.tonboelens.nl

-- 
bombing for peace is like fucking for virginity
diff -aur mairix-0.15.2/rfc822.c mairix-0.15.2-gzip/rfc822.c
--- mairix-0.15.2/rfc822.c      Thu Feb  3 19:52:02 2005
+++ mairix-0.15.2-gzip/rfc822.c Fri Apr 15 07:07:42 2005
@@ -30,6 +30,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <sys/mman.h>
+#include <zlib.h>
 
 
 struct DLL {/*{{{*/
@@ -923,11 +924,21 @@
   return result;
   
 }
+
+/*}}}*/
+int is_gzip(const char *filename) {/*{{{*/
+    size_t len = strlen(filename);
+    int ptr = len - 3;
+    if (len > 3 && strncasecmp(&filename[ptr], ".gz", 3) == 0) {
+        return 1;
+    } else {
+        return 0;
+    }
+}
 /*}}}*/
 void create_ro_mapping(const char *filename, unsigned char **data, int 
*len)/*{{{*/
 {
   struct stat sb;
-  int fd;
   if (stat(filename, &sb) < 0) 
   {
     perror("Could not stat");
@@ -946,23 +957,51 @@
     return;
   }
 
-  fd = open(filename, O_RDONLY);
-  if (fd < 0)
-  {
-    perror("Could not open");
-    *data = NULL;
-    return;
-  }
+  if (is_gzip(filename)) {
+    gzFile *fd;
+    size_t buf_size = 5 * 1024 * 1024;
+
+    fd = gzopen(filename, "rb");
+    if (fd < 0)
+    {
+        perror("Could not open");
+        *data = NULL;
+        return;
+    }
+    *data = malloc(buf_size);
+    *len = gzread(fd, *data, buf_size);
+    if (*len >= buf_size) {
+        int read = 0;
+        do {
+            *data = realloc(*data, *len + buf_size);
+            *len += read = gzread(fd, *data + *len, buf_size);
+        } while (read > 0);
+    }
+    *data = realloc(*data, *len);
 
-  *data = (char *) mmap(0, *len, PROT_READ, MAP_SHARED, fd, 0);
-  if (close(fd) < 0)
-    perror("close");
-  if (*data == MAP_FAILED) {
-    perror("mmap");
-    *data = NULL;
-    return;
+    if (gzclose(fd) < 0)
+        perror("close");
+  } else {
+    int fd;
+    fd = open(filename, O_RDONLY);
+    if (fd < 0)
+    {
+        perror("Could not open");
+        *data = NULL;
+        return;
+    }
+
+    *data = (char *) mmap(0, *len, PROT_READ, MAP_SHARED, fd, 0);
+    if (close(fd) < 0)
+        perror("close");
+    if (*data == MAP_FAILED) {
+        perror("mmap");
+        *data = NULL;
+        return;
+    }
   }
 }
+
 /*}}}*/
 struct rfc822 *make_rfc822(char *filename)/*{{{*/
 {
@@ -980,8 +1019,10 @@
   /* Now process the data */
     result = data_to_rfc822(data, len);
 
-    if (munmap(data, (size_t) len) < 0) {
-      perror("Could not munmap");
+    if (is_gzip(filename)) {
+        free(data);
+    } else if (munmap(data, (size_t) len) < 0) {
+        perror("Could not munmap");
     }
   }