1 /*
2 ** Copyright 1998 - 2001 Double Precision, Inc.  See COPYING for
3 ** distribution information.
4 */
5 
6 #if	HAVE_CONFIG_H
7 #include "rfc2045_config.h"
8 #endif
9 #include	"rfc2045.h"
10 #include	<string.h>
11 #if	HAVE_STRINGS_H
12 #include	<strings.h>
13 #endif
14 #include	<stdlib.h>
15 #include	<stdio.h>
16 
17 
18 extern void rfc2045_enomem();
19 
rfc2045_ac_check(struct rfc2045 * p,int rwmode)20 int rfc2045_ac_check(struct rfc2045 *p, int rwmode)
21 {
22 int	flag=0;		/* Flag - rewriting suggested */
23 struct	rfc2045 *c;
24 int	hasnon7bit=p->has8bitchars;
25 		/* hasnon7bit: 8bit chars in this section or subsections */
26 const char *te;
27 int	is8bitte;
28 
29 	for (c=p->firstpart; c; c=c->next)
30 		if (!c->isdummy)
31 		{
32 			if (rfc2045_ac_check(c, rwmode))	flag=1;
33 			if (c->content_transfer_encoding &&
34 			    strcmp(c->content_transfer_encoding, "7bit") &&
35 			    strcmp(c->content_transfer_encoding, "uuencode") &&
36 				strcmp(c->content_transfer_encoding, "quoted-printable"))
37 				hasnon7bit=1;
38 			if (c->has8bitchars)
39 				p->has8bitchars=1;
40 		}
41 
42 	if (RFC2045_ISMIME1DEF(p->mime_version) && !p->content_type)
43 	{
44 		if ((p->content_type=strdup("text/plain")) == 0)
45 			rfc2045_enomem();
46 		if (p->mime_version)
47 		{
48 			flag=1;
49 		}
50 	}
51 
52 	if (RFC2045_ISMIME1DEF(p->mime_version)
53 		&& !rfc2045_getattr(p->content_type_attr, "charset")
54 		&& strncasecmp(p->content_type, "text/", 5) == 0)
55 	{
56 		if (rfc2045_attrset(&p->content_type_attr, "charset",
57 				    rfc2045_getdefaultcharset()) < 0)
58 			rfc2045_enomem();
59 
60 		if (p->mime_version
61 
62 			&& p->firstpart == 0 /* sam - don't trigger rewrites on changes to multipart headers */
63 
64 			)
65 		{
66 			flag=1;
67 		}
68 	}
69 
70 	if (RFC2045_ISMIME1DEF(p->mime_version)
71 		&& !p->content_transfer_encoding)
72 	{
73 		if ((p->content_transfer_encoding=strdup(
74 			hasnon7bit ? "8bit":"7bit")) == 0)
75 			rfc2045_enomem();
76 		if (p->mime_version
77 
78 			&& p->firstpart == 0 /* sam - don't trigger rewrites on changes to multipart headers */
79 			)
80 		{
81 			flag=1;
82 		}
83 	}
84 
85 #if 0
86 	if (RFC2045_ISMIME1DEF(p->mime_version)
87 		&& strncmp(p->content_type, "text/", 5) == 0 && !hasnon7bit
88 		&& strcmp(p->content_transfer_encoding, "7bit"))
89 	{
90 		if (p->mime_version)
91 		{
92 			flag=1;
93 		}
94 	}
95 #endif
96 
97 	if (RFC2045_ISMIME1DEF(p->mime_version))
98 	{
99 		/* Check for conversions */
100 
101 		te=p->content_transfer_encoding;
102 		is8bitte=strcasecmp(te, "base64") &&
103 			strcasecmp(te, "quoted-printable") &&
104 			strcasecmp(te, "uuencode") &&
105 			strcasecmp(te, "7bit");	/* 8 bit contents */
106 
107 		if (is8bitte && !p->has8bitchars && !p->haslongline)
108 		{
109 			if (p->rw_transfer_encoding)
110 				free(p->rw_transfer_encoding);
111 			if ((p->rw_transfer_encoding=strdup("7bit")) == 0)
112 				rfc2045_enomem();
113 			flag=1;
114 			is8bitte=0;
115 		}
116 
117 		if (rwmode == RFC2045_RW_7BIT && (is8bitte || p->haslongline))
118 		{
119 			if (p->rw_transfer_encoding)
120 				free(p->rw_transfer_encoding);
121 			if ((p->rw_transfer_encoding=strdup("quoted-printable"))
122 				== 0)
123 				rfc2045_enomem();
124 			flag=1;
125 		}
126 		else if (strcasecmp(te, "quoted-printable") == 0 &&
127 			 ((rwmode == RFC2045_RW_8BIT &&
128 			   !p->haslongline)
129 			  ||
130 			  (rwmode == RFC2045_RW_8BIT_ALWAYS)))
131 		{
132 			if (p->rw_transfer_encoding)
133 				free(p->rw_transfer_encoding);
134 			if ((p->rw_transfer_encoding=strdup(hasnon7bit
135 					? "8bit":"7bit")) == 0)
136 				rfc2045_enomem();
137 			flag=1;
138 		}
139 	}
140 
141 	if (!p->mime_version)
142 	{
143 		if ((p->mime_version=strdup("1.0")) == 0)
144 			rfc2045_enomem();
145 	}
146 	return (flag);
147 }
148