fsf changes, meant to be rebased on upstream
[squirrelmail.git] / plugins / message_details / message_details_bottom.php
1 <?php
2
3 /**
4 * Message Details plugin - bottom frame with message structure and rfc822 body
5 *
6 * Plugin to view the RFC822 raw message output and the bodystructure of a message
7 *
8 * @author Marc Groot Koerkamp
9 * @copyright 2002 Marc Groot Koerkamp, The Netherlands
10 * @copyright 2002-2021 The SquirrelMail Project Team
11 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
12 * @version $Id$
13 * @package plugins
14 * @subpackage message_details
15 */
16 //FIXME: this file uses HTML extensively and eventually needs to be "templatized" (don't echo HTML directly)
17
18 /**
19 * Include the SquirrelMail initialization file.
20 */
21 require('../../include/init.php');
22 require(SM_PATH . 'functions/imap_general.php');
23 require(SM_PATH . 'functions/imap_messages.php');
24 require(SM_PATH . 'functions/mime.php');
25
26 sqgetGlobalVar('get_message_details', $md_action, SQ_GET);
27
28 /**
29 * Controls display of 8bit symbols in message source
30 * @global boolean $msgd_8bit_in_hex;
31 */
32 global $msgd_8bit_in_hex;
33 $msgd_8bit_in_hex=false;
34
35 if (!empty($md_action)) {
36 sqgetGlobalVar('passed_id', $passed_id, SQ_GET, NULL, SQ_TYPE_BIGINT);
37 if (!sqgetGlobalVar('passed_ent_id', $passed_ent_id, SQ_GET))
38 $passed_ent_id = 0;
39 sqgetGlobalVar('mailbox', $mailbox, SQ_GET);
40 /*
41 * change $unformatted to TRUE if you want to see
42 * message source without formating
43 */
44 $unformatted = FALSE;
45 echo get_message_details($mailbox, $passed_id, $passed_ent_id, $unformatted);
46 }
47
48
49 // ---------- function definitions ----------
50
51 /**
52 * Converts 8bit string to hex
53 *
54 * Replaces 8bit symbols with their hex strings,
55 * encloses them in curly brackets and uses different color.
56 * @param string $string text
57 * @return string
58 * @since 1.5.1
59 */
60 function msgd_convert_to_hex($string) {
61 global $color;
62 return preg_replace("/([\200-\377])/e","'<font color=\"$color[2]\">{'.dechex(ord('\\1')).'}</font>'",$string);
63 }
64
65 /**
66 * Calculates id of MIME entity
67 * @param string $entString
68 * @param integer $direction
69 * @return string
70 * @access private
71 */
72 function CalcEntity($entString, $direction) {
73 $result = $entString;
74 if ($direction == -1) {
75 $pos = strrpos($entString,'.');
76 $result = substr($entString,0,$pos);
77 }
78
79 switch ($direction) {
80 case 0:
81 $pos = strrpos($entString,'.');
82 if ($pos === false) {
83 $entString++;
84 $result= $entString;
85 }
86 else {
87 $level = substr($entString,0,$pos);
88 $sublevel = substr($entString,$pos+1);
89 $sublevel++;
90 $result = "$level".'.'."$sublevel";
91 }
92 break;
93 case 1:
94 $result = "$entString".".0";
95 break;
96 default:
97 break;
98 }
99 return ($result);
100 }
101
102
103 /**
104 * Returns actual message details
105 * @param string $mailbox
106 * @param string $passed_id
107 * @param string $passed_ent_id
108 * @param boolean $stripHTML If TRUE, only plain text is returned,
109 * default is FALSE, wherein output contains
110 * pretty-HTMLification of message body
111 * @return string The formatted message details
112 * @access public
113 */
114 function get_message_details($mailbox, $passed_id, $passed_ent_id=0, $stripHTML=FALSE) {
115 global $imapServerAddress, $imapPort, $imap_stream_options,
116 $color,$msgd_8bit_in_hex, $username;
117
118 $returnValue = '';
119
120 $imapConnection = sqimap_login($username, false, $imapServerAddress, $imapPort, 0, $imap_stream_options);
121 $read = sqimap_mailbox_select($imapConnection, $mailbox);
122 if (!empty($passed_ent_id))
123 $body = sqimap_run_command($imapConnection, "FETCH $passed_id BODY[$passed_ent_id]",true, $response, $readmessage, TRUE);
124 else
125 $body = sqimap_run_command($imapConnection, "FETCH $passed_id RFC822",true, $response, $readmessage, TRUE);
126 $message_body = '';
127 $header = false;
128 $mimepart = false;
129 $bnd_end = false;
130 $messageheader = true;
131 $messageheaderstart=false;
132 $boundaries = array();
133 $entities = array();
134 sqsession_unregister("entities");
135 $pre = '<b>';
136 $end = '</b>';
137 $entStr = '';
138 $bla ='';
139 $content = array ();
140 $content_indx = -1;
141 $contentset = false;
142
143 $count=count($body);
144 $body[$count-1] = substr($body[$count-1], -1);
145 for ($i=1; $i < $count; $i++) {
146 $line = rtrim($body[$i]);
147 if ($line == '') {
148 $pre = '';
149 $end = '';
150 if ($bnd_end) {
151 $header = true;
152 $mimepart = false;
153 } else if ($messageheader) {
154 if ($header) {
155 $header=false;
156 $end = '</div><div class="ent_body" id="'.$entStr.'B">';
157 }
158 $mimepart = -$header;
159 $bnd_end = false;
160 if ($messageheaderstart) {
161 $messageheaderstart=false;
162 }
163 } else if ($messageheaderstart) {
164 $messageheader= false;
165 } else {
166 if ($header) {
167 $pre = '';
168 $end = '</div><div class="ent_body" id="'.$entStr.'B">';
169 }
170 $header = false;
171 $mimepart=true;
172 }
173 $contentset = false;
174 $nameset = false;
175 } else {
176 if (!$header && $messageheader) {
177 $messageheaderstart=true;
178 if ($pre != '<b>') {
179 $pre = '<i><font color ="'.$color[1].'">';
180 $end = '</i></font>';
181 }
182 }
183 if (!$messageheader && !$header ) {
184 $mimepart=true;
185 } else {
186 $mimepart=false;
187 }
188 $pre = '';
189 $end = '';
190 }
191 if ( ( $header || $messageheader) && (preg_match("/^.*boundary=\"?(.+(?=\")|.+).*/i",$line,$reg)) ) {
192 $bnd = $reg[1];
193 $bndreg = $bnd;
194 $bndreg = str_replace("\\","\\\\",$bndreg);
195 $bndreg = str_replace("?","\\?",$bndreg);
196 $bndreg = str_replace("+","\\+",$bndreg);
197 $bndreg = str_replace(".","\\.",$bndreg);
198 $bndreg = str_replace("/","\\/",$bndreg);
199 $bndreg = str_replace("-","\\-",$bndreg);
200 $bndreg = str_replace("(","\\(",$bndreg);
201 $bndreg = str_replace(")","\\)",$bndreg);
202
203 $boundaries[] = array( 'bnd' => $bnd, 'bndreg' => $bndreg);
204 $messageheader = false;
205 $messageheaderstart=false;
206 $mimepart=false;
207 if ($entStr=='') {
208 $entStr='0';
209 } else {
210 $entStr = CalcEntity("$entStr",1);
211 }
212 }
213
214 if (($line != '' && $line[0] == '-' || $header) && isset($boundaries[0])) {
215 $cnt=count($boundaries)-1;
216 $bnd = $boundaries[$cnt]['bnd'];
217 $bndreg = $boundaries[$cnt]['bndreg'];
218
219 $regstr = '/^--'."($bndreg)".".*".'/';
220 if (preg_match($regstr,$line,$reg) ) {
221 $bndlen = strlen($reg[1]);
222 $bndend = false;
223 if (strlen($line) > ($bndlen + 3)) {
224 if ($line[$bndlen+2] == '-' && $line[$bndlen+3] == '-')
225 $bndend = true;
226 }
227 if ($bndend) {
228 $entStr = CalcEntity("$entStr",-1);
229 array_pop($boundaries);
230 $pre .= '<b><font color ="'.$color[2].'">';
231 $end .= '</font></b>';
232 $header = true;
233 $mimepart = false;
234 $bnd_end = true;
235 $encoding = '';
236 } else {
237 $header = true;
238 $bnd_end = false;
239 $entStr = CalcEntity("$entStr",0);
240 $content_indx++;
241 $content[$content_indx]=array();
242 $content[$content_indx]['ent'] = '<a href="#' . $entStr . '">' . $entStr . '</a>';
243 $pre .= '</div><div class="entheader" id="'.
244 $entStr.'H"><a name="'."$entStr".'"></a><b><font color="'.$color[2].'">';
245 $end .= '</font></b>';
246 $header = true;
247 $mimepart = false;
248 $encoding = '';
249 }
250 } else {
251 if ($header) {
252 if (!$contentset && preg_match("/^.*(content-type:)\s*(\w+)\/(\w+).*/i",$line,$reg)) {
253 if (strtolower($reg[2]) == 'message' && strtolower($reg[3]) == 'rfc822') {
254 $messageheader = true;
255 }
256 $content[$content_indx]['type'] = "$reg[2]/$reg[3]";
257 $contentset = true;
258 if ($reg[2] == 'image') {
259 $entities["$entStr"] = array();
260 $entities["$entStr"]['entity'] = $entStr;
261 $entities["$entStr"]['contenttype']=$reg[2].'/'.$reg[3];
262 }
263 } else if (!$nameset && preg_match("/^.*(name=\s*)\"(.*)\".*/i",$line,$reg)) {
264 $name = sm_encode_html_special_chars($reg[2]);
265 $content[$content_indx]['name'] = decodeHeader($name);
266 $nameset = true;
267 if (isset($entities["$entStr"])) {
268 $entities["$entStr"]['name'] = urlEncode($reg[2]);
269 }
270 } else if (preg_match("/^.*(content-transfer-encoding:)\s*(\w+-?(\w+)?).*/i",$line,$reg) ) {
271 $encoding = $reg[2];
272 if (isset($entities["$entStr"])) {
273 $entities["$entStr"]['encoding']=$reg[2];
274 }
275 $content[$content_indx]['encoding'] = $encoding;
276 $mimeentity = '';
277 }
278
279 $pre .= '<b><font color='.$color[7].'">';
280 $end .= '</font></b>';
281 //$mimepart=false;
282 }
283 }
284 }
285
286 if ($stripHTML) {
287 $message_body .= $line . "\r\n";
288 } else {
289 $line = sm_encode_html_special_chars($line);
290 if ($msgd_8bit_in_hex) $line = msgd_convert_to_hex($line);
291 $message_body .= "$pre"."$line"."$end"."\r\n";
292 }
293 }
294
295 //$returnValue .= returnTime($start).'<br />';
296 $xtra = <<<ECHO
297
298 <style type="text/css">
299 <!--
300 .ent_body {
301 display:inline;
302 }
303
304 .header {
305 display:inline;
306 }
307
308 .entheader {
309 display:inline;
310 width:99%;
311 }
312 -->
313 </style>
314
315 ECHO;
316
317 if (!$stripHTML) {
318 ob_start();
319 displayHtmlHeader( _("Message Details"), $xtra, FALSE );
320 $returnValue .= ob_get_contents();
321 ob_end_clean();
322 }
323
324 /* body */
325 if (!$stripHTML) {
326 $returnValue .= "<body text=\"$color[8]\" bgcolor=\"$color[4]\" link=\"$color[7]\" vlink=\"$color[7]\" alink=\"$color[7]\">\n";
327 $returnValue .= '<font face="monospace">'."\n";
328 $returnValue .= '<br />'."\n";
329 }
330
331 if (count($content) > 0 && !$stripHTML) {
332 $returnValue .= '<h2>'._("Bodystructure")."</h2>\n\n";
333 $returnValue .= '<table border="1" width="98%"><thead>'.
334 '<tr bgcolor="'.$color[7].'">'.
335 '<td><b><font color="'.$color[5].'">'._("Entity").'</font></b></td>'.
336 '<td><b><font color="'.$color[5].'">'._("Content-Type").'</font></b></td>'.
337 '<td><b><font color="'.$color[5].'">'._("Name").'</font></b></td>'.
338 '<td><b><font color="'.$color[5].'">'._("Encoding").'</font></b></td>'.
339 '</tr>'.
340 '</thead><tbody>';
341 for ($i = 0; $i < count($content);$i++) {
342 $returnValue .= '<tr><td>';
343 $returnValue .= $content[$i]['ent'].'</td><td>';
344 if (isset($content[$i]['type'])) {
345 $returnValue .= $content[$i]['type'];
346 } else $returnValue .= 'TEXT/PLAIN';
347 $returnValue .= '</td><td>';
348 if (isset($content[$i]['name'])) {
349 $returnValue .= $content[$i]['name'];
350 } else $returnValue .= '&nbsp;';
351 $returnValue .= '</td><td>';
352 if (isset($content[$i]['encoding'])) {
353 $returnValue .= $content[$i]['encoding'];
354 } else $returnValue .= '&nbsp;';
355 $returnValue .= '</td></tr>'."\n";
356 }
357 $returnValue .= '</tbody></table><br />'."\n";
358 }
359
360 if (!$stripHTML) {
361 $returnValue .= '<h2>'._("RFC822 Message body")."</h2>\n\n";
362 $returnValue .= '<pre><div><div class="header">';
363 } else {
364 $returnValue .= '<pre>';
365 }
366
367 $returnValue .= $message_body;
368
369 if (!$stripHTML) {
370 $returnValue .= '</div></div></pre></font></body></html>';
371 } else {
372 $returnValue .= '</pre>';
373 }
374 return $returnValue;
375 }