From: Martin Mares Date: Fri, 19 Nov 2010 12:18:53 +0000 (+0100) Subject: Added a very primitive mailbox parser X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=926700467bf0e7203be3e08a52be922889180cc0;hp=6cee6073073b0098fe861bf36c0bcbd8e2c3f359;p=maildups.git Added a very primitive mailbox parser So far, it only extracts headers of all messages. --- diff --git a/Makefile b/Makefile index 16548e9..51e0144 100644 --- a/Makefile +++ b/Makefile @@ -2,19 +2,21 @@ CFLAGS=-O2 -Wall -W -Wno-parentheses -Wstrict-prototypes -Wmissing-prototypes -Winline $(DEBUG) -std=gnu99 -DVERSION=$(VERSION) -DYEAR=$(YEAR) VERSION=1.0 -YEAR=2009 +YEAR=2010 -all: mdup smail mrate +all: mdup smail mrate mparse mdup: mdup.o util.o sha1.o smail: smail.o util.o mrate: mrate.o util.o +mparse: mparse.o util.o mdup.o: mdup.c util.h smail.o: smail.c util.h mrate.o: mrate.c util.h util.o: util.c util.h sha1.o: sha1.c util.h +mparse.o: mparse.c util.h clean: rm -f `find . -name "*~" -or -name "*.[oa]" -or -name "\#*\#" -or -name TAGS -or -name core` diff --git a/mparse.c b/mparse.c new file mode 100644 index 0000000..9c31851 --- /dev/null +++ b/mparse.c @@ -0,0 +1,115 @@ +/* + * Mailbox Parser (so far very primitive) + * + * (c) 2010 Martin Mares + */ + +#include +#include +#include +#include + +#include "util.h" + +const char progname[] = "mparse"; + +#define BUFSIZE 65536 + +static char buf[BUFSIZE]; +static char *bpos=buf, *bend=buf; + +static char *getline(void) +{ + if (!bpos) + return NULL; + + for (;;) + { + int remains = bend - bpos; + if (remains) + { + char *nl = memchr(bpos, '\n', remains); + if (nl) + { + char *p = bpos; + if (nl > p && nl[-1] == '\r') + nl[-1] = 0; + *nl++ = 0; + bpos = nl; + return p; + } + memmove(buf, bpos, remains); + } + bpos = buf; + bend = buf + remains; + + int space = BUFSIZE - remains; + if (!space) + die("Line too long"); + int len = read(0, bend, space); + if (len < 0) + die("Read error: %m"); + if (!len) + { + bpos = NULL; + if (bend > buf) + { + *bend = 0; + return buf; + } + return NULL; + } + bend = bend + len; + } +} + +enum state { + S_INITIAL, + S_HEADER, + S_BODY, +}; + +int +main(int argc UNUSED, char **argv UNUSED) +{ + char *c; + enum state state = S_INITIAL; + + while (c = getline()) + { + // printf("<%s>\n", c); + if (state == S_INITIAL || state == S_BODY) + { + if (!strncmp(c, "From ", 5)) + { + state = S_HEADER; + fputs(c, stdout); + } + } + else + { + if (!*c) + { + puts("\n"); + state = S_BODY; + } + else if (*c == ' ' || *c == '\t') + { + while (*c == ' ' || *c == '\t') + c++; + putchar(' '); + fputs(c, stdout); + } + else + { + putchar('\n'); + fputs(c, stdout); + } + } + } + + if (state == S_HEADER) + printf("\nX-Warning: Incomplete mail\n\n"); + + return 0; +}