File mailx-12.2-mime.dif of Package mailx

--- def.h
+++ def.h	2007-04-17 11:32:43.960721000 +0000
@@ -142,7 +142,8 @@ enum mimeclean {
 	MIME_LONGLINES	= 002,		/* has lines too long for RFC 2822 */
 	MIME_CTRLCHAR	= 004,		/* contains control characters */
 	MIME_HASNUL	= 010,		/* contains \0 characters */
-	MIME_NOTERMNL	= 020		/* lacks a terminating newline */
+	MIME_NOTERMNL	= 020,		/* lacks a terminating newline */
+	MIME_UTF8	= 040		/* UTF-8 high bit characters */
 };
 
 enum tdflags {
--- mime.c
+++ mime.c	2007-04-17 13:08:06.352702764 +0000
@@ -258,7 +258,10 @@ getcharset(int isclean)
 	if (isclean & (MIME_CTRLCHAR|MIME_HASNUL))
 		charset = NULL;
 	else if (isclean & MIME_HIGHBIT) {
-		charset = wantcharset ? wantcharset : value("charset");
+		if (isclean & MIME_UTF8)
+			charset = defcharset;
+		if (charset == NULL)
+			charset = wantcharset ? wantcharset : value("charset");
 		if (charset == NULL) {
 			char *t = value("ttycharset");
 			if (t == NULL || (ascncasecmp("ANSI_X3.4", t, 9) == 0))
@@ -742,6 +745,7 @@ mime_isclean(FILE *f)
 		lastc = c;
 		c = getc(f);
 		curlen++;
+	check:
 		if (c == '\n' || c == EOF) {
 			/*
 			 * RFC 821 imposes a maximum line length of 1000
@@ -754,10 +758,38 @@ mime_isclean(FILE *f)
 			curlen = 1;
 		} else if (c & 0200) {
 			isclean |= MIME_HIGHBIT;
+			if (c & 0100) {
+				int n, follow;
+
+				if      ((c & 040) == 0)	/* 110xxxxx */
+					follow = 1;
+				else if ((c & 020) == 0)	/* 1110xxxx */
+					follow = 2;
+				else if ((c & 010) == 0)	/* 11110xxx */
+					follow = 3;
+				else if ((c & 004) == 0)	/* 111110xx */
+					follow = 4;
+				else if ((c & 002) == 0)	/* 1111110x */
+					follow = 5;
+				else
+					continue;
+
+				for (n = 0; n < follow; n++) {
+					lastc = c;
+					c = getc(f);
+
+					if ((c & 0200) == 0 || (c & 0100) ||
+					    (c == '\0') || (c == '\n') || (c == EOF)) {
+						curlen += n;
+						goto check;
+					}
+				}
+				isclean |= MIME_UTF8;
+			}
 		} else if (c == '\0') {
 			isclean |= MIME_HASNUL;
 			break;
-		} else if ((c < 040 && (c != '\t' && c != '\f')) || c == 0177) {
+		} else if ((c < 040 && (c != '\t' && c != '\f' && c != '\b')) || c == 0177) {
 			isclean |= MIME_CTRLCHAR;
 		}
 	} while (c != EOF);
@@ -826,13 +858,16 @@ get_mime_convert(FILE *fp, char **conten
 			 * ^I or ^L in text/plain bodies. However, some
 			 * obscure character sets actually contain these
 			 * characters, so the content type can be set.
+			 * Beside ^I or ^L from RFC 2046 we accept also
+			 * backspace ^H often used in enhanced text.
 			 */
 			if ((*contenttype = value("contenttype-cntrl")) == NULL)
 				*contenttype = "application/octet-stream";
 		} else
 			*contenttype = "text/plain";
 		*charset = getcharset(*isclean);
-	}
+	} else if (ascncasecmp(*contenttype, "text/", 5) == 0)
+		*charset = getcharset(*isclean);
 	return convert;
 }
 
