Added a constat to all files in functions/ to be able to chech whether the
[squirrelmail.git] / functions / mime.php
1 <?
2 /** mime.php
3 **
4 ** This contains the functions necessary to detect and decode MIME
5 ** messages.
6 **
7 **/
8
9 $mime_php = true;
10
11 if (!isset($i18n_php))
12 include "../functions/i18n.php";
13
14 /** This is the first function called. It decides if this is a multipart
15 message or if it should be handled as a single entity
16 **/
17 function decodeMime($body, $bound, $type0, $type1, $encoding, &$entities) {
18 if ($type0 == "multipart") {
19 $bound = trim($bound);
20 $i = 0;
21 while (($i < count($body)) && (substr($body[$i], 0, strlen("--$bound--")) != "--$bound--")) {
22 if (trim($body[$i]) == "--$bound") {
23 $j = $i+1;
24 $p = 0;
25
26 /** Lets find the header for this entity **/
27 /** If the first line after the boundary is blank, we
28 use default values **/
29 if (trim($body[$j]) == "") {
30 $ent_type0 = "text";
31 $ent_type1 = "plain";
32 $charset = "us-ascii";
33 $j++;
34 /** If the first line ISNT blank, read in the header
35 for this entity **/
36 } else {
37 while ((substr(trim($body[$j]), 0, strlen("--$bound")) != "--$bound") && (trim($body[$j]) != "")) {
38 $entity_header[$p] = $body[$j];
39 $j++;
40 $p++;
41 }
42 /** All of these values are getting passed back to us **/
43 sqimap_get_entity_header($imapConnection, $entity_header, $ent_type0, $ent_type1, $ent_bound, $encoding, $charset, $filename);
44 }
45
46
47 /** OK, we have the header information, now lets decide
48 what to do with it **/
49 if ($ent_type0 == "multipart") {
50 $y = 0;
51 while (substr($body[$j], 0, strlen("--$bound--")) != "--$bound--") {
52 $ent_body[$y] = $body[$j];
53 $y++;
54 $j++;
55 }
56 $ent = decodeMime($ent_body, $ent_bound, $ent_type0, $ent_type1, $entities);
57 $entities = $ent;
58 } else {
59 $j++;
60 $entity_body = "";
61 while (substr(trim($body[$j]), 0, strlen("--$bound")) != "--$bound") {
62 $entity_body .= $body[$j];
63 $j++;
64 }
65 $count = count($entities);
66 $entities[$count] = getEntity($entity_body, $ent_bound, $ent_type0, $ent_type1, $encoding, $charset, $filename);
67 }
68 }
69 $i++;
70 }
71 } else {
72 /** If this isn't a multipart message **/
73 $j = 0;
74 $entity_body = "";
75 while ($j < count($body)) {
76 $entity_body .= $body[$j];
77 $j++;
78 }
79
80 $count = count($entities);
81 $entities[$count] = getEntity($entity_body, $bound, $type0, $type1, $encoding, $charset, $filename);
82 }
83
84 return $entities;
85 }
86
87 /** This gets one entity's properties **/
88 function getEntity($body, $bound, $type0, $type1, $encoding, $charset, $filename) {
89 $msg["TYPE0"] = $type0;
90 $msg["TYPE1"] = $type1;
91 $msg["ENCODING"] = $encoding;
92 $msg["CHARSET"] = $charset;
93 $msg["FILENAME"] = $filename;
94
95 $msg["BODY"] = $body;
96
97 return $msg;
98 }
99
100 /** This will check whether or not the message contains a certain type. It
101 searches through all the entities for a match.
102 **/
103 function containsType($message, $type0, $type1, &$ent_num) {
104 $type0 = strtolower($type0);
105 $type1 = strtolower($type1);
106 for ($i = 0; $i < count($message["ENTITIES"]); $i++) {
107 /** Check only on type0 **/
108 if ( $type1 == "any_type" ) {
109 if ( ($message["ENTITIES"][$i]["TYPE0"] == $type0) ) {
110 $ent_num = $i;
111 return true;
112 }
113
114 /** Check on type0 and type1 **/
115 } else {
116 if ( ($message["ENTITIES"][$i]["TYPE0"] == $type0) && ($message["ENTITIES"][$i]["TYPE1"] == $type1) ) {
117 $ent_num = $i;
118 return true;
119 }
120 }
121 }
122 return false;
123 }
124
125 /** This returns a parsed string called $body. That string can then
126 be displayed as the actual message in the HTML. It contains
127 everything needed, including HTML Tags, Attachments at the
128 bottom, etc.
129 **/
130 function formatBody($message, $color, $wrap_at) {
131
132 /** this if statement checks for the entity to show as the
133 primary message. To add more of them, just put them in the
134 order that is their priority.
135 **/
136 $id = $message["INFO"]["ID"];
137 $urlmailbox = urlencode($message["INFO"]["MAILBOX"]);
138
139 if (containsType($message, "text", "html", $ent_num)) {
140 $body = decodeBody($message["ENTITIES"][$ent_num]["BODY"], $message["ENTITIES"][$ent_num]["ENCODING"]);
141 } else if (containsType($message, "text", "plain", $ent_num)) {
142 $body = decodeBody($message["ENTITIES"][$ent_num]["BODY"], $message["ENTITIES"][$ent_num]["ENCODING"]);
143 }
144 // add other primary displaying message types here
145 else {
146 // find any type that's displayable
147 if (containsType($message, "text", "any_type", $ent_num)) {
148 $body = decodeBody($message["ENTITIES"][$ent_num]["BODY"], $message["ENTITIES"][$ent_num]["ENCODING"]);
149 } else if (containsType($message, "message", "any_type", $ent_num)) {
150 $body = decodeBody($message["ENTITIES"][$ent_num]["BODY"], $message["ENTITIES"][$ent_num]["ENCODING"]);
151 }
152 }
153
154 /** If there are other types that shouldn't be formatted, add
155 them here **/
156 if ($message["ENTITIES"][$ent_num]["TYPE1"] != "html")
157 $body = translateText($body, $wrap_at);
158
159
160 $body .= "<BR><SMALL><CENTER><A HREF=\"../src/download.php?absolute_dl=true&passed_id=$id&passed_ent_id=$ent_num&mailbox=$urlmailbox\">". _("Download this as a file") ."</A></CENTER><BR></SMALL>";
161
162 /** Display the ATTACHMENTS: message if there's more than one part **/
163 if (count($message["ENTITIES"]) > 1) {
164 $body .= "<TABLE WIDTH=100% CELLSPACING=0 CELLPADDING=4 BORDER=0><TR><TD BGCOLOR=\"$color[0]\">";
165 $body .= "<TT><B>ATTACHMENTS:</B></TT>";
166 $body .= "</TD></TR><TR><TD BGCOLOR=\"$color[0]\">";
167 $num = 0;
168
169 for ($i = 0; $i < count($message["ENTITIES"]); $i++) {
170 /** If we've displayed this entity, go to the next one **/
171 if ($ent_num == $i)
172 continue;
173
174 $type0 = strtolower($message["ENTITIES"][$i]["TYPE0"]);
175 $type1 = strtolower($message["ENTITIES"][$i]["TYPE1"]);
176
177 $num++;
178 $filename = $message["ENTITIES"][$i]["FILENAME"];
179 if (trim($filename) == "") {
180 $display_filename = "untitled$i";
181 } else {
182 $display_filename = $filename;
183 }
184
185 $urlMailbox = urlencode($message["INFO"]["MAILBOX"]);
186 $id = $message["INFO"]["ID"];
187 $body .= "<TT>&nbsp;&nbsp;&nbsp;<A HREF=\"../src/download.php?passed_id=$id&mailbox=$urlMailbox&passed_ent_id=$i\">" . $display_filename . "</A>&nbsp;&nbsp;<SMALL>(TYPE: $type0/$type1)</SMALL></TT><BR>";
188 }
189 $body .= "</TD></TR></TABLE>";
190 }
191 return $body;
192 }
193
194
195
196 /** this function decodes the body depending on the encoding type. **/
197 function decodeBody($body, $encoding) {
198 $encoding = strtolower($encoding);
199
200 if ($encoding == "quoted-printable") {
201 $body = quoted_printable_decode($body);
202
203 while (ereg("=\n", $body))
204 $body = ereg_replace ("=\n", "", $body);
205 } else if ($encoding == "base64") {
206 $body = base64_decode($body);
207 }
208
209 // All other encodings are returned raw.
210 return $body;
211 }
212
213
214 // This functions decode strings that is encoded according to
215 // RFC1522 (MIME Part Two: Message Header Extensions for Non-ASCII Text).
216 function decodeHeader ($string) {
217 if (eregi('=\?([^?]+)\?(q|b)\?([^?]+)\?=',
218 $string, $res)) {
219 if (ucfirst($res[2]) == "B") {
220 $replace = base64_decode($res[3]);
221 } else {
222 $replace = ereg_replace("_", " ", $res[3]);
223 $replace = quoted_printable_decode($replace);
224 }
225
226 $replace = charset_decode ($res[1], $replace);
227
228 $string = eregi_replace
229 ('=\?([^?]+)\?(q|b)\?([^?]+)\?=',
230 $replace, $string);
231 // In case there should be more encoding in the string: recurse
232 return (decodeHeader($string));
233 } else
234 return ($string);
235 }
236
237 ?>