fsf changes, meant to be rebased on upstream
[squirrelmail.git] / plugins / message_details / message_details_bottom.php
CommitLineData
bbdea028 1<?php
4b4abf93 2
86c62251 3/**
4 * Message Details plugin - bottom frame with message structure and rfc822 body
8d6a115b 5 *
6 * Plugin to view the RFC822 raw message output and the bodystructure of a message
7 *
86c62251 8 * @author Marc Groot Koerkamp
30460a05 9 * @copyright 2002 Marc Groot Koerkamp, The Netherlands
77a1e3d1 10 * @copyright 2002-2022 The SquirrelMail Project Team
86c62251 11 * @license http://opensource.org/licenses/gpl-license.php GNU Public License
12 * @version $Id$
ea5f4b8e 13 * @package plugins
14 * @subpackage message_details
8d6a115b 15 */
fab8e10c 16//FIXME: this file uses HTML extensively and eventually needs to be "templatized" (don't echo HTML directly)
bbdea028 17
202bcbcc 18/**
19 * Include the SquirrelMail initialization file.
20 */
21require('../../include/init.php');
22require(SM_PATH . 'functions/imap_general.php');
23require(SM_PATH . 'functions/imap_messages.php');
24require(SM_PATH . 'functions/mime.php');
bbdea028 25
f4450417 26sqgetGlobalVar('get_message_details', $md_action, SQ_GET);
bbdea028 27
24e1fb21 28/**
29 * Controls display of 8bit symbols in message source
30 * @global boolean $msgd_8bit_in_hex;
31 */
32global $msgd_8bit_in_hex;
33$msgd_8bit_in_hex=false;
34
4588f43d 35if (!empty($md_action)) {
51bbe8fa 36 sqgetGlobalVar('passed_id', $passed_id, SQ_GET, NULL, SQ_TYPE_BIGINT);
fab8e10c 37 if (!sqgetGlobalVar('passed_ent_id', $passed_ent_id, SQ_GET))
38 $passed_ent_id = 0;
f4450417 39 sqgetGlobalVar('mailbox', $mailbox, SQ_GET);
4588f43d 40 /*
fab8e10c 41 * change $unformatted to TRUE if you want to see
4588f43d 42 * message source without formating
43 */
fab8e10c 44 $unformatted = FALSE;
45 echo get_message_details($mailbox, $passed_id, $passed_ent_id, $unformatted);
f4450417 46}
47
48
49// ---------- function definitions ----------
04f6008a 50
24e1fb21 51/**
52 * Converts 8bit string to hex
53 *
f8a1ed5a 54 * Replaces 8bit symbols with their hex strings,
24e1fb21 55 * encloses them in curly brackets and uses different color.
56 * @param string $string text
57 * @return string
58 * @since 1.5.1
59 */
60function 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}
04f6008a 64
5d73c31d 65/**
66 * Calculates id of MIME entity
67 * @param string $entString
68 * @param integer $direction
69 * @return string
e9ec1bd8 70 * @access private
5d73c31d 71 */
bbdea028 72function CalcEntity($entString, $direction) {
73 $result = $entString;
74 if ($direction == -1) {
5c325683 75 $pos = strrpos($entString,'.');
76 $result = substr($entString,0,$pos);
bbdea028 77 }
78
79 switch ($direction) {
796f91d9 80 case 0:
81 $pos = strrpos($entString,'.');
82 if ($pos === false) {
83 $entString++;
84 $result= $entString;
91e0dccc 85 }
796f91d9 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;
bbdea028 98 }
99 return ($result);
100}
101
f4450417 102
f4450417 103/**
104 * Returns actual message details
105 * @param string $mailbox
106 * @param string $passed_id
fab8e10c 107 * @param string $passed_ent_id
f8a1ed5a 108 * @param boolean $stripHTML If TRUE, only plain text is returned,
109 * default is FALSE, wherein output contains
f4450417 110 * pretty-HTMLification of message body
111 * @return string The formatted message details
112 * @access public
113 */
fab8e10c 114function get_message_details($mailbox, $passed_id, $passed_ent_id=0, $stripHTML=FALSE) {
a9805897 115 global $imapServerAddress, $imapPort, $imap_stream_options,
9aaa9ae2 116 $color,$msgd_8bit_in_hex, $username;
4588f43d 117
118 $returnValue = '';
119
a9805897 120 $imapConnection = sqimap_login($username, false, $imapServerAddress, $imapPort, 0, $imap_stream_options);
4588f43d 121 $read = sqimap_mailbox_select($imapConnection, $mailbox);
fab8e10c 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);
4588f43d 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();
ffa9cc0e 134 sqsession_unregister("entities");
4588f43d 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;
796f91d9 172 }
4588f43d 173 $contentset = false;
174 $nameset = false;
796f91d9 175 } else {
4588f43d 176 if (!$header && $messageheader) {
177 $messageheaderstart=true;
178 if ($pre != '<b>') {
179 $pre = '<i><font color ="'.$color[1].'">';
180 $end = '</i></font>';
181 }
796f91d9 182 }
4588f43d 183 if (!$messageheader && !$header ) {
184 $mimepart=true;
185 } else {
186 $mimepart=false;
796f91d9 187 }
4588f43d 188 $pre = '';
189 $end = '';
91e0dccc 190 }
4588f43d 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;
796f91d9 206 $mimepart=false;
4588f43d 207 if ($entStr=='') {
208 $entStr='0';
796f91d9 209 } else {
4588f43d 210 $entStr = CalcEntity("$entStr",1);
796f91d9 211 }
4588f43d 212 }
213
1710ad65 214 if (($line != '' && $line[0] == '-' || $header) && isset($boundaries[0])) {
4588f43d 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)) {
1710ad65 224 if ($line[$bndlen+2] == '-' && $line[$bndlen+3] == '-')
4588f43d 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();
64dabfa1 242 $content[$content_indx]['ent'] = '<a href="#' . $entStr . '">' . $entStr . '</a>';
4588f43d 243 $pre .= '</div><div class="entheader" id="'.
64dabfa1 244 $entStr.'H"><a name="'."$entStr".'"></a><b><font color="'.$color[2].'">';
4588f43d 245 $end .= '</font></b>';
246 $header = true;
247 $mimepart = false;
248 $encoding = '';
796f91d9 249 }
4588f43d 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)) {
3047e291 264 $name = sm_encode_html_special_chars($reg[2]);
4588f43d 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 }
bbdea028 278
4588f43d 279 $pre .= '<b><font color='.$color[7].'">';
280 $end .= '</font></b>';
281 //$mimepart=false;
282 }
796f91d9 283 }
284 }
4588f43d 285
286 if ($stripHTML) {
287 $message_body .= $line . "\r\n";
288 } else {
3047e291 289 $line = sm_encode_html_special_chars($line);
4588f43d 290 if ($msgd_8bit_in_hex) $line = msgd_convert_to_hex($line);
291 $message_body .= "$pre"."$line"."$end"."\r\n";
bbdea028 292 }
796f91d9 293 }
4588f43d 294
f4450417 295//$returnValue .= returnTime($start).'<br />';
bbdea028 296$xtra = <<<ECHO
297
a74103dd 298<style type="text/css">
bbdea028 299<!--
300.ent_body {
301 display:inline;
302}
303
304.header {
305 display:inline;
306}
307
308.entheader {
309 display:inline;
bbdea028 310 width:99%;
311}
684f1a88 312-->
796f91d9 313</style>
bbdea028 314
315ECHO;
316
4588f43d 317 if (!$stripHTML) {
318 ob_start();
319 displayHtmlHeader( _("Message Details"), $xtra, FALSE );
320 $returnValue .= ob_get_contents();
321 ob_end_clean();
bbdea028 322 }
f4450417 323
4588f43d 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 }
f4450417 330
4588f43d 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 }
f4450417 359
4588f43d 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 }
f4450417 366
4588f43d 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;
f4450417 375}