Exemplo n.º 1
0
 /**
  * Send a command to the IMAP server and retrieve
  * the response
  *
  * @param string $command The command to send
  *
  * @param string $data    If we are issuing a command
  *                        that means the server will
  *                        consequently expect literal
  *                        data sent then this is that data.
  *
  * @return mixed          Server response string on success
  *                        or bool false on error
  */
 function sendCmd($command, $data = null, $fh = false)
 {
     if (!is_resource($this->socket->fp)) {
         $this->lastError = IC_NOT_CONNECTED;
         return false;
     }
     if (feof($this->socket->fp)) {
         $this->lastError = IC_NOT_CONNECTED;
         return false;
     }
     $cid = $this->cid;
     $this->socket->writeLine("{$this->cid} {$command}");
     $this->cid++;
     if ($this->debug) {
         $this->debugOutput("C: {$cid} {$command}\n");
     }
     $resp = '';
     $loop = 0;
     $lines = 0;
     $bytesRead = 0;
     $respSize = 0;
     $code = '';
     $fetch = substr($command, 0, 5) == 'FETCH';
     $select = substr($command, 0, 6) == 'SELECT';
     while (true) {
         // Check we are still connected
         if (!is_resource($this->socket->fp)) {
             return $resp;
         }
         if (feof($this->socket->fp)) {
             $this->lastError = IC_NOT_CONNECTED;
             return false;
         }
         $line = $this->socket->gets(8192);
         // 8192 same buffer used in Pear Net::POP3
         if ($this->debug) {
             $this->debugOutput("S: {$line}");
         }
         if (preg_match("/^{$cid} (OK|BAD|NO)/", $line, $m)) {
             $code = $m[1];
         } elseif (!$fetch && !$select && preg_match("/^\\* (BAD|NO|BYE)/", $line, $m)) {
             $code = $m[1];
         }
         // UW-IMAP been brain dead for 'status' command on a mailbox
         if ($code == 'NO' && preg_match("/NO CLIENT BUG DETECTED/", $line)) {
             $code = '';
             continue;
         } else {
             if ($code == 'BAD' || $code == 'NO' || $code == 'BYE') {
                 return false;
             } else {
                 if ($code == 'OK') {
                     return !empty($resp) ? $resp : $line;
                 }
             }
         }
         $lines++;
         // If writing to the filehandle, get msg size and skip the first line response from the IMAP server
         if (is_resource($fh) && preg_match('/^\\* /', $line) && $lines == '1') {
             preg_match('/\\{(\\d+)\\}/', $line, $m);
             $respSize = $m[1];
             continue;
         }
         // Check if we are sending literal data
         // and server is ready for literal data
         if ($data && preg_match('/^\\+/', $line)) {
             $size = $this->socket->write($data);
             if ($this->debug) {
                 $this->debugOutput("C: {$cid} {$data}\n");
             }
             sleep(1);
             $this->socket->write("\r\n");
             continue;
         }
         // Double check that we are not hung on a
         // command (ie not enough data sent)
         if ($data && $line == '') {
             // Send some new lines to try and
             // reach expected bytes
             $this->socket->writeLine('');
             if ($this->debug) {
                 $this->debugOutput("C: {$cid} \n");
             }
         }
         // Replace/fix - Under cyrus, multiple IMAP logins, mailbox locks, sockets are closed automatically
         if ($line == '' && $loop > 1000) {
             return $resp;
         } else {
             if ($line == '') {
                 $loop++;
             }
         }
         // Print to the filehandle only up to $respSize bytes so we do not append the last IMAP header on the message
         if ($stop) {
             continue;
         } elseif (is_resource($fh)) {
             $bytesRead += strlen($line);
             // Strip Control-M chars
             $line = preg_replace('/\\cM+$/', '', $line);
             fwrite($fh, $line);
             // Only read up to expected byte size
             if ($bytesRead == $respSize) {
                 $stop = true;
             }
         } else {
             $resp .= "{$line}";
         }
     }
 }