$OpenBSD: patch-src_procmime_c,v 1.11 2015/01/14 12:18:43 landry Exp $
http://www.thewildbeast.co.uk/claws-mail/bugzilla/show_bug.cgi?id=2640
http://www.thewildbeast.co.uk/claws-mail/bugzilla/show_bug.cgi?id=2641
http://www.thewildbeast.co.uk/claws-mail/bugzilla/show_bug.cgi?id=2642
http://www.thewildbeast.co.uk/claws-mail/bugzilla/show_bug.cgi?id=2743
--- src/procmime.c.orig	Mon Oct 27 19:58:13 2014
+++ src/procmime.c	Mon Jan 12 23:00:15 2015
@@ -634,10 +634,22 @@ gboolean procmime_encode_content(MimeInfo *mimeinfo, E
 			g_free(tmp_file);
 		}
 	} else if (encoding == ENC_QUOTED_PRINTABLE) {
-		gchar inbuf[BUFFSIZE], outbuf[BUFFSIZE * 4];
+		gchar inbuf[79], outbuf[77];
+		gint n, len = 0;
+		gboolean firstrun = TRUE;
 
-		while (SC_FGETS(inbuf, sizeof(inbuf), infp) != NULL) {
-			qp_encode_line(outbuf, inbuf);
+		while ((len += fread(inbuf + len, 1,
+			sizeof(inbuf) - len - 1,
+			infp)) > 0)
+		{
+			if (firstrun == FALSE)
+				if (fputs("\r\n", outfp) == EOF)
+					err = TRUE;
+			inbuf[len] = '\0';
+			n = qp_encode(mimeinfo->type == MIMETYPE_TEXT,
+					outbuf, inbuf, len);
+			len -= n;
+			memmove(inbuf, inbuf + n, len);
 
 			if (!strncmp("From ", outbuf, sizeof("From ")-1)) {
 				gchar *tmpbuf = outbuf;
@@ -652,14 +664,39 @@ gboolean procmime_encode_content(MimeInfo *mimeinfo, E
 				if (SC_FPUTS(outbuf, outfp) == EOF)
 					err = TRUE;
 			}
+			firstrun = FALSE;
 		}
 	} else {
-		gchar buf[BUFFSIZE];
+		gchar buf[MAXSMTPTEXTLEN+1];
+		gint leftover = 0;
 
-		while (SC_FGETS(buf, sizeof(buf), infp) != NULL) {
-			strcrchomp(buf);
-			if (SC_FPUTS(buf, outfp) == EOF)
+		while (fgets(buf + leftover,
+				sizeof(buf) - leftover,
+				infp) != NULL)
+		{
+			gchar *l, *c = buf;
+			leftover = 0;
+
+			while (*c != '\0') {
+				if (
+					*c == '\n'
+					|| (*c == '\r' && *(c+1) == '\n'))
+				{
+					*c = '\0';
+					break;
+				}
+				c++;
+			}
+			while (c - buf > MAXSMTPTEXTLEN - 2) {
+				*c = *(c-1);
+				*--c = '\0';
+				leftover++;
+			}
+			if (fputs(buf, outfp) == EOF || putc('\n', outfp) == EOF)
+
 				err = TRUE;
+			for (l = buf; l-buf < leftover; l++)
+				*l = *++c;
 		}
 	}
 
@@ -1203,7 +1240,7 @@ GList *procmime_get_mime_type_list(void)
 #endif
 	{
 		fp_is_glob_file = FALSE;
-		if ((fp = procmime_fopen("/etc/mime.types", "rb")) == NULL) {
+		if ((fp = procmime_fopen("/var/www/conf/mime.types", "rb")) == NULL) {
 			if ((fp = procmime_fopen(SYSCONFDIR "/mime.types", "rb")) 
 				== NULL) {
 				FILE_OP_ERROR(SYSCONFDIR "/mime.types", 
@@ -1283,11 +1320,12 @@ EncodingType procmime_get_encoding_for_text_file(const
 {
 	FILE *fp;
 	guchar buf[BUFFSIZE];
+	gboolean cr = FALSE;
 	size_t len;
+	gint linelen = 0, maxlinelen = 0;
 	size_t octet_chars = 0;
 	size_t total_len = 0;
 	gfloat octet_percentage;
-	gboolean force_b64 = FALSE;
 
 	if ((fp = procmime_fopen(file, "rb")) == NULL) {
 		FILE_OP_ERROR(file, "fopen");
@@ -1299,11 +1337,27 @@ EncodingType procmime_get_encoding_for_text_file(const
 		gint i;
 
 		for (p = buf, i = 0; i < len; ++p, ++i) {
-			if (*p & 0x80)
-				++octet_chars;
-			if (*p == '\0') {
-				force_b64 = TRUE;
-				*has_binary = TRUE;
+			switch (*p) {
+				case '\n':
+					if (cr) linelen--;
+					maxlinelen = MAX(linelen, maxlinelen);
+					linelen = 0;
+					cr = FALSE;
+					break;
+				case '\r':
+					cr = TRUE;
+					linelen++;
+					break;
+				case '\0':
+					*has_binary = TRUE;
+					maxlinelen = G_MAXINT;
+					cr = FALSE;
+					break;
+				default:
+					if (*p & 0x80)
+						octet_chars++;
+					linelen++;
+					cr = FALSE;
 			}
 		}
 		total_len += len;
@@ -1317,15 +1371,20 @@ EncodingType procmime_get_encoding_for_text_file(const
 		octet_percentage = 0.0;
 
 	debug_print("procmime_get_encoding_for_text_file(): "
-		    "8bit chars: %zd / %zd (%f%%)\n", octet_chars, total_len,
-		    100.0 * octet_percentage);
+			"8bit chars: %zd / %zd (%f%%). "
+			"maximum line length: %d chars\n",
+			octet_chars, total_len, 100.0 * octet_percentage,
+			maxlinelen);
 
-	if (octet_percentage > 0.20 || force_b64) {
+	if (octet_percentage > 0.20) {
 		debug_print("using BASE64\n");
 		return ENC_BASE64;
-	} else if (octet_chars > 0) {
+	} else if (maxlinelen > MAXSMTPTEXTLEN-2) {
 		debug_print("using quoted-printable\n");
 		return ENC_QUOTED_PRINTABLE;
+	} else if (octet_chars > 0) {
+		debug_print("using 8bit\n");
+		return ENC_8BIT;
 	} else {
 		debug_print("using 7bit\n");
 		return ENC_7BIT;
