]> mj.ucw.cz Git - maildups.git/commitdiff
Added a very primitive mailbox parser
authorMartin Mares <mj@ucw.cz>
Fri, 19 Nov 2010 12:18:53 +0000 (13:18 +0100)
committerMartin Mares <mj@ucw.cz>
Fri, 19 Nov 2010 12:18:53 +0000 (13:18 +0100)
So far, it only extracts headers of all messages.

Makefile
mparse.c [new file with mode: 0644]

index 16548e9d8aca2f69b5734fe7ee3422b4473e0aa3..51e0144664ca1db237b5be26b8ec9355a210f0bf 100644 (file)
--- 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 (file)
index 0000000..9c31851
--- /dev/null
+++ b/mparse.c
@@ -0,0 +1,115 @@
+/*
+ *     Mailbox Parser (so far very primitive)
+ *
+ *     (c) 2010 Martin Mares <mj@ucw.cz>
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#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;
+}