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");
}
}