Added full character translation tables for ISO-8859-1, 7 and 15.
[squirrelmail.git] / functions / mime.php
CommitLineData
aceb0d5c 1<?
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 **/
4ccd80f8 17 function decodeMime($body, $bound, $type0, $type1, $encoding, &$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 }
56 $ent = decodeMime($ent_body, $ent_bound, $ent_type0, $ent_type1, $entities);
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) {
7831268e 131
d068c0ec 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.
4809f489 135 **/
7085fa78 136 $id = $message["INFO"]["ID"];
137 $urlmailbox = urlencode($message["INFO"]["MAILBOX"]);
7085fa78 138
b1dadc61 139 if (containsType($message, "text", "html", $ent_num)) {
a8648d75 140 $body = decodeBody($message["ENTITIES"][$ent_num]["BODY"], $message["ENTITIES"][$ent_num]["ENCODING"]);
17ce8467 141 $charset = $message["ENTITIES"][$ent_num]["CHARSET"];
b1dadc61 142 } else if (containsType($message, "text", "plain", $ent_num)) {
a8648d75 143 $body = decodeBody($message["ENTITIES"][$ent_num]["BODY"], $message["ENTITIES"][$ent_num]["ENCODING"]);
17ce8467 144 $charset = $message["ENTITIES"][$ent_num]["CHARSET"];
4809f489 145 }
146 // add other primary displaying message types here
b1dadc61 147 else {
148 // find any type that's displayable
149 if (containsType($message, "text", "any_type", $ent_num)) {
a8648d75 150 $body = decodeBody($message["ENTITIES"][$ent_num]["BODY"], $message["ENTITIES"][$ent_num]["ENCODING"]);
17ce8467 151 $charset = $message["ENTITIES"][$ent_num]["CHARSET"];
b1dadc61 152 } else if (containsType($message, "message", "any_type", $ent_num)) {
a8648d75 153 $body = decodeBody($message["ENTITIES"][$ent_num]["BODY"], $message["ENTITIES"][$ent_num]["ENCODING"]);
17ce8467 154 $charset = $message["ENTITIES"][$ent_num]["CHARSET"];
8405ee35 155 }
156 }
157
d068c0ec 158 /** If there are other types that shouldn't be formatted, add
159 them here **/
78509c54 160 if ($message["ENTITIES"][$ent_num]["TYPE1"] != "html")
17ce8467 161 $body = translateText($body, $wrap_at, $charset);
a8648d75 162
78509c54 163
9f9d7d28 164 $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>";
7831268e 165
b1dadc61 166 /** Display the ATTACHMENTS: message if there's more than one part **/
167 if (count($message["ENTITIES"]) > 1) {
7831268e 168 $body .= "<TABLE WIDTH=100% CELLSPACING=0 CELLPADDING=4 BORDER=0><TR><TD BGCOLOR=\"$color[0]\">";
169 $body .= "<TT><B>ATTACHMENTS:</B></TT>";
170 $body .= "</TD></TR><TR><TD BGCOLOR=\"$color[0]\">";
b1dadc61 171 $num = 0;
172
173 for ($i = 0; $i < count($message["ENTITIES"]); $i++) {
174 /** If we've displayed this entity, go to the next one **/
175 if ($ent_num == $i)
176 continue;
177
178 $type0 = strtolower($message["ENTITIES"][$i]["TYPE0"]);
179 $type1 = strtolower($message["ENTITIES"][$i]["TYPE1"]);
180
181 $num++;
7c9499e1 182 $filename = $message["ENTITIES"][$i]["FILENAME"];
b1dadc61 183 if (trim($filename) == "") {
7085fa78 184 $display_filename = "untitled$i";
b1dadc61 185 } else {
186 $display_filename = $filename;
187 }
7c9499e1 188
97be2168 189 $urlMailbox = urlencode($message["INFO"]["MAILBOX"]);
190 $id = $message["INFO"]["ID"];
7831268e 191 $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>";
8405ee35 192 }
7831268e 193 $body .= "</TD></TR></TABLE>";
8405ee35 194 }
d4467150 195 return $body;
196 }
197
4809f489 198
199
200 /** this function decodes the body depending on the encoding type. **/
d4467150 201 function decodeBody($body, $encoding) {
202 $encoding = strtolower($encoding);
7831268e 203
ef3f274f 204 if ($encoding == "quoted-printable") {
205 $body = quoted_printable_decode($body);
db87f79c 206
ef3f274f 207 while (ereg("=\n", $body))
208 $body = ereg_replace ("=\n", "", $body);
97be2168 209 } else if ($encoding == "base64") {
ef3f274f 210 $body = base64_decode($body);
d4467150 211 }
ef3f274f 212
213 // All other encodings are returned raw.
214 return $body;
aceb0d5c 215 }
a4c2cd49 216
217
218 // This functions decode strings that is encoded according to
219 // RFC1522 (MIME Part Two: Message Header Extensions for Non-ASCII Text).
2e434774 220 function decodeHeader ($string) {
1fd97780 221 if (eregi('=\?([^?]+)\?(q|b)\?([^?]+)\?=',
a4c2cd49 222 $string, $res)) {
1fd97780 223 if (ucfirst($res[2]) == "B") {
224 $replace = base64_decode($res[3]);
a4c2cd49 225 } else {
1fd97780 226 $replace = ereg_replace("_", " ", $res[3]);
a4c2cd49 227 $replace = quoted_printable_decode($replace);
228 }
229
1fd97780 230 $replace = charset_decode ($res[1], $replace);
a4c2cd49 231
232 $string = eregi_replace
1fd97780 233 ('=\?([^?]+)\?(q|b)\?([^?]+)\?=',
a4c2cd49 234 $replace, $string);
2e434774 235 // In case there should be more encoding in the string: recurse
236 return (decodeHeader($string));
a4c2cd49 237 } else
238 return ($string);
239 }
240
9f9d7d28 241?>