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> <A HREF=\"../src/download.php?PHPSESSID=$PHPSESSID&passed_id=$id&mailbox=$urlMailbox&passed_ent_id=$i\">" . $display_filename . "</A> <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 | ?> |