changed <? to <?php in everything
[squirrelmail.git] / functions / mime.php
CommitLineData
59177427 1<?php
aceb0d5c 2 /** mime.php
3 **
d068c0ec 4 ** This contains the functions necessary to detect and decode MIME
5 ** messages.
6 **
aceb0d5c 7 **/
8
d068c0ec 9 $mime_php = true;
aceb0d5c 10
1fd97780 11 if (!isset($i18n_php))
12 include "../functions/i18n.php";
13
4809f489 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 **/
bf74a636 17 function decodeMime($body, $bound, $type0, $type1, $encoding, $charset, &$entities) {
aceb0d5c 18 if ($type0 == "multipart") {
aceb0d5c 19 $bound = trim($bound);
f7835374 20 $i = 0;
4809f489 21 while (($i < count($body)) && (substr($body[$i], 0, strlen("--$bound--")) != "--$bound--")) {
22 if (trim($body[$i]) == "--$bound") {
23 $j = $i+1;
aceb0d5c 24 $p = 0;
25
4809f489 26 /** Lets find the header for this entity **/
d068c0ec 27 /** If the first line after the boundary is blank, we
28 use default values **/
4809f489 29 if (trim($body[$j]) == "") {
30 $ent_type0 = "text";
31 $ent_type1 = "plain";
32 $charset = "us-ascii";
aceb0d5c 33 $j++;
d068c0ec 34 /** If the first line ISNT blank, read in the header
35 for this entity **/
4809f489 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 **/
d29aac0e 43 sqimap_get_entity_header($imapConnection, $entity_header, $ent_type0, $ent_type1, $ent_bound, $encoding, $charset, $filename);
aceb0d5c 44 }
bcb432a3 45
bcb432a3 46
d068c0ec 47 /** OK, we have the header information, now lets decide
48 what to do with it **/
4809f489 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 }
bf74a636 56 $ent = decodeMime($ent_body, $ent_bound, $ent_type0, $ent_type1, $charset, $entities);
4809f489 57 $entities = $ent;
bcb432a3 58 } else {
7c9499e1 59 $j++;
60 $entity_body = "";
4809f489 61 while (substr(trim($body[$j]), 0, strlen("--$bound")) != "--$bound") {
bcb432a3 62 $entity_body .= $body[$j];
63 $j++;
64 }
4809f489 65 $count = count($entities);
66 $entities[$count] = getEntity($entity_body, $ent_bound, $ent_type0, $ent_type1, $encoding, $charset, $filename);
bcb432a3 67 }
aceb0d5c 68 }
69 $i++;
70 }
d4467150 71 } else {
7831268e 72 /** If this isn't a multipart message **/
73 $j = 0;
74 $entity_body = "";
78509c54 75 while ($j < count($body)) {
7831268e 76 $entity_body .= $body[$j];
77 $j++;
78 }
79
4809f489 80 $count = count($entities);
7831268e 81 $entities[$count] = getEntity($entity_body, $bound, $type0, $type1, $encoding, $charset, $filename);
d4467150 82 }
83
4809f489 84 return $entities;
d4467150 85 }
86
87 /** This gets one entity's properties **/
7c9499e1 88 function getEntity($body, $bound, $type0, $type1, $encoding, $charset, $filename) {
4809f489 89 $msg["TYPE0"] = $type0;
90 $msg["TYPE1"] = $type1;
91 $msg["ENCODING"] = $encoding;
92 $msg["CHARSET"] = $charset;
93 $msg["FILENAME"] = $filename;
d4467150 94
7831268e 95 $msg["BODY"] = $body;
aceb0d5c 96
d4467150 97 return $msg;
98 }
99
4809f489 100 /** This will check whether or not the message contains a certain type. It
101 searches through all the entities for a match.
102 **/
b1dadc61 103 function containsType($message, $type0, $type1, &$ent_num) {
104 $type0 = strtolower($type0);
105 $type1 = strtolower($type1);
d4467150 106 for ($i = 0; $i < count($message["ENTITIES"]); $i++) {
b1dadc61 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 }
d4467150 120 }
121 }
b1dadc61 122 return false;
123 }
8405ee35 124
d068c0ec 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.
4809f489 129 **/
a8648d75 130 function formatBody($message, $color, $wrap_at) {
2a32fc83 131 global $PHPSESSID;
7831268e 132
d068c0ec 133 /** this if statement checks for the entity to show as the
134 primary message. To add more of them, just put them in the
135 order that is their priority.
4809f489 136 **/
7085fa78 137 $id = $message["INFO"]["ID"];
138 $urlmailbox = urlencode($message["INFO"]["MAILBOX"]);
7085fa78 139
b1dadc61 140 if (containsType($message, "text", "html", $ent_num)) {
a8648d75 141 $body = decodeBody($message["ENTITIES"][$ent_num]["BODY"], $message["ENTITIES"][$ent_num]["ENCODING"]);
17ce8467 142 $charset = $message["ENTITIES"][$ent_num]["CHARSET"];
b1dadc61 143 } else if (containsType($message, "text", "plain", $ent_num)) {
a8648d75 144 $body = decodeBody($message["ENTITIES"][$ent_num]["BODY"], $message["ENTITIES"][$ent_num]["ENCODING"]);
17ce8467 145 $charset = $message["ENTITIES"][$ent_num]["CHARSET"];
4809f489 146 }
147 // add other primary displaying message types here
b1dadc61 148 else {
149 // find any type that's displayable
150 if (containsType($message, "text", "any_type", $ent_num)) {
a8648d75 151 $body = decodeBody($message["ENTITIES"][$ent_num]["BODY"], $message["ENTITIES"][$ent_num]["ENCODING"]);
17ce8467 152 $charset = $message["ENTITIES"][$ent_num]["CHARSET"];
b1dadc61 153 } else if (containsType($message, "message", "any_type", $ent_num)) {
a8648d75 154 $body = decodeBody($message["ENTITIES"][$ent_num]["BODY"], $message["ENTITIES"][$ent_num]["ENCODING"]);
17ce8467 155 $charset = $message["ENTITIES"][$ent_num]["CHARSET"];
8405ee35 156 }
157 }
158
d068c0ec 159 /** If there are other types that shouldn't be formatted, add
160 them here **/
78509c54 161 if ($message["ENTITIES"][$ent_num]["TYPE1"] != "html")
17ce8467 162 $body = translateText($body, $wrap_at, $charset);
a8648d75 163
78509c54 164
2a32fc83 165 $body .= "<BR><SMALL><CENTER><A HREF=\"../src/download.php?PHPSESSID=$PHPSESSID&absolute_dl=true&passed_id=$id&passed_ent_id=$ent_num&mailbox=$urlmailbox\">". _("Download this as a file") ."</A></CENTER><BR></SMALL>";
7831268e 166
b1dadc61 167 /** Display the ATTACHMENTS: message if there's more than one part **/
168 if (count($message["ENTITIES"]) > 1) {
7831268e 169 $body .= "<TABLE WIDTH=100% CELLSPACING=0 CELLPADDING=4 BORDER=0><TR><TD BGCOLOR=\"$color[0]\">";
170 $body .= "<TT><B>ATTACHMENTS:</B></TT>";
171 $body .= "</TD></TR><TR><TD BGCOLOR=\"$color[0]\">";
b1dadc61 172 $num = 0;
173
174 for ($i = 0; $i < count($message["ENTITIES"]); $i++) {
175 /** If we've displayed this entity, go to the next one **/
176 if ($ent_num == $i)
177 continue;
178
179 $type0 = strtolower($message["ENTITIES"][$i]["TYPE0"]);
180 $type1 = strtolower($message["ENTITIES"][$i]["TYPE1"]);
181
182 $num++;
7c9499e1 183 $filename = $message["ENTITIES"][$i]["FILENAME"];
b1dadc61 184 if (trim($filename) == "") {
7085fa78 185 $display_filename = "untitled$i";
b1dadc61 186 } else {
187 $display_filename = $filename;
188 }
7c9499e1 189
97be2168 190 $urlMailbox = urlencode($message["INFO"]["MAILBOX"]);
191 $id = $message["INFO"]["ID"];
2a32fc83 192 $body .= "<TT>&nbsp;&nbsp;&nbsp;<A HREF=\"../src/download.php?PHPSESSID=$PHPSESSID&passed_id=$id&mailbox=$urlMailbox&passed_ent_id=$i\">" . $display_filename . "</A>&nbsp;&nbsp;<SMALL>(TYPE: $type0/$type1)</SMALL></TT><BR>";
8405ee35 193 }
7831268e 194 $body .= "</TD></TR></TABLE>";
8405ee35 195 }
d4467150 196 return $body;
197 }
198
4809f489 199
200
201 /** this function decodes the body depending on the encoding type. **/
d4467150 202 function decodeBody($body, $encoding) {
203 $encoding = strtolower($encoding);
7831268e 204
ef3f274f 205 if ($encoding == "quoted-printable") {
206 $body = quoted_printable_decode($body);
db87f79c 207
ef3f274f 208 while (ereg("=\n", $body))
209 $body = ereg_replace ("=\n", "", $body);
97be2168 210 } else if ($encoding == "base64") {
ef3f274f 211 $body = base64_decode($body);
d4467150 212 }
ef3f274f 213
214 // All other encodings are returned raw.
215 return $body;
aceb0d5c 216 }
a4c2cd49 217
218
219 // This functions decode strings that is encoded according to
220 // RFC1522 (MIME Part Two: Message Header Extensions for Non-ASCII Text).
2e434774 221 function decodeHeader ($string) {
1fd97780 222 if (eregi('=\?([^?]+)\?(q|b)\?([^?]+)\?=',
a4c2cd49 223 $string, $res)) {
1fd97780 224 if (ucfirst($res[2]) == "B") {
225 $replace = base64_decode($res[3]);
a4c2cd49 226 } else {
1fd97780 227 $replace = ereg_replace("_", " ", $res[3]);
a4c2cd49 228 $replace = quoted_printable_decode($replace);
229 }
230
1fd97780 231 $replace = charset_decode ($res[1], $replace);
a4c2cd49 232
233 $string = eregi_replace
1fd97780 234 ('=\?([^?]+)\?(q|b)\?([^?]+)\?=',
a4c2cd49 235 $replace, $string);
2e434774 236 // In case there should be more encoding in the string: recurse
237 return (decodeHeader($string));
a4c2cd49 238 } else
239 return ($string);
240 }
241
c3084273 242 // Encode a string according to RFC 1522 for use in headers if it
243 // contains 8-bit characters
244 function encodeHeader ($string) {
245 global $default_charset;
246
247 // Encode only if the string contains 8-bit characters
248 if (ereg("[\200-\377]", $string)) {
249 $newstring = "=?$default_charset?Q?";
250 $newstring .= str_replace(" ", "_", $string);
251
252 while (ereg("([\200-\377])", $newstring, $regs)) {
253 $replace = $regs[1];
254 $insert = "=" . bin2hex($replace);
255 $newstring = str_replace($replace, $insert, $newstring);
256 }
257
258 $newstring .= "?=";
259
260 return $newstring;
261 }
262
263 return $string;
264 }
265
9f9d7d28 266?>