From cbd76c30acf7d90b38ca03be0bbfcbd118daf561 Mon Sep 17 00:00:00 2001
From: "Bernhard R. Link" <brlink@debian.org>
Date: Sat, 19 Dec 2009 13:03:49 +0100
Subject: Add header parsing code to replace the non-free one removed

---
 Makefile.in |   3 +-
 headers.c   | 248 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 xbuffy.c    |  26 +++----
 xbuffy.h    |   4 +-
 4 files changed, 265 insertions(+), 16 deletions(-)
 create mode 100644 headers.c

diff --git a/Makefile.in b/Makefile.in
index 63420cc..a639526 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -24,8 +24,7 @@ LDFLAGS=@LDFLAGS@
 LIBS=@LIBS@
 
 LIBDYN = $(srcdir)/libdyn/libdyn.a
-OBJS = xbuffy.o boxfile.o realfrom.o getword.o len_next.o move_left.o \
-       remfirstwd.o header_cmp.o @NNTP_OBJS@
+OBJS = xbuffy.o boxfile.o headers.o @NNTP_OBJS@
 DOC = README xbuffy.man boxfile.fmt boxfile.sample
 DEFAULTS = XBuffy.ad
 HDRS = xbuffy.h xbuffy.xbm
diff --git a/headers.c b/headers.c
new file mode 100644
index 0000000..b443dfb
--- /dev/null
+++ b/headers.c
@@ -0,0 +1,248 @@
+/*******************************************************************************
+
+     Copyright (c) 2006     Bernhard R. Link <brlink@debian.org>
+
+     The X Consortium, and any party obtaining a copy of these files,
+     directly or indirectly, is granted, free of charge, a
+     full and unrestricted irrevocable, world-wide, paid up, royalty-free,
+     nonexclusive right and license to deal in this software and
+     documentation files (the "Software"), including without limitation the
+     rights to use, copy, modify, merge, publish, distribute, sublicense,
+     and/or sell copies of the Software, and to permit persons who receive
+     copies from any such party to do so.
+
+     This  program  is  distributed  in  the hope that it will be useful, but
+     WITHOUT   ANY   WARRANTY;   without   even  the   implied   warranty  of
+     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+*******************************************************************************/
+/* mail header handling stuff */
+
+#include <ctype.h>
+#include <string.h>
+#include <strings.h>
+
+#include <xbuffy.h>
+
+int cmp_header(const char *buffer, const char *header) {
+	size_t len = strlen(header);
+
+	return strncasecmp(buffer, header, len) == 0
+		&& buffer[len] == ':';
+}
+
+int cmp_header_get(const char *buffer, const char *header, const char **p) {
+	size_t len = strlen(header);
+
+	if (strncasecmp(buffer, header, len) == 0
+			&& buffer[len] == ':') {
+		buffer += len;
+		do {
+			buffer++;
+			while (*buffer == ' ' || *buffer == '\t' ) {
+				buffer++;
+			}
+		} while ( *buffer == '\n' &&
+				(buffer[1] == ' ' || buffer[1] == '\t'));
+		*p = buffer;
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+int proper_mailstart(const char *buffer) {
+	char word[4]; int wordlen;
+
+#define FROM "From"
+	if (strncmp(buffer,FROM,sizeof(FROM)-1) != 0)
+		return 0;
+	buffer += sizeof(FROM)-1;
+	if (buffer[0] != ' ')
+		return 0;
+	while (*buffer && isspace(*buffer))
+		buffer++;
+	/* over from address */
+	while (*buffer && !isspace(*buffer)) {
+		if (*buffer == '\\') {
+			buffer++;
+			if (*buffer == '\0' )
+				return 0;
+			buffer++;
+		}
+		if (*buffer == '"') {
+			while (*buffer != '"') {
+				if (*buffer == '\\')
+					buffer++;
+				if (*buffer == '\0')
+					return 0;
+				buffer++;
+			}
+		}
+		buffer++;
+	}
+	if (*buffer == '\0')
+		return 0;
+	while (*buffer && isspace(*buffer))
+		buffer++;
+	/* weekday */
+	wordlen = 0;
+	while (*buffer && !isspace(*buffer)) {
+		if (*buffer == '\\') {
+			buffer++;
+			if (*buffer == '\0' )
+				return 0;
+			if (wordlen < 3)
+				word[wordlen++] = tolower(*buffer);
+			buffer++;
+		}
+		if (*buffer == '"') {
+			while (*buffer != '"') {
+				if (*buffer == '\\')
+					buffer++;
+				if (*buffer == '\0')
+					return 0;
+				if (wordlen < 3)
+					word[wordlen++] = tolower(*buffer);
+				buffer++;
+			}
+		} else {
+			if (wordlen < 3)
+				word[wordlen++] = tolower(*buffer);
+		}
+		buffer++;
+	}
+	if (*buffer == '\0')
+		return 0;
+	while (*buffer && isspace(*buffer))
+		buffer++;
+	word[wordlen] = '\0';
+	switch (word[0]) {
+		case 'f':
+			if (word[1] != 'r' || word[2] != 'i')
+				return 0;
+			break;
+		case 'm':
+			if (word[1] != 'o' || word[2] != 'n')
+				return 0;
+			break;
+		case 's':
+			if ((word[1] != 'u' || word[2] != 'n')
+			   &&(word[1] != 'a' || word[2] != 't'))
+				return 0;
+			break;
+		case 't':
+			if ((word[1] != 'u' || word[2] != 'e')
+			   &&(word[1] != 'h' || word[2] != 'u'))
+				return 0;
+			break;
+		case 'w':
+			if (word[1] != 'e' || word[2] != 'd')
+				return 0;
+			break;
+		default:
+			return 0;
+	}
+	/* month */
+	wordlen = 0;
+	while (*buffer && !isspace(*buffer)) {
+		if (*buffer == '\\') {
+			buffer++;
+			if (*buffer == '\0' )
+				return 0;
+			if (wordlen < 3)
+				word[wordlen++] = tolower(*buffer);
+			buffer++;
+		}
+		if (*buffer == '"') {
+			while (*buffer != '"') {
+				if (*buffer == '\\')
+					buffer++;
+				if (*buffer == '\0')
+					return 0;
+				if (wordlen < 3)
+					word[wordlen++] = tolower(*buffer);
+				buffer++;
+			}
+		} else {
+			if (wordlen < 3)
+				word[wordlen++] = tolower(*buffer);
+		}
+		buffer++;
+	}
+	if (*buffer == '\0')
+		return 0;
+	while (*buffer && isspace(*buffer))
+		buffer++;
+	word[wordlen] = '\0';
+	switch (word[0]) {
+		case 'a':
+			if ((word[1] != 'p' || word[2] != 'r')
+			   &&(word[1] != 'u' || word[2] != 'g'))
+				return 0;
+			break;
+		case 'd':
+			if (word[1] != 'e' || word[2] != 'c')
+				return 0;
+			break;
+		case 'f':
+			if (word[1] != 'e' || word[2] != 'b')
+				return 0;
+			break;
+		case 'j':
+			if ((word[1] != 'a' || word[2] != 'n')
+			   &&(word[1] != 'u' ||
+				   (word[2] != 'n' && word[2] !='l')))
+				return 0;
+			break;
+		case 'm':
+			if (word[1] != 'a' ||
+				(word[2] != 'r' && word[2] != 'y'))
+				return 0;
+			break;
+		case 'n':
+			if (word[1] != 'o' || word[2] != 'v')
+				return 0;
+			break;
+		case 'o':
+			if (word[1] != 'c' || word[2] != 't')
+				return 0;
+			break;
+		case 's':
+			if (word[1] != 'e' || word[2] != 'p')
+				return 0;
+			break;
+		default:
+			return 0;
+	}
+
+	/* day of month*/
+	wordlen = 0;
+	while (*buffer && !isspace(*buffer)) {
+		if (*buffer == '\\') {
+			buffer++;
+			if (*buffer < '0' || *buffer > '9')
+				return 0;
+			wordlen = wordlen*10+((*buffer)-'0');
+			buffer++;
+		}
+		if (*buffer == '"') {
+			while (*buffer != '"') {
+				if (*buffer == '\\')
+					buffer++;
+				if (*buffer < '0' || *buffer > '9')
+					return 0;
+				wordlen = wordlen*10+((*buffer)-'0');
+				buffer++;
+			}
+		} else {
+			if (*buffer < '0' || *buffer > '9')
+				return 0;
+			wordlen = wordlen*10+((*buffer)-'0');
+		}
+		buffer++;
+	}
+	if (wordlen == 0 || wordlen > 31)
+		return 0;
+	return 1;
+}
diff --git a/xbuffy.c b/xbuffy.c
index 29c5f78..abf18a1 100644
--- a/xbuffy.c
+++ b/xbuffy.c
@@ -719,6 +719,7 @@ int CountMBoxMail(mailBox, headerString)
 {
     FILE *fp = 0;
     char buffer[MAX_STRING];
+    const char *p;
     char From[MAX_STRING], Subject[MAX_STRING];
     register int count = 0;
     int status = UNKNOWN;
@@ -744,7 +745,7 @@ int CountMBoxMail(mailBox, headerString)
             while ((c = getc(fp)) != EOF && c != '\n'); /* keep reading */
         }
 
-        if ((!in_header) && (real_from(buffer)))
+        if ((!in_header) && (proper_mailstart(buffer)))
         {
 	    has_CL = FALSE;
             in_header = TRUE;
@@ -752,27 +753,26 @@ int CountMBoxMail(mailBox, headerString)
         }
         else if (in_header)
         {
-            if (header_cmp(buffer, "From", NULL))
+            if (cmp_header(buffer, "From"))
             {
                 strcpy(From, buffer);
             }
 
 	   
-	   if (header_cmp(buffer, "Content-Length", NULL))
+	   if (cmp_header_get(buffer, "Content-Length", &p))
 	   {
 	      has_CL = TRUE;
-	      CL = atol(buffer+15);
+	      CL = atol(p);
 	   }
 
-            if (header_cmp(buffer, "Subject", NULL))
+            if (cmp_header(buffer, "Subject"))
             {
                 strcpy(Subject, buffer);
             }
 
-            if (header_cmp(buffer, "Status", NULL))
+            if (cmp_header_get(buffer, "Status", &p))
             {
-                remove_header_keyword(buffer);
-                if (*buffer == 'N')
+                if (*p == 'N')
                     status = NEW_MSG;
                 else
                     status = READ_MSG;
@@ -814,6 +814,7 @@ int CountDirMail(mailBox, headerString)
     DIR *dp = 0;
     FILE *fp = 0;
     char buffer[MAX_STRING];
+    const char *p;
     char From[MAX_STRING], Subject[MAX_STRING];
     char path[_POSIX_PATH_MAX];
     int status;
@@ -872,20 +873,19 @@ int CountDirMail(mailBox, headerString)
 		while ((c = getc(fp)) != EOF && c != '\n'); /* keep reading */
 	      }
 	      if (headerString != NULL && 
-		  header_cmp(buffer, "From", NULL))
+		  cmp_header(buffer, "From"))
 	      {
 		strcpy(From, buffer);
 	      } 
 	      else if (headerString != NULL && 
-		       header_cmp(buffer, "Subject", NULL))
+		       cmp_header(buffer, "Subject"))
 	      {
 		strcpy(Subject, buffer);
 	      } 
 	      else if (mailBox->type == MHDIR && 
-                       header_cmp(buffer, "Status", NULL))
+                       cmp_header_get(buffer, "Status", &p))
 	      {
-		remove_header_keyword(buffer);
-		if (*buffer == 'N')
+		if (*p == 'N')
 		  status = NEW_MSG;
 		else
 		  status = READ_MSG;
diff --git a/xbuffy.h b/xbuffy.h
index 406df0f..e831240 100644
--- a/xbuffy.h
+++ b/xbuffy.h
@@ -127,5 +127,7 @@ typedef struct ApplicationData_s ApplicationData_t;
 #define NEWstrlen(s) (s == NULL ? 0 : strlen(s))
 #define NEWstrdup(s) (s == NULL ? NULL : strdup(s))
 
-extern char *header_cmp();
+int cmp_header(const char *, const char *);
+int cmp_header_get(const char *buffer, const char *header, const char **p);
+int proper_mailstart(const char *);
 #endif /* _XBUFFY_H_ */
