// // This file is part of IlohaMail. IlohaMail is free software released // under the GPL license. See enclosed file COPYING for details, or // see http://www.fsf.org/copyleft/gpl.html // ///////////////////////////////////////////////////////// /******************************************************** FILE: include/mime.inc PURPOSE: Provide functions for handling mime messages. USAGE: Use iil_C_FetchStructureString to get IMAP structure stirng, then pass that through iml_GetRawStructureArray() to get root node to a nested data structure. Pass root node to the iml_GetPart*() functions to retreive individual bits of info. ********************************************************/ $MIME_INVALID = -1; $MIME_TEXT = 0; $MIME_MULTIPART = 1; $MIME_MESSAGE = 2; $MIME_APPLICATION = 3; $MIME_AUDIO = 4; $MIME_IMAGE = 5; $MIME_VIDEO = 6; $MIME_OTHER = 7; function iml_ClosingParenPos($str, $start){ $level=0; $len = strlen($str); $in_quote = 0; for ($i=$start;$i<$len;$i++){ if ($str[$i]=="\"") $in_quote = ($in_quote + 1) % 2; if (!$in_quote){ if ($str[$i]=="(") $level++; else if (($level > 0) && ($str[$i]==")")) $level--; else if (($level == 0) && ($str[$i]==")")) return $i; } } } function iml_ParseBSString($str){ $id = 0; $a = array(); $len = strlen($str); $in_quote = 0; for ($i=0; $i<$len; $i++){ if ($str[$i] == "\"") $in_quote = ($in_quote + 1) % 2; else if (!$in_quote){ if ($str[$i] == " ") $id++; //space means new element else if ($str[$i]=="("){ //new part $i++; $endPos = iml_ClosingParenPos($str, $i); $partLen = $endPos - $i; $part = substr($str, $i, $partLen); $a[$id] = iml_ParseBSString($part); //send part string if ($verbose){ echo "{>".$endPos."}"; flush(); } $i = $endPos; }else $a[$id].=$str[$i]; //add to current element in array }else if ($in_quote){ if ($str[$i]=="\\") $i++; //escape backslashes else $a[$id].=$str[$i]; //add to current element in array } } reset($a); return $a; } function iml_GetRawStructureArray($str){ $line=substr($str, 1, strlen($str) - 2); $line = str_replace(")(", ") (", $line); $struct = iml_ParseBSString($line); if ((strcasecmp($struct[0], "message")==0) && (strcasecmp($struct[1], "rfc822")==0)){ $struct = array($struct); } return $struct; } function iml_GetPartArray($a, $part){ if (!is_array($a)) return false; if (strpos($part, ".") > 0){ $original_part = $part; $pos = strpos($part, "."); $rest = substr($original_part, $pos+1); $part = substr($original_part, 0, $pos); if ((strcasecmp($a[0], "message")==0) && (strcasecmp($a[1], "rfc822")==0)){ $a = $a[8]; } //echo "m - part: $original_part current: $part rest: $rest array: ".implode(" ", $a)."
\n"; return iml_GetPartArray($a[$part-1], $rest); }else if ($part>0){ if ((strcasecmp($a[0], "message")==0) && (strcasecmp($a[1], "rfc822")==0)){ $a = $a[8]; } //echo "s - part: $part rest: $rest array: ".implode(" ", $a)."
\n"; if (is_array($a[$part-1])) return $a[$part-1]; else return $a; }else if (($part==0) || (empty($part))){ return $a; } } function iml_GetNumParts($a, $part){ if (is_array($a)){ $parent=iml_GetPartArray($a, $part); if ((strcasecmp($parent[0], "message")==0) && (strcasecmp($parent[1], "rfc822")==0)){ $parent = $parent[8]; } $is_array=true; $c=0; while (( list ($key, $val) = each ($parent) )&&($is_array)){ $is_array=is_array($parent[$key]); if ($is_array) $c++; } return $c; } return false; } function iml_GetPartTypeString($a, $part){ $part_a=iml_GetPartArray($a, $part); if ($part_a){ if (is_array($part_a[0])){ $type_str = "MULTIPART/"; reset($part_a); while(list($n,$element)=each($part_a)){ if (!is_array($part_a[$n])){ $type_str.=$part_a[$n]; break; } } return $type_str; }else return $part_a[0]."/".$part_a[1]; }else return false; } function iml_GetFirstTextPart($structure,$part){ if ($part==0) $part=""; $typeCode = -1; while ($typeCode!=0){ $typeCode = iml_GetPartTypeCode($structure, $part); if ($typeCode == 1){ $part .= (empty($part)?"":".")."1"; }else if ($typeCode > 0){ $parts_a = explode(".", $part); $lastPart = count($parts_a) - 1; $parts_a[$lastPart] = (int)$parts_a[$lastPart] + 1; $part = implode(".", $parts_a); }else if ($typeCode == -1){ return ""; } } return $part; } function iml_GetPartTypeCode($a, $part){ $types=array(0=>"text",1=>"multipart",2=>"message",3=>"application",4=>"audio",5=>"image",6=>"video",7=>"other"); $part_a=iml_GetPartArray($a, $part); if ($part_a){ if (is_array($part_a[0])) $str="multipart"; else $str=$part_a[0]; $code=7; while ( list($key, $val) = each($types)) if (strcasecmp($val, $str)==0) $code=$key; return $code; }else return -1; } function iml_GetPartEncodingCode($a, $part){ $encodings=array("7BIT", "8BIT", "BINARY", "BASE64", "QUOTED-PRINTABLE", "OTHER"); $part_a=iml_GetPartArray($a, $part); if ($part_a){ if (is_array($part_a[0])) return -1; else $str=$part_a[5]; $code=5; while ( list($key, $val) = each($encodings)) if (strcasecmp($val, $str)==0) $code=$key; return $code; }else return -1; } function iml_GetPartEncodingString($a, $part){ $part_a=iml_GetPartArray($a, $part); if ($part_a){ if (is_array($part_a[0])) return -1; else return $part_a[5]; }else return -1; } function iml_GetPartSize($a, $part){ $part_a=iml_GetPartArray($a, $part); if ($part_a){ if (is_array($part_a[0])) return -1; else return $part_a[6]; }else return -1; } function iml_GetPartID($a, $part){ $part_a=iml_GetPartArray($a, $part); if ($part_a){ if (is_array($part_a[0])) return -1; else return $part_a[3]; }else return -1; } function iml_GetPartDisposition($a, $part){ $part_a=iml_GetPartArray($a, $part); if ($part_a){ if (is_array($part_a[0])) return -1; else{ $id = count($part_a) - 2; if (is_array($part_a[$id])) return $part_a[$id][0]; else return ""; } }else return ""; } function iml_GetPartName($a, $part){ $part_a=iml_GetPartArray($a, $part); if ($part_a){ if (is_array($part_a[0])) return -1; else{ $name = ""; if (is_array($part_a[2])){ //first look in content type $name=""; while ( list($key, $val) = each ($part_a[2])){ if ((strcasecmp($val, "NAME")==0)||(strcasecmp($val, "FILENAME")==0)) $name=$part_a[2][$key+1]; } } if (empty($name)){ //check in content disposition $id = count($part_a) - 2; if ((is_array($part_a[$id])) && (is_array($part_a[$id][1]))){ $array = $part_a[$id][1]; while ( list($key, $val) = each($array)){ if ((strcasecmp($val, "NAME")==0)||(strcasecmp($val, "FILENAME")==0)) $name=$array[$key+1]; } } } return $name; } }else return ""; } function iml_GetPartCharset($a, $part){ $part_a=iml_GetPartArray($a, $part); if ($part_a){ if (is_array($part_a[0])) return -1; else{ if (is_array($part_a[2])){ $name=""; while ( list($key, $val) = each ($part_a[2])) if (strcasecmp($val, "charset")==0) $name=$part_a[2][$key+1]; return $name; } else return ""; } }else return ""; } function iml_GetPartList($a, $part){ //echo "MOO?"; flush(); $data = array(); $num_parts = iml_GetNumParts($a, $part); //echo "($num_parts)"; flush(); if ($num_parts !== false){ //echo "\n"; for ($i = 0; $i<$num_parts; $i++){ $part_code = $part.(empty($part)?"":".").($i+1); $part_type = iml_GetPartTypeCode($a, $part_code); $part_disposition = iml_GetPartDisposition($a, $part_code); //echo "\n"; if (strcasecmp($part_disposition, "attachment")!=0 && (($part_type == 1) || ($part_type==2))){ $data = array_merge($data, iml_GetPartList($a, $part_code)); }else{ $data[$part_code]["typestring"] = iml_GetPartTypeString($a, $part_code); $data[$part_code]["disposition"] = $part_disposition; $data[$part_code]["size"] = iml_GetPartSize($a, $part_code); $data[$part_code]["name"] = iml_GetPartName($a, $part_code); $data[$part_code]["id"] = iml_GetPartID($a, $part_code); } } } return $data; } function iml_GetNextPart($part){ if (strpos($part, ".")===false) return $part++; else{ $parts_a = explode(".", $part); $num_levels = count($parts_a); $parts_a[$num_levels-1]++; return implode(".", $parts_a); } } ?>