--- sendout.c
+++ sendout.c	2007-04-17 13:11:40.576871634 +0000
@@ -206,7 +206,7 @@ attach_file(struct attachment *ap, FILE
 	size_t bufsize, count;
 	int	lastc = EOF;
 #ifdef	HAVE_ICONV
-	char	*tcs;
+	char	*tcs = NULL;
 #endif
 
 	if ((fi = Fopen(ap->a_name, "r")) == NULL) {
@@ -231,8 +231,16 @@ attach_file(struct attachment *ap, FILE
 		send_boundary, contenttype);
 	if (charset == NULL)
 		putc('\n', fo);
-	else
-		fprintf(fo, ";\n charset=%s\n", charset);
+	else {
+#ifdef	HAVE_ICONV
+		if (wantcharset && ascncasecmp(wantcharset, "ANSI_X3.4", 9))
+			tcs = wantcharset;
+		if (tcs)
+			fprintf(fo, ";\n charset=%s\n", tcs);
+		else
+#endif
+			fprintf(fo, ";\n charset=%s\n", charset);
+	}
 	if (ap->a_content_disposition == NULL)
 		ap->a_content_disposition = "attachment";
 	fprintf(fo, "Content-Transfer-Encoding: %s\n"
@@ -254,16 +262,15 @@ attach_file(struct attachment *ap, FILE
 		iconv_close(iconvd);
 		iconvd = (iconv_t)-1;
 	}
-	tcs = gettcharset();
 	if ((isclean & (MIME_HASNUL|MIME_CTRLCHAR)) == 0 &&
 			ascncasecmp(contenttype, "text/", 5) == 0 &&
 			isclean & MIME_HIGHBIT &&
-			charset != NULL && asccasecmp(charset, tcs)) {
-		if ((iconvd = iconv_open_ft(charset, tcs)) == (iconv_t)-1 &&
+			charset != NULL && tcs != NULL && asccasecmp(charset, tcs)) {
+		if ((iconvd = iconv_open_ft(tcs, charset)) == (iconv_t)-1 &&
 				errno != 0) {
 			if (errno == EINVAL)
 				fprintf(stderr, catgets(catd, CATSET, 179,
-			"Cannot convert from %s to %s\n"), tcs, charset);
+			"Cannot convert from %s to %s\n"), charset, tcs);
 			else
 				perror("iconv_open");
 			Fclose(fi);
@@ -467,6 +474,7 @@ infix(struct header *hp, FILE *fi, int d
 	}
 	if ((isclean & (MIME_HASNUL|MIME_CTRLCHAR)) == 0 &&
 			ascncasecmp(contenttype, "text/", 5) == 0 &&
+			ascncasecmp(tcs, "ANSI_X3.4", 9) &&
 			isclean & MIME_HIGHBIT &&
 			charset != NULL && asccasecmp(charset, tcs)) {
 		if (iconvd != (iconv_t)-1)
@@ -1162,8 +1170,9 @@ puthead(struct header *hp, FILE *fo, enu
 				return 1;
 		if ((addr = hp->h_organization) != NULL ||
 				(addr = value("ORGANIZATION")) != NULL) {
+			size_t len = strlen(addr);
 			fwrite("Organization: ", sizeof (char), 14, fo);
-			if (mime_write(addr, sizeof *addr, strlen(addr), fo,
+			if (len && mime_write(addr, sizeof *addr, len, fo,
 					action == SEND_TODISP ?
 					CONV_NONE:CONV_TOHDR,
 					action == SEND_TODISP ?
@@ -1208,9 +1217,10 @@ puthead(struct header *hp, FILE *fo, enu
 	if (hp->h_subject != NULL && w & GSUBJECT) {
 		fwrite("Subject: ", sizeof (char), 9, fo);
 		if (ascncasecmp(hp->h_subject, "re: ", 4) == 0) {
+			size_t len = strlen(hp->h_subject + 4);
 			fwrite("Re: ", sizeof (char), 4, fo);
-			if (mime_write(hp->h_subject + 4, sizeof *hp->h_subject,
-					strlen(hp->h_subject + 4),
+			if (len && mime_write(hp->h_subject + 4,
+					sizeof *hp->h_subject, len,
 					fo, action == SEND_TODISP ?
 					CONV_NONE:CONV_TOHDR,
 					action == SEND_TODISP ?
@@ -1218,8 +1228,9 @@ puthead(struct header *hp, FILE *fo, enu
 					NULL, (size_t)0) == 0)
 				return 1;
 		} else if (*hp->h_subject) {
-			if (mime_write(hp->h_subject, sizeof *hp->h_subject,
-					strlen(hp->h_subject),
+			size_t len = strlen(hp->h_subject);
+			if (len && mime_write(hp->h_subject,
+					sizeof *hp->h_subject, len,
 					fo, action == SEND_TODISP ?
 					CONV_NONE:CONV_TOHDR,
 					action == SEND_TODISP ?
openSUSE Build Service is sponsored by