Don't report about a new mail when there hasn't been one, i.e. if only
[infodrom/newmail] / mbox.c
diff --git a/mbox.c b/mbox.c
index 0e69ecd..ecb0c54 100644 (file)
--- a/mbox.c
+++ b/mbox.c
@@ -35,14 +35,16 @@ struct mail {
   off_t size;
 };
 
-#define HDR_LEN        128
+#define HDR_LEN        1024
+#define TAB    0x09
+#define LWSP   0x20
 
 /*
  * Like strncpy() but with terminated result.
  */
 char *stringcopy(char *dest, const char *src, size_t n)
 {
-  strncpy(dest, src, n-1);
+  strncpy (dest, src, n-1);
   dest[n-1] = '\0';
   return dest;
 }
@@ -98,36 +100,53 @@ char *realname(char *from)
     if (*cpl == '"' && *cpr == '"') { cpl++;cpr--; }
 
     if (cpr > cpl) {
-      stringcopy(name, cpl,
-                sizeof(name) < cpr-cpl+2?sizeof(name):cpr-cpl+2);
+      stringcopy (name, cpl,
+                 sizeof(name) < cpr-cpl+2?sizeof(name):cpr-cpl+2);
 
       if (index(name, '"') != NULL)
-       stringcopy(name, strip_quotes(name), sizeof(name));
+       stringcopy (name, strip_quotes(name), sizeof(name));
     } else {
       /* Apparently no realname included */
       cpl = index(from, '<');
       cpr = index(from, '>');
-      stringcopy(name, cpl+1,
-                sizeof(name) < cpr-cpl?sizeof(name):cpr-cpl);
+      stringcopy (name, cpl+1,
+                 sizeof(name) < cpr-cpl?sizeof(name):cpr-cpl);
     }
 
   /* From: login@host.domain (REALNAME) */
   } else if ((cpl = index(from, '(')) != NULL && (cpr = index(from, ')')) != NULL) {
-    stringcopy(name, cpl+1,
-              sizeof(name) < cpr-cpl?sizeof(name):cpr-cpl);
+    stringcopy (name, cpl+1,
+               sizeof(name) < cpr-cpl?sizeof(name):cpr-cpl);
 
   /* From: login@host.domain */
   } else {
     /* Strip leading spaces */
     cpl=from;while (*cpl && isspace(*cpl)) cpl++;
     for (cpr=cpl; *cpr && !isspace(*cpr); cpr++);
-    stringcopy(name, cpl,
-              sizeof(name) < cpr-cpl+1?sizeof(name):cpr-cpl+1);
+    stringcopy (name, cpl,
+               sizeof(name) < cpr-cpl+1?sizeof(name):cpr-cpl+1);
   }
 
   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;
@@ -135,7 +154,9 @@ int inspect_mbox(char *path, char *prefix, off_t size, int opt_flags)
   char tmp[512];
   char *cp;
   int inheader = 1;
+  int readnewline = 0;
   int newmail = 0;
+  int lookahead;
 
   char from_[HDR_LEN] = "";
   char from[HDR_LEN] = "";
@@ -157,7 +178,36 @@ 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 || lookahead == LWSP) {
+         if (buf[strlen(buf)-1] != LWSP)
+           strncat (buf, " ", sizeof(buf)-strlen(buf)-1);
+         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;
@@ -170,13 +220,14 @@ int inspect_mbox(char *path, char *prefix, off_t size, int opt_flags)
        newmail = 1;
 
        if (strlen(from))
-         stringcopy(realfrom, realname(from), sizeof(realfrom));
-#ifdef todo
+         stringcopy (realfrom, realname(from), sizeof(realfrom));
+       else if (strlen(from_))
+         stringcopy (realfrom, reduce_from_(from_), sizeof(realfrom));
        else
-         stringcopy(realfrom, reduce_from_(from_), sizeof(realfrom));
-#endif
+         realfrom[0] = '\0';
 
-       emit(prefix, realfrom, subject, priority, opt_flags);
+       if (realfrom[0] != '\0')
+         emit (prefix, realfrom, subject, priority, opt_flags);
 
 #ifdef FROM_DETECTION
        from_[0] = from[0] = to[0] = subject[0] = '\0';
@@ -186,24 +237,28 @@ int inspect_mbox(char *path, char *prefix, off_t size, int opt_flags)
        priority = 0;
       } else {
        if (strncasecmp(buf, "From ", 5) == 0)
-         stringcopy(from_, buf+5, sizeof(from_));
+         stringcopy (from_, buf+5, sizeof(from_));
        else if (strncasecmp(buf, "From: ", 6) == 0)
-         stringcopy(from, buf+6, sizeof(from));
+         stringcopy (from, buf+6, sizeof(from));
 #ifdef FROM_DETECTION
        else if (strncasecmp(buf, "To: ", 4) == 0)
-         stringcopy(to, buf+4, sizeof(to));
+         stringcopy (to, buf+4, sizeof(to));
 #endif
        else if (strncasecmp(buf, "Subject: ", 9) == 0)
-         stringcopy(subject, buf+9, sizeof(subject));
+         stringcopy (subject, buf+9, sizeof(subject));
        else if (strncasecmp(buf, "Priority: urgent", 16) == 0 && buf[16] == '\0')
          priority = 1;
        else if (strncasecmp(buf, "X-Priority: 1", 13) == 0 && buf[13] == '\0')
          priority = 1;
       }
-    } else if (strncasecmp(buf, "From ", 5) == 0) {
+    } else if (strlen(buf) == 0) {
+      readnewline = 1;
+    } else if (readnewline && strncasecmp(buf, "From ", 5) == 0) {
       inheader = 1;
-      stringcopy(from_, buf+5, sizeof(from_));
-    }
+      readnewline = 0;
+      stringcopy (from_, buf+5, sizeof(from_));
+    } else
+      readnewline = 0;
   }
 
   fclose(f);