Added support for multi-line header lines
[infodrom/newmail] / mbox.c
diff --git a/mbox.c b/mbox.c
index 15887f7..a15b9e2 100644 (file)
--- a/mbox.c
+++ b/mbox.c
@@ -36,6 +36,7 @@ struct mail {
 };
 
 #define HDR_LEN        128
+#define TAB    0x09
 
 /*
  * Like strncpy() but with terminated result.
@@ -128,6 +129,23 @@ char *realname(char *from)
   return name;
 }
 
+/*
+ * Tries to extract useful content from the From_ line
+ */
+char *reduce_from_(char *from_)
+{
+  static char name[HDR_LEN];
+  char *cpl, *cpr;
+
+  for (cpl=from_; *cpl &&  isspace(*cpl); cpl++);
+  for (cpr=cpl;   *cpr && !isspace(*cpr); cpr++);
+
+  if (cpr > cpl)
+    stringcopy(name, cpl, 
+              sizeof(name) < cpr-cpl+1?sizeof(name):cpr-cpl+1);
+  return name;
+}
+
 int inspect_mbox(char *path, char *prefix, off_t size, int opt_flags)
 {
   FILE *f;
@@ -137,6 +155,7 @@ int inspect_mbox(char *path, char *prefix, off_t size, int opt_flags)
   int inheader = 1;
   int readnewline = 0;
   int newmail = 0;
+  int lookahead;
 
   char from_[HDR_LEN] = "";
   char from[HDR_LEN] = "";
@@ -158,7 +177,34 @@ int inspect_mbox(char *path, char *prefix, off_t size, int opt_flags)
       continue;
     if (strlen(buf) > 0 && buf[strlen(buf)-1] == '\n') {
       buf[strlen(buf)-1] = '\0';
+      if (strlen(buf) > 0 && buf[strlen(buf)-1] == '\r')
+       buf[strlen(buf)-1] = '\0';
+
+      if (inheader && !feof(f)) {
+       lookahead = fgetc(f);
+       if (lookahead == TAB) {
+         if ((cp = fgets(tmp, sizeof(tmp), f)) != NULL) {
+           strncat(buf, tmp, sizeof(buf)-strlen(buf)-1);
+           if (strlen(buf) > 0 && buf[strlen(buf)-1] == '\n')
+             buf[strlen(buf)-1] = '\0';
+           if (strlen(buf) > 0 && buf[strlen(buf)-1] == '\r')
+             buf[strlen(buf)-1] = '\0';
+
+           if (strlen(tmp) > 0 && buf[strlen(tmp)-1] == '\n') {
+             /* Read the remainder */
+             while (!feof(f) && fgets(tmp, sizeof(tmp), f) != NULL) {
+               if (strlen(tmp) > 0 && tmp[strlen(tmp)-1] == '\n')
+                 break;
+             }
+           }
+         }
+       } else
+         /* Rewind by one character for next read */
+         if (lookahead != EOF)
+           fseek(f, -1, SEEK_CUR);
+      }
     } else {
+      /* Read the remainder */
       while (!feof(f) && fgets(tmp, sizeof(tmp), f) != NULL) {
        if (strlen(tmp) > 0 && tmp[strlen(tmp)-1] == '\n')
          break;
@@ -172,10 +218,8 @@ int inspect_mbox(char *path, char *prefix, off_t size, int opt_flags)
 
        if (strlen(from))
          stringcopy(realfrom, realname(from), sizeof(realfrom));
-#ifdef todo
        else
          stringcopy(realfrom, reduce_from_(from_), sizeof(realfrom));
-#endif
 
        emit(prefix, realfrom, subject, priority, opt_flags);