alecpl
2009-05-30 32ca1f9fc8a78e092565b51cc97faa724bb4e6cf
program/lib/imap.inc
@@ -81,6 +81,9 @@
      - added \* flag support 
      - use PREG instead of EREG
      - removed caching functions
      - handling connection startup response
      - added UID EXPUNGE support
      - fixed problem with double quotes and spaces in folder names in LIST and LSUB
********************************************************/
@@ -91,9 +94,6 @@
 * @todo Refactor code.
 * @todo Replace echo-debugging (make it adhere to config setting and log)
 */
// changed path to work within roundcube webmail
include_once 'lib/icl_commons.inc';
if (!isset($IMAP_USE_HEADER_DATE) || !$IMAP_USE_HEADER_DATE) {
@@ -232,7 +232,7 @@
   return $res;
}
function iil_ReadLine($fp, $size) {
function iil_ReadLine($fp, $size=1024) {
   $line = '';
   if (!$fp) {
@@ -255,7 +255,7 @@
   return $line;
}
function iil_MultLine($fp, $line) {
function iil_MultLine($fp, $line, $escape=false) {
   $line = chop($line);
   if (preg_match('/\{[0-9]+\}$/', $line)) {
      $out = '';
@@ -266,7 +266,8 @@
         $line = iil_ReadBytes($fp, $bytes); 
         $out .= $line;
      }
      $line = $a[1][0] . "\"$out\"";
      $line = $a[1][0] . '"' . ($escape ? iil_Escape($out) : $out) . '"';
//      console('[...] '. $out);
   }
   return $line;
@@ -617,9 +618,19 @@
      return false;
   }
   $iil_error .= "Socket connection established\r\n";
   $line       = iil_ReadLine($conn->fp, 4096);
   stream_set_timeout($conn->fp, 10);
   $line = stream_get_line($conn->fp, 8192, "\r\n");
   // Connected to wrong port or connection error?
   if (!preg_match('/^\* (OK|PREAUTH)/i', $line)) {
      if ($line)
         $iil_error = "Wrong startup greeting ($host:$ICL_PORT): $line";
      else
         $iil_error = "Empty startup greeting ($host:$ICL_PORT)";
           $iil_errornum = -2;
           return false;
   }
   // RFC3501 [7.1] optional CAPABILITY response
   if (preg_match('/\[CAPABILITY ([^]]+)\]/i', $line, $matches)) {
      $conn->capability = explode(' ', strtoupper($matches[1]));
@@ -716,19 +727,20 @@
}
function iil_ExplodeQuotedString($delimiter, $string) {
   $quotes = explode('"', $string);
   while ( list($key, $val) = each($quotes)) {
      if (($key % 2) == 1) {
         $quotes[$key] = str_replace($delimiter, "_!@!_", $quotes[$key]);
          }
   $result = array();
   $strlen = strlen($string);
   for ($q=$p=$i=0; $i < $strlen; $i++) {
           if ($string[$i] == "\"" && $string[$i-1] != "\\") {
         $q = $q ? false : true;
      }
      else if (!$q && preg_match("/$delimiter/", $string[$i])) {
         $result[] = substr($string, $p, $i - $p);
         $p = $i + 1;
      }
   }
   $string = implode('"', $quotes);
   $result = explode($delimiter, $string);
   while ( list($key, $val) = each($result) ) {
      $result[$key] = str_replace('_!@!_', $delimiter, $result[$key]);
   }
   $result[] = substr($string, $p);
   return $result;
}
@@ -1519,7 +1531,7 @@
      $conn->error = "Couldn't select $mailbox";
      return false;
   }
   if ($add)
      $add = ' '.strtoupper(trim($add));
@@ -1855,11 +1867,13 @@
   return $result;
}
function iil_C_Expunge(&$conn, $mailbox) {
function iil_C_Expunge(&$conn, $mailbox, $messages=NULL) {
   if (iil_C_Select($conn, $mailbox)) {
      $c = 0;
      iil_PutLine($conn->fp, "exp1 EXPUNGE");
      $command = $messages ? "UID EXPUNGE $messages" : "EXPUNGE";
      iil_PutLine($conn->fp, "exp1 $command");
      do {
         $line=chop(iil_ReadLine($conn->fp, 100));
         if ($line[0] == '*') {
@@ -2022,12 +2036,13 @@
}
function iil_C_Move(&$conn, $messages, $from, $to) {
    $fp = $conn->fp;
    if (!$from || !$to) {
        return -1;
    }
    $r = iil_C_Copy($conn, $messages, $from,$to);
    $r = iil_C_Copy($conn, $messages, $from, $to);
    if ($r==0) {
        return iil_C_Delete($conn, $from, $messages);
    }
@@ -2136,7 +2151,7 @@
   // get folder list
   do {
      $line = iil_ReadLine($fp, 500);
      $line = iil_MultLine($fp, $line);
      $line = iil_MultLine($fp, $line, true);
      $a = explode(' ', $line);
      if (($line[0] == '*') && ($a[1] == 'LIST')) {
@@ -2144,7 +2159,7 @@
              // split one line
         $a = iil_ExplodeQuotedString(' ', $line);
              // last string is folder name
         $folder = trim($a[count($a)-1], '"');
         $folder = preg_replace(array('/^"/', '/"$/'), '', iil_UnEscape($a[count($a)-1]));
            
              if (empty($ignore) || (!empty($ignore)
                     && !preg_match('/'.preg_quote(ignore, '/').'/i', $folder))) {
@@ -2201,7 +2216,7 @@
   // get folder list
   do {
      $line = iil_ReadLine($fp, 500);
      $line = iil_MultLine($fp, $line);
      $line = iil_MultLine($fp, $line, true);
      $a    = explode(' ', $line);
        
      if (($line[0] == '*') && ($a[1] == 'LSUB' || $a[1] == 'LIST')) {
@@ -2209,11 +2224,9 @@
            
              // split one line
         $a = iil_ExplodeQuotedString(' ', $line);
              // last string is folder name
              //$folder = UTF7DecodeString(str_replace('"', '', $a[count($a)-1]));
              $folder = trim($a[count($a)-1], '"');
             $folder = preg_replace(array('/^"/', '/"$/'), '', iil_UnEscape($a[count($a)-1]));
         if ((!in_array($folder, $folders)) && (empty($ignore)
                     || (!empty($ignore) && !preg_match('/'.preg_quote(ignore, '/').'/i', $folder)))) {
             $folders[$i] = $folder;
@@ -2308,30 +2321,42 @@
   $part = empty($part) ? 'HEADER' : $part.'.MIME';
        return iil_C_HandlePartBody($conn, $mailbox, $id, $part, 1);
        return iil_C_HandlePartBody($conn, $mailbox, $id, $part);
}
function iil_C_HandlePartBody(&$conn, $mailbox, $id, $part='', $mode=1, $file=NULL) {
   /* modes:
        1: return string (or write to $file pointer)
        2: print
        3: base64 and print (or write to $file pointer)
   */
function iil_C_HandlePartBody(&$conn, $mailbox, $id, $part='', $encoding=NULL, $print=NULL, $file=NULL) {
   
   $fp     = $conn->fp;
   $result = false;
   switch ($encoding) {
      case 'base64':
         $mode = 1;
      break;
      case 'quoted-printable':
         $mode = 2;
      break;
      case 'x-uuencode':
      case 'x-uue':
      case 'uue':
      case 'uuencode':
         $mode = 3;
      break;
      default:
         $mode = 0;
   }
   
   if (iil_C_Select($conn, $mailbox)) {
          $reply_key = '* ' . $id;
          // format request
      $key     = 'ftch' . ($c++) . ' ';
      $request = $key . "FETCH $id (BODY.PEEK[$part])";
      $key     = 'ftch0';
      $request = $key . " FETCH $id (BODY.PEEK[$part])";
          // send request
      if (!iil_PutLine($fp, $request)) {
          return false;
          }
          // receive reply line
          do {
              $line = chop(iil_ReadLine($fp, 1000));
@@ -2352,14 +2377,13 @@
            $result = substr($line, $from, $len);
         }
       
                   if ($mode == 2) {
                      echo $result;
                   } else if ($mode == 3) {
            if ($file)
               fwrite($file, base64_decode($result));
                     else
               echo base64_decode($result);
         }
              if ($mode == 1)
            $result = base64_decode($result);
         else if ($mode == 2)
            $result = quoted_printable_decode($result);
         else if ($mode == 3)
            $result = convert_uudecode($result);
          } else if ($line[$len-1] == '}') {
                   //multi-line request, find sizes of content and receive that many bytes
              $from     = strpos($line, '{') + 1;
@@ -2378,16 +2402,8 @@
                      }
                     $bytes -= strlen($line);
            $line = rtrim($line, "\t\r\n\0\x0B");
                      if ($mode == 1) {
               if ($file)
                  fwrite($file, $line . "\n");
                             else
                  $result .= $line . "\n";
                      } else if ($mode == 2) {
                             echo $line . "\n";
                      } else if ($mode == 3) {
               $line = rtrim($line, "\t\r\n\0\x0B");
               // create chunks with proper length for base64 decoding
               $line = $prev.$line;
               $length = strlen($line);
@@ -2401,54 +2417,68 @@
               if ($file)
                  fwrite($file, base64_decode($line));
                        else
                        else if ($print)
                  echo base64_decode($line);
               else
                  $result .= base64_decode($line);
            } else if ($mode == 2) {
               $line = rtrim($line, "\t\r\0\x0B");
               if ($file)
                  fwrite($file, quoted_printable_decode($line));
                        else if ($print)
                  echo quoted_printable_decode($line);
               else
                  $result .= quoted_printable_decode($line);
            } else if ($mode == 3) {
               $line = rtrim($line, "\t\r\n\0\x0B");
               if ($line == 'end' || preg_match('/^begin\s+[0-7]+\s+.+$/', $line))
                  continue;
               if ($file)
                  fwrite($file, convert_uudecode($line));
                        else if ($print)
                  echo convert_uudecode($line);
               else
                  $result .= convert_uudecode($line);
            } else {
               $line = rtrim($line, "\t\r\n\0\x0B");
               if ($file)
                  fwrite($file, $line . "\n");
                             else if ($print)
                  echo $line . "\n";
               else
                  $result .= $line . "\n";
            }
              }
          }
           // read in anything up until last line
      if (!$end)
         do {
                 $line = iil_ReadLine($fp, 1024);
         } while (!iil_StartsWith($line, $key, true));
        
      if ($mode == 3 && $file) {
         return true;
      }
          if ($result) {
             $result = rtrim($result, "\t\r\n\0\x0B");
         if ($file) {
            fwrite($file, $result);
            return true;
         }
         return $result; // substr($result, 0, strlen($result)-1);
         } else if ($print) {
            echo $result;
         } else
            return $result; // substr($result, 0, strlen($result)-1);
          }
          
      return false;
      return true;
   }
    
   if ($mode==1) {
      if ($file && $result) {
         fwrite($file, $result);
         return true;
      }
          return $result;
   }
   return false;
}
function iil_C_FetchPartBody(&$conn, $mailbox, $id, $part, $file=NULL) {
   return iil_C_HandlePartBody($conn, $mailbox, $id, $part, 1, $file);
   return iil_C_HandlePartBody($conn, $mailbox, $id, $part, NULL, NULL, $file);
}
function iil_C_PrintPartBody(&$conn, $mailbox, $id, $part) {
   iil_C_HandlePartBody($conn, $mailbox, $id, $part, 2);
}
function iil_C_PrintBase64Body(&$conn, $mailbox, $id, $part) {
   iil_C_HandlePartBody($conn, $mailbox, $id, $part, 3);
   iil_C_HandlePartBody($conn, $mailbox, $id, $part, NULL, true, NULL);
}
function iil_C_CreateFolder(&$conn, $folder) {
@@ -2594,13 +2624,6 @@
      }
   }
   return $result;
}
function iil_C_PrintSource(&$conn, $folder, $id, $part) {
   $header = iil_C_FetchPartHeader($conn, $folder, $id, $part);
   //echo str_replace("\r", '', $header);
   echo $header;
   echo iil_C_PrintPartBody($conn, $folder, $id, $part);
}
function iil_C_GetQuota(&$conn) {