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 / imap.inc < prev    next >
Encoding:
Text File  |  2003-12-14  |  35.1 KB  |  1,332 lines

  1. <?php
  2. /////////////////////////////////////////////////////////
  3. //    
  4. //    Iloha IMAP Library (IIL)
  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/imap.inc
  17.     PURPOSE:
  18.         Provide alternative IMAP library that doesn't rely on the standard 
  19.         C-Client based version.  This allows IlohaMail to function regardless
  20.         of whether or not the PHP build it's running on has IMAP functionality
  21.         built-in.
  22.     USEAGE:
  23.         Function containing "_C_" in name require connection handler to be
  24.         passed as one of the parameters.  To obtain connection handler, use
  25.         iil_Connect()
  26.  
  27. ********************************************************/
  28.  
  29. include_once("../include/utf7.inc");
  30.  
  31. $iil_error;
  32. $iil_errornum;
  33. $iil_selected;
  34.  
  35. class iilConnection{
  36.     var $fp;
  37.     var $error;
  38.     var $errorNum;
  39.     var $selected;
  40.     var $message;
  41.     var $host;
  42. }
  43.  
  44. class iilBasicHeader{
  45.     var $id;
  46.     var $uid;
  47.     var $subject;
  48.     var $from;
  49.     var $to;
  50.     var $cc;
  51.     var $replyto;
  52.     var $date;
  53.     var $messageID;
  54.     var $size;
  55.     var $encoding;
  56.     var $ctype;
  57.     var $flags;
  58.     var $timestamp;
  59.     var $seen;
  60.     var $deleted;
  61.     var $recent;
  62.     var $answered;
  63. }
  64.  
  65. function iil_xor($string, $string2){
  66.     $result = "";
  67.     $size = strlen($string);
  68.     for ($i=0; $i<$size; $i++) $result .= chr(ord($string[$i]) ^ ord($string2[$i]));
  69.         
  70.     return $result;
  71. }
  72.  
  73. function iil_ReadLine($fp, $size){
  74.     $line="";
  75.     if ($fp){
  76.         do{
  77.             $buffer = fgets($fp, 1024);
  78.             $endID = strlen($buffer) - 1;
  79.             $end = ($buffer[$endID] == "\n");
  80.             $line.=$buffer;
  81.         }while(!$end);
  82.     }
  83.     return $line;
  84. }
  85.  
  86. function iil_ReadReply($fp){
  87.     do{
  88.         $line = chop(trim(iil_ReadLine($fp, 1024)));
  89.     }while($line[0]=="*");
  90.     
  91.     return $line;
  92. }
  93.  
  94. function iil_ParseResult($string){
  95.     $a=explode(" ", $string);
  96.     if (count($a) > 2){
  97.         if (strcasecmp($a[1], "OK")==0) return 0;
  98.         else if (strcasecmp($a[1], "NO")) return -1;
  99.         else if (strcasecmp($a[1], "BAD")) return -2;
  100.     }else return -3;
  101. }
  102.  
  103. // check if $string starts with $match
  104. function iil_StartsWith($string, $match){
  105.     if ($string[0]==$match[0]){
  106.         $pos=strpos($string, $match);
  107.         if ( $pos === false) return false;
  108.         else if ( $pos == 0) return true;
  109.         else return false;
  110.     }else{
  111.         return false;
  112.     }
  113. }
  114.  
  115. function iil_C_Authenticate(&$conn, $user, $pass, $encChallenge){
  116.     
  117.     // initialize ipad, opad
  118.     for ($i=0;$i<64;$i++){
  119.         $ipad.=chr(0x36);
  120.         $opad.=chr(0x5C);
  121.     }
  122.     // pad $pass so it's 64 bytes
  123.     $padLen = 64 - strlen($pass);
  124.     for ($i=0;$i<$padLen;$i++) $pass .= chr(0);
  125.     // generate hash
  126.     $hash = md5(iil_xor($pass,$opad).pack("H*",md5(iil_xor($pass, $ipad).base64_decode($encChallenge))));
  127.     // generate reply
  128.     $reply = base64_encode($user." ".$hash);
  129.     
  130.     // send result, get reply
  131.     fputs($conn->fp, $reply."\r\n");
  132.     $line = iil_ReadLine($conn->fp, 1024);
  133.     
  134.     // process result
  135.     if (iil_ParseResult($line)==0){
  136.         $conn->error .= "";
  137.         $conn->errorNum = 0;
  138.         return $conn->fp;
  139.     }else{
  140.         $conn->error .= "Authentication failed (AUTH): <br>\"".$line."\"";
  141.         $conn->errorNum = -2;
  142.         return false;
  143.     }
  144. }
  145.  
  146. function iil_C_Login(&$conn, $user, $password){
  147.  
  148.     fputs($conn->fp, "a001 LOGIN $user \"$password\"\r\n");
  149.         
  150.     do{
  151.         $line = iil_ReadReply($conn->fp);
  152.     }while(!iil_StartsWith($line, "a001 "));
  153.     $a=explode(" ", $line);
  154.     if (strcmp($a[1],"OK")==0){
  155.         $result=$conn->fp;
  156.         $conn->error.="";
  157.         $conn->errorNum = 0;
  158.     }else{
  159.         $result=false;
  160.         fclose($conn->fp);
  161.         $conn->error .= "Authentication failed (LOGIN):<br>\"".$line."\"";
  162.         $conn->errorNum = -2;
  163.     }
  164.     return $result;
  165. }
  166.  
  167. function iil_Connect($host, $user, $password){    
  168.     global $iil_error, $iil_errornum;
  169.     global $ICL_SSL, $ICL_PORT;
  170.     
  171.     $iil_error = "";
  172.     $iil_errornum = 0;
  173.     
  174.     //strip slashes
  175.     $user = stripslashes($user);
  176.     $password = stripslashes($password);
  177.     
  178.     //set auth method
  179.     $auth_method = "plain";
  180.     if (func_num_args() >= 4){
  181.         $auth_array = func_get_arg(3);
  182.         if (is_array($auth_array)) $auth_method = $auth_array["imap"];
  183.         if (empty($auth_method)) $auth_method = "plain";
  184.     }
  185.     $message = "INITIAL: $auth_method\n";
  186.         
  187.     $result = false;
  188.     
  189.     //initialize connection
  190.     $conn = new iilConnection;
  191.     $conn->error="";
  192.     $conn->errorNum=0;
  193.     $conn->selected="";
  194.     $conn->host = $host;
  195.     
  196.     //check input
  197.     if (empty($host)) $iil_error .= "Invalid host<br>\n";
  198.     if (empty($user)) $iil_error .= "Invalid user<br>\n";
  199.     if (empty($password)) $iil_error .= "Invalid password<br>\n";
  200.     if (!empty($iil_error)) return false;
  201.     
  202.     //check for SSL
  203.     if ($ICL_SSL){
  204.         $host = "ssl://".$host;
  205.     }
  206.     
  207.     //open socket connection
  208.     $conn->fp = fsockopen($host, $ICL_PORT);
  209.     if ($conn->fp){
  210.         $iil_error.="Socket connection established\r\n";
  211.         $line=iil_ReadLine($conn->fp, 300);
  212.                         
  213.         if (strcasecmp($auth_method, "check")==0){
  214.             //check for supported auth methods
  215.             
  216.             //default to plain text auth
  217.             $auth_method = "plain";
  218.             
  219.             //check for CRAM-MD5
  220.             fputs($conn->fp, "cp01 CAPABILITY\r\n");
  221.             do{
  222.             $line = trim(chop(iil_ReadLine($conn->fp, 100)));
  223.                 $a = explode(" ", $line);
  224.                 if ($line[0]=="*"){
  225.                     while ( list($k, $w) = each($a) ){
  226.                         if ((strcasecmp($w, "AUTH=CRAM_MD5")==0)||
  227.                             (strcasecmp($w, "AUTH=CRAM-MD5")==0)){
  228.                                 $auth_method = "auth";
  229.                             }
  230.                     }
  231.                 }
  232.             }while($a[0]!="cp01");
  233.         }
  234.  
  235.         if (strcasecmp($auth_method, "auth")==0){
  236.             $conn->message.="Trying CRAM-MD5\n";
  237.             //do CRAM-MD5 authentication
  238.             fputs($conn->fp, "a000 AUTHENTICATE CRAM-MD5\r\n");
  239.             $line = trim(chop(iil_ReadLine($conn->fp, 1024)));
  240.             if ($line[0]=="+"){
  241.                 $conn->message.="Got challenge: $line\n";
  242.                 //got a challenge string, try CRAM-5
  243.                 $result = iil_C_Authenticate($conn, $user, $password, substr($line,2));
  244.                 $conn->message.= "Tried CRAM-MD5: $result \n";
  245.             }else{
  246.                 $conn->message.="No challenge ($line), try plain\n";
  247.                 $auth = "plain";
  248.             }
  249.         }
  250.         
  251.         if ((!$result)||(strcasecmp($auth, "plain")==0)){
  252.             //do plain text auth
  253.             $result = iil_C_Login($conn, $user, $password);
  254.             $conn->message.="Tried PLAIN: $result \n";
  255.         }
  256.         
  257.         $conn->message .= $auth;
  258.         
  259.         if (!$result){
  260.             $iil_error = $conn->error;
  261.             $iil_errornum = $conn->errorNum;
  262.         }else{
  263.             //$iil_error .= "Authenticated: ".$conn->fp."\n";
  264.         }
  265.     }else{
  266.         $iil_error = "Could not connect to $host at port $ICL_PORT";
  267.         $iil_errornum = -1;
  268.         return false;
  269.     }
  270.     
  271.     if ($result) return $conn;
  272.     else return false;
  273. }
  274.  
  275. function iil_Close(&$conn){
  276.     if (fputs($conn->fp, "I LOGOUT\r\n")){
  277.         fgets($conn->fp, 1024);
  278.         fclose($conn->fp);
  279.     }
  280. }
  281.  
  282. function iil_ClearCache($user, $host){
  283. }
  284.  
  285. function iil_ExplodeQuotedString($delimiter, $string){
  286.     $quotes=explode("\"", $string);
  287.     while ( list($key, $val) = each($quotes))
  288.         if (($key % 2) == 1) 
  289.             $quotes[$key] = str_replace($delimiter, "_!@!_", $quotes[$key]);
  290.     $string=implode("\"", $quotes);
  291.     
  292.     $result=explode($delimiter, $string);
  293.     while ( list($key, $val) = each($result) )
  294.         $result[$key] = str_replace("_!@!_", $delimiter, $result[$key]);
  295.     
  296.     return $result;
  297. }
  298.  
  299. function iil_CheckForRecent($host, $user, $password, $mailbox){
  300.     if (empty($mailbox)) $mailbox="INBOX";
  301.     
  302.     $conn=iil_Connect($host, $user, $password, "plain");
  303.     $fp = $conn->fp;
  304.     if ($fp){
  305.         fputs($fp, "a002 EXAMINE \"".UTF7EncodeString($mailbox)."\"\r\n");
  306.         do{
  307.             $line=chop(iil_ReadLine($fp, 300));
  308.             $a=explode(" ", $line);
  309.             if (($a[0]=="*") && (strcasecmp($a[2], "RECENT")==0))  $result=(int)$a[1];
  310.         }while (!iil_StartsWith($a[0],"a002"));
  311.  
  312.         fputs($fp, "a003 LOGOUT\r\n");
  313.         fclose($fp);
  314.     }else $result=-2;
  315.     
  316.     return $result;
  317. }
  318.  
  319. function iil_C_CheckForRecent(&$conn, $mailbox){
  320.     if (empty($mailbox)) $mailbox="INBOX";
  321.     
  322.     $fp = $conn->fp;
  323.     if ($fp){
  324.         fputs($fp, "a002 EXAMINE \"".UTF7EncodeString($mailbox)."\"\r\n");
  325.         do{
  326.             $line=chop(iil_ReadLine($fp, 300));
  327.             $a=explode(" ", $line);
  328.             if (($a[0]=="*") && (strcasecmp($a[2], "RECENT")==0))  $result=(int)$a[1];
  329.         }while (!iil_StartsWith($a[0],"a002"));
  330.  
  331.     }else $result=-2;
  332.     
  333.     return $result;
  334. }
  335.  
  336. function iil_C_Select(&$conn, $mailbox){
  337.     $fp = $conn->fp;
  338.     
  339.     if (strcmp($conn->selected, $mailbox)==0) return true;
  340.     
  341.     if (fputs($fp, "sel1 SELECT \"".UTF7EncodeString($mailbox)."\"\r\n")){
  342.         do{
  343.             $line=chop(iil_ReadLine($fp, 300));
  344.         }while (!iil_StartsWith($line, "sel1"));
  345.  
  346.         $a=explode(" ", $line);
  347.  
  348.         if (strcasecmp($a[1],"OK")==0){
  349.             $conn->selected = $mailbox;
  350.             return true;
  351.         }else return false;
  352.     }else{
  353.         return false;
  354.     }
  355. }
  356.  
  357. function iil_C_CountMessages(&$conn, $mailbox){
  358.     $num=-1;
  359.     $fp = $conn->fp;
  360.         
  361.     if (fputs($fp, "cm1 SELECT \"".UTF7EncodeString($mailbox)."\"\r\n")){
  362.         do{
  363.             $line=chop(iil_ReadLine($fp, 300));
  364.             $a=explode(" ", $line);
  365.             if ((count($a) == 3) && (strcasecmp($a[2], "EXISTS")==0)) $num=(int)$a[1];
  366.         }while (!iil_StartsWith($a[0],"cm1"));
  367.     }
  368.     
  369.     return $num;
  370. }
  371.  
  372. function iil_SplitHeaderLine($string){
  373.     $pos=strpos($string, ":");
  374.     if ($pos>0){
  375.         $res[0]=substr($string, 0, $pos);
  376.         $res[1]=trim(substr($string, $pos+1));
  377.         return $res;
  378.     }else{
  379.         return $string;
  380.     }
  381. }
  382.  
  383. function iil_StrToTime($str){
  384.     //replace double spaces with single space
  385.     $str = trim($str);
  386.     $str = str_replace("  ", " ", $str);
  387.     
  388.     //strip off day of week
  389.     $pos=strpos($str, " ");
  390.     $word = substr($str, 0, $pos);
  391.     if (!is_numeric($word)) $str = substr($str, $pos+1);
  392.  
  393.     //explode, take good parts
  394.     $a=explode(" ",$str);
  395.     $month_a=array("Jan"=>1,"Feb"=>2,"Mar"=>3,"Apr"=>4,"May"=>5,"Jun"=>6,"Jul"=>7,"Aug"=>8,"Sep"=>9,"Oct"=>10,"Nov"=>11,"Dec"=>12);
  396.     $month_str=$a[1];
  397.     $month=$month_a[$month_str];
  398.     $day=$a[0];
  399.     $year=$a[2];
  400.     $time=$a[3];
  401.     $tz_str = $a[4];
  402.     $tz = substr($tz_str, 0, 3);
  403.     $ta=explode(":",$time);
  404.     $hour=(int)$ta[0]-(int)$tz;
  405.     $minute=$ta[1];
  406.     $second=$ta[2];
  407.  
  408.     //make UNIX timestamp
  409.     return mktime($hour, $minute, $second, $month, $day, $year);
  410. }
  411.  
  412. function iil_C_FetchHeaderIndex(&$conn, $mailbox, $message_set, $index_field){
  413.     $c=0;
  414.     $result=array();
  415.     $fp = $conn->fp;
  416.         
  417.     if (empty($index_field)) $index_field="DATE";
  418.     $index_field = strtoupper($index_field);
  419.     
  420.     $fields_a=array(
  421.                                 "DATE"=>6,
  422.                                 "FROM"=>1,
  423.                                 "TO"=>1,
  424.                                 "SUBJECT"=>1,
  425.                                 "UID"=>2,
  426.                                 "SIZE"=>2,
  427.                                 "SEEN"=>3,
  428.                                 "RECENT"=>4,
  429.                                 "DELETED"=>5
  430.                             );
  431.     
  432.     $mode=$fields_a[$index_field];
  433.     if (!($mode > 0)) return false;
  434.  
  435.     /*  Do "SELECT" command */
  436.     if (!iil_C_Select($conn, $mailbox)) return false;
  437.     
  438.     /* FETCH date,from,subject headers */
  439.     if ($mode==1){
  440.         $key="fhi".($c++);
  441.         $request=$key." FETCH $message_set (BODY.PEEK[HEADER.FIELDS ($index_field)])\r\n";
  442.         if (!fputs($fp, $request)) return false;
  443.         do{
  444.             $line=chop(iil_ReadLine($fp, 200));
  445.             $a=explode(" ", $line);
  446.             if (($line[0]=="*") && ($a[2]=="FETCH")){
  447.                 $id=$a[1];
  448.  
  449.                 $str=$line=chop(iil_ReadLine($fp, 300));
  450.  
  451.                 while($line[0]!=")"){                    //caution, this line works only in this particular case
  452.                     $line=chop(iil_ReadLine($fp, 300));
  453.                     if ($line[0]!=")"){
  454.                         if (ord($line[0]) <= 32){            //continuation from previous header line
  455.                             $str.=" ".trim($line);
  456.                         }
  457.                         if ((ord($line[0]) > 32) || (strlen($line[0]) == 0)){
  458.                             list($field, $string) = iil_SplitHeaderLine($str);
  459.                             if (strcasecmp($field, "date")==0){
  460.                                 $result[$id]=iil_StrToTime($string);
  461.                             }else{
  462.                                 $result[$id]=strtoupper(str_replace("\"", "", $string));
  463.                             }
  464.                             $str=$line;
  465.                         }
  466.                     }
  467.                 }
  468.             }
  469.         }while(!iil_StartsWith($a[0], $key));
  470.     }else if ($mode==6){
  471.         $key="fhi".($c++);
  472.         $request = $key." FETCH $message_set (INTERNALDATE)\r\n";
  473.         if (!fputs($fp, $request)) return false;
  474.         do{
  475.             $line=chop(iil_ReadLine($fp, 200));
  476.             if ($line[0]=="*"){
  477.                 //original: "* 10 FETCH (INTERNALDATE "31-Jul-2002 09:18:02 -0500")"
  478.                 $paren_pos = strpos($line, "(");
  479.                 $foo = substr($line, 0, $paren_pos);
  480.                 $a = explode(" ", $foo);
  481.                 $id = $a[1];
  482.                 
  483.                 $open_pos = strpos($line, "\"") + 1;
  484.                 $close_pos = strrpos($line, "\"");
  485.                 if ($open_pos && $close_pos){
  486.                     $len = $close_pos - $open_pos;
  487.                     $time_str = substr($line, $open_pos, $len);
  488.                     $result[$id] = strtotime($time_str);
  489.                 }
  490.             }else{
  491.                 $a = explode(" ", $line);
  492.             }
  493.         }while(!iil_StartsWith($a[0], $key));
  494.     }else{
  495.         if ($mode >= 3) $field_name="FLAGS";
  496.         else if ($index_field=="SIZE") $field_name="RFC822.SIZE";
  497.         else $field_name=$index_field;
  498.  
  499.         /*             FETCH uid, size, flags        */
  500.         $key="fhi".($c++);
  501.         $request=$key." FETCH $message_set ($field_name)\r\n";
  502.         if (!fputs($fp, $request)) return false;
  503.         do{
  504.             $line=chop(iil_ReadLine($fp, 200));
  505.             $a = explode(" ", $line);
  506.             if (($line[0]=="*") && ($a[2]=="FETCH")){
  507.                 $line=str_replace("(", "", $line);
  508.                 $line=str_replace(")", "", $line);
  509.                 $a=explode(" ", $line);
  510.             
  511.                 /*  Caution, bad assumptions, next several lines */
  512.                 $id=$a[1];
  513.                 if ($mode==2) $result[$id]=$a[4];
  514.                 else{
  515.                     $haystack=strtoupper($line);
  516.                     $result[$id]=(strpos($haystack, $index_field) > 0 ? "F" : "N");
  517.                 }
  518.             }
  519.         }while(!iil_StartsWith($line, $key));
  520.     }
  521.     return $result;    
  522.  
  523. }
  524.  
  525. function iil_C_FetchHeaders(&$conn, $mailbox, $message_set){
  526.     $c=0;
  527.     $result=array();
  528.     $fp = $conn->fp;
  529.     
  530.     /*  Do "SELECT" command */
  531.     if (!iil_C_Select($conn, $mailbox)) return false;
  532.  
  533.     /* FETCH date,from,subject headers */
  534.     $key="fh".($c++);
  535.     $request=$key." FETCH $message_set (BODY.PEEK[HEADER.FIELDS (DATE FROM TO SUBJECT REPLY-TO CC CONTENT-TRANSFER-ENCODING CONTENT-TYPE MESSAGE-ID)])\r\n";
  536.         
  537.     if (!fputs($fp, $request)) return false;
  538.     do{
  539.         $line=chop(iil_ReadLine($fp, 200));
  540.         $a=explode(" ", $line);
  541.         if (($line[0]=="*") && ($a[2]=="FETCH")){
  542.             $id=$a[1];
  543.             $result[$id]=new iilBasicHeader;
  544.             $result[$id]->id = $id;
  545.             $result[$id]->subject = "";
  546.             /*
  547.                 Start parsing headers.  The problem is, some header "lines" take up multiple lines.
  548.                 So, we'll read ahead, and if the one we're reading now is a valid header, we'll
  549.                 process the previous line.  Otherwise, we'll keep adding the strings until we come
  550.                 to the next valid header line.
  551.             */
  552.             $i = 0;
  553.             $lines = array();
  554.             do{
  555.                 $line = chop(iil_ReadLine($fp, 300));
  556.                 if (ord($line[0])<=32) $lines[$i].=(empty($lines[$i])?"":"\n").trim(chop($line));
  557.                 else{
  558.                     $i++;
  559.                     $lines[$i] = trim(chop($line));
  560.                 }
  561.             }while($line[0]!=")");
  562.             
  563.             //process header, fill iilBasicHeader obj.
  564.             //    initialize
  565.             if (is_array($headers)){
  566.                 reset($headers);
  567.                 while ( list($k, $bar) = each($headers) ) $headers[$k] = "";
  568.             }
  569.  
  570.             //    create array with header field:data
  571.             $headers = array();
  572.             while ( list($lines_key, $str) = each($lines) ){
  573.                 list($field, $string) = iil_SplitHeaderLine($str);
  574.                 $field = strtolower($field);
  575.                 $headers[$field] = $string;
  576.             }
  577.             $result[$id]->date = $headers["date"];
  578.             $result[$id]->timestamp = iil_StrToTime($headers["date"]);
  579.             $result[$id]->from = $headers["from"];
  580.             $result[$id]->to = str_replace("\n", " ", $headers["to"]);
  581.             $result[$id]->subject = str_replace("\n", " ", $headers["subject"]);
  582.             $result[$id]->replyto = str_replace("\n", " ", $headers["reply-to"]);
  583.             $result[$id]->cc = str_replace("\n", " ", $headers["cc"]);
  584.             $result[$id]->encoding = str_replace("\n", " ", $headers["content-transfer-encoding"]);
  585.             $result[$id]->ctype = str_replace("\n", " ", $headers["content-type"]);
  586.             list($result[$id]->ctype,$foo) = explode(";", $headers["content-type"]);
  587.             $messageID = $headers["message-id"];
  588.             $result[$id]->messageID = substr(substr($messageID, 1), 0, strlen($messageID)-2);
  589.         }
  590.     }while(strcmp($a[0], $key)!=0);
  591.         
  592.     /* 
  593.         FETCH uid, size, flags
  594.         Sample reply line: "* 3 FETCH (UID 2417 RFC822.SIZE 2730 FLAGS (\Seen \Deleted))"
  595.     */
  596.     $command_key="fh".($c++);
  597.     $request= $command_key." FETCH $message_set (UID RFC822.SIZE FLAGS INTERNALDATE)\r\n";
  598.     if (!fputs($fp, $request)) return false;
  599.     do{
  600.         $line=chop(iil_ReadLine($fp, 200));
  601.         //$a = explode(" ", $line);
  602.         //if (($line[0]=="*") && ($a[2]=="FETCH")){
  603.         if ($line[0]=="*"){
  604.             //echo "<!-- $line //-->\n";
  605.             //get outter most parens
  606.             $open_pos = strpos($line, "(") + 1;
  607.             $close_pos = strrpos($line, ")");
  608.             if ($open_pos && $close_pos){
  609.                 //extract ID from pre-paren
  610.                 $pre_str = substr($line, 0, $open_pos);
  611.                 $pre_a = explode(" ", $line);
  612.                 $id = $pre_a[1];
  613.                 
  614.                 //get data
  615.                 $len = $close_pos - $open_pos;
  616.                 $str = substr($line, $open_pos, $len);
  617.                 
  618.                 //swap parents with quotes, then explode
  619.                 $str = eregi_replace("[()]", "\"", $str);
  620.                 $a = iil_ExplodeQuotedString(" ", $str);
  621.                 
  622.                 //did we get the right number of replies?
  623.                 if (count($a)==8){
  624.                     for ($i=0;$i<8;$i=$i+2){
  625.                         if (strcasecmp($a[$i],"UID")==0) $result[$id]->uid=$a[$i+1];
  626.                         else if (strcasecmp($a[$i],"RFC822.SIZE")==0) $result[$id]->size=$a[$i+1];
  627.                         else if (strcasecmp($a[$i],"INTERNALDATE")==0) $time_str = $a[$i+1];
  628.                         else if (strcasecmp($a[$i],"FLAGS")==0) $flags_str = $a[$i+1];
  629.                     }
  630.  
  631.                     // process flags
  632.                     $flags_str = eregi_replace("[\\\"]", "", $flags_str);
  633.                     $flags_a = explode(" ", $flags_str);
  634.                     //echo "<!-- ID: $id FLAGS: ".implode(",", $flags_a)." //-->\n";
  635.                     
  636.                     $result[$id]->seen = false;
  637.                     $result[$id]->recent = false;
  638.                     $result[$id]->deleted = false;
  639.                     $result[$id]->answered = false;
  640.                     if (is_array($flags_a)){
  641.                         reset($flags_a);
  642.                         while (list($key,$val)=each($flags_a)){
  643.                             if (strcasecmp($val,"Seen")==0) $result[$id]->seen = true;
  644.                             else if (strcasecmp($val, "Deleted")==0) $result[$id]->deleted=true;
  645.                             else if (strcasecmp($val, "Recent")==0) $result[$id]->recent = true;
  646.                             else if (strcasecmp($val, "Answered")==0) $result[$id]->answered = true;
  647.                         }
  648.                         $result[$id]->flags=$flags;
  649.                     }
  650.                 
  651.                     //get timezone
  652.                     $time_str = substr($time_str, 0, -1);
  653.                     $time_zone_str = substr($time_str, -5); //extract timezone
  654.                     $time_str = substr($time_str, 1, -6); //remove quotes
  655.                     $time_zone = (int)substr($time_zone_str, 1, 2); //get first two digits
  656.                     if ($time_zone_str[0]=="-") $time_zone = $time_zone * -1; //minus?
  657.                     
  658.                     //calculate timestamp
  659.                     $timestamp = strtotime($time_str); //return's server's time
  660.                     $na_timestamp = $timestamp;
  661.                     $timestamp -= $time_zone * 3600; //compensate for tz, get GMT
  662.                     $result[$id]->timestamp = $timestamp;
  663.                     
  664.                     //echo "<!-- ID: $id : $time_str -- local: $na_timestamp (".date("F j, Y, g:i a", $na_timestamp).") tz: $time_zone -- GMT: ".$timestamp." (".date("F j, Y, g:i a", $timestamp).")  //-->\n";
  665.                 }else{
  666.                     //echo "<!-- ERROR: $id : $str //-->\n";
  667.                 }
  668.             }
  669.         }
  670.     }while(strpos($line, $command_key)===false);
  671.         
  672.     return $result;
  673. }
  674.  
  675.  
  676. function iil_C_FetchHeader(&$conn, $mailbox, $id){
  677.     $fp = $conn->fp;
  678.     $a=iil_C_FetchHeaders($conn, $mailbox, $id);
  679.     if (is_array($a)) return $a[$id];
  680.     else return false;
  681. }
  682.  
  683.  
  684. function iil_SortHeaders($a, $field, $flag){
  685.     if (empty($field)) $field="uid";
  686.     $field=strtolower($field);
  687.     if ($field=="date") $field="timestamp";
  688.     if (empty($flag)) $flag="ASC";
  689.     $flag=strtoupper($flag);
  690.     
  691.     $c=count($a);
  692.     if ($c>0){
  693.         /*
  694.             Strategy:
  695.             First, we'll create an "index" array.
  696.             Then, we'll use sort() on that array, 
  697.             and use that to sort the main array.
  698.         */
  699.                 
  700.                 // create "index" array
  701.         $index=array();
  702.         reset($a);
  703.         while (list($key, $val)=each($a)){
  704.             $data=$a[$key]->$field;
  705.             if (is_string($data)) $data=strtoupper(str_replace("\"", "", $data));
  706.             $index[$key]=$data;
  707.         }
  708.         
  709.         // sort index
  710.         $i=0;
  711.         if ($flag=="ASC") asort($index);
  712.         else arsort($index);
  713.         
  714.         // form new array based on index 
  715.         $result=array();
  716.         reset($index);
  717.         while (list($key, $val)=each($index)){
  718.             $result[$i]=$a[$key];
  719.             $i++;
  720.         }
  721.     }
  722.     
  723.     return $result;
  724. }
  725.  
  726. function iil_C_Expunge(&$conn, $mailbox){
  727.     $fp = $conn->fp;
  728.     if (iil_C_Select($conn, $mailbox)){
  729.         $c=0;
  730.         fputs($fp, "exp1 EXPUNGE\r\n");
  731.         do{
  732.             $line=chop(iil_ReadLine($fp, 100));
  733.             if ($line[0]=="*") $c++;
  734.         }while (!iil_StartsWith($line, "exp1"));
  735.         
  736.         if (iil_ParseResult($line) == 0) return $c;
  737.         else{
  738.             $conn->error = $line;
  739.             return -1;
  740.         }
  741.     }
  742.     
  743.     return -1;
  744. }
  745.  
  746. function iil_C_Flag(&$conn, $mailbox, $messages, $flag){
  747.     $fp = $conn->fp;
  748.     $flags=array(
  749.                     "SEEN"=>"\\Seen",
  750.                     "DELETED"=>"\\DELETED",
  751.                     "RECENT"=>"\\RECENT",
  752.                     "ANSWERED"=>"\\Answered",
  753.                     "DRAFT"=>"\\Draft"
  754.                     );
  755.     $flag=strtoupper($flag);
  756.     $flag=$flags[$flag];
  757.     if (iil_C_Select($conn, $mailbox)){
  758.         $c=0;
  759.         fputs($fp, "del1 STORE $messages +FLAGS (".$flag.")\r\n");
  760.         do{
  761.             $line=chop(iil_ReadLine($fp, 100));
  762.             if ($line[0]=="*") $c++;
  763.         }while (!iil_StartsWith($line, "del1"));
  764.         
  765.         if (iil_ParseResult($line) == 0) return $c;
  766.         else{
  767.             $conn->error = $line;
  768.             return -1;
  769.         }
  770.     }else{
  771.         $conn->error = "Select failed";
  772.         return -1;
  773.     }
  774. }
  775.  
  776. function iil_C_Delete(&$conn, $mailbox, $messages){
  777.     $fp = $conn->fp;
  778.     if (iil_C_Select($conn, $mailbox)){
  779.         $c=0;
  780.         fputs($fp, "del1 STORE $messages +FLAGS (\\Deleted)\r\n");
  781.         do{
  782.             $line=chop(iil_ReadLine($fp, 100));
  783.             if ($line[0]=="*") $c++;
  784.         }while (!iil_StartsWith($line, "del1"));
  785.         
  786.         if (iil_ParseResult($line) == 0) return $c;
  787.         else return -1;
  788.     }else{
  789.         return -1;
  790.     }
  791. }
  792.  
  793. function iil_C_Undelete(&$conn, $mailbox, $messages){
  794.     $fp = $conn->fp;
  795.     if (iil_C_Select($conn, $mailbox)){
  796.         $c=0;
  797.         fputs($fp, "del1 STORE $messages -FLAGS (\\Deleted)\r\n");
  798.         do{
  799.             $line=chop(iil_ReadLine($fp, 100));
  800.             if ($line[0]=="*") $c++;
  801.         }while (!iil_StartsWith($line, "del1"));
  802.         
  803.         if (iil_ParseResult($line) == 0) return $c;
  804.         else return -1;
  805.     }else{
  806.         return -1;
  807.     }
  808. }
  809.  
  810.  
  811. function iil_C_Unseen(&$conn, $mailbox, $message){
  812.     $fp = $conn->fp;
  813.     if (iil_C_Select($conn, $mailbox)){
  814.         $c=0;
  815.         $command = "uns1 STORE $message -FLAGS (\\Seen)\r\n";
  816.         fputs($fp, $command);
  817.         do{
  818.             $line=chop(iil_ReadLine($fp, 100));
  819.             if ($line[0]=="*") $c++;
  820.         }while (!iil_StartsWith($line, "uns1"));
  821.         
  822.         if (iil_ParseResult($line) == 0) return $c;
  823.         else{
  824.             $conn->error = $command."-".$line;
  825.             return -1;
  826.         }
  827.     }else{
  828.         return -1;
  829.     }
  830. }
  831.  
  832.  
  833. function iil_C_Copy(&$conn, $messages, $from, $to){
  834.     $fp = $conn->fp;
  835.     if (iil_C_Select($conn, $from)){
  836.         $c=0;
  837.         
  838.         fputs($fp, "cpy1 COPY $messages \"".UTF7EncodeString($to)."\"\r\n");
  839.         $line=iil_ReadReply($fp);
  840.         return iil_ParseResult($line);
  841.     }else{
  842.         return -1;
  843.     }
  844. }
  845.  
  846. function iil_FormatSearchDate($month, $day, $year){
  847.     $month = (int)$month;
  848.     $months=array(
  849.             1=>"Jan", 2=>"Feb", 3=>"Mar", 4=>"Apr", 
  850.             5=>"May", 6=>"Jun", 7=>"Jul", 8=>"Aug", 
  851.             9=>"Sep", 10=>"Oct", 11=>"Nov", 12=>"Dec"
  852.             );
  853.     return $day."-".$months[$month]."-".$year;
  854. }
  855.  
  856. function iil_C_CountUnseen(&$conn, $folder){
  857.     $index = iil_C_Search($conn, $folder, "ALL UNSEEN");
  858.     if (is_array($index)){
  859.         $str = implode(",", $index);
  860.         if (empty($str)) return false;
  861.         else return count($index);
  862.     }else return false;
  863. }
  864.  
  865. function iil_C_UID2ID(&$conn, $folder, $uid){
  866.     if ($uid > 0){
  867.         $id_a = iil_C_Search($conn, $folder, "UID $uid");
  868.         if (is_array($id_a)){
  869.             $count = count($id_a);
  870.             if ($count > 1) return false;
  871.             else return $id_a[0];
  872.         }
  873.     }
  874.     return false;
  875. }
  876.  
  877. function iil_C_Search(&$conn, $folder, $criteria){
  878.     $fp = $conn->fp;
  879.     if (iil_C_Select($conn, $folder)){
  880.         $c=0;
  881.         
  882.         $query = "srch1 SEARCH ".chop($criteria)."\r\n";
  883.         fputs($fp, $query);
  884.         do{
  885.             $line=trim(chop(iil_ReadLine($fp, 10000)));
  886.             if ($line[0]=="*"){
  887.                 $str = trim(substr($line, 8));
  888.                 $messages = explode(" ", $str);
  889.             }
  890.         }while(!iil_StartsWith($line, "srch1"));
  891.         
  892.         $result_code=iil_ParseResult($line);
  893.         if ($result_code==0) return $messages;
  894.         else{
  895.             $conn->error = "iil_C_Search: ".$line."<br>\n";
  896.             return false;
  897.         }
  898.         
  899.     }else{
  900.         $conn->error = "iil_C_Search: Couldn't select \"$folder\" <br>\n";
  901.         return false;
  902.     }
  903. }
  904.  
  905. function iil_C_Move(&$conn, $messages, $from, $to){
  906.     $fp = $conn->fp;
  907.     $r=iil_C_Copy($conn, $messages, $from,$to);
  908.     if ($r==0){
  909.         return iil_C_Delete($conn, $from, $messages);
  910.     }else{
  911.         return $r;
  912.     }
  913. }
  914.  
  915. function iil_C_GetHierarchyDelimiter(&$conn){
  916.     $fp = $conn->fp;
  917.     $delimiter = false;
  918.     if (!fputs($fp, "ghd LIST \"\" \"\"\r\n")) return false;
  919.     do{
  920.         $line=iil_ReadLine($fp, 500);
  921.         if ($line[0]=="*"){
  922.             $line = rtrim($line);
  923.             $a=iil_ExplodeQuotedString(" ", $line);
  924.             if ($a[0]=="*") $delimiter = str_replace("\"", "", $a[count($a)-2]);
  925.         }
  926.     }while (!iil_StartsWith($line, "ghd"));
  927.  
  928.     return $delimiter;
  929. }
  930.  
  931. function iil_C_ListMailboxes(&$conn, $ref, $mailbox){
  932.     global $IGNORE_FOLDERS;
  933.     
  934.     $ignore = $IGNORE_FOLDERS[strtolower($conn->host)];
  935.         
  936.     $fp = $conn->fp;
  937.     if (empty($mailbox)) $mailbox="*";
  938.     // send command
  939.     if (!fputs($fp, "lmb LIST \"".$ref."\" \"".UTF7EncodeString($mailbox)."\"\r\n")) return false;
  940.     $i=0;
  941.     // get folder list
  942.     do{
  943.         $line=iil_ReadLine($fp, 500);
  944.         $a = explode(" ", $line);
  945.         if (($line[0]=="*") && ($a[1]=="LIST")){
  946.             $line = rtrim($line);
  947.             // split one line
  948.             $a=iil_ExplodeQuotedString(" ", $line);
  949.             // last string is folder name
  950.             $folder = UTF7DecodeString(str_replace("\"", "", $a[count($a)-1]));
  951.             if (empty($ignore) || (!empty($ignore) && !eregi($ignore, $folder))) $folders[$i] = $folder;
  952.             // second from last is delimiter
  953.             $delim = str_replace("\"", "", $a[count($a)-2]);
  954.             // is it a container?
  955.             $i++;
  956.         }
  957.     }while (!iil_StartsWith($line, "lmb"));
  958.  
  959.     if (is_array($folders)){
  960.         if (!empty($ref)){
  961.             // if rootdir was specified, make sure it's the first element
  962.             // some IMAP servers (i.e. Courier) won't return it
  963.             if ($ref[strlen($ref)-1]==$delim) $ref = substr($ref, 0, strlen($ref)-1);
  964.             if ($folders[0]!=$ref) array_unshift($folders, $ref);
  965.         }
  966.         return $folders;
  967.     }else return false;
  968. }
  969.  
  970.  
  971. function iil_C_ListSubscribed(&$conn, $ref, $mailbox){
  972.     global $IGNORE_FOLDERS;
  973.     
  974.     $ignore = $IGNORE_FOLDERS[strtolower($conn->host)];
  975.     
  976.     $fp = $conn->fp;
  977.     if (empty($mailbox)) $mailbox="*";
  978.     $folders = array();
  979.     // send command
  980.     if (!fputs($fp, "lsb LSUB \"".$ref."\" \"".UTF7EncodeString($mailbox)."\"\r\n")) return false;
  981.     $i=0;
  982.     // get folder list
  983.     do{
  984.         $line=iil_ReadLine($fp, 500);
  985.         $a = explode(" ", $line);
  986.         if (($line[0]=="*") && ($a[1]=="LSUB")){
  987.             $line = rtrim($line);
  988.             // split one line
  989.             $a=iil_ExplodeQuotedString(" ", $line);
  990.             // last string is folder name
  991.             $folder = UTF7DecodeString(str_replace("\"", "", $a[count($a)-1]));
  992.             if ((!in_array($folder, $folders)) && (empty($ignore) || (!empty($ignore) && !eregi($ignore, $folder)))) $folders[$i] = $folder;
  993.             // second from last is delimiter
  994.             $delim = str_replace("\"", "", $a[count($a)-2]);
  995.             // is it a container?
  996.             $i++;
  997.         }
  998.     }while (!iil_StartsWith($line, "lsb"));
  999.  
  1000.     if (is_array($folders)){
  1001.         if (!empty($ref)){
  1002.             // if rootdir was specified, make sure it's the first element
  1003.             // some IMAP servers (i.e. Courier) won't return it
  1004.             if ($ref[strlen($ref)-1]==$delim) $ref = substr($ref, 0, strlen($ref)-1);
  1005.             if ($folders[0]!=$ref) array_unshift($folders, $ref);
  1006.         }
  1007.         return $folders;
  1008.     }else{
  1009.         $conn->error = $line;
  1010.         return false;
  1011.     }
  1012. }
  1013.  
  1014.  
  1015. function iil_C_Subscribe(&$conn, $folder){
  1016.     $fp = $conn->fp;
  1017.  
  1018.     $query = "sub1 SUBSCRIBE \"".UTF7EncodeString($folder)."\"\r\n";
  1019.     fputs($fp, $query);
  1020.     $line=trim(chop(iil_ReadLine($fp, 10000)));
  1021.     return iil_ParseResult($line);
  1022. }
  1023.  
  1024.  
  1025. function iil_C_UnSubscribe(&$conn, $folder){
  1026.     $fp = $conn->fp;
  1027.  
  1028.     $query = "usub1 UNSUBSCRIBE \"".UTF7EncodeString($folder)."\"\r\n";
  1029.     fputs($fp, $query);
  1030.     $line=trim(chop(iil_ReadLine($fp, 10000)));
  1031.     return iil_ParseResult($line);
  1032. }
  1033.  
  1034.  
  1035. function iil_C_FetchPartHeader(&$conn, $mailbox, $id, $part){
  1036.     $fp = $conn->fp;
  1037.     $result=false;
  1038.     if (($part==0)||(empty($part))) $part="HEADER";
  1039.     else $part.=".MIME";
  1040.     
  1041.     if (iil_C_Select($conn, $mailbox)){
  1042.         $key="fh".($c++);
  1043.         $request=$key." FETCH $id (BODY.PEEK[$part])\r\n";
  1044.         if (!fputs($fp, $request)) return false;
  1045.         do{
  1046.             $line=chop(iil_ReadLine($fp, 200));
  1047.             $a=explode(" ", $line);
  1048.             if (($line[0]=="*") && ($a[2]=="FETCH") && ($line[strlen($line)-1]!=")")){
  1049.                 $line=iil_ReadLine($fp, 300);
  1050.                 while(chop($line)!=")"){
  1051.                     $result.=$line;
  1052.                     $line=iil_ReadLine($fp, 300);
  1053.                 }
  1054.             }
  1055.         }while(strcmp($a[0], $key)!=0);
  1056.     }
  1057.     
  1058.     return $result;
  1059. }
  1060.  
  1061.  
  1062. function iil_C_HandlePartBody(&$conn, $mailbox, $id, $part, $mode){
  1063.     /* modes:
  1064.         1: return string
  1065.         2: print
  1066.         3: base64 and print
  1067.     */
  1068.     $fp = $conn->fp;
  1069.     $result=false;
  1070.     if (($part==0)||(empty($part))) $part="TEXT";
  1071.     
  1072.     if (iil_C_Select($conn, $mailbox)){
  1073.         $reply_key="* ".$id;
  1074.         // format request
  1075.         $key="ftch".($c++)." ";
  1076.         $request=$key."FETCH $id (BODY.PEEK[$part])\r\n";
  1077.         // send request
  1078.         if (!fputs($fp, $request)) return false;
  1079.         // receive reply line
  1080.         do{
  1081.             $line = chop(iil_ReadLine($fp, 1000));
  1082.             $a = explode(" ", $line);
  1083.         }while ($a[2]!="FETCH");
  1084.         $len = strlen($line);
  1085.         if ($line[$len-1] == ")"){
  1086.             //one line response, get everything between first and last quotes
  1087.             $from = strpos($line, "\"") + 1;
  1088.             $to = strrpos($line, "\"");
  1089.             $len = $to - $from;
  1090.             if ($mode==1) $result = substr($line, $from, $len);
  1091.             else if ($mode==2) echo substr($line, $from, $len);
  1092.             else if ($mode==3) echo base64_decode(substr($line, $from, $len));
  1093.         }else if ($line[$len-1] == "}"){
  1094.             //multi-line request, find sizes of content and receive that many bytes
  1095.             $from = strpos($line, "{") + 1;
  1096.             $to = strrpos($line, "}");
  1097.             $len = $to - $from;
  1098.             $sizeStr = substr($line, $from, $len);
  1099.             $bytes = (int)$sizeStr;
  1100.             $received = 0;
  1101.             while ($received < $bytes){
  1102.                 $remaining = $bytes - $received;
  1103.                 $line = iil_ReadLine($fp, 1024);
  1104.                 $len = strlen($line);
  1105.                 if ($len > $remaining) substr($line, 0, $remaining);
  1106.                 $received += strlen($line);
  1107.                 if ($mode==1) $result .= chop($line)."\n";
  1108.                 else if ($mode==2){ echo chop($line)."\n"; flush(); }
  1109.                 else if ($mode==3){ echo base64_decode($line); flush(); }
  1110.             }
  1111.         }
  1112.         // read in anything up until 'til last line
  1113.         do{
  1114.             $line = iil_ReadLine($fp, 1024);
  1115.         }while(!iil_StartsWith($line, $key));
  1116.         
  1117.         // flag as "seen"
  1118.         if ($result){
  1119.             //iil_C_Flag($conn, $mailbox, $id, "SEEN");
  1120.             return substr($result, 0, strlen($result)-1);
  1121.         }else return false;
  1122.     }else{
  1123.         echo "Select failed.";
  1124.     }
  1125.     
  1126.     if ($mode==1) return $result;
  1127.     else return $received;
  1128. }
  1129.  
  1130. function iil_C_FetchPartBody(&$conn, $mailbox, $id, $part){
  1131.     return iil_C_HandlePartBody($conn, $mailbox, $id, $part, 1);
  1132. }
  1133.  
  1134. function iil_C_PrintPartBody(&$conn, $mailbox, $id, $part){
  1135.     iil_C_HandlePartBody($conn, $mailbox, $id, $part, 2);
  1136. }
  1137.  
  1138. function iil_C_PrintBase64Body(&$conn, $mailbox, $id, $part){
  1139.     iil_C_HandlePartBody($conn, $mailbox, $id, $part, 3);
  1140. }
  1141.  
  1142. function iil_C_CreateFolder(&$conn, $folder){
  1143.     $fp = $conn->fp;
  1144.     if (fputs($fp, "c CREATE \"".UTF7EncodeString($folder)."\"\r\n")){
  1145.         do{
  1146.             $line=iil_ReadLine($fp, 300);
  1147.         }while($line[0]!="c");
  1148.         $conn->error = $line;
  1149.         return (iil_ParseResult($line)==0);
  1150.     }else{
  1151.         return false;
  1152.     }
  1153. }
  1154.  
  1155. function iil_C_RenameFolder(&$conn, $from, $to){
  1156.     $fp = $conn->fp;
  1157.     if (fputs($fp, "r RENAME \"".UTF7EncodeString($from)."\" \"".UTF7EncodeString($to)."\"\r\n")){
  1158.         do{
  1159.             $line=iil_ReadLine($fp, 300);
  1160.         }while($line[0]!="r");
  1161.         return (iil_ParseResult($line)==0);
  1162.     }else{
  1163.         return false;
  1164.     }    
  1165. }
  1166.  
  1167. function iil_C_DeleteFolder(&$conn, $folder){
  1168.     $fp = $conn->fp;
  1169.     if (fputs($fp, "d DELETE \"".UTF7EncodeString($folder)."\"\r\n")){
  1170.         do{
  1171.             $line=iil_ReadLine($fp, 300);
  1172.         }while($line[0]!="d");
  1173.         return (iil_ParseResult($line)==0);
  1174.     }else{
  1175.         return false;
  1176.     }
  1177. }
  1178.  
  1179. function iil_C_Append(&$conn, $folder, $message){
  1180.     $fp = $conn->fp;
  1181.  
  1182.     $message = str_replace("\r", "", $message);
  1183.     $message = str_replace("\n", "\r\n", $message);        
  1184.  
  1185.     $len = strlen($message);
  1186.     $request="A APPEND \"".UTF7EncodeString($folder)."\" (\\Seen) {".$len."}\r\n";
  1187.     if (fputs($fp, $request)){
  1188.         $line=iil_ReadLine($fp, 100);
  1189.  
  1190.         $sent = fwrite($fp, $message."\r\n");
  1191.         flush();
  1192.         do{
  1193.             $line=iil_ReadLine($fp, 1000);
  1194.         }while($line[0]!="A");
  1195.     
  1196.         $result = (iil_ParseResult($line)==0);
  1197.         if (!$result) $conn->error .= $line."<br>\n";
  1198.         return $result;
  1199.     
  1200.     }else{
  1201.         $conn->error .= "Couldn't send command \"$request\"<br>\n";
  1202.         return false;
  1203.     }
  1204. }
  1205.  
  1206.  
  1207. function iil_C_AppendFromFile(&$conn, $folder, $path){
  1208.     //open message file
  1209.     $in_fp = false;                
  1210.     if (file_exists(realpath($path))) $in_fp = fopen($path, "r");
  1211.     if (!$in_fp){ 
  1212.         $conn->error .= "Couldn't open $path for reading<br>\n";
  1213.         return false;
  1214.     }
  1215.     
  1216.     $fp = $conn->fp;
  1217.     $len = filesize($path);
  1218.     
  1219.     //send APPEND command
  1220.     $request="A APPEND \"".UTF7EncodeString($folder)."\" (\\Seen) {".$len."}\r\n";
  1221.     $bytes_sent = 0;
  1222.     if (fputs($fp, $request)){
  1223.         $line=iil_ReadLine($fp, 100);
  1224.                 
  1225.         //send file
  1226.         while(!feof($in_fp)){
  1227.             $buffer = fgets($in_fp, 4096);
  1228.             $bytes_sent += strlen($buffer);
  1229.             fputs($fp, $buffer);
  1230.         }
  1231.         fclose($in_fp);
  1232.  
  1233.         fputs($fp, "\r\n");
  1234.  
  1235.         //read response
  1236.         do{
  1237.             $line=iil_ReadLine($fp, 1000);
  1238.         }while($line[0]!="A");
  1239.             
  1240.         $result = (iil_ParseResult($line)==0);
  1241.         if (!$result) $conn->error .= $line."<br>\n";
  1242.         return $result;
  1243.     
  1244.     }else{
  1245.         $conn->error .= "Couldn't send command \"$request\"<br>\n";
  1246.         return false;
  1247.     }
  1248. }
  1249.  
  1250.  
  1251. function iil_C_FetchStructureString(&$conn, $folder, $id){
  1252.     $fp = $conn->fp;
  1253.     $result=false;
  1254.     if (iil_C_Select($conn, $folder)){
  1255.         $key = "F1247";
  1256.         if (fputs($fp, "$key FETCH $id (BODYSTRUCTURE)\r\n")){
  1257.             do{
  1258.                 $line=chop(iil_ReadLine($fp, 5000));
  1259.                 if ($line[0]=="*"){
  1260.                     if (ereg("}$", $line)){
  1261.                         preg_match("/(.+){([0-9]+)}/", $str, $match);  
  1262.                         $result = $match[1];
  1263.                         do{
  1264.                             $line = chop(iil_ReadLine($fp, 100));
  1265.                             if (!preg_match("/^$key/", $line)) $result .= $line;
  1266.                             else $done = true;
  1267.                         }while(!$done);
  1268.                     }else{
  1269.                         $result = $line;
  1270.                     }
  1271.                     list($pre, $post) = explode("BODYSTRUCTURE ", $result);
  1272.                     $result = substr($post, 0, strlen($post)-1);        //truncate last ')' and return
  1273.                 }
  1274.             }while (!preg_match("/^$key/",$line));
  1275.         }
  1276.     }
  1277.     return $result;
  1278. }
  1279.  
  1280. function iil_C_PrintSource(&$conn, $folder, $id, $part){
  1281.     $header = iil_C_FetchPartHeader($conn, $folder, $id, $part);
  1282.     //echo str_replace("\r", "", $header);
  1283.     echo $header;
  1284.     echo iil_C_PrintPartBody($conn, $folder, $id, $part);
  1285. }
  1286.  
  1287. function iil_C_GetQuota(&$conn){
  1288. /*
  1289. b GETQUOTAROOT "INBOX"
  1290. * QUOTAROOT INBOX user/rchijiiwa1
  1291. * QUOTA user/rchijiiwa1 (STORAGE 654 9765)
  1292. b OK Completed
  1293. */
  1294.     $fp = $conn->fp;
  1295.     $result=false;
  1296.     $quota_line = "";
  1297.     
  1298.     //get line containing quota info
  1299.     if (fputs($fp, "QUOT1 GETQUOTAROOT \"INBOX\"\r\n")){
  1300.         do{
  1301.             $line=chop(iil_ReadLine($fp, 5000));
  1302.             if (iil_StartsWith($line, "* QUOTA ")) $quota_line = $line;
  1303.         }while(!iil_StartsWith($line, "QUOT1"));
  1304.     }
  1305.     
  1306.     //return false if not found, parse if found
  1307.     if (!empty($quota_line)){
  1308.         $quota_line = eregi_replace("[()]", "", $quota_line);
  1309.         $parts = explode(" ", $quota_line);
  1310.         $storage_part = array_search("STORAGE", $parts);
  1311.         if ($storage_part>0){
  1312.             $result = array();
  1313.             $used = $parts[$storage_part+1];
  1314.             $total = $parts[$storage_part+2];
  1315.             $result["used"] = $used;
  1316.             $result["total"] = $total;
  1317.             $result["percent"] = round(($used/$total)*100);
  1318.             $result["free"] = 100 - $result["percent"];
  1319.         }
  1320.     }
  1321.     
  1322.     return $result;
  1323. }
  1324.  
  1325.  
  1326. function iil_C_ClearFolder(&$conn, $folder){
  1327.     $num_in_trash = iil_C_CountMessages($conn, $folder);
  1328.     if ($num_in_trash > 0) iil_C_Delete($conn, $folder, "1:".$num_in_trash);
  1329.     return (iil_C_Expunge($conn, $folder) >= 0);
  1330. }
  1331.  
  1332. ?>