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