From f101b728d9315f430d900df1e4afbb2da4da8252 Mon Sep 17 00:00:00 2001 From: Christian Neukirchen Date: Thu, 14 Jul 2016 15:21:37 +0200 Subject: blaze822: add mmap-based mail reader --- blaze822.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++--- blaze822.h | 3 ++- 2 files changed, 56 insertions(+), 4 deletions(-) diff --git a/blaze822.c b/blaze822.c index 7794301..53fc2e4 100644 --- a/blaze822.c +++ b/blaze822.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -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) { diff --git a/blaze822.h b/blaze822.h index a969aaa..7626ca2 100644 --- a/blaze822.h +++ b/blaze822.h @@ -6,7 +6,8 @@ struct message; // blaze822.c struct message *blaze822(char *file); // just header -struct message *blaze822_file(char *file); // header + body +struct message *blaze822_file(char *file); // header + body (read(2)) +struct message *blaze822_mmap(char *file); // header + body (mmap(2)) struct message *blaze822_mem(char *buf, size_t len); // header + body char *blaze822_hdr_(struct message *mesg, const char *hdr, size_t len); -- cgit 1.4.1