svncommit
2009-05-12 f22c2cefb4c7f8b1a995d5de6f706d49861c473c
program/lib/imap.inc
@@ -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();
}
/**
@@ -257,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);
@@ -319,7 +319,7 @@
   if (strncmp($string, $match, $len) == 0) {
      return true;
   }
   if ($error && preg_match('/^\* (BYE|BAD) /', $string)) {
   if ($error && preg_match('/^\* (BYE|BAD) /i', $string)) {
      return true;
   }
   return false;
@@ -335,6 +335,7 @@
   }
   if ($bye && strncmp($string, '* BYE ', 6) == 0) {
      return true;
   }
   return false;
}
@@ -381,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) {
@@ -538,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 = '';
@@ -564,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;
@@ -598,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";
@@ -624,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
@@ -683,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) {
@@ -823,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));
@@ -1255,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) {
@@ -1325,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) {
@@ -1366,7 +1242,7 @@
         if ($debug) {
             echo $line . "\n";
              }
         if (ereg('\{[0-9]+\}$', $line)) {
         if (preg_match('/\{[0-9]+\}$/', $line)) {
            $a     = explode(' ', $line);
            $new = array();
@@ -1384,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] != ')');
@@ -1401,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";
@@ -1434,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)) {
@@ -1471,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'];
      }
@@ -1632,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;
   
@@ -1651,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';
@@ -1682,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;
@@ -1713,7 +1563,7 @@
            $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?
@@ -1830,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';
@@ -1871,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;
@@ -1888,21 +1738,19 @@
                  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 = eregi_replace('[\\\"]', '', $flags_str);
            $flags_str = preg_replace('/[\\\"]/', '', $flags_str);
            $flags_a   = explode(' ', $flags_str);
               
            if (is_array($flags_a)) {
@@ -1935,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);
   }
@@ -2043,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] == '*') {
@@ -2052,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;
@@ -2092,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 {
@@ -2137,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));
@@ -2157,7 +2004,7 @@
      }
      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);
         }
@@ -2300,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;
              }
            
@@ -2368,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;
              }
            
@@ -2476,7 +2323,7 @@
   
   if (iil_C_Select($conn, $mailbox)) {
          $reply_key = '* ' . $id;
          // format request
      $key     = 'ftch' . ($c++) . ' ';
      $request = $key . "FETCH $id (BODY.PEEK[$part])";
@@ -2489,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
@@ -2560,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;
@@ -2578,12 +2426,10 @@
          }
          
      return false;
   } else {
      echo 'Select failed.';
   }
    
   if ($mode==1) {
      if ($file) {
      if ($file && $result) {
         fwrite($file, $result);
         return true;
      }
@@ -2781,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);
      
@@ -2806,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);
}