svncommit
2009-05-12 f22c2cefb4c7f8b1a995d5de6f706d49861c473c
program/lib/imap.inc
@@ -68,7 +68,7 @@
      - iil_C_HandlePartBody(): added 6th argument and fixed endless loop
      - added iil_PutLineC() 
      - fixed iil_C_Sort() to support very long and/or divided responses
      - added BYE response simple support for endless loop prevention
      - added BYE/BAD response simple support for endless loop prevention
      - added 3rd argument in iil_StartsWith* functions
      - fix iil_C_FetchPartHeader() in some cases by use of iil_C_HandlePartBody()
      - allow iil_C_HandlePartBody() to fetch whole message
@@ -79,6 +79,8 @@
      - include BODYSTRUCTURE in iil_C_FetchHeaders()
      - added iil_C_FetchMIMEHeaders() function
      - added \* flag support 
      - use PREG instead of EREG
      - removed caching functions
********************************************************/
@@ -134,9 +136,6 @@
   var $selected;
   var $message;
   var $host;
   var $cache;
   var $uid_cache;
   var $do_cache;
   var $exists;
   var $recent;
   var $rootdir;
@@ -182,6 +181,7 @@
   var $forwarded = false;
   var $junk = false;
   var $flagged = false;
   var $others = array();
}
/**
@@ -220,6 +220,9 @@
         if(preg_match('/^\{[0-9]+\}\r\n$/', $parts[$i+1])) {
            $res += iil_PutLine($fp, $parts[$i].$parts[$i+1], false);
            $line = iil_ReadLine($fp, 1000);
            // handle error in command
            if ($line[0] != '+')
               return false;
            $i++;
         }
         else
@@ -254,7 +257,7 @@
function iil_MultLine($fp, $line) {
   $line = chop($line);
   if (ereg('\{[0-9]+\}$', $line)) {
   if (preg_match('/\{[0-9]+\}$/', $line)) {
      $out = '';
        
      preg_match_all('/(.*)\{([0-9]+)\}$/', $line, $a);
@@ -292,7 +295,7 @@
}
function iil_ParseResult($string) {
   $a=explode(' ', $string);
   $a = explode(' ', $string);
   if (count($a) > 2) {
      if (strcasecmp($a[1], 'OK') == 0) {
         return 0;
@@ -307,8 +310,8 @@
   return -4;
}
// check if $string starts with $match
function iil_StartsWith($string, $match, $bye=false) {
// check if $string starts with $match (or * BYE/BAD)
function iil_StartsWith($string, $match, $error=false) {
   $len = strlen($match);
   if ($len == 0) {
      return false;
@@ -316,7 +319,7 @@
   if (strncmp($string, $match, $len) == 0) {
      return true;
   }
   if ($bye && strncmp($string, '* BYE ', 6) == 0) {
   if ($error && preg_match('/^\* (BYE|BAD) /i', $string)) {
      return true;
   }
   return false;
@@ -332,6 +335,7 @@
   }
   if ($bye && strncmp($string, '* BYE ', 6) == 0) {
      return true;
   }
   return false;
}
@@ -378,6 +382,12 @@
   }
   return false;
}
function iil_C_ClearCapability(&$conn)
{
   $conn->capability = array();
   $conn->capability_readed = false;
}
function iil_C_Authenticate(&$conn, $user, $pass, $encChallenge) {
@@ -535,7 +545,6 @@
function iil_Connect($host, $user, $password, $options=null) {   
   global $iil_error, $iil_errornum;
   global $ICL_SSL, $ICL_PORT;
   global $IMAP_NO_CACHE;
   global $my_prefs, $IMAP_USE_INTERNAL_DATE;
   
   $iil_error = '';
@@ -561,16 +570,13 @@
      
   $result = false;
   
   //initialize connection
   // initialize connection
   $conn              = new iilConnection;
   $conn->error       = '';
   $conn->errorNum    = 0;
   $conn->selected    = '';
   $conn->user        = $user;
   $conn->host        = $host;
   $conn->cache       = array();
   $conn->do_cache    = (function_exists("cache_write")&&!$IMAP_NO_CACHE);
   $conn->cache_dirty = array();
   
   if ($my_prefs['sort_field'] == 'INTERNALDATE') {
      $IMAP_USE_INTERNAL_DATE = true;
@@ -595,16 +601,15 @@
      $iil_errornum = -1;
      return false;
   }
   if (!$ICL_PORT) {
      $ICL_PORT = 143;
   }
   //check for SSL
   if ($ICL_SSL) {
   if ($ICL_SSL && $ICL_SSL != 'tls') {
      $host = $ICL_SSL . '://' . $host;
   }
   //open socket connection
   $conn->fp = fsockopen($host, $ICL_PORT, $errno, $errstr, 10);
   if (!$conn->fp) {
          $iil_error = "Could not connect to $host at port $ICL_PORT: $errstr";
@@ -621,6 +626,29 @@
   }
   $conn->message .= $line;
   // TLS connection
   if ($ICL_SSL == 'tls' && iil_C_GetCapability($conn, 'STARTTLS')) {
           if (version_compare(PHP_VERSION, '5.1.0', '>=')) {
                     iil_PutLine($conn->fp, 'stls000 STARTTLS');
         $line = iil_ReadLine($conn->fp, 4096);
                   if (!iil_StartsWith($line, 'stls000 OK')) {
            $iil_error = "Server responded to STARTTLS with: $line";
            $iil_errornum = -2;
                          return false;
                   }
         if (!stream_socket_enable_crypto($conn->fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
            $iil_error = "Unable to negotiate TLS";
            $iil_errornum = -2;
            return false;
         }
         // Now we're authenticated, capabilities need to be reread
         iil_C_ClearCapability($conn);
           }
   }
   if (strcasecmp($auth_method, "check") == 0) {
      //check for supported auth methods
@@ -680,92 +708,11 @@
}
function iil_Close(&$conn) {
   iil_C_WriteCache($conn);
   if (iil_PutLine($conn->fp, "I LOGOUT")) {
      fgets($conn->fp, 1024);
      fclose($conn->fp);
      $conn->fp = false;
   }
}
function iil_ClearCache($user, $host) {
}
function iil_C_WriteCache(&$conn) {
   //echo "<!-- doing iil_C_WriteCache //-->\n";
   if (!$conn->do_cache) return false;
   if (is_array($conn->cache)) {
      while (list($folder,$data)=each($conn->cache)) {
         if ($folder && is_array($data) && $conn->cache_dirty[$folder]) {
            $key = $folder.".imap";
            $result = cache_write($conn->user, $conn->host, $key, $data, true);
            //echo "<!-- writing $key $data: $result //-->\n";
         }
      }
   }
}
function iil_C_EnableCache(&$conn) {
   $conn->do_cache = true;
}
function iil_C_DisableCache(&$conn) {
   $conn->do_cache = false;
}
function iil_C_LoadCache(&$conn, $folder) {
   if (!$conn->do_cache) {
       return false;
   }
   $key = $folder.'.imap';
   if (!is_array($conn->cache[$folder])) {
      $conn->cache[$folder]       = cache_read($conn->user, $conn->host, $key);
      $conn->cache_dirty[$folder] = false;
   }
}
function iil_C_ExpireCachedItems(&$conn, $folder, $message_set) {
   if (!$conn->do_cache) {
      return;   //caching disabled
   }
   if (!is_array($conn->cache[$folder])) {
          return;   //cache not initialized|empty
   }
   if (count($conn->cache[$folder]) == 0) {
          return;   //cache not initialized|empty
   }
   $uids = iil_C_FetchHeaderIndex($conn, $folder, $message_set, 'UID');
   $num_removed = 0;
   if (is_array($uids)) {
      //echo "<!-- unsetting: ".implode(",",$uids)." //-->\n";
      while (list($n,$uid)=each($uids)) {
         unset($conn->cache[$folder][$uid]);
         //$conn->cache[$folder][$uid] = false;
         //$num_removed++;
      }
      $conn->cache_dirty[$folder] = true;
      //echo '<!--'."\n";
      //print_r($conn->cache);
      //echo "\n".'//-->'."\n";
   } else {
      echo "<!-- failed to get uids: $message_set //-->\n";
   }
   /*
   if ($num_removed>0) {
      $new_cache;
      reset($conn->cache[$folder]);
      while (list($uid,$item)=each($conn->cache[$folder])) {
         if ($item) $new_cache[$uid] = $conn->cache[$folder][$uid];
      }
      $conn->cache[$folder] = $new_cache;
   }
   */
}
function iil_ExplodeQuotedString($delimiter, $string) {
@@ -820,8 +767,6 @@
      return true;
   }
    
   iil_C_LoadCache($conn, $mailbox);
   if (iil_PutLine($conn->fp, "sel1 SELECT \"".iil_Escape($mailbox).'"')) {
      do {
         $line = chop(iil_ReadLine($conn->fp, 300));
@@ -1252,50 +1197,7 @@
   }
   $message_set = '1' . ($num>1?':' . $num:'');
   
   //if cache not enabled, just call iil_C_FetchHeaderIndex on 'UID' field
   if (!$conn->do_cache)
      return iil_C_FetchHeaderIndex($conn, $mailbox, $message_set, 'UID');
   //otherwise, let's check cache first
   $key        = $mailbox.'.uids';
   $cache_good = true;
   if ($conn->uid_cache) {
       $data = $conn->uid_cache;
   } else {
       $data = cache_read($conn->user, $conn->host, $key);
   }
   //was anything cached at all?
   if ($data === false) {
       $cache_good = -1;
   }
   //make sure number of messages were the same
   if ($cache_good > 0 && $data['n'] != $num) {
       $cache_good = -2;
   }
   //if everything's okay so far...
   if ($cache_good > 0) {
      //check UIDs of highest mid with current and cached
      $temp = iil_C_Search($conn, $mailbox, 'UID ' . $data['d'][$num]);
      if (!$temp || !is_array($temp) || $temp[0] != $num) {
          $cache_good = -3;
          }
   }
   //if cached data's good, return it
   if ($cache_good > 0) {
      return $data['d'];
   }
   //otherwise, we need to fetch it
   $data      = array('n' => $num, 'd' => array());
   $data['d'] = iil_C_FetchHeaderIndex($conn, $mailbox, $message_set, 'UID');
   cache_write($conn->user, $conn->host, $key, $data);
   $conn->uid_cache = $data;
   return $data['d'];
   return iil_C_FetchHeaderIndex($conn, $mailbox, $message_set, 'UID');
}
function iil_SortThreadHeaders($headers, $index_a, $uids) {
@@ -1322,30 +1224,7 @@
   $uids   = iil_C_FetchUIDs($conn, $mailbox);
   $debug  = false;
   
   /* Get cached records where possible */
   if ($conn->do_cache) {
      $cached = cache_read($conn->user, $conn->host, $mailbox.'.thhd');
      if ($cached && is_array($uids) && count($uids)>0) {
         $needed_set = '';
         foreach ($uids as $id=>$uid) {
            if ($cached[$uid]) {
               $result[$uid]     = $cached[$uid];
               $result[$uid]->id = $id;
            } else {
                $needed_set .= ($needed_set ? ',' : '') . $id;
                     }
         }
         if ($needed_set) {
             $message_set = $needed_set;
         } else {
             $message_set = '';
              }
      }
   }
   $message_set = iil_CompressMessageSet($message_set);
   if ($debug) {
       echo "Still need: ".$message_set;
   }
    
   /* if we're missing any, get them */
   if ($message_set) {
@@ -1363,7 +1242,7 @@
         if ($debug) {
             echo $line . "\n";
              }
         if (ereg('\{[0-9]+\}$', $line)) {
         if (preg_match('/\{[0-9]+\}$/', $line)) {
            $a     = explode(' ', $line);
            $new = array();
@@ -1381,7 +1260,7 @@
                  $new[strtoupper($field_name)] = trim($field_val);
               } else if (ereg('^[[:space:]]', $line)) {
               } else if (preg_match('/^\s+/', $line)) {
                  $new[strtoupper($field_name)] .= trim($line);
               }
            } while ($line[0] != ')');
@@ -1398,13 +1277,6 @@
   /* sort headers */
   if (is_array($index_a)) {
      $result = iil_SortThreadHeaders($result, $index_a, $uids);   
   }
   /* write new set to cache */
   if ($conn->do_cache) {
      if (count($result)!=count($cached)) {
         cache_write($conn->user, $conn->host, $mailbox . '.thhd', $result);
          }
   }
   
   //echo 'iil_FetchThreadHeaders:'."\n";
@@ -1431,7 +1303,7 @@
   $fp        = $conn->fp;
   $debug     = false;
   
   $sbj_filter_pat = '[a-zA-Z]{2,3}(\[[0-9]*\])?:([[:space:]]*)';
   $sbj_filter_pat = '/[a-z]{2,3}(\[[0-9]*\])?:(\s*)/i';
   
   /*  Do "SELECT" command */
   if (!iil_C_Select($conn, $mailbox)) {
@@ -1468,18 +1340,18 @@
      }
        
      /* if subject contains 'RE:' or has in-reply-to header, it's a reply */
      $sbj_pre ='';
      $sbj_pre = '';
      $has_re = false;
      if (eregi($sbj_filter_pat, $new['SUBJECT'])) {
      if (preg_match($sbj_filter_pat, $new['SUBJECT'])) {
          $has_re = true;
      }
          if ($has_re||$new['IN-REPLY-TO']) {
          if ($has_re || $new['IN-REPLY-TO']) {
               $sbj_pre = 'RE:';
      }
        
      /* strip out 're:', 'fw:' etc */
      if ($has_re) {
          $sbj = ereg_replace($sbj_filter_pat, '', $new['SUBJECT']);
          $sbj = preg_replace($sbj_filter_pat, '', $new['SUBJECT']);
      } else {
          $sbj = $new['SUBJECT'];
      }
@@ -1629,7 +1501,7 @@
   return $t_index;
}
function iil_C_FetchHeaders(&$conn, $mailbox, $message_set, $uidfetch=false, $bodystr=false)
function iil_C_FetchHeaders(&$conn, $mailbox, $message_set, $uidfetch=false, $bodystr=false, $add='')
{
   global $IMAP_USE_INTERNAL_DATE;
   
@@ -1648,27 +1520,8 @@
      return false;
   }
      
   /* Get cached records where possible */
   if ($conn->do_cache) {
      $uids = iil_C_FetchHeaderIndex($conn, $mailbox, $message_set, "UID");
      if (is_array($uids) && count($conn->cache[$mailbox]>0)) {
         $needed_set = '';
         while (list($id,$uid)=each($uids)) {
            if ($conn->cache[$mailbox][$uid]) {
               $result[$id]     = $conn->cache[$mailbox][$uid];
               $result[$id]->id = $id;
            } else {
                $needed_set.=($needed_set ? ',': '') . $id;
            }
         }
         //echo "<!-- iil_C_FetchHeader\nMessage Set: $message_set\nNeeded Set:$needed_set\n//-->\n";
         if ($needed_set) {
            $message_set = iil_CompressMessageSet($needed_set);
         } else {
            return $result;
         }
      }
   }
   if ($add)
      $add = ' '.strtoupper(trim($add));
   /* FETCH uid, size, flags and headers */
   $key       = 'FH12';
@@ -1679,7 +1532,7 @@
   $request .= "BODY.PEEK[HEADER.FIELDS ";
   $request .= "(DATE FROM TO SUBJECT REPLY-TO IN-REPLY-TO CC BCC ";
   $request .= "CONTENT-TRANSFER-ENCODING CONTENT-TYPE MESSAGE-ID ";
   $request .= "REFERENCES DISPOSITION-NOTIFICATION-TO X-PRIORITY)])";
   $request .= "REFERENCES DISPOSITION-NOTIFICATION-TO X-PRIORITY".$add.")])";
   if (!iil_PutLine($fp, $request)) {
      return false;
@@ -1687,7 +1540,7 @@
   do {
      $line = iil_ReadLine($fp, 1024);
      $line = iil_MultLine($fp, $line);
      $a    = explode(' ', $line);
      if (($line[0] == '*') && ($a[2] == 'FETCH')) {
         $id = $a[1];
@@ -1710,12 +1563,12 @@
            $str = $matches[1];
            // swap parents with quotes, then explode
            $str = eregi_replace("[()]", "\"", $str);
            $str = preg_replace('/[()]/', '"', $str);
            $a = iil_ExplodeQuotedString(' ', $str);
            // did we get the right number of replies?
            $parts_count = count($a);
            if ($parts_count>=8) {
            if ($parts_count>=6) {
               for ($i=0; $i<$parts_count; $i=$i+2) {
                  if (strcasecmp($a[$i],'UID') == 0)
                     $result[$id]->uid = $a[$i+1];
@@ -1725,34 +1578,6 @@
                     $time_str = $a[$i+1];
                  else if (strcasecmp($a[$i],'FLAGS') == 0)
                     $flags_str = $a[$i+1];
               }
               // process flags
               $flags_str = eregi_replace('[\\\"]', '', $flags_str);
               $flags_a   = explode(' ', $flags_str);
               if (is_array($flags_a)) {
                  reset($flags_a);
                  while (list(,$val)=each($flags_a)) {
                     if (strcasecmp($val,'Seen') == 0) {
                         $result[$id]->seen = true;
                     } else if (strcasecmp($val, 'Deleted') == 0) {
                         $result[$id]->deleted=true;
                     } else if (strcasecmp($val, 'Recent') == 0) {
                         $result[$id]->recent = true;
                     } else if (strcasecmp($val, 'Answered') == 0) {
                         $result[$id]->answered = true;
                     } else if (strcasecmp($val, '$Forwarded') == 0) {
                         $result[$id]->forwarded = true;
                     } else if (strcasecmp($val, 'Draft') == 0) {
                         $result[$id]->is_draft = true;
                     } else if (strcasecmp($val, '$MDNSent') == 0) {
                         $result[$id]->mdn_sent = true;
                     } else if (strcasecmp($val, 'Flagged') == 0) {
                          $result[$id]->flagged = true;
                     }
                  }
                  $result[$id]->flags = $flags_a;
               }
               $time_str = str_replace('"', '', $time_str);
@@ -1797,7 +1622,7 @@
            // re-parse (see below)
            foreach ($reslines as $line) {
               if (ord($line[0])<=32) {
                   $lines[$ln] .= (empty($lines[$ln])?'':"\n").trim($line);
                  $lines[$ln] .= (empty($lines[$ln])?'':"\n").trim($line);
               } else {
                  $lines[++$ln] = trim($line);
               }
@@ -1814,23 +1639,28 @@
         do {
            $line = chop(iil_ReadLine($fp, 300), "\r\n");
            if (ord($line[0])<=32) {
                $lines[$ln] .= (empty($lines[$ln])?'':"\n").trim($line);
            } else {
               $lines[++$ln] = trim($line);
            }
            /*
               The preg_match below works around communigate imap, which outputs " UID <number>)".
               Without this, the while statement continues on and gets the "FH0 OK completed" message.
               If this loop gets the ending message, then the outer loop does not receive it from radline on line 1249.
               This in causes the if statement on line 1278 to never be true, which causes the headers to end up missing
               If the if statement was changed to pick up the fh0 from this loop, then it causes the outer loop to spin
               An alternative might be:
               if (!preg_match("/:/",$line) && preg_match("/\)$/",$line)) break;
               however, unsure how well this would work with all imap clients.
            */
            // The preg_match below works around communigate imap, which outputs " UID <number>)".
            // Without this, the while statement continues on and gets the "FH0 OK completed" message.
            // If this loop gets the ending message, then the outer loop does not receive it from radline on line 1249.
            // This in causes the if statement on line 1278 to never be true, which causes the headers to end up missing
            // If the if statement was changed to pick up the fh0 from this loop, then it causes the outer loop to spin
            // An alternative might be:
            // if (!preg_match("/:/",$line) && preg_match("/\)$/",$line)) break;
            // however, unsure how well this would work with all imap clients.
            if (preg_match("/^\s*UID [0-9]+\)$/", $line)) {
                break;
            }
            // handle FLAGS reply after headers (AOL, Zimbra?)
            if (preg_match('/\s+FLAGS \((.*)\)\)$/', $line, $matches)) {
               $flags_str = $matches[1];
               break;
            }
            if (ord($line[0])<=32) {
               $lines[$ln] .= (empty($lines[$ln])?'':"\n").trim($line);
            } else {
               $lines[++$ln] = trim($line);
            }
         // patch from "Maksim Rubis" <siburny@hotmail.com>
         } while (trim($line[0]) != ')' && strncmp($line, $key, strlen($key)));
@@ -1850,7 +1680,7 @@
               list($field, $string) = iil_SplitHeaderLine($str);
               
               $field  = strtolower($field);
                                        $string = ereg_replace("\n[[:space:]]*"," ",$string);
               $string = preg_replace('/\n\s*/', ' ', $string);
               
               switch ($field) {
               case 'date';
@@ -1891,7 +1721,7 @@
                  }
                  break;
               case 'in-reply-to':
                  $result[$id]->in_reply_to = ereg_replace("[\n<>]", '', $string);
                  $result[$id]->in_reply_to = preg_replace('/[\n<>]/', '', $string);
                  break;
               case 'references':
                  $result[$id]->references = $string;
@@ -1908,16 +1738,44 @@
                  if (preg_match('/^(\d+)/', $string, $matches))
                     $result[$id]->priority = intval($matches[1]);
                  break;
               default:
                  if (strlen($field) > 2)
                     $result[$id]->others[$field] = $string;
                  break;
               } // end switch ()
            } // end while ()
            if ($conn->do_cache) {
               $uid = $result[$id]->uid;
               $conn->cache[$mailbox][$uid] = $result[$id];
               $conn->cache_dirty[$mailbox] = true;
            }
         } else {
            $a = explode(' ', $line);
         }
         // process flags
         if (!empty($flags_str)) {
            $flags_str = preg_replace('/[\\\"]/', '', $flags_str);
            $flags_a   = explode(' ', $flags_str);
            if (is_array($flags_a)) {
               reset($flags_a);
               while (list(,$val)=each($flags_a)) {
                  if (strcasecmp($val,'Seen') == 0) {
                      $result[$id]->seen = true;
                  } else if (strcasecmp($val, 'Deleted') == 0) {
                      $result[$id]->deleted=true;
                  } else if (strcasecmp($val, 'Recent') == 0) {
                      $result[$id]->recent = true;
                  } else if (strcasecmp($val, 'Answered') == 0) {
                     $result[$id]->answered = true;
                  } else if (strcasecmp($val, '$Forwarded') == 0) {
                     $result[$id]->forwarded = true;
                  } else if (strcasecmp($val, 'Draft') == 0) {
                     $result[$id]->is_draft = true;
                  } else if (strcasecmp($val, '$MDNSent') == 0) {
                     $result[$id]->mdn_sent = true;
                  } else if (strcasecmp($val, 'Flagged') == 0) {
                           $result[$id]->flagged = true;
                  }
               }
               $result[$id]->flags = $flags_a;
            }
         }
      }
   } while (strcmp($a[0], $key) != 0);
@@ -1925,9 +1783,9 @@
   return $result;
}
function iil_C_FetchHeader(&$conn, $mailbox, $id, $uidfetch=false, $bodystr=false) {
function iil_C_FetchHeader(&$conn, $mailbox, $id, $uidfetch=false, $bodystr=false, $add='') {
   $a  = iil_C_FetchHeaders($conn, $mailbox, $id, $uidfetch, $bodystr);
   $a  = iil_C_FetchHeaders($conn, $mailbox, $id, $uidfetch, $bodystr, $add);
   if (is_array($a)) {
      return array_shift($a);
   }
@@ -2033,7 +1891,7 @@
    
   if (iil_C_Select($conn, $mailbox)) {
      $c = 0;
      iil_PutLine($fp, "flg STORE $messages " . $mod . "FLAGS (" . $flag . ")");
      iil_PutLine($fp, "flg UID STORE $messages " . $mod . "FLAGS (" . $flag . ")");
      do {
         $line=chop(iil_ReadLine($fp, 100));
         if ($line[0] == '*') {
@@ -2042,7 +1900,6 @@
      } while (!iil_StartsWith($line, 'flg', true));
      if (iil_ParseResult($line) == 0) {
         iil_C_ExpireCachedItems($conn, $mailbox, $messages);
         return $c;
      }
      $conn->error = $line;
@@ -2082,7 +1939,7 @@
   if (iil_C_Select($conn, $from)) {
      $c=0;
      
      iil_PutLine($fp, "cpy1 COPY $messages \"".iil_Escape($to)."\"");
      iil_PutLine($fp, "cpy1 UID COPY $messages \"".iil_Escape($to)."\"");
      $line=iil_ReadReply($fp);
      return iil_ParseResult($line);
   } else {
@@ -2127,7 +1984,7 @@
      if (iil_PutLine($fp, "$key FETCH $id (UID)")) {
         do {
            $line=chop(iil_ReadLine($fp, 1024));
            if (eregi("^\* $id FETCH \(UID (.*)\)", $line, $r)) {
            if (preg_match("/^\* $id FETCH \(UID (.*)\)/i", $line, $r)) {
               $result = $r[1];
            }
         } while (!preg_match("/^$key/", $line));
@@ -2142,10 +1999,12 @@
      $c = 0;
      
      $query = 'srch1 SEARCH ' . chop($criteria);
      iil_PutLineC($fp, $query);
      if (!iil_PutLineC($fp, $query)) {
         return false;
      }
      do {
         $line=trim(iil_ReadLine($fp, 10000));
         if (eregi("^\* SEARCH", $line)) {
         if (preg_match('/^\* SEARCH/i', $line)) {
            $str = trim(substr($line, 8));
            $messages = explode(' ', $str);
         }
@@ -2288,7 +2147,7 @@
         $folder = trim($a[count($a)-1], '"');
            
              if (empty($ignore) || (!empty($ignore)
                     && !eregi($ignore, $folder))) {
                     && !preg_match('/'.preg_quote(ignore, '/').'/i', $folder))) {
                     $folders[$i] = $folder;
              }
            
@@ -2356,7 +2215,7 @@
              $folder = trim($a[count($a)-1], '"');
            
         if ((!in_array($folder, $folders)) && (empty($ignore)
                     || (!empty($ignore) && !eregi($ignore, $folder)))) {
                     || (!empty($ignore) && !preg_match('/'.preg_quote(ignore, '/').'/i', $folder)))) {
             $folders[$i] = $folder;
              }
            
@@ -2421,7 +2280,7 @@
   // format request
   foreach($parts as $part)
      $peeks[] = "BODY[$part.MIME]";
      $peeks[] = "BODY.PEEK[$part.MIME]";
   
   $request = "$key FETCH $id (" . implode(' ', $peeks) . ')';
@@ -2464,7 +2323,7 @@
   
   if (iil_C_Select($conn, $mailbox)) {
          $reply_key = '* ' . $id;
          // format request
      $key     = 'ftch' . ($c++) . ' ';
      $request = $key . "FETCH $id (BODY.PEEK[$part])";
@@ -2477,7 +2336,7 @@
          do {
              $line = chop(iil_ReadLine($fp, 1000));
              $a    = explode(' ', $line);
          } while ($a[2] != 'FETCH');
          } while (!($end = iil_StartsWith($line, $key, true)) && $a[2] != 'FETCH');
          $len = strlen($line);
      // handle empty "* X FETCH ()" response
@@ -2508,7 +2367,8 @@
              $len      = $to - $from;
                   $sizeStr  = substr($line, $from, $len);
              $bytes    = (int)$sizeStr;
         $prev     = '';
              while ($bytes > 0) {
                          $line      = iil_ReadLine($fp, 1024);
                     $len       = strlen($line);
@@ -2518,14 +2378,27 @@
                      }
                     $bytes -= strlen($line);
            $line = rtrim($line, "\t\r\n\0\x0B");
                      if ($mode == 1) {
               if ($file)
                  fwrite($file, rtrim($line, "\t\r\n\0\x0B") . "\n");
                  fwrite($file, $line . "\n");
                             else
                  $result .= rtrim($line, "\t\r\n\0\x0B") . "\n";
                  $result .= $line . "\n";
                      } else if ($mode == 2) {
                             echo rtrim($line, "\t\r\n\0\x0B") . "\n";
                             echo $line . "\n";
                      } else if ($mode == 3) {
               // create chunks with proper length for base64 decoding
               $line = $prev.$line;
               $length = strlen($line);
               if ($length % 4) {
                  $length = floor($length / 4) * 4;
                  $prev = substr($line, $length);
                  $line = substr($line, 0, $length);
               }
               else
                  $prev = '';
               if ($file)
                  fwrite($file, base64_decode($line));
                        else
@@ -2534,9 +2407,10 @@
              }
          }
           // read in anything up until last line
      do {
              $line = iil_ReadLine($fp, 1024);
      } while (!iil_StartsWith($line, $key, true));
      if (!$end)
         do {
                 $line = iil_ReadLine($fp, 1024);
         } while (!iil_StartsWith($line, $key, true));
        
      if ($mode == 3 && $file) {
         return true;
@@ -2552,12 +2426,10 @@
          }
          
      return false;
   } else {
      echo 'Select failed.';
   }
    
   if ($mode==1) {
      if ($file) {
      if ($file && $result) {
         fwrite($file, $result);
         return true;
      }
@@ -2755,7 +2627,7 @@
   // return false if not found, parse if found
   $min_free = PHP_INT_MAX;
   foreach ($quota_lines as $key => $quota_line) {
      $quota_line   = eregi_replace('[()]', '', $quota_line);
      $quota_line   = preg_replace('/[()]/', '', $quota_line);
      $parts        = explode(' ', $quota_line);
      $storage_part = array_search('STORAGE', $parts);
      
@@ -2780,7 +2652,7 @@
function iil_C_ClearFolder(&$conn, $folder) {
   $num_in_trash = iil_C_CountMessages($conn, $folder);
   if ($num_in_trash > 0) {
      iil_C_Delete($conn, $folder, '1:' . $num_in_trash);
      iil_C_Delete($conn, $folder, '1:*');
   }
   return (iil_C_Expunge($conn, $folder) >= 0);
}