diff options
author | Christian Neukirchen <chneukirchen@gmail.com> | 2016-07-14 15:21:37 +0200 |
---|---|---|
committer | Christian Neukirchen <chneukirchen@gmail.com> | 2016-07-14 15:21:37 +0200 |
commit | f101b728d9315f430d900df1e4afbb2da4da8252 (patch) | |
tree | 1b7164a23bac978f4d56529ca311b704b19b7477 /blaze822.c | |
parent | 13eefbba7234ad1596e6d308d41846daa9d31594 (diff) | |
download | mblaze-f101b728d9315f430d900df1e4afbb2da4da8252.tar.gz mblaze-f101b728d9315f430d900df1e4afbb2da4da8252.tar.xz mblaze-f101b728d9315f430d900df1e4afbb2da4da8252.zip |
blaze822: add mmap-based mail reader
Diffstat (limited to 'blaze822.c')
-rw-r--r-- | blaze822.c | 57 |
1 files changed, 54 insertions, 3 deletions
diff --git a/blaze822.c b/blaze822.c index 7794301..53fc2e4 100644 --- a/blaze822.c +++ b/blaze822.c @@ -6,6 +6,7 @@ #include <stdint.h> #include <sys/types.h> #include <sys/stat.h> +#include <sys/mman.h> #include <fcntl.h> #include <unistd.h> #include <ctype.h> @@ -364,7 +365,6 @@ blaze822(char *file) return mesg; } - struct message * blaze822_mem(char *src, size_t len) { @@ -411,8 +411,12 @@ blaze822_free(struct message *mesg) { if (!mesg) return; - free(mesg->msg); - free(mesg->bodychunk); + if (mesg->bodychunk == mesg->msg) { + munmap(mesg->bodychunk, mesg->bodyend - mesg->msg); + } else { + free(mesg->msg); + free(mesg->bodychunk); + } free(mesg); } @@ -495,6 +499,53 @@ error: return 0; } +struct message * +blaze822_mmap(char *file) +{ + int fd = open(file, O_RDONLY); + if (fd < 0) + return 0; + + struct stat st; + if (fstat(fd, &st) < 0) + goto error; + + size_t len = st.st_size; + + struct message *mesg = malloc(sizeof (struct message)); + if (!mesg) + goto error; + + char *buf = mmap(0, len+1, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + if (buf == MAP_FAILED) { + perror("mmap"); + goto error; + } + close(fd); + + char *end; + if ((end = memmem(buf, len, "\n\n", 2))) { + mesg->body = end+2; + } else if ((end = memmem(buf, len, "\r\n\r\n", 4))) { + mesg->body = end+4; + } else { + end = buf + len; + mesg->body = end; + } + + unfold_hdr(buf, end); + + mesg->msg = mesg->bodychunk = buf; + mesg->end = end; + mesg->bodyend = buf + len; + + return mesg; + +error: + close(fd); + return 0; +} + char * blaze822_body(struct message *mesg) { |