a28846920be2f665bf977cbb8194f1e7ad7e49a1
6 * Copyright (c) 2002 The SquirrelMail Project Team
7 * Licensed under the GNU GPL. For full terms see the file COPYING.
10 * This contains functions needed to handle mime messages.
19 * input: header_string or array
40 $more_headers = array(); /* only needed for constructing headers
43 function parseHeader($hdr)
47 $hdr = implode('',$hdr);
49 /* first we unfold the header */
50 $hdr = trim(str_replace(array("\r\n\t","\r\n "),array('',''),$hdr));
52 * now we can make a new header array with each element representing
55 $hdr = explode("\r\n" , $hdr);
56 foreach ($hdr as $line)
58 $pos = strpos($line,':');
61 $field = substr($line,0,$pos);
62 $value = trim(substr($line,$pos+
1));
63 if(!preg_match('/^X.*/i',$field)) {
64 $value = $this->stripComments($value);
66 $this->parseField($field,$value);
69 if ($this->content_type
== '')
71 $this->parseContentType('text/plain; charset=us-ascii');
75 function stripComments($value)
77 $cnt = strlen($value);
87 while ($value{$i} != '"')
89 if ($value{$i} == '\\')
101 while ($value{$i} != ')')
103 if ($value{$i} == '\\')
119 function parseField($field,$value)
121 $field = strtolower($field);
125 $d = strtr($value, array(' ' => ' '));
126 $d = explode(' ', $d);
127 $this->date
= getTimeStamp($d);
130 $this->subject
= $value;
133 $this->from
= $this->parseAddress($value,true);
136 $this->sender
= $this->parseAddress($value);
139 $this->reply_to
= $this->parseAddress($value, true);
142 $this->to
= $this->parseAddress($value, true);
145 $this->cc
= $this->parseAddress($value, true);
148 $this->bcc
= $this->parseAddress($value, true);
150 case ('in-reply-to'):
151 $this->in_reply_to
= $value;
154 $this->message_id
= $value;
156 case ('disposition-notification-to'):
157 $this->dnt
= $this->parseAddress($value);
159 case ('mime-Version'):
160 $value = str_replace(' ','',$value);
166 case ('content-type'):
167 $this->parseContentType($value);
169 case ('content-disposition'):
170 $this->parseDisposition($value);
174 $this->xmailer
= $value;
177 $this->xmailer
= $value;
180 $this->priority
= $value;
183 $this->mlist('post',$value);
186 $this->mlist('reply',$value);
188 case ('list-subscribe'):
189 $this->mlist('subscribe',$value);
191 case ('list-unsubscribe'):
192 $this->mlist('unsubscribe',$value);
194 case ('list-archive'):
195 $this->mlist('archive',$value);
198 $this->mlist('owner',$value);
201 $this->mlist('help',$value);
204 $this->mlist('id',$value);
211 function parseAddress($address, $ar=false, $addr_ar = array(), $group = '')
214 $j = strlen( $address );
217 while ( $pos < $j ) {
218 switch ($address{$pos})
220 case ('"'): /* get the personal name */
222 if ($address{$pos} == '"')
227 while ( $pos < $j && $address{$pos} != '"')
229 if (substr($address, $pos, 2) == '\\"')
231 $name .= $address{$pos};
233 } elseif (substr($address, $pos, 2) == '\\\\')
235 $name .= $address{$pos};
238 $name .= $address{$pos};
244 case ('<'): /* get email address */
247 while ( $pos < $j && $address{$pos} != '>' )
249 $addr .= $address{$pos};
254 case ('('): /* rip off comments */
257 while ( $pos < $j && $address{$pos} != ')' )
259 $addr .= $address{$pos};
262 $address_start = substr($address,0,$addr_start);
263 $address_end = substr($address,$pos+
1);
264 $address = $address_start . $address_end;
265 $j = strlen( $address );
269 case (','): /* we reached a delimiter */
272 $addr = substr($address,0,$pos);
273 } elseif ($name == '') {
274 $name = trim(substr($address,0,$addr_start));
277 $at = strpos($addr, '@');
278 $addr_structure = new address_structure();
279 $addr_structure->personal
= $name;
280 $addr_structure->group
= $group;
283 $addr_structure->mailbox
= substr($addr,0,$at);
284 $addr_structure->host
= substr($addr,$at+
1);
287 $addr_structure->mailbox
= $addr;
289 $address = trim(substr($address,$pos+
1));
290 $j = strlen( $address );
294 $addr_ar[] = $addr_structure;
296 case (':'): /* process the group addresses */
298 $group = substr($address,0,$pos);
299 $address = substr($address,$pos+
1);
300 $result = $this->parseAddress($address, $ar, $addr_ar, $group);
301 $addr_ar = $result[0];
303 $address = substr($address,$pos);
304 $j = strlen( $address );
311 $address = substr($address, 0, $pos-1);
323 $addr = substr($address,0,$pos);
324 } elseif ($name == '')
326 $name = trim(substr($address,0,$addr_start));
328 $at = strpos($addr, '@');
329 $addr_structure = new address_structure();
330 $addr_structure->group
= $group;
333 $addr_structure->mailbox
= trim(substr($addr,0,$at));
334 $addr_structure->host
= trim(substr($addr,$at+
1));
337 $addr_structure->mailbox
= trim($addr);
339 if ($group && $addr == '') /* no addresses found in group */
341 $name = "$group: Undisclosed recipients;";
342 $addr_structure->personal
= $name;
343 $addr_ar[] = $addr_structure;
344 return (array($addr_ar,$pos+
1));
347 $addr_structure->personal
= $name;
350 $addr_ar[] = $addr_structure;
358 return ($addr_ar[0]);
362 function parseContentType($value)
364 $pos = strpos($value,';');
368 $type = trim(substr($value,0,$pos));
369 $props = trim(substr($type,$pos+
1));
374 $content_type = new content_type($type);
377 $properties = $this->parseProperties($props);
378 if (!isset($properties['charset']))
380 $properties['charset'] = 'us-ascii';
382 $content_type->properties
= $this->parseProperties($props);
384 $this->content_type
= $content_type;
387 function parseProperties($value)
389 $propArray = explode(';',$value);
390 $propResultArray = array();
391 foreach ($propArray as $prop)
394 $pos = strpos($prop,'=');
397 $key = trim(substr($prop,0,$pos));
398 $val = trim(substr($prop,$pos+
1));
401 $val = substr($val,1,-1);
403 $propResultArray[$key] = $val;
406 return $propResultArray;
409 function parseDisposition($value)
411 $pos = strpos($value,';');
415 $name = trim(substr($value,0,$pos));
416 $props = trim(substr($type,$pos+
1));
421 $props_a = $this->parseProperties($props);
422 $disp = new disposition($name);
423 $disp->properties
= $props_a;
424 $this->disposition
= $disp;
427 function mlist($field, $value)
430 $value_a = explode(',',$value);
431 foreach ($value_a as $val) {
435 $val = substr($val,1,-1);
437 if (substr($val,0,7) == 'mailto:')
439 $res_a['mailto'] = substr($val,7);
442 $res_a['href'] = $val;
445 $this->mlist
[$field] = $res_a;
449 * function to get the addres strings out of the header.
450 * Arguments: string or array of strings !
451 * example1: header->getAddr_s('to').
452 * example2: header->getAddr_s(array('to','cc','bcc'))
454 function getAddr_s($arr, $separator=', ')
459 foreach($arr as $arg )
461 $result = $this->getAddr_s($arg);
464 $s .= $separator . $result;
467 if ($s) $s = substr($s,2);
472 eval('$addr = $this->'.$arr.';') ;
475 foreach ($addr as $addr_o)
477 if (is_object($addr_o))
479 $s .= $addr_o->getAddress() . $separator;
482 $s = substr($s,0,-strlen($separator));
485 if (is_object($addr))
487 $s .= $addr->getAddress();
494 function getAddr_a($arg, $excl_arr=array(), $arr = array())
498 foreach($arg as $argument )
500 $arr = $this->getAddr_a($argument, $excl_arr, $arr);
505 eval('$addr = $this->'.$arg.';') ;
508 foreach ($addr as $addr_o)
510 if (is_object($addr_o))
512 if (isset($addr_o->host
) && $addr_o->host
!='')
514 $email = $addr_o->mailbox
.'@'.$addr_o->host
;
517 $email = $addr_o->mailbox
;
519 $email = strtolower($email);
520 if ($email && !isset($arr[$email]) && !isset($excl_arr[$email]))
522 $arr[$email] = $addr_o->personal
;
528 if (is_object($addr))
530 if (isset($addr->host
))
532 $email = $addr->mailbox
.'@'.$addr->host
;
535 $email = $addr->mailbox
;
537 $email = strtolower($email);
538 if ($email && !isset($arr[$email]) && !isset($excl_arr[$email]))
540 $arr[$email] = $addr->personal
;
548 function getContentType($type0, $type1)
550 $type0 = $this->content_type
->type0
;
551 $type1 = $this->content_type
->type1
;
552 return $this->content_type
->properties
;
558 /** msg_header contains all variables available in a bodystructure **/
559 /** entity like described in rfc2060 **/
563 $parameters = array(),
573 * returns addres_list of supplied argument
574 * arguments: array('to', 'from', ...) or just a string like 'to'.
575 * result: string: address1, addres2, ....
578 function setVar($var, $value)
580 $this->{$var} = $value;
583 function getParameter($par)
585 $value = strtolower($par);
586 if (isset($this->parameters
[$par]))
588 return $this->parameters
[$par];
593 function setParameter($parameter, $value)
595 $this->parameters
[strtolower($parameter)] = $value;
601 class address_structure
603 var $personal = '', $adl = '', $mailbox = '', $host = '', $group = '';
605 function getAddress($full=true)
607 if (is_object($this))
609 if (isset($this->host
) && $this->host
!='')
611 $email = $this->mailbox
.'@'.$this->host
;
614 $email = $this->mailbox
;
616 if (trim($this->personal
) !='')
620 $addr = '"' . $this->personal
. '" <' .$email.'>';
623 $addr = $this->personal
;
625 $best_dpl = $this->personal
;
644 /** message is the object that contains messages. It is a recursive
645 object in that through the $entities variable, it can contain
646 more objects of type message. See documentation in mime.txt for
647 a better description of how this works.
649 var $rfc822_header = '',
655 $parent_ent, $entity,
656 $parent = '', $decoded_body='',
657 $is_seen = 0, $is_answered = 0, $is_deleted = 0, $is_flagged = 0,
660 $offset = 0, /* for fetching body parts out of raw messages */
661 $length = 0; /* for fetching body parts out of raw messages */
663 function setEnt($ent)
665 $this->entity_id
= $ent;
668 function addEntity ($msg)
670 $msg->parent
= &$this;
671 $this->entities
[] = $msg;
674 function getFilename()
677 if (is_object($this->header
->disposition
))
679 $filename = $this->header
->disposition
->getproperty('filename');
682 $filename = $this->header
->disposition
->getproperty('name');
687 $filename = 'untitled-'.$this->entity_id
;
693 function addRFC822Header($read)
695 $header = new rfc822_header();
696 $this->rfc822_header
= $header->parseHeader($read);
699 function getEntity($ent)
701 $cur_ent = $this->entity_id
;
703 if ($cur_ent == '' ||
$cur_ent == '0')
705 $cur_ent_a = array();
708 $cur_ent_a = explode('.',$this->entity_id
);
710 $ent_a = explode('.',$ent);
712 $cnt = count($ent_a);
714 for ($i=0;$i<$cnt -1;$i++
)
716 if (isset($cur_ent_a[$i]) && $cur_ent_a[$i] != $ent_a[$i])
719 $cur_ent_a = explode('.',$msg->entity_id
);
721 } else if (!isset($cur_ent_a[$i]))
723 if (isset($msg->entities
[($ent_a[$i]-1)]))
725 $msg = $msg->entities
[($ent_a[$i]-1)];
727 $msg = $msg->entities
[0];
730 if ($msg->type0
== 'message' && $msg->type1
== 'rfc822')
732 /*this is a header for a message/rfc822 entity */
733 $msg = $msg->entities
[0];
737 if ($msg->type0
== 'message' && $msg->type1
== 'rfc822')
739 /*this is a header for a message/rfc822 entity */
740 $msg = $msg->entities
[0];
743 if (isset($msg->entities
[($ent_a[$cnt-1])-1]))
745 if (is_object($msg->entities
[($ent_a[$cnt-1])-1]))
747 $msg = $msg->entities
[($ent_a[$cnt-1]-1)];
756 $this->body_part
= $s;
762 $msg->body_part
= '';
764 while ( isset($msg->entities
[$i]))
766 $msg->entities
[$i]->clean_up();
771 function getMailbox()
774 while (is_object($msg->parent
))
778 return $msg->mailbox
;
781 function calcEntity($msg)
783 if ($this->type0
== 'message' && $this->type1
== 'rfc822')
785 $msg->entity_id
= $this->entity_id
.'.0'; /* header of message/rfc822 */
786 } else if (isset($this->entity_id
) && $this->entity_id
!='')
788 $ent_no = count($this->entities
)+
1;
789 $par_ent = substr($this->entity_id
,-2);
790 if ($par_ent{0} == '.')
792 $par_ent = $par_ent{1};
796 $ent_no = count($this->entities
)+
1;
799 $ent = substr($this->entity_id
,0,strrpos($this->entity_id
,'.'));
802 $ent = $ent . ".$ent_no";
807 $msg->entity_id
= $ent;
810 $msg->entity_id
= $ent_no;
814 $ent = $this->entity_id
. ".$ent_no";
815 $msg->entity_id
= $ent;
819 $msg->entity_id
= '0';
821 return $msg->entity_id
;
826 * Bodystructure parser, a recursive function for generating the
827 * entity-tree with all the mime-parts.
829 * It follows RFC2060 and stores all the described fields in the
834 * Ask for me (Marc Groot Koerkamp, stekkel@users.sourceforge.net.
837 function parseStructure($read, $i=0)
841 $cnt = strlen($read);
844 $char = strtoupper($read{$i});
852 $msg = new message();
853 $hdr = new msg_header();
854 $hdr->type0
= 'text';
855 $hdr->type1
= 'plain';
856 $hdr->encoding
= 'us-ascii';
857 $msg->entity_id
= $this->calcEntity($msg);
860 $msg->header
->type0
= 'multipart';
861 $msg->type0
= 'multipart';
862 while ($read{$i} == '(')
864 $res = $msg->parseStructure($read,$i);
866 $msg->addEntity($res[0]);
874 /* multipart properties */
876 $res = $this->parseProperties($read,$i);
883 if (isset($msg->type0
) && $msg->type0
== 'multipart')
886 $res = $msg->parseDisposition($read,$i);
889 } else /* properties */
891 $res = $msg->parseProperties($read,$i);
898 if (isset($msg->type0
) && $msg->type0
== 'multipart')
901 $res= $msg->parseLanguage($read,$i);
906 if ($arg_a[0] == 'message' && $arg_a[1] == 'rfc822')
908 $msg->header
->type0
= $arg_a[0];
909 $msg->type0
= $arg_a[0];
910 $msg->header
->type1
= $arg_a[1];
911 $msg->type1
= $arg_a[1];
912 $rfc822_hdr = new rfc822_header();
913 $res = $msg->parseEnvelope($read,$i,$rfc822_hdr);
915 $msg->rfc822_header
= $res[0];
917 while ($i < $cnt && $read{$i} != '(')
921 $res = $msg->parseStructure($read,$i);
923 $msg->addEntity($res[0]);
928 $res = $msg->parseDisposition($read,$i);
934 if ($arg_a[0] == 'text' ||
935 ($arg_a[0] == 'message' && $arg_a[1] == 'rfc822'))
938 $res = $msg->parseDisposition($read,$i);
944 $res = $msg->parseLanguage($read,$i);
951 if ($arg_a[0] == 'text' ||
952 ($arg_a[0] == 'message' && $arg_a[1] == 'rfc822'))
955 $res = $msg->parseLanguage($read,$i);
960 $i = $msg->parseParenthesis($read,$i);
961 $arg_a[] = ''; /* not yet desribed in rfc2060 */
966 /* unknown argument, skip this part */
967 $i = $msg->parseParenthesis($read,$i);
975 /* inside an entity -> start processing */
976 $debug = substr($read,$i,20);
977 $res = $msg->parseQuote($read,$i);
981 if ($arg_no < 3) $arg_s = strtolower($arg_s); /* type0 and type1 */
986 /* probably NIL argument */
987 if (strtoupper(substr($read,$i,4)) == 'NIL ' ||
988 strtoupper(substr($read,$i,4)) == 'NIL)')
996 /* process the literal value */
997 $res = $msg->parseLiteral($read,$i);
1002 case (is_numeric($read{$i}) ):
1003 /* process integers */
1004 if ($read{$i} == ' ') break;
1005 $arg_s = $read{$i};;
1007 while (preg_match('/^[0-9]{1}$/',$read{$i}))
1009 $arg_s .= $read{$i};
1016 if (isset($msg->type0
) && $msg->type0
== 'multipart')
1025 if ($arg_a[0] == 'text' ||
1026 ($arg_a[0] == 'message' && $arg_a[1] == 'rfc822'))
1028 $shifted_args = true;
1031 $shifted_args = false;
1033 $hdr->type0
= $arg_a[0];
1034 $hdr->type1
= $arg_a[1];
1036 $msg->type0
= $arg_a[0];
1037 $msg->type1
= $arg_a[1];
1042 $hdr->parameters
= $arg_a[2];
1044 $hdr->id
= str_replace( '<', '', str_replace( '>', '', $arg_a[3] ) );
1045 $hdr->description
= $arg_a[4];
1046 $hdr->encoding
= strtolower($arg_a[5]);
1047 $hdr->entity_id
= $msg->entity_id
;
1048 $hdr->size
= $arg_a[6];
1051 $hdr->lines
= $arg_a[7];
1052 if (isset($arg_a[8]))
1054 $hdr->md5
= $arg_a[8];
1056 if (isset($arg_a[9]))
1058 $hdr->disposition
= $arg_a[9];
1060 if (isset($arg_a[10]))
1062 $hdr->language
= $arg_a[10];
1066 if (isset($arg_a[7]))
1068 $hdr->md5
= $arg_a[7];
1070 if (isset($arg_a[8]))
1072 $hdr->disposition
= $arg_a[8];
1074 if (isset($arg_a[9]))
1076 $hdr->language
= $arg_a[9];
1079 $msg->header
= $hdr;
1082 if (substr($msg->entity_id
,-2) == '.0' && $msg->type0
!='multipart')
1086 return (array($msg, $i));
1089 $hdr->type0
= 'multipart';
1090 $hdr->type1
= $arg_a[0];
1091 $msg->type0
= 'multipart';
1092 $msg->type1
= $arg_a[0];
1093 if (is_array($arg_a[1]))
1095 $hdr->parameters
= $arg_a[1];
1097 if (isset($arg_a[2]))
1099 $hdr->disposition
= $arg_a[2];
1101 if (isset($arg_a[3]))
1103 $hdr->language
= $arg_a[3];
1105 $msg->header
= $hdr;
1106 return (array($msg, $i));
1113 } /* parsestructure */
1115 function parseProperties($read, $i)
1117 $properties = array();
1120 while ($read{$i} != ')')
1122 if ($read{$i} == '"')
1124 $res = $this->parseQuote($read,$i);
1127 } else if ($read{$i} == '{')
1129 $res = $this->parseLiteral($read,$i);
1133 if ($prop_name == '' && $arg_s)
1135 $prop_name = strtolower($arg_s);
1136 $properties[$prop_name] = '';
1138 } elseif ($prop_name != '' && $arg_s != '')
1140 $properties[$prop_name] = $arg_s;
1146 return (array($properties, $i));
1149 function parseEnvelope($read, $i, $hdr)
1153 $cnt = strlen($read);
1154 while ($i< $cnt && $read{$i} != ')')
1157 $char = strtoupper($read{$i});
1161 $res = $this->parseQuote($read,$i);
1167 $res = $this->parseLiteral($read,$i);
1173 /* probably NIL argument */
1174 if (strtoupper(substr($read,$i,3)) == 'NIL') {
1181 /* Address structure
1182 * With group support.
1183 * Note: Group support is useless on SMTP connections
1184 * because the protocol doesn't support it
1189 while ($i < $cnt && $read{$i} != ')')
1191 if ($read{$i} == '(')
1193 $res = $this->parseAddress($read,$i);
1196 if ($addr->host
== '' && $addr->mailbox
!= '')
1198 /* start of group */
1199 $group = $addr->mailbox
;
1200 $group_addr = $addr;
1202 } elseif ($group && $addr->host
== '' && $addr->mailbox
== '')
1205 if ($a == $j+
1) /* no group members */
1207 $group_addr->group
= $group;
1208 $group_addr->mailbox
= '';
1209 $group_addr->personal
= "$group: Undisclosed recipients;";
1210 $addr_a[] = $group_addr;
1215 $addr->group
= $group;
1229 if (count($arg_a) > 9)
1231 /* argument 1: date */
1232 $d = strtr($arg_a[0], array(' ' => ' '));
1233 $d = explode(' ', $d);
1234 $hdr->date
= getTimeStamp($d);
1235 /* argument 2: subject */
1236 if (!trim($arg_a[1]))
1238 $arg_a[1]= _("(no subject)");
1240 $hdr->subject
= $arg_a[1];
1241 /* argument 3: from */
1242 $hdr->from
= $arg_a[2][0];
1243 /* argument 4: sender */
1244 $hdr->sender
= $arg_a[3][0];
1245 /* argument 5: reply-to */
1246 $hdr->replyto
= $arg_a[4][0];
1247 /* argument 6: to */
1248 $hdr->to
= $arg_a[5];
1249 /* argument 7: cc */
1250 $hdr->cc
= $arg_a[6];
1251 /* argument 8: bcc */
1252 $hdr->bcc
= $arg_a[7];
1253 /* argument 9: in-reply-to */
1254 $hdr->inreplyto
= $arg_a[8];
1255 /* argument 10: message-id */
1256 $hdr->message_id
= $arg_a[9];
1258 return (array($hdr,$i));
1261 function parseLiteral($read, $i)
1265 while ($read{$i} != '}')
1267 $lit_cnt .= $read{$i};
1270 $lit_cnt +
=2; /* add the { and } characters */
1272 for ($j = 0; $j < $lit_cnt; $j++
)
1277 return (array($s, $i));
1280 function parseQuote($read, $i)
1284 while ($read{$i} != '"')
1286 if ($read{$i} == '\\')
1293 return (array($s, $i));
1296 function parseAddress($read, $i)
1299 while ($read{$i} != ')' )
1301 $char = strtoupper($read{$i});
1305 $res = $this->parseQuote($read,$i);
1310 $res = $this->parseLiteral($read,$i);
1316 if (strtoupper(substr($read,$i,3)) == 'NIL') {
1326 if (count($arg_a) == 4)
1328 $adr = new address_structure();
1329 $adr->personal
= $arg_a[0];
1330 $adr->adl
= $arg_a[1];
1331 $adr->mailbox
= $arg_a[2];
1332 $adr->host
= $arg_a[3];
1337 return (array($adr,$i));
1340 function parseDisposition($read,$i)
1343 while ($read{$i} != ')')
1348 $res = $this->parseQuote($read,$i);
1353 $res = $this->parseLiteral($read,$i);
1358 $res = $this->parseProperties($read,$i);
1367 if (isset($arg_a[0]))
1369 $disp = new disposition($arg_a[0]);
1370 if (isset($arg_a[1]))
1372 $disp->properties
= $arg_a[1];
1375 if (is_object($disp))
1377 return (array($disp, $i));
1380 return (array('',$i));
1384 function parseLanguage($read,$i)
1386 /* no idea how to process this one without examples */
1388 while ($read{$i} != ')')
1393 $res = $this->parseQuote($read,$i);
1398 $res = $this->parseLiteral($read,$i);
1403 $res = $this->parseProperties($read,$i);
1412 if (isset($arg_a[0]))
1414 $lang = new language($arg_a[0]);
1415 if (isset($arg_a[1]))
1417 $lang->properties
= $arg_a[1];
1420 if (is_object($lang))
1422 return (array($lang, $i));
1425 return (array('', $i));
1429 function parseParenthesis($read,$i)
1431 while ($read{$i} != ')')
1436 $res = $this->parseQuote($read,$i);
1440 $res = $this->parseLiteral($read,$i);
1444 $res = $this->parseParenthesis($read,$i);
1455 /* function to fill the message structure in case the bodystructure
1456 isn't available NOT FINISHED YET
1458 function parseMessage($read, $type0, $type1)
1463 $rfc822_header = true;
1464 $mime_header = false;
1467 $mime_header = true;
1468 $rfc822_header = false;
1474 for ($i=1; $i < $count; $i++
)
1476 $line = trim($body[$i]);
1477 if ( ( $mime_header ||
$rfc822_header) &&
1478 (preg_match("/^.*boundary=\"?(.+(?=\")|.+).*/i",$line,$reg)) )
1482 $bndreg = str_replace("\\","\\\\",$bndreg);
1483 $bndreg = str_replace("?","\\?",$bndreg);
1484 $bndreg = str_replace("+","\\+",$bndreg);
1485 $bndreg = str_replace(".","\\.",$bndreg);
1486 $bndreg = str_replace("/","\\/",$bndreg);
1487 $bndreg = str_replace("-","\\-",$bndreg);
1488 $bndreg = str_replace("(","\\(",$bndreg);
1489 $bndreg = str_replace(")","\\)",$bndreg);
1490 } elseif ( $rfc822_header && $line == '' )
1492 $rfc822_header = false;
1493 if ($msg->type0
== 'multipart')
1495 $mime_header = true;
1499 if (($line{0} == '-' ||
$rfc822_header) && isset($boundaries[0]))
1501 $cnt=count($boundaries)-1;
1502 $bnd = $boundaries[$cnt]['bnd'];
1503 $bndreg = $boundaries[$cnt]['bndreg'];
1505 $regstr = '/^--'."($bndreg)".".*".'/';
1506 if (preg_match($regstr,$line,$reg) )
1508 $bndlen = strlen($reg[1]);
1510 if (strlen($line) > ($bndlen +
3))
1512 if ($line{$bndlen+
2} == '-' && $line{$bndlen+
3} == '-')
1517 /* calc offset and return $msg */
1518 // $entStr = CalcEntity("$entStr",-1);
1519 array_pop($boundaries);
1520 $mime_header = true;
1524 $mime_header = true;
1526 // $entStr = CalcEntity("$entStr",0);
1539 function findDisplayEntity ($entity = array(), $alt_order = array('text/plain','text/html'))
1542 $type = $this->type0
.'/'.$this->type1
;
1543 if ( $type == 'multipart/alternative')
1545 $msg = $this->findAlternativeEntity($alt_order);
1546 if (count($msg->entities
) == 0)
1548 $entity[] = $msg->entity_id
;
1551 $entity = $msg->findDisplayEntity($entity, $alt_order);
1554 } else if ( $type == 'multipart/related')
1556 $msgs = $this->findRelatedEntity();
1557 foreach ($msgs as $msg)
1559 if (count($msg->entities
) == 0)
1561 $entity[] = $msg->entity_id
;
1564 $entity = $msg->findDisplayEntity($entity,$alt_order);
1567 if (count($msgs) > 0) {
1570 } else if ($this->type0
== 'text' &&
1571 ($this->type1
== 'plain' ||
1572 $this->type1
== 'html' ||
1573 $this->type1
== 'message') &&
1574 isset($this->entity_id
) )
1576 if (count($this->entities
) == 0)
1578 if (strtolower($this->header
->disposition
->name
) != 'attachment')
1580 $entity[] = $this->entity_id
;
1586 foreach ($this->entities
as $ent) {
1587 if(strtolower($ent->header
->disposition
->name
) != 'attachment' &&
1588 ($ent->type0
!= 'message' && $ent->type1
!= 'rfc822'))
1590 $entity = $ent->findDisplayEntity($entity, $alt_order);
1595 while ( isset($this->entities[$i]) && !$found &&
1596 (strtolower($this->entities[$i]->header->disposition->name)
1598 ($this->entities[$i]->type0 != 'message' &&
1599 $this->entities[$i]->type1 != 'rfc822' )
1602 $entity = $this->entities[$i]->findDisplayEntity($entity, $alt_order);
1609 function findAlternativeEntity ($alt_order)
1611 /* if we are dealing with alternative parts then we choose the best
1612 * viewable message supported by SM.
1616 $altcount = count($alt_order);
1617 foreach($this->entities
as $ent)
1619 $type = $ent->header
->type0
.'/'.$ent->header
->type1
;
1620 if ($type == 'multipart/related')
1622 $type = $ent->header
->getParameter('type');
1624 for ($j = $best_view; $j < $altcount; $j++
)
1626 if ($alt_order[$j] == $type && $j >= $best_view)
1636 function findRelatedEntity ()
1639 $entcount = count($this->entities
);
1640 for ($i = 0; $i < $entcount; $i++
)
1642 $type = $this->entities
[$i]->header
->type0
.'/'.$this->entities
[$i]->header
->type1
;
1643 if ($this->header
->getParameter('type') == $type)
1645 $msgs[] = $this->entities
[$i];
1651 function getAttachments($exclude_id=array(), $result = array())
1653 if ($this->type0
== 'message' && $this->type1
== 'rfc822')
1655 $this = $this->entities
[0];
1657 if (count($this->entities
))
1659 foreach ($this->entities
as $entity)
1662 foreach ($exclude_id as $excl)
1664 if ($entity->entity_id
=== $excl)
1671 if ($entity->type0
== 'multipart' &&
1672 $entity->type1
!= 'related')
1674 $result = $entity->getAttachments($exclude_id, $result);
1675 } else if ($entity->type0
!= 'multipart')
1677 $result[] = $entity;
1684 foreach ($exclude_id as $excl)
1686 if ($this->entity_id
== $excl)
1706 function disposition($name)
1708 $this->name
= $name;
1709 $this->properties
= array();
1712 function getProperty($par)
1714 $value = strtolower($par);
1715 if (isset($this->properties
[$par]))
1717 return $this->properties
[$par];
1726 function language($name)
1728 $this->name
= $name;
1729 $this->properties
= array();
1738 function content_type($type)
1740 $pos = strpos($type,'/');
1743 $this->type0
= substr($type,0,$pos);
1744 $this->type1
= substr($type,$pos+
1);
1747 $this->type0
= $type;
1749 $this->properties
= array();