home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / tsw / TSW_3.3.4.exe / Apache2 / admin / pop3.inc < prev    next >
Encoding:
Text File  |  2003-12-27  |  32.9 KB  |  1,267 lines

  1. <?php
  2. /////////////////////////////////////////////////////////
  3. //    
  4. //    POP3.inc
  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/pop3.inc
  17.     PURPOSE:
  18.         POP3 equivalence of imap.inc
  19.     USEAGE:
  20.         Function containing "_C_" in name require connection handler to be
  21.         passed as one of the parameters.  To obtain connection handler, use
  22.         iil_Connect()
  23.  
  24. ********************************************************/
  25.  
  26. $iil_error;
  27. $iil_errornum;
  28. $iil_selected;
  29.  
  30. class iilConnection{
  31.     var $fp;
  32.     var $login;
  33.     var $password;
  34.     var $host;
  35.     var $error;
  36.     var $errorNum;
  37.     var $selected;
  38.     var $cacheFP;
  39.     var $cacheMode;
  40. }
  41.  
  42. class iilBasicHeader{
  43.     var $id;
  44.     var $uid;
  45.     var $subject;
  46.     var $from;
  47.     var $to;
  48.     var $cc;
  49.     var $replyto;
  50.     var $date;
  51.     var $messageID;
  52.     var $size;
  53.     var $encoding;
  54.     var    $ctype;
  55.     var $flags;
  56.     var $timestamp;
  57.     var $seen;
  58.     var $deleted;
  59.     var $recent;
  60.     var $answered;
  61. }
  62.  
  63. function iil_xor($string, $string2){
  64.     $result = "";
  65.     $size = strlen($string);
  66.     for ($i=0; $i<$size; $i++) $result .= chr(ord($string[$i]) ^ ord($string2[$i]));
  67.         
  68.     return $result;
  69. }
  70.  
  71. function iil_ConnectionOpen($fp){
  72.     $status = socket_get_status($fp);
  73.     if (($status['timed_out']) || ($status['blocked']) || ($status['eof'])) return false;
  74.     else return true;
  75. }
  76.  
  77. function iil_ReadLine($fp, $size){
  78.     $line="";
  79.     if (($fp)&&(!feof($fp))){
  80.         do{
  81.             $buffer = fgets($fp, 1024);
  82.             $endID = strlen($buffer) - 1;
  83.             $end = (($buffer[$endID] == "\n")||(feof($fp)));
  84.             $line.=$buffer;
  85.         }while(!$end);
  86.     }
  87.     if ((feof($fp)) && (!empty($line))) $line.="\n";
  88.     return $line;
  89. }
  90.  
  91. function iil_C_ReadLine(&$conn){
  92.     if ($conn->cacheMode == "x"){
  93.         socket_set_timeout($conn->fp, 10);
  94.         return iil_ReadLine($conn->fp, 300);
  95.     }else if ($conn->cacheMode == "r"){
  96.         $line = iil_ReadLine($conn->cacheFP, 300);
  97.         //echo $line."<br>\n"; flush();
  98.         return $line;
  99.     }else if ($conn->cacheMode == "w"){
  100.         socket_set_timeout($conn->fp, 10);
  101.         $line = iil_ReadLine($conn->fp, 300);
  102.         fputs($conn->cacheFP, $line);
  103.         return $line;
  104.     }
  105. }
  106.  
  107. function iil_ReadReply($fp){
  108.     do{
  109.         $line = chop(trim(iil_ReadLine($fp, 1024)));
  110.     }while($line[0]=="*");
  111.     
  112.     return $line;
  113. }
  114.  
  115. function iil_ParseResult($string){
  116.     if ((($string[0]=="+") || ($string[0]=="-")) && ($string[1]!=" ")){
  117.         $string = $string[0]." ".substr($string, 1);
  118.     }
  119.     $a=explode(" ", $string);
  120.     if (count($a) > 2){
  121.         if (strcasecmp($a[1], "OK")==0) return 0;
  122.         else if (strcasecmp($a[1], "NO")) return -1;
  123.         else if (strcasecmp($a[1], "BAD")) return -2;
  124.     }else return -3;
  125. }
  126.  
  127. // check if $string starts with $match
  128. function iil_StartsWith($string, $match){
  129.     if ((empty($string)) || (empty($match))) return false;
  130.     
  131.     if ($string[0]==$match[0]){
  132.         $pos=strpos($string, $match);
  133.         if ( $pos === false) return false;
  134.         else if ( $pos == 0) return true;
  135.         else return false;
  136.     }else{
  137.         return false;
  138.     }
  139. }
  140.  
  141. function iil_Close(&$conn){
  142.     if (fputs($conn->fp, "QUIT\r\n")){
  143.         fgets($conn->fp, 1024);
  144.         fclose($conn->fp);
  145.     }
  146. }
  147.  
  148. function iil_C_CramMD5(&$conn, $user, $pass){
  149.     $conn->message .= "Doing CRAM-MD5\n";
  150.     fputs($conn->fp, "AUTH CRAM-MD5\r\n");
  151.     $line = chop(iil_ReadLine($conn->fp, 1024));
  152.     //echo "<!-- got reply: $line //-->\n";
  153.     if ($line[0]=="+"){
  154.         $encChallenge = substr($line, 2);
  155.         //echo "<!-- challenge: \"$encChallenge\" //-->\n";
  156.     }else{
  157.         //didn't get valid challenge
  158.         $conn->message .= "Didn't get challenge, got: \"$line\"\n";
  159.         return false;
  160.     }
  161.     
  162.     // initialize ipad, opad
  163.     for ($i=0;$i<64;$i++){
  164.         $ipad.=chr(0x36);
  165.         $opad.=chr(0x5C);
  166.     }
  167.     // pad $pass so it's 64 bytes
  168.     $padLen = 64 - strlen($pass);
  169.     for ($i=0;$i<$padLen;$i++) $pass .= chr(0);
  170.     // generate hash
  171.     $hash = md5(iil_xor($pass,$opad).pack("H*",md5(iil_xor($pass, $ipad).base64_decode($encChallenge))));
  172.     // generate reply
  173.     $reply = base64_encode($user." ".$hash);
  174.     
  175.     // send result, get reply
  176.     fputs($conn->fp, $reply."\r\n");
  177.     $line = iil_ReadLine($conn->fp, 1024);
  178.     
  179.     // process result
  180.     if (iil_ParseResult($line)==0){
  181.         $conn->error = "";
  182.         $conn->errorNum = 0;
  183.         $conn->message .= "CRAM-MD5 returning true\n";
  184.         return true;
  185.     }else{
  186.         $conn->error = "Authentication failed (AUTH): <br>\"".$line."\"";
  187.         $conn->errorNum = -2;
  188.         $conn->message .= "CRAM-MD5 failed: $line\n";
  189.         //echo "<!-- ".$conn->error." //-->\n";
  190.         return false;
  191.     }
  192. }
  193.  
  194. function iil_C_APOP($conn, $user, $password, $timestamp){
  195.     
  196.     $digest = md5($timestamp.$password);
  197.     
  198.     fputs($conn->fp, "APOP $user $digest\r\n");
  199.     $line = iil_ReadLine($conn->fp, 1024);
  200.     
  201.     if ($line[0]=="+") return true;
  202.     else{
  203.         return false;
  204.     }
  205. }
  206.  
  207. function iil_Connect($host, $user, $password){    
  208.     global $iil_error, $iil_errornum;
  209.     
  210.     $result = false;
  211.  
  212.     //strip slashes
  213.     $user = stripslashes($user);
  214.     $password = stripslashes($password);
  215.     
  216.     //set auth method
  217.     $auth_method = "plain";
  218.     if (func_num_args() >= 4){
  219.         $auth_array = func_get_arg(3);
  220.         if (is_array($auth_array)) $auth_method = $auth_array["pop3"];
  221.         if (empty($auth_method)) $auth_method = "plain";
  222.     }
  223.     
  224.     //initialize connection object
  225.     $conn = new iilConnection;
  226.     $conn->error="";
  227.     $conn->errorNum=0;
  228.     $conn->login = $user;
  229.     $conn->password = $password;
  230.     $conn->host = $host;
  231.     $conn->selected="";
  232.     
  233.     //initiate connection
  234.     $conn->fp=fsockopen($host, 110);
  235.     if ($conn->fp){
  236.         $iil_error.="Socket connection established\r\n";
  237.         $line=iil_ReadLine($conn->fp, 300);
  238.         
  239.         //check for time stamp
  240.         //it's the last "word" and has the form:
  241.         //    <somestring>
  242.         $sig_a = explode(" ", chop($line));
  243.         $last = count($sig_a)-1;
  244.         $timestamp = $sig_a[$last];
  245.         //echo "<!-- last word: \"$timestamp\" //-->\n";
  246.         $last_letter = strlen($timestamp)-1;
  247.         if (($timestamp[0]=="<") && ($timestamp[$last_letter]==">")){
  248.             $try_apop = true;
  249.         }else{
  250.             $try_apop = false;
  251.             $timestamp = "";
  252.         }
  253.         
  254.         if ($auth_method != "plain"){
  255.             fputs($conn->fp, "AUTH\r\n");
  256.             $line = iil_ReadLine($conn->fp, 300);
  257.             if ($line[0]=="+"){
  258.                 //auth command succeeded
  259.                 //get list of auth methods
  260.                 do{
  261.                     $line = iil_ReadLine($conn->fp, 300);
  262.                     $new_auth = strtolower(chop($line));
  263.                     $auth_methods[$new_auth] = 1;
  264.                 }while($line[0]!=".");
  265.                 
  266.                 //echo "<!-- got auth methods //-->\n";
  267.                 
  268.                 if ($auth_method == "check") $auth_method = "auth";
  269.             }else{
  270.                 //auth command failed
  271.                 //revert to plain text
  272.                 $auth_method = "plain";
  273.             }
  274.         }
  275.         
  276.         //try AUTH CRAM-MD5
  277.         if (($auth_method=="auth") && ($auth_methods["cram-md5"])){
  278.             //echo "<!-- doing CRAM-MD5 //-->\n";
  279.             $result = iil_C_CramMD5($conn, $user, $password);
  280.             $conn->message .= "CRAM_MD5: $result\n";
  281.         }
  282.         
  283.         //try APOP?
  284.         if ((!$result) && ($try_apop) && ($timestamp) && $auth_method!="plain"){
  285.             $result = iil_C_APOP($conn, $user, $password, $timestamp);
  286.             $conn->message .= "\nAPOP: $try_apop $result\n";
  287.         }
  288.  
  289.         if (!$result){
  290.             //do plain auth
  291.             fputs($conn->fp, "USER $user\r\n");
  292.             $line = trim(chop(iil_ReadLine($conn->fp, 1024)));
  293.             if (iil_StartsWith($line, "+OK")){
  294.                 fputs($conn->fp, "PASS $password\r\n");
  295.                 $line = trim(chop(iil_ReadLine($conn->fp, 1024)));
  296.                 if (iil_StartsWith($line, "+OK"))
  297.                     $result = true;
  298.                 else{
  299.                     $iil_errornum = -11;
  300.                     $iil_error = $line;
  301.                     iil_Close($conn);
  302.                     return false;
  303.                 }
  304.             }else{
  305.                 $iil_errornum = -2;
  306.                 $iil_error = "Unknown user: $user \"$line\"<br>Messages:".$conn->message;
  307.                 iil_Close($conn);
  308.                 return false;
  309.             }
  310.         }
  311.     }else{
  312.         $iil_error = "Could not connect to $host at port 110";
  313.         $iil_errornum = -1;
  314.         return false;
  315.     }
  316.     
  317.     if ($result) return $conn;
  318.     else return false;
  319. }
  320.  
  321. function iil_ExplodeQuotedString($delimiter, $string){
  322.     $quotes=explode("\"", $string);
  323.     while ( list($key, $val) = each($quotes))
  324.         if (($key % 2) == 1) 
  325.             $quotes[$key] = str_replace($delimiter, "_!@!_", $quotes[$key]);
  326.     $string=implode("\"", $quotes);
  327.     
  328.     $result=explode($delimiter, $string);
  329.     while ( list($key, $val) = each($result) )
  330.         $result[$key] = str_replace("_!@!_", $delimiter, $result[$key]);
  331.     
  332.     return $result;
  333. }
  334.  
  335. function iil_CheckForRecent($host, $user, $password, $mailbox){
  336.     return 0;
  337. }
  338.  
  339. function iil_C_Select(&$conn, $mailbox){
  340.     return true;
  341. }
  342.  
  343. function iil_C_CountMessages(&$conn, $mailbox){
  344.     $num=-1;
  345.     $fp = $conn->fp;
  346.     
  347.     if (fputs($fp, "STAT\r\n")){
  348.         $line=chop(fgets($fp, 300));
  349.         $a=explode(" ", $line);
  350.         $num=(int)$a[1];
  351.         $size = (int)$a[2];
  352.     }
  353.     
  354.     return $num;
  355. }
  356.  
  357. function iil_SplitHeaderLine($string){
  358.     $pos=strpos($string, ":");
  359.     if ($pos>0){
  360.         $res[0]=substr($string, 0, $pos);
  361.         $res[1]=substr($string, $pos+2);
  362.         return $res;
  363.     }else{
  364.         return $string;
  365.     }
  366. }
  367.  
  368. function iil_StrToTime($str){
  369.     //replace double spaces with single space
  370.     $str = trim($str);
  371.     $str = str_replace("  ", " ", $str);
  372.     
  373.     //strip off day of week
  374.     $pos=strpos($str, " ");
  375.     $word = substr($str, 0, $pos);
  376.     if (!is_numeric($word)) $str = substr($str, $pos+1);
  377.  
  378.     //explode, take good parts
  379.     $a=explode(" ",$str);
  380.     $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);
  381.     $month_str=$a[1];
  382.     $month=$month_a[$month_str];
  383.     $day=$a[0];
  384.     $year=$a[2];
  385.     $time=$a[3];
  386.     $tz_str = $a[4];
  387.     $tz = substr($tz_str, 0, 3);
  388.     $ta=explode(":",$time);
  389.     $hour=(int)$ta[0]-(int)$tz;
  390.     $minute=$ta[1];
  391.     $second=$ta[2];
  392.  
  393.     //make UNIX timestamp
  394.     return mktime($hour, $minute, $second, $month, $day, $year);
  395. }
  396.  
  397. function iil_F_List($fp){
  398.     fputs($fp, "LIST\r\n");
  399.     $line = fgets($fp, 128);
  400.     if ($line[0]=="+"){
  401.         do{
  402.             $line = fgets($fp, 128);
  403.             if ($line[0]!="."){
  404.                 $a = explode(" ", $line);
  405.                 $id = (int)$a[0];
  406.                 $size = (int)$a[1];
  407.                 $index[$id] = $size;
  408.             }
  409.         }while($line[0]!=".");
  410.     }
  411.     return $index;
  412. }
  413.  
  414. function iil_F_GetMessageID($fp, $id){
  415.     $messageID = "";
  416.     
  417.     fputs($fp, "TOP $id 0\r\n");
  418.     $line = fgets($fp, 128);
  419.     if ($line[0]=="+"){
  420.         do{
  421.             //go through headers...
  422.             $line = chop(iil_ReadLine($fp, 300));
  423.             $a = iil_SplitHeaderLine($line);
  424.             if (strcasecmp($a[0], "message-id")==0){
  425.                 $messageID = trim(chop($a[1]));
  426.                 $messageID = substr(substr($messageID, 1), 0, strlen($messageID)-2);
  427.             }
  428.         }while($line[0]!=".");
  429.     }
  430.     return $messageID;
  431. }
  432.  
  433. function iil_C_FetchHeaderIndex(&$conn, $mailbox, $message_set, $index_field){
  434.     return false;
  435.     
  436.     /*
  437.         NOTE:
  438.         Following code is a complete functional implementation of this particular function,
  439.         compatible with it's IMAP equivalence.  Only problem is, with POP3, it's less efficient
  440.         because the entire header for all messages have to be read in. 
  441.     */
  442.     
  443.     $fp = $conn->fp;
  444.     $result = array();
  445.     $index_field = strtoupper($index_field);
  446.     
  447.     //get index list
  448.     $index = iil_F_List($fp);
  449.  
  450.     if (strcmp($index_field, "SIZE")==0){
  451.         return $index;
  452.     }else{
  453.         reset($index);
  454.         //loop through all items
  455.         while ( list($id, $val) = each($index) ){
  456.             //fetch header
  457.             fputs($fp, "TOP $id 0\r\n");
  458.             $line = fgets($fp, 128);
  459.             if ($line[0]=="+"){
  460.                 do{
  461.                     //go through headers...
  462.                     $line = chop(iil_ReadLine($fp, 300));
  463.                     $a = iil_SplitHeaderLine($line);
  464.                     //look for line containg field we want
  465.                     if (strcasecmp($index_field,"date")==0) $a[1] = iil_StrToTime($a[1]);
  466.                     if (strcasecmp($a[0], $index_field)==0) $result[$id] = $a[1];
  467.                 }while($line[0]!=".");
  468.             }
  469.         }
  470.     }
  471.     
  472.     return $result;
  473. }
  474.  
  475. function iil_C_FetchHeaders(&$conn, $mailbox, $message_set){
  476.  
  477.     //echo microtime()."....starting iil_C_FetchHeaders $message_set <br>\n"; flush();
  478.  
  479.     if (strpos($message_set, ":")>0){
  480.         $a = explode(":", $message_set);
  481.         $from_i = (int)$a[0];
  482.         $to_i = (int)$a[1];
  483.     }else if (strpos($message_set, ",")>0){
  484.         $a = explode(",", $message_set);
  485.         $n = count($a);
  486.         $from_i = (int)$a[0];
  487.         $to_i = (int)$a[$n-1];
  488.     }else{
  489.         $from_i = $to_i = $message_set;
  490.     }
  491.         
  492.     $fp = $conn->fp;
  493.     $index = iil_F_List($fp);
  494.     
  495.     $c = 0;
  496.     $lines = array();
  497.     for ($id=$from_i;(($id<=$to_i)&&($fp));$id++){
  498.         //echo "[".microtime().":begin $id]"; flush();
  499.         
  500.         fputs($fp, "TOP $id 0\r\n");
  501.         $line = fgets($fp, 128);
  502.         
  503.         //echo "[".microtime().":requested]"; flush();
  504.         //echo "Requested $id ..."; flush();
  505.         if ($line[0]=="+"){
  506.  
  507.             //initialize new iilBasicHeader object
  508.             $result[$id] = new iilBasicHeader;
  509.             $result[$id]->size = $index[$id];
  510.             $result[$id]->id = $id;
  511.             $result[$id]->subject = "";
  512.             $result[$id]->seen = false;
  513.             $result[$id]->recent = false;
  514.             $result[$id]->deleted = false;
  515.             $result[$id]->answered = false;
  516.             
  517.             //fetch header into array
  518.             do{
  519.                 socket_set_timeout($fp, 10);
  520.                 $line = chop(iil_ReadLine($fp, 300));
  521.                 if (strlen($line)>2){
  522.                     if (ord($line[0]) <= 32) $lines[$c] .= (empty($lines[$c])?"":"\n").trim($line);
  523.                     else{
  524.                         $c++;
  525.                         $lines[$c]=$line;
  526.                     }
  527.                 }
  528.             }while(($line[0]!=".")&&($fp));
  529.             
  530.             //echo "[".microtime().":fetched header]"; flush();
  531.             
  532.             //process header, fill iilBasicHeader obj.
  533.             //    initialize
  534.             if (is_array($header_fields)){
  535.                 reset($header_fields);
  536.                 while ( list($k, $bar) = each($header_fields) ) $header_fields[$k] = "";
  537.             }
  538.  
  539.             //    create array with header field:data
  540.             $numlines = count($lines);
  541.             while (list($k,$string) = each($lines)){
  542.                 $pos=strpos($string, ":");
  543.                 if ($pos>0){
  544.                     $field = strtolower(substr($string, 0, $pos));
  545.                     $string = substr($string, $pos+2);
  546.                 }else{
  547.                     $field = "";
  548.                 }
  549.  
  550.                 $header_fields[$field] = $string;
  551.             }
  552.             
  553.             //    fill in object
  554.             $result[$id]->date = $header_fields["date"];
  555.             $result[$id]->timestamp = iil_StrToTime($result[$id]->date);
  556.             $result[$id]->from = $header_fields["from"];
  557.             $result[$id]->to = $header_fields["to"];
  558.             $result[$id]->subject = $header_fields["subject"];
  559.             $result[$id]->replyto = $header_fields["reply-to"];
  560.             $result[$id]->cc = $header_fields["cc"];
  561.             $result[$id]->messageID = substr(substr($header_fields["message-id"], 1), 0, strlen($header_fields["message-id"])-2);
  562.             $result[$id]->encoding = $header_fields["content-transfer-encoding"];
  563.             $result[$id]->ctype = $header_fields["content-type"];
  564.  
  565.             //echo "[".microtime().":filled]<br>\n"; flush();
  566.         }
  567.     }
  568.     //echo microtime().".....done"; flush();
  569.     
  570.     return $result;
  571. }
  572.  
  573.  
  574. function iil_C_FetchHeader(&$conn, $mailbox, $id){
  575.     $fp = $conn->fp;
  576.  
  577.     $index = iil_F_List($fp);
  578.  
  579.     fputs($fp, "TOP $id 0\r\n");
  580.     $line = fgets($fp, 128);
  581.     if ($line[0]=="+"){
  582.         //initialize new iilBasicHeader object
  583.         $result = new iilBasicHeader;
  584.         $result->size = $index[$id];
  585.         $result->id = $id;
  586.         
  587.         //fetch header into array
  588.         do{
  589.             $line = chop(iil_ReadLine($fp, 300));
  590.             if (strlen($line)>2){
  591.                 if (ord($line[0]) <= 32) $lines[$c] .= (empty($lines[$c])?"":"\n").trim($line);
  592.                 else{
  593.                     $c++;
  594.                     $lines[$c]=$line;
  595.                 }
  596.             }
  597.         }while($line[0]!=".");
  598.         
  599.         //process header, fill iilBasicHeader obj.
  600.         $numlines = count($lines);
  601.         for ($i=0;$i<$numlines;$i++){
  602.             //echo $lines[$i]."<br>\n";
  603.             list($field, $string) = iil_SplitHeaderLine($lines[$i]);
  604.             
  605.             if (strcasecmp($field, "date")==0){
  606.                 $result->date = $string;
  607.                 $result->timestamp = iil_StrToTime($string);
  608.             }
  609.             else if (strcasecmp($field, "from")==0) $result->from = str_replace("\n", " ", $string);
  610.             else if (strcasecmp($field, "to")==0) $result->to = $string;
  611.             else if (strcasecmp($field, "subject")==0) $result->subject = str_replace("\n", "", $string);
  612.             else if (strcasecmp($field, "reply-to")==0) $result->replyto=$string;
  613.             else if (strcasecmp($field, "cc")==0) $result->cc = str_replace("\n", " ", $string);
  614.             else if (strcasecmp($field, "Content-Transfer-Encoding")==0) $result->encoding=$string;
  615.             else if (strcasecmp($field, "message-id")==0)
  616.                 $result->messageID = substr(substr($string, 1), 0, strlen($string)-2);
  617.         }
  618.         return $result;
  619.     }else{
  620.         return false;
  621.     }
  622.     /*
  623.     $a=iil_C_FetchHeaders($conn, $mailbox, $id);
  624.     if (is_array($a)) return $a[$id];
  625.     else return false;
  626.     */
  627. }
  628.  
  629.  
  630. function iil_SortHeaders($a, $field, $flag){
  631.     if (empty($field)) $field="uid";
  632.     $field=strtolower($field);
  633.     if ($field=="date") $field="timestamp";
  634.     if (empty($flag)) $flag="ASC";
  635.     $flag=strtoupper($flag);
  636.     
  637.     $c=count($a);
  638.     if ($c>0){
  639.         /*
  640.             Strategy:
  641.             First, we'll create an "index" array.
  642.             Then, we'll use sort() on that array, 
  643.             and use that to sort the main array.
  644.         */
  645.                 
  646.                 // create "index" array
  647.         $index=array();
  648.         reset($a);
  649.         while (list($key, $val)=each($a)){
  650.             $data=$a[$key]->$field;
  651.             if (is_string($data)) $data=strtoupper(str_replace("\"", "", $data));
  652.             $index[$key]=$data;
  653.         }
  654.         
  655.         // sort index
  656.         $i=0;
  657.         if ($flag=="ASC") asort($index);
  658.         else arsort($index);
  659.         
  660.         // form new array based on index 
  661.         $result=array();
  662.         reset($index);
  663.         while (list($key, $val)=each($index)){
  664.             $result[$i]=$a[$key];
  665.             $i++;
  666.         }
  667.     }
  668.     
  669.     return $result;
  670. }
  671.  
  672. function iil_C_Expunge(&$conn, $mailbox){
  673.     return 0;
  674. }
  675.  
  676. function iil_C_Flag(&$conn, $mailbox, $messages, $flag){
  677.     return 0;
  678. }
  679.  
  680. function iil_C_Delete(&$conn, $mailbox, $messages){
  681.     $fp = $conn->fp;
  682.  
  683.     $c = 0;
  684.     if (strpos($messages, ":")!==false){
  685.         $a = explode(":", $messages);
  686.         $start = $a[0];
  687.         $end = $a[1];
  688.         for ($i=$start;$i<=$end;$i++) $messages .= (empty($messages)?"":",").$i;
  689.     }
  690.     $message_list = explode(",", $messages);
  691.     while ( list($key, $val) = each($message_list) ){
  692.         fputs($fp, "DELE $val\r\n");
  693.         $line = iil_ReadLine($fp, 300);
  694.         if ($line[0]=="+"){
  695.             $c++;
  696.         }
  697.     }
  698.     
  699.     //disconnect and reconnect to expunge
  700.     iil_Close($conn);
  701.     $conn = iil_Connect($conn->host, $conn->login, $conn->password);
  702.     
  703.     return $c;
  704. }
  705.  
  706. function iil_C_Undelete(&$conn, $mailbox, $messages){
  707.     return -1;
  708. }
  709.  
  710. function iil_C_Unseen(&$conn, $mailbox, $messages){
  711.     return -1;
  712. }
  713.  
  714. function iil_C_Copy(&$conn, $messages, $from, $to){
  715.     return 0;
  716. }
  717.  
  718. function iil_FormatSearchDate($month, $day, $year){
  719.     $months=array(
  720.             1=>"Jan", 2=>"Feb", 3=>"Mar", 4=>"Apr", 
  721.             5=>"May", 6=>"Jun", 7=>"Jul", 8=>"Aug", 
  722.             9=>"Sep", 10=>"Oct", 11=>"Nov", 12=>"Dec"
  723.             );
  724.     return $day."-".$months[$month]."-".$year;
  725. }
  726.  
  727. function iil_C_Search(&$conn, $folder, $criteria){
  728.     return false;
  729. }
  730.  
  731. function iil_C_Move(&$conn, $messages, $from, $to){
  732.     return 0;
  733. }
  734.  
  735. function iil_C_GetHierarchyDelimiter(&$conn){
  736.     return "/";
  737. }
  738.  
  739. function iil_C_ListMailboxes(&$conn, $ref, $mailbox){
  740.     return array("INBOX");
  741. }
  742.  
  743. function iil_ActionPrintBody($line){
  744.     echo chop($line)."\n"; flush();
  745.     return "";
  746. }
  747.  
  748. function iil_ActionFetchBody($line){
  749.     return chop($line)."\n";
  750. }
  751.  
  752. function iil_ActionBase64Decode($line){
  753.     echo base64_decode(chop($line)); flush();
  754.     return "";
  755. }
  756.  
  757. function iil_ActionFetchHeader($line){
  758.     return "";
  759. }
  760.  
  761. function iil_ClearCache($login, $host){
  762.     global $CACHE_DIR;
  763.     
  764.     $cacheDir = $CACHE_DIR;
  765.     if (empty($cacheDir)) $cacheDir = "../cache/";
  766.     if (!file_exists(realpath($cacheDir))) $conn->errorNum = -2;
  767.     else{
  768.         $cacheDir = $cacheDir.ereg_replace("[\\/]", "", $login.".".$host);
  769.         if (!file_exists(realpath($cacheDir))) mkdir($cacheDir, 0700);
  770.     }
  771.     if (file_exists(realpath($cacheDir))){
  772.         if ($handle = opendir($cacheDir)) {
  773.             while (false !== ($file = readdir($handle))) { 
  774.                 if ($file != "." && $file != "..") { 
  775.                     $file_path = $cacheDir."/".$file;
  776.                     //echo $file_path."<br>\n";
  777.                     unlink($file_path);
  778.                 } 
  779.             }
  780.             closedir($handle); 
  781.         }
  782.     }    
  783. }
  784.  
  785. function iil_C_OpenMessage(&$conn, $id){
  786.     /*
  787.         POST-CONDITIONS:
  788.             TRUE: if cache file has been opened
  789.             FALSE: if cache file is not open
  790.             $conn->cacheMode:
  791.                 x: failed
  792.                 w: open cache for writing
  793.                 r: cache opened for reading
  794.     */
  795.     global $CACHE_DIR;
  796.     
  797.     $conn->messageID = iil_F_GetMessageID($conn->fp, $id);
  798.     $messageID = $conn->messageID;
  799.     
  800.     $conn->errorNum = 0;
  801.     $conn->cacheMode = "x";
  802.     if (!empty($messageID)){
  803.         $cacheDir = $CACHE_DIR;
  804.         if (empty($cacheDir)) $cacheDir = "../cache/";
  805.         if (!file_exists(realpath($cacheDir))) $conn->errorNum = -2;
  806.         else{
  807.             $cacheDir = $cacheDir."/".ereg_replace("[\\/]", "", $conn->login.".".$conn->host);
  808.             if (!file_exists(realpath($cacheDir))) mkdir($cacheDir, 0700);
  809.         }
  810.         if (file_exists(realpath($cacheDir))){
  811.             $cachePath = $cacheDir."/".urlencode($messageID);
  812.             if (file_exists(realpath($cachePath))) $mode = "r";
  813.             else $mode = "w";
  814.             
  815.             $conn->cacheFP = fopen($cachePath, $mode);
  816.             if ($conn->cacheFP){
  817.                 $conn->cacheMode = $mode;
  818.                 return true;
  819.             }else{
  820.                 $conn->errorNum = -3;
  821.                 $conn->error = "Couldn't open cache for reading";
  822.             }
  823.         }else{
  824.             $conn->errorNum = -2;
  825.             $conn->error = "Invalid cache directory";
  826.         }
  827.     }else{
  828.         $conn->errorNum = -1;
  829.         $conn->error = "Invalid messageID";
  830.     }
  831.     return false;
  832. }
  833.  
  834. function iil_C_CloseMessage(&$conn){
  835.     if (($conn->cacheMode=="r") || ($conn->cacheMode=="w")) fclose($conn->cacheFP);
  836.     $conn->cacheMode = "x";
  837.     $conn->messageID = "";
  838. }
  839.  
  840. function iil_C_FetchBodyPart(&$conn, $boundary, &$last_line, $the_part, &$part, $action, $bytes_total, &$bytes_read){
  841.     if ($the_part==0) $the_part="";
  842.     $original_boundary = $boundary; 
  843.     $raw_header = "";
  844.     $raw_text = "";
  845.     
  846.     if ($conn->cacheMode=="r") $fp = $conn->cacheFP;
  847.     else $fp = $conn->fp;
  848.  
  849.     // read headers from file
  850.     $lines = array();
  851.     $count = 0;
  852.     do{
  853.         $line = iil_C_ReadLine($conn);
  854.         $bytes_read+=strlen($line);
  855.         $raw_header .= $line;
  856.         $line = chop($line);
  857.         if (!empty($line)){
  858.             //echo "Read: ".$line."<br>\n";
  859.             $c = 0;
  860.             if (ord($line[0]) <= 32) $lines[$count].=" ".trim($line);
  861.             else{
  862.                 $count++;
  863.                 $lines[$count] = $line;
  864.                 //echo "\t".$count.":".$line."\n";
  865.             }
  866.         }
  867.     }while(!empty($line));
  868.     if ((strcmp($part, $the_part)==0)&&(strcmp($action, "FetchHeader")==0)) $str=$raw_header;
  869.     
  870.     //echo "Read header: ".count($lines)." lines\n"; flush();
  871.     
  872.     // parse header into associative array
  873.     $header = iil_ContentHeaderArray($lines);
  874.     
  875.     //echo "Parsed headers\n"; flush();
  876.     //echo implode("\n", $lines)."\n\n";
  877.     
  878.     //echo $header["content-type"]["major"]." vs multipart";
  879.     
  880.     // generate bodystructure string(s)
  881.     if (strcasecmp($header["content-type"]["major"], "multipart")==0){
  882.         //echo "Parsing multipart\n"; flush();
  883.         
  884.         $params = $header["content-type"]["parameters"];
  885.         while ( list($k, $v) = each($params) ) if (strcasecmp($v, "\"boundary\"")==0) $boundary = "--".str_replace("\"","",$params[$k+1]);
  886.         //echo "Boundary: ".$boundary."<br>\n";
  887.         do{
  888.             $line = iil_C_ReadLine($conn);
  889.             $bytes_read+=strlen($line);
  890.         }while(!iil_StartsWith($line, $boundary));
  891.  
  892.         //parse body parts
  893.         $part_num = 0;
  894.         do{
  895.             $part_num++;
  896.             $next_part = $part.(!empty($part)?".":"").$part_num;
  897.             $str .= iil_C_FetchBodyPart($conn, $boundary, $last_line, $the_part, $next_part, $action, $bytes_total, $bytes_read);
  898.             $end = (((strlen($last_line) - strlen($boundary)) > 0) || (chop($last_line)=="."));
  899.         }while((!$end) && (!feof($fp))&&(chop($last_line)!="."));
  900.  
  901.         //read up to next message boundary
  902.         if (chop($last_line)!="."){
  903.             do{
  904.                 $line = iil_C_ReadLine($conn);
  905.                 $bytes_read += strlen($line);
  906.                 $end = ((iil_StartsWith($line, $original_boundary)) || (chop($last_line)=="."));
  907.             }while((!$end)&&(!feof($fp))&&(chop($line)!="."));
  908.             $last_line = chop($line);
  909.         }
  910.     }else if (strcasecmp($header["content-type"]["major"], "message")==0){
  911.         //read blank lines (up to and including first line, which hopefully isn't important)
  912.         do{
  913.             $line = iil_C_ReadLine($conn);
  914.         }while(iil_StartsWith($line, "\n"));
  915.         
  916.         $str .= iil_C_FetchBodyPart($conn, $boundary, $last_line, $the_part, $part, $action, $bytes_total, $bytes_read);
  917.     }else{
  918.         // read actual data
  919.         //echo "Will do action: $action <br>\n"; flush();
  920.         if (strcmp($part, $the_part)==0){
  921.             $this_is_it=ture;
  922.             $handler = "iil_Action".$action;
  923.         }else $this_is_it = false;
  924.         do{
  925.             $line = iil_C_ReadLine($conn);
  926.             $bytes_read += strlen($line);
  927.             if (($this_is_it)&&(!iil_StartsWith($line, $boundary))&&(chop($line)!=".")) $str.=$handler($line);
  928.             $line = chop($line);
  929.             //echo "Read $bytes_read of $bytes_total bytes<br>\n"; flush();
  930.         }while((!iil_StartsWith($line, $boundary)) && ((!feof($fp))&&($line!=".")));
  931.         $last_line = $line;
  932.     }
  933.     
  934.     //echo "Read $bytes_read out of $bytes_total <br>\n"; flush();
  935.  
  936.     return $str;
  937. }
  938.  
  939. function iil_C_HandlePartBody(&$conn, $id, $part, $action){
  940.         
  941.     iil_C_OpenMessage($conn, $id);
  942.     
  943.     //echo "Message opened\n"; flush();
  944.     
  945.     if (($conn->cacheMode=="x") || ($conn->cacheMode=="w")){
  946.         $fp = $conn->fp;
  947.         fputs($fp, "RETR $id\r\n");
  948.         $line = fgets($fp, 100);
  949.         if ($line[0]!="+"){
  950.             $conn->errorNum = -10;
  951.             $conn->error = "POP3 error:".$line;
  952.         }
  953.     }
  954.  
  955.     //echo "FP opened\n";
  956.  
  957.     if ($conn->fp){
  958.         //echo "Going ingot iil_C_FetchBodyPart\n";
  959.         $result =  iil_C_FetchBodyPart($conn, "", $line, $part, $part_blah, $action, $total_size, $bytes);
  960.     }else{
  961.         $conn->error = "Bad fp";
  962.     }
  963.     iil_C_CloseMessage($conn);
  964.     
  965.     return $result;
  966. }
  967.  
  968. function iil_C_FetchPartBody(&$conn, $mailbox, $id, $part){
  969.     return iil_C_HandlePartBody($conn, $id, $part, "FetchBody");
  970. }
  971.  
  972. function iil_C_PrintPartBody(&$conn, $mailbox, $id, $part){
  973.     return iil_C_HandlePartBody($conn, $id, $part, "PrintBody");
  974. }
  975.  
  976. function iil_C_PrintBase64Body(&$conn, $mailbox, $id, $part){
  977.     return iil_C_HandlePartBody($conn, $id, $part, "Base64Decode");
  978. }
  979.  
  980. function iil_C_FetchPartHeader(&$conn, $mailbox, $id, $part){
  981.     return iil_C_HandlePartBody($conn, $id, $part, "FetchHeader");
  982. }
  983.  
  984. function iil_C_CreateFolder(&$conn, $folder){
  985.     return false;
  986. }
  987.  
  988. function iil_C_RenameFolder(&$conn, $from, $to){
  989.     return false;
  990. }
  991.  
  992. function iil_C_DeleteFolder(&$conn, $folder){
  993.     return false;
  994. }
  995.  
  996. function iil_C_Append(&$conn, $folder, $message){
  997.     return false;
  998. }
  999.  
  1000. function iil_ReadHeader($fp){
  1001.     $lines = array();
  1002.     $c = 0;
  1003.     //echo "++++<br>\n";
  1004.     do{
  1005.         $line = chop(iil_ReadLine($fp, 300));
  1006.         if (!empty($line)){
  1007.             //echo "Read: ".$line."<br>\n";
  1008.             if (ord($line[0]) <= 32) $lines[$c].=" ".trim($line);
  1009.             else{
  1010.                 $c++;
  1011.                 $lines[$c] = $line;
  1012.             }
  1013.         }
  1014.     }while(!empty($line));
  1015.     //echo "++++<br>\n";
  1016.     
  1017.     return $lines;
  1018. }
  1019.  
  1020. function iil_ParseContentHeader($data){
  1021.     $parameters = array();
  1022.  
  1023.     $pos = strpos($data, ";");
  1024.     if ($pos === false){
  1025.         //no';'? then no parameters, all we have is main data
  1026.         $major_data = $data;
  1027.     }else{
  1028.         //every thing before first ';' is main data
  1029.         $major_data = substr($data, 0, $pos);
  1030.         $data = substr($data, $pos+1);
  1031.         
  1032.         //go through parameter list (delimited by ';')
  1033.         $parameters_a = explode(";", $data);
  1034.         while ( list($key, $val) = each($parameters_a) ){
  1035.             // split param name from param data
  1036.             $val = trim(chop($val));
  1037.             $eqpos = strpos($val, "=");
  1038.             $p_field = substr($val, 0, $eqpos);
  1039.             $p_data = substr($val, $eqpos+1);
  1040.             $field = trim(chop($p_field));
  1041.             $p_data = trim(chop($p_data));
  1042.             // add quotes
  1043.             if ($p_data[0]!="\"") $p_data = "\"".$p_data."\"";
  1044.             $p_field = "\"".$p_field."\"";
  1045.             // add to array
  1046.             array_push($parameters, $p_field);
  1047.             array_push($parameters, $p_data);
  1048.         }
  1049.     }
  1050.     $result["data"] = trim(chop($major_data));
  1051.     if (count($parameters) > 0) $result["parameters"] = $parameters;
  1052.     else $result["parameters"] = "NIL";
  1053.     
  1054.     return $result;
  1055. }
  1056.  
  1057. function iil_ContentHeaderArray($lines){
  1058.     //echo "---<br>\n";
  1059.     $num_lines = count($lines);
  1060.     //initialize header variables with default (fall back) values
  1061.     $header["content-type"]["major"] = "text";
  1062.     $header["content-type"]["minor"] = "plain";
  1063.     $header["content-transfer-encoding"]["data"] = "8bit";
  1064.     while ( list($key, $line) = each($lines) ){
  1065.         //echo $line."<br>\n";
  1066.         list($field, $data) = iil_SplitHeaderLine($line);
  1067.         // is this a content header?
  1068.         if (iil_StartsWith($field, "Content")){
  1069.             $field = strtolower($field);
  1070.             // parse line, add "data" and "parameters" to header[]
  1071.             $header[$field] = iil_ParseContentHeader($data);
  1072.             // need some special care for "content-type" header line
  1073.             if (strcasecmp($field, "content-type")==0){
  1074.                 $typeStr = $header["content-type"]["data"];
  1075.                 //split major and minor content types
  1076.                 $slashPos = strpos($typeStr,"/");
  1077.                 $major_type = substr($typeStr, 0, $slashPos);
  1078.                 $minor_type = substr($typeStr, $slashPos+1);
  1079.                 $header["content-type"]["major"] = strtolower($major_type);
  1080.                 $header["content-type"]["minor"] = strtolower($minor_type);
  1081.             }
  1082.         }
  1083.     }
  1084.     return $header;
  1085. }
  1086.  
  1087. function iil_C_ReadNParse($conn, $boundary, &$last_line){
  1088.  
  1089.     $original_boundary = $boundary; 
  1090.     
  1091.     if ($conn->cacheMode=="r") $fp = $conn->cacheFP;
  1092.     else $fp = $conn->fp;
  1093.  
  1094.     // read headers from file
  1095.     $lines = iil_ReadHeader($fp);
  1096.     if (count($lines) == 0) return "";
  1097.     if ($conn->cacheMode=="w") fputs($conn->cacheFP, implode("\n", $lines)."\n\n");    
  1098.         
  1099.     // parse header into associative array
  1100.     $header = iil_ContentHeaderArray($lines);
  1101.     
  1102.     // generate bodystructure string(s)
  1103.     if (strcasecmp($header["content-type"]["major"], "multipart")==0){
  1104.         $params = $header["content-type"]["parameters"];
  1105.         while ( list($k, $v) = each($params) ) if (strcasecmp($v, "\"boundary\"")==0) $boundary = "--".str_replace("\"","",$params[$k+1]);
  1106.         do{
  1107.             $line = iil_C_ReadLine($conn);
  1108.         }while(!iil_StartsWith($line, $boundary));
  1109.         $str = "(";
  1110.         //parse body parts
  1111.         do{
  1112.             $str .= iil_C_ReadNParse($conn, $boundary, $last_line);
  1113.             $end = (((strlen($last_line) - strlen($boundary)) > 0) || (chop($last_line)=="."));
  1114.         }while((!$end) && (!feof($fp))&&($line!="."));
  1115.         
  1116.         $str .=" \"".$header["content-type"]["minor"]."\" (".implode(" ", $params).") NIL NIL)";
  1117.  
  1118.         //if next boundary encountered
  1119.         if ((chop($line)!=".") && (chop($last_line)!=".")){
  1120.             //read up to next message boundary
  1121.             do{
  1122.                 $line = iil_C_ReadLine($conn);
  1123.                 $end = ((iil_StartsWith($line, $original_boundary)) || (chop($last_line)=="."));
  1124.             }while((!$end)&&(!feof($fp))&&(chop($line)!=".")) ;
  1125.             $last_line = chop($line);
  1126.         }
  1127.     }else if (strcasecmp($header["content-type"]["major"], "message")==0){
  1128.         //read blank lines (up to and including first line, which hopefully isn't important)
  1129.         do{
  1130.             $line = iil_C_ReadLine($conn);
  1131.         }while(iil_StartsWith($line, "\n"));
  1132.         
  1133.         //format structure string
  1134.         $str = '("'.$header["content-type"]["major"].'" "'.$header["content-type"]["minor"].'"';
  1135.         $str.= ' NIL NIL NIL';
  1136.         $str.= ' "'.$header["content-transfer-encoding"]["data"].'"';
  1137.         $byte_count = 'NIL';
  1138.         $str.= " $byte_count NIL ";
  1139.         
  1140.         //recursively parse content
  1141.         $str.= iil_C_ReadNParse($conn, $boundary, $last_line);
  1142.         
  1143.         //more structure stuff
  1144.         $line_count = 'NIL';
  1145.         $str.= " $line_count NIL ";
  1146.         if (!empty($header["content-disposition"]["data"])){
  1147.             $param_a = $header["content-disposition"]["parameters"];
  1148.             $str .= "(\"".$header["content-disposition"]["data"]."\" ";
  1149.             if ((is_array($param_a)) && (count($param_a) > 0))
  1150.                 $str .="(".implode(" ", $param_a).")";
  1151.             else $str .="NIL";
  1152.             $str .= ") ";
  1153.         }else $str .= "NIL ";
  1154.         $str.= ' NIL)';
  1155.     }else{
  1156.         // read actual data
  1157.         $content_size = 0;
  1158.         $num_lines = 0;
  1159.         do{
  1160.             $line = iil_C_ReadLine($conn);
  1161.             $content_size += strlen($line);
  1162.             $num_lines++;
  1163.             $line = chop($line);
  1164.         }while((!iil_StartsWith($line, $boundary)) && ((!feof($fp))&&($line!=".")));
  1165.         $last_line = $line;
  1166.                 
  1167.         // generate bodystructure string
  1168.         $str = "(";
  1169.         $str .= "\"".$header["content-type"]["major"]."\" ";
  1170.         $str .= "\"".$header["content-type"]["minor"]."\" ";
  1171.         if ((is_array($header["content-type"]["parameters"]))&&(count($header["content-type"]["parameters"]) > 0))
  1172.             $str .="(".implode(" ", $header["content-type"]["parameters"]).") ";
  1173.         else
  1174.             $str .= "NIL ";
  1175.         if ($header["content-id"]["data"])
  1176.             $str .= "\"".$header["content-id"]["data"]."\" ";
  1177.         else
  1178.             $str .= "NIL ";
  1179.         $str .= "NIL ";
  1180.         $str .= "\"".$header["content-transfer-encoding"]["data"]."\" ";
  1181.         $str .= $content_size." ";
  1182.         if (strcasecmp($header["content-type"]["major"], "text")==0)
  1183.             $str .= $num_lines." ";
  1184.         $str .= "NIL ";
  1185.         if (!empty($header["content-disposition"]["data"])){
  1186.             $param_a = $header["content-disposition"]["parameters"];
  1187.             $str .= "(\"".$header["content-disposition"]["data"]."\" ";
  1188.             if ((is_array($param_a)) && (count($param_a) > 0))
  1189.                 $str .="(".implode(" ", $param_a).")";
  1190.             else $str .="NIL";
  1191.             $str .= ") ";
  1192.         }else $str .= "NIL ";
  1193.         $str .= "NIL ";
  1194.         $str = substr($str, 0, strlen($str)-1);
  1195.         $str .= ")";
  1196.     }
  1197.     
  1198.     return $str;
  1199. }
  1200.  
  1201. function iil_C_FetchStructureString(&$conn, $folder, $id){
  1202.     $fp = $conn->fp;
  1203.         
  1204.     iil_C_OpenMessage($conn,$id);
  1205.     
  1206.     if (($conn->cacheMode=="x") || ($conn->cacheMode=="w")){
  1207.         fputs($fp, "RETR $id\r\n");
  1208.         $line = fgets($fp, 100);
  1209.         if ($line[0]!="+"){
  1210.             $conn->errorNum = -10;
  1211.             $conn->error = "POP3 error:".$line;
  1212.         }
  1213.     }
  1214.  
  1215.     if ($conn->fp){
  1216.         $str =  iil_C_ReadNParse($conn, "", $line);
  1217.     }
  1218.     
  1219.     iil_C_CloseMessage($conn);
  1220.     
  1221.     return $str;
  1222. }
  1223.  
  1224. function iil_C_PrintSource(&$conn, $folder, $id, $part){
  1225.     iil_C_OpenMessage($conn,$id);
  1226.     
  1227.     if ($conn->cacheMode=="r") $fp = $conn->cacheFP;
  1228.     else $fp = $conn->fp;
  1229.     
  1230.     if (($conn->cacheMode=="x") || ($conn->cacheMode=="w")){
  1231.         fputs($fp, "RETR $id\r\n");
  1232.         $line = fgets($fp, 100);
  1233.         if ($line[0]!="+"){
  1234.             $conn->errorNum = -10;
  1235.             $conn->error = "POP3 error:".$line;
  1236.         }
  1237.     }
  1238.  
  1239.     if ($fp){
  1240.         do{
  1241.             $line = iil_ReadLine($fp, 300);
  1242.             echo $line;
  1243.         }while((chop($line)!=".")&&(!feof($fp)));
  1244.     }
  1245.     iil_C_CloseMessage($conn);
  1246. }
  1247.  
  1248. function iil_C_GetQuota($conn){
  1249.     global $POP_QUOTA;
  1250.     
  1251.     $index = iil_F_List($conn->fp);
  1252.     $used = 0;
  1253.     if (is_array($index)) while ( list($k,$size) = each($index) ) $used += $size;
  1254.     else $used = 0;
  1255.     $total = $POP_QUOTA[$conn->host];
  1256.     
  1257.     $used = (int)($used/1024);
  1258.     $result["used"] = $used;
  1259.     $result["total"] = (empty($total)?"??":$total);
  1260.     $result["percent"] = (empty($total)?"??":round(($used/$total)*100));
  1261.     $result["free"] = 100 - $result["percent"];
  1262.     
  1263.     return $result;
  1264. }
  1265.  
  1266. ?>
  1267.