source: subversion/branches/devel-vnext/program/lib/mime.inc @ 589

Last change on this file since 589 was 589, checked in by till, 6 years ago

+ rc1 based checkin

File size: 9.0 KB
Line 
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
35function 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
49function 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
82function 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
93function 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 $a;
112        }else if (($part==0) || (empty($part))){
113                return $a;
114        }
115}
116
117function 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
137function iml_GetPartTypeString($a, $part){
138        $part_a=iml_GetPartArray($a, $part);
139        if ($part_a){
140                if (is_array($part_a[0])){
141                        $type_str = "MULTIPART/";
142                        reset($part_a);
143                        while(list($n,$element)=each($part_a)){
144                                if (!is_array($part_a[$n])){
145                                        $type_str.=$part_a[$n];
146                                        break;
147                                }
148                        }
149                        return $type_str;
150                }else return $part_a[0]."/".$part_a[1];
151        }else return false;
152}
153
154function iml_GetFirstTextPart($structure,$part){
155    if ($part==0) $part="";
156    $typeCode = -1;
157    while ($typeCode!=0){
158        $typeCode = iml_GetPartTypeCode($structure, $part);
159        if ($typeCode == 1){
160            $part .= (empty($part)?"":".")."1";
161        }else if ($typeCode > 0){
162            $parts_a = explode(".", $part);
163            $lastPart = count($parts_a) - 1;
164            $parts_a[$lastPart] = (int)$parts_a[$lastPart] + 1;
165            $part = implode(".", $parts_a);
166        }else if ($typeCode == -1){
167            return "";
168        }
169    }
170   
171    return $part;
172}
173
174function iml_GetPartTypeCode($a, $part){
175        $types=array(0=>"text",1=>"multipart",2=>"message",3=>"application",4=>"audio",5=>"image",6=>"video",7=>"other");
176
177        $part_a=iml_GetPartArray($a, $part);
178        if ($part_a){
179                if (is_array($part_a[0])) $str="multipart";
180                else $str=$part_a[0];
181
182                $code=7;
183                while ( list($key, $val) = each($types)) if (strcasecmp($val, $str)==0) $code=$key;
184                return $code;
185        }else return -1;
186}
187
188function iml_GetPartEncodingCode($a, $part){
189        $encodings=array("7BIT", "8BIT", "BINARY", "BASE64", "QUOTED-PRINTABLE", "OTHER");
190
191        $part_a=iml_GetPartArray($a, $part);
192        if ($part_a){
193                if (is_array($part_a[0])) return -1;
194                else $str=$part_a[5];
195
196                $code=5;
197                while ( list($key, $val) = each($encodings)) if (strcasecmp($val, $str)==0) $code=$key;
198
199                return $code;
200
201        }else return -1;
202}
203
204function iml_GetPartEncodingString($a, $part){
205        $part_a=iml_GetPartArray($a, $part);
206        if ($part_a){
207                if (is_array($part_a[0])) return -1;
208                else return $part_a[5];
209        }else return -1;
210}
211
212function iml_GetPartSize($a, $part){
213        $part_a=iml_GetPartArray($a, $part);
214        if ($part_a){
215                if (is_array($part_a[0])) return -1;
216                else return $part_a[6];
217        }else return -1;
218}
219
220function iml_GetPartID($a, $part){
221        $part_a=iml_GetPartArray($a, $part);
222        if ($part_a){
223                if (is_array($part_a[0])) return -1;
224                else return $part_a[3];
225        }else return -1;
226}
227
228function iml_GetPartDisposition($a, $part){
229        $part_a=iml_GetPartArray($a, $part);
230        if ($part_a){
231                if (is_array($part_a[0])) return -1;
232                else{
233            $id = count($part_a) - 2;
234                        if (is_array($part_a[$id])) return $part_a[$id][0];
235                        else return "";
236                }
237        }else return "";
238}
239
240function iml_GetPartName($a, $part){
241        $part_a=iml_GetPartArray($a, $part);
242        if ($part_a){
243                if (is_array($part_a[0])) return -1;
244                else{
245            $name = "";
246                        if (is_array($part_a[2])){
247                //first look in content type
248                                $name="";
249                                while ( list($key, $val) = each ($part_a[2])){
250                    if ((strcasecmp($val, "NAME")==0)||(strcasecmp($val, "FILENAME")==0))
251                        $name=$part_a[2][$key+1];
252                }
253                        }
254            if (empty($name)){
255                //check in content disposition
256                $id = count($part_a) - 2;
257                if ((is_array($part_a[$id])) && (is_array($part_a[$id][1]))){
258                    $array = $part_a[$id][1];
259                    while ( list($key, $val) = each($array)){
260                        if ((strcasecmp($val, "NAME")==0)||(strcasecmp($val, "FILENAME")==0))
261                            $name=$array[$key+1];
262                    }
263                }
264            }
265                        return $name;
266                }
267        }else return "";
268}
269
270
271function iml_GetPartCharset($a, $part){
272        $part_a=iml_GetPartArray($a, $part);
273        if ($part_a){
274                if (is_array($part_a[0])) return -1;
275                else{
276                        if (is_array($part_a[2])){
277                                $name="";
278                                while ( list($key, $val) = each ($part_a[2])) if (strcasecmp($val, "charset")==0) $name=$part_a[2][$key+1];
279                                return $name;
280                        }
281                        else return "";
282                }
283        }else return "";
284}
285
286function iml_GetPartList($a, $part){
287        //echo "MOO?"; flush();
288        $data = array();
289        $num_parts = iml_GetNumParts($a, $part);
290        //echo "($num_parts)"; flush();
291        if ($num_parts !== false){
292                //echo "<!-- ($num_parts parts)//-->\n";
293                for ($i = 0; $i<$num_parts; $i++){
294                        $part_code = $part.(empty($part)?"":".").($i+1);
295                        $part_type = iml_GetPartTypeCode($a, $part_code);
296                        $part_disposition = iml_GetPartDisposition($a, $part_code);
297                        //echo "<!-- part: $part_code type: $part_type //-->\n";
298                        if (strcasecmp($part_disposition, "attachment")!=0 &&
299                                (($part_type == 1) || ($part_type==2))){
300                                $data = array_merge($data, iml_GetPartList($a, $part_code));
301                        }else{
302                                $data[$part_code]["typestring"] = iml_GetPartTypeString($a, $part_code);
303                                $data[$part_code]["disposition"] = $part_disposition;
304                                $data[$part_code]["size"] = iml_GetPartSize($a, $part_code);
305                                $data[$part_code]["name"] = iml_GetPartName($a, $part_code);
306                                $data[$part_code]["id"] = iml_GetPartID($a, $part_code);
307                        }
308                }
309        }
310        return $data;
311}
312
313function iml_GetNextPart($part){
314        if (strpos($part, ".")===false) return $part++;
315        else{
316                $parts_a = explode(".", $part);
317                $num_levels = count($parts_a);
318                $parts_a[$num_levels-1]++;
319                return implode(".", $parts_a);
320        }
321}
322?>
Note: See TracBrowser for help on using the repository browser.