home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.4.0.exe / Apache2 / admin / mime.inc < prev    next >
Encoding:
Text File  |  2003-12-27  |  8.8 KB  |  313 lines

  1. <?php
  2. /////////////////////////////////////////////////////////
  3. //    
  4. //    Iloha MIME Library (IML)
  5. //
  6. //    (C)Copyright 2002 Ryo Chijiiwa <Ryo@IlohaMail.org>
  7. //
  8. //    This file is part of IlohaMail. IlohaMail is free software released 
  9. //    under the GPL license.  See enclosed file COPYING for details, or 
  10. //    see http://www.fsf.org/copyleft/gpl.html
  11. //
  12. /////////////////////////////////////////////////////////
  13.  
  14. /********************************************************
  15.  
  16.     FILE: include/mime.inc
  17.     PURPOSE:
  18.         Provide functions for handling mime messages.
  19.     USAGE:
  20.         Use iil_C_FetchStructureString to get IMAP structure stirng, then pass that through
  21.         iml_GetRawStructureArray() to get root node to a nested data structure.
  22.         Pass root node to the iml_GetPart*() functions to retreive individual bits of info.
  23.  
  24. ********************************************************/
  25. $MIME_INVALID = -1;
  26. $MIME_TEXT = 0;
  27. $MIME_MULTIPART = 1;
  28. $MIME_MESSAGE = 2;
  29. $MIME_APPLICATION = 3;
  30. $MIME_AUDIO = 4;
  31. $MIME_IMAGE = 5;
  32. $MIME_VIDEO = 6;
  33. $MIME_OTHER = 7;
  34.  
  35. function iml_ClosingParenPos($str, $start){
  36.     $level=0;
  37.     $len = strlen($str);
  38.     $in_quote = 0;
  39.     for ($i=$start;$i<$len;$i++){
  40.         if ($str[$i]=="\"") $in_quote = ($in_quote + 1) % 2;
  41.         if (!$in_quote){
  42.             if ($str[$i]=="(") $level++;
  43.             else if (($level > 0) && ($str[$i]==")")) $level--;
  44.             else if (($level == 0) && ($str[$i]==")")) return $i;
  45.         }
  46.     }
  47. }
  48.  
  49. function iml_ParseBSString($str){    
  50.     
  51.     $id = 0;
  52.     $a = array();
  53.     $len = strlen($str);
  54.     
  55.     $in_quote = 0;
  56.     for ($i=0; $i<$len; $i++){
  57.         if ($str[$i] == "\"") $in_quote = ($in_quote + 1) % 2;
  58.         else if (!$in_quote){
  59.             if ($str[$i] == " ") $id++; //space means new element
  60.             else if ($str[$i]=="("){ //new part
  61.                 $i++;
  62.                 $endPos = iml_ClosingParenPos($str, $i);
  63.                 $partLen = $endPos - $i;
  64.                 $part = substr($str, $i, $partLen);
  65.                 $a[$id] = iml_ParseBSString($part); //send part string
  66.                 if ($verbose){
  67.                     echo "{>".$endPos."}";
  68.                     flush();
  69.                 }
  70.                 $i = $endPos;
  71.             }else $a[$id].=$str[$i]; //add to current element in array
  72.         }else if ($in_quote){
  73.             if ($str[$i]=="\\") $i++; //escape backslashes
  74.             else $a[$id].=$str[$i]; //add to current element in array
  75.         }
  76.     }
  77.         
  78.     reset($a);
  79.     return $a;
  80. }
  81.  
  82. function iml_GetRawStructureArray($str){
  83.     $line=substr($str, 1, strlen($str) - 2);
  84.     $line = str_replace(")(", ") (", $line);
  85.     
  86.     $struct = iml_ParseBSString($line);
  87.     if ((strcasecmp($struct[0], "message")==0) && (strcasecmp($struct[1], "rfc822")==0)){
  88.         $struct = array($struct);
  89.     }
  90.     return $struct;
  91. }
  92.  
  93. function iml_GetPartArray($a, $part){
  94.     if (!is_array($a)) return false;
  95.     if (strpos($part, ".") > 0){
  96.         $original_part = $part;
  97.         $pos = strpos($part, ".");
  98.         $rest = substr($original_part, $pos+1);
  99.         $part = substr($original_part, 0, $pos);
  100.         if ((strcasecmp($a[0], "message")==0) && (strcasecmp($a[1], "rfc822")==0)){
  101.             $a = $a[8];
  102.         }
  103.         //echo "m - part: $original_part current: $part rest: $rest array: ".implode(" ", $a)."<br>\n";
  104.         return iml_GetPartArray($a[$part-1], $rest);
  105.     }else if ($part>0){
  106.         if ((strcasecmp($a[0], "message")==0) && (strcasecmp($a[1], "rfc822")==0)){
  107.             $a = $a[8];
  108.         }
  109.         //echo "s - part: $part rest: $rest array: ".implode(" ", $a)."<br>\n";
  110.         if (is_array($a[$part-1])) return $a[$part-1];
  111.         else return false;
  112.     }else if (($part==0) || (empty($part))){
  113.         return $a;
  114.     }
  115. }
  116.  
  117. function iml_GetNumParts($a, $part){
  118.     if (is_array($a)){
  119.         $parent=iml_GetPartArray($a, $part);
  120.         
  121.         if ((strcasecmp($parent[0], "message")==0) && (strcasecmp($parent[1], "rfc822")==0)){
  122.             $parent = $parent[8];
  123.         }
  124.  
  125.         $is_array=true;
  126.         $c=0;
  127.         while (( list ($key, $val) = each ($parent) )&&($is_array)){
  128.             $is_array=is_array($parent[$key]);
  129.             if ($is_array) $c++;
  130.         }
  131.         return $c;
  132.     }
  133.     
  134.     return false;
  135. }
  136.  
  137. function iml_GetPartTypeString($a, $part){
  138.     $part_a=iml_GetPartArray($a, $part);
  139.     if ($part_a){
  140.         if (is_array($part_a[0])) return "MULTIPART/".$part_a[count($part_a)-4];
  141.         else return $part_a[0]."/".$part_a[1];
  142.     }else return false;
  143. }
  144.  
  145. function iml_GetFirstTextPart($structure,$part){
  146.     if ($part==0) $part="";
  147.     $typeCode = -1;
  148.     while ($typeCode!=0){
  149.         $typeCode = iml_GetPartTypeCode($structure, $part);
  150.         if ($typeCode == 1){
  151.             $part .= (empty($part)?"":".")."1";
  152.         }else if ($typeCode > 0){
  153.             $parts_a = explode(".", $part);
  154.             $lastPart = count($parts_a) - 1;
  155.             $parts_a[$lastPart] = (int)$parts_a[$lastPart] + 1;
  156.             $part = implode(".", $parts_a);
  157.         }else if ($typeCode == -1){
  158.             return "";
  159.         }
  160.     }
  161.     
  162.     return $part;
  163. }
  164.  
  165. function iml_GetPartTypeCode($a, $part){
  166.     $types=array(0=>"text",1=>"multipart",2=>"message",3=>"application",4=>"audio",5=>"image",6=>"video",7=>"other");
  167.  
  168.     $part_a=iml_GetPartArray($a, $part);
  169.     if ($part_a){
  170.         if (is_array($part_a[0])) $str="multipart";
  171.         else $str=$part_a[0];
  172.  
  173.         $code=7;
  174.         while ( list($key, $val) = each($types)) if (strcasecmp($val, $str)==0) $code=$key;
  175.         return $code;
  176.     }else return -1;
  177. }
  178.  
  179. function iml_GetPartEncodingCode($a, $part){
  180.     $encodings=array("7BIT", "8BIT", "BINARY", "BASE64", "QUOTED-PRINTABLE", "OTHER");
  181.  
  182.     $part_a=iml_GetPartArray($a, $part);
  183.     if ($part_a){
  184.         if (is_array($part_a[0])) return -1;
  185.         else $str=$part_a[5];
  186.  
  187.         $code=5;
  188.         while ( list($key, $val) = each($encodings)) if (strcasecmp($val, $str)==0) $code=$key;
  189.  
  190.         return $code;
  191.  
  192.     }else return -1;
  193. }
  194.  
  195. function iml_GetPartEncodingString($a, $part){
  196.     $part_a=iml_GetPartArray($a, $part);
  197.     if ($part_a){
  198.         if (is_array($part_a[0])) return -1;
  199.         else return $part_a[5];
  200.     }else return -1;
  201. }
  202.  
  203. function iml_GetPartSize($a, $part){
  204.     $part_a=iml_GetPartArray($a, $part);
  205.     if ($part_a){
  206.         if (is_array($part_a[0])) return -1;
  207.         else return $part_a[6];
  208.     }else return -1;
  209. }
  210.  
  211. function iml_GetPartID($a, $part){
  212.     $part_a=iml_GetPartArray($a, $part);
  213.     if ($part_a){
  214.         if (is_array($part_a[0])) return -1;
  215.         else return $part_a[3];
  216.     }else return -1;
  217. }
  218.  
  219. function iml_GetPartDisposition($a, $part){
  220.     $part_a=iml_GetPartArray($a, $part);
  221.     if ($part_a){
  222.         if (is_array($part_a[0])) return -1;
  223.         else{
  224.             $id = count($part_a) - 2;
  225.             if (is_array($part_a[$id])) return $part_a[$id][0];
  226.             else return "";
  227.         }
  228.     }else return "";
  229. }
  230.  
  231. function iml_GetPartName($a, $part){
  232.     $part_a=iml_GetPartArray($a, $part);
  233.     if ($part_a){
  234.         if (is_array($part_a[0])) return -1;
  235.         else{
  236.             $name = "";
  237.             if (is_array($part_a[2])){
  238.                 //first look in content type
  239.                 $name="";
  240.                 while ( list($key, $val) = each ($part_a[2])){
  241.                     if ((strcasecmp($val, "NAME")==0)||(strcasecmp($val, "FILENAME")==0)) 
  242.                         $name=$part_a[2][$key+1];
  243.                 }
  244.             }
  245.             if (empty($name)){
  246.                 //check in content disposition
  247.                 $id = count($part_a) - 2;
  248.                 if ((is_array($part_a[$id])) && (is_array($part_a[$id][1]))){
  249.                     $array = $part_a[$id][1];
  250.                     while ( list($key, $val) = each($array)){
  251.                         if ((strcasecmp($val, "NAME")==0)||(strcasecmp($val, "FILENAME")==0)) 
  252.                             $name=$array[$key+1];
  253.                     }
  254.                 }
  255.             }
  256.             return $name;
  257.         }
  258.     }else return "";
  259. }
  260.  
  261.  
  262. function iml_GetPartCharset($a, $part){
  263.     $part_a=iml_GetPartArray($a, $part);
  264.     if ($part_a){
  265.         if (is_array($part_a[0])) return -1;
  266.         else{
  267.             if (is_array($part_a[2])){
  268.                 $name="";
  269.                 while ( list($key, $val) = each ($part_a[2])) if (strcasecmp($val, "charset")==0) $name=$part_a[2][$key+1];
  270.                 return $name;
  271.             }
  272.             else return "";
  273.         }
  274.     }else return "";
  275. }
  276.  
  277. function iml_GetPartList($a, $part){
  278.     //echo "MOO?"; flush();
  279.     $data = array();
  280.     $num_parts = iml_GetNumParts($a, $part);
  281.     //echo "($num_parts)"; flush();
  282.     if ($num_parts !== false){
  283.         //echo "<!-- ($num_parts parts)//-->\n";
  284.         for ($i = 0; $i<$num_parts; $i++){
  285.             $part_code = $part.(empty($part)?"":".").($i+1);
  286.             $part_type = iml_GetPartTypeCode($a, $part_code);
  287.             $part_disposition = iml_GetPartDisposition($a, $part_code);
  288.             //echo "<!-- part: $part_code type: $part_type //-->\n";
  289.             if (strcasecmp($part_disposition, "attachment")!=0 && 
  290.                 (($part_type == 1) || ($part_type==2))){
  291.                 $data = array_merge($data, iml_GetPartList($a, $part_code));
  292.             }else{
  293.                 $data[$part_code]["typestring"] = iml_GetPartTypeString($a, $part_code);
  294.                 $data[$part_code]["disposition"] = $part_disposition;
  295.                 $data[$part_code]["size"] = iml_GetPartSize($a, $part_code);
  296.                 $data[$part_code]["name"] = iml_GetPartName($a, $part_code);
  297.                 $data[$part_code]["id"] = iml_GetPartID($a, $part_code);
  298.             }
  299.         }
  300.     }
  301.     return $data;
  302. }
  303.  
  304. function iml_GetNextPart($part){
  305.     if (strpos($part, ".")===false) return $part++;
  306.     else{
  307.         $parts_a = explode(".", $part);
  308.         $num_levels = count($parts_a);
  309.         $parts_a[$num_levels-1]++;
  310.         return implode(".", $parts_a);
  311.     }
  312. }
  313. ?>