| | |
| | | <?php |
| | | |
| | | /* |
| | | /** |
| | | +-----------------------------------------------------------------------+ |
| | | | program/include/rcube_imap_generic.php | |
| | | | | |
| | |
| | | { |
| | | public $error; |
| | | public $errornum; |
| | | public $message; |
| | | public $result; |
| | | public $resultcode; |
| | | public $data = array(); |
| | | public $flags = array( |
| | | 'SEEN' => '\\Seen', |
| | |
| | | const ERROR_NO = -1; |
| | | const ERROR_BAD = -2; |
| | | const ERROR_BYE = -3; |
| | | const ERROR_COMMAND = -5; |
| | | const ERROR_UNKNOWN = -4; |
| | | const ERROR_COMMAND = -5; |
| | | const ERROR_READONLY = -6; |
| | | |
| | | const COMMAND_NORESPONSE = 1; |
| | | const COMMAND_CAPABILITY = 2; |
| | |
| | | return $data; |
| | | } |
| | | |
| | | // don't use it in loops, until you exactly know what you're doing |
| | | function readReply(&$untagged=null) |
| | | { |
| | | do { |
| | |
| | | $str = trim($matches[2]); |
| | | |
| | | if ($res == 'OK') { |
| | | return $this->errornum = self::ERROR_OK; |
| | | $this->errornum = self::ERROR_OK; |
| | | } else if ($res == 'NO') { |
| | | $this->errornum = self::ERROR_NO; |
| | | } else if ($res == 'BAD') { |
| | |
| | | $this->errornum = self::ERROR_BYE; |
| | | } |
| | | |
| | | if ($str) |
| | | if ($str) { |
| | | $str = trim($str); |
| | | // get response string and code (RFC5530) |
| | | if (preg_match("/^\[([a-z-]+)\]/i", $str, $m)) { |
| | | $this->resultcode = strtoupper($m[1]); |
| | | $str = trim(substr($str, strlen($m[1]) + 2)); |
| | | } |
| | | else { |
| | | $this->resultcode = null; |
| | | } |
| | | $this->result = $str; |
| | | |
| | | if ($this->errornum != self::ERROR_OK) { |
| | | $this->error = $err_prefix ? $err_prefix.$str : $str; |
| | | } |
| | | } |
| | | |
| | | return $this->errornum; |
| | | } |
| | | return self::ERROR_UNKNOWN; |
| | | } |
| | | |
| | | private function setError($code, $msg='') |
| | | function setError($code, $msg='') |
| | | { |
| | | $this->errornum = $code; |
| | | $this->error = $msg; |
| | |
| | | } |
| | | |
| | | $this->putLine($this->nextTag() . " AUTHENTICATE $type"); |
| | | $line = trim($this->readLine(1024)); |
| | | $line = trim($this->readReply()); |
| | | |
| | | if ($line[0] == '+') { |
| | | $challenge = substr($line, 2); |
| | |
| | | |
| | | // send result |
| | | $this->putLine($reply); |
| | | $line = $this->readLine(1024); |
| | | $line = trim($this->readReply()); |
| | | |
| | | if ($line[0] == '+') { |
| | | $challenge = substr($line, 2); |
| | |
| | | $this->putLine(''); |
| | | } |
| | | |
| | | $line = $this->readLine(1024); |
| | | $line = $this->readReply(); |
| | | $result = $this->parseResult($line); |
| | | } |
| | | else { // PLAIN |
| | |
| | | } |
| | | else { |
| | | $this->putLine($this->nextTag() . " AUTHENTICATE PLAIN"); |
| | | $line = trim($this->readLine(1024)); |
| | | $line = trim($this->readReply()); |
| | | |
| | | if ($line[0] != '+') { |
| | | return $this->parseResult($line); |
| | |
| | | |
| | | // send result, get reply and process it |
| | | $this->putLine($reply); |
| | | $line = $this->readLine(1024); |
| | | $line = $this->readReply(); |
| | | $result = $this->parseResult($line); |
| | | } |
| | | } |
| | |
| | | return $this->fp; |
| | | } |
| | | else { |
| | | $this->setError($result, "Unable to authenticate user ($type): $line"); |
| | | $this->setError($result, "AUTHENTICATE $type: $line"); |
| | | } |
| | | |
| | | return $result; |
| | |
| | | $error = sprintf("Empty startup greeting (%s:%d)", $host, $this->prefs['port']); |
| | | |
| | | $this->setError(self::ERROR_BAD, $error); |
| | | $this->close(); |
| | | $this->closeConnection(); |
| | | return false; |
| | | } |
| | | |
| | |
| | | $this->parseCapability($matches[1], true); |
| | | } |
| | | |
| | | $this->message = $line; |
| | | |
| | | // TLS connection |
| | | if ($this->prefs['ssl_mode'] == 'tls' && $this->getCapability('STARTTLS')) { |
| | | if (version_compare(PHP_VERSION, '5.1.0', '>=')) { |
| | | $res = $this->execute('STARTTLS'); |
| | | |
| | | if ($res[0] != self::ERROR_OK) { |
| | | $this->close(); |
| | | $this->closeConnection(); |
| | | return false; |
| | | } |
| | | |
| | | if (!stream_socket_enable_crypto($this->fp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) { |
| | | $this->setError(self::ERROR_BAD, "Unable to negotiate TLS"); |
| | | $this->close(); |
| | | $this->closeConnection(); |
| | | return false; |
| | | } |
| | | |
| | |
| | | // Prevent from sending credentials in plain text when connection is not secure |
| | | if ($auth_method == 'LOGIN' && $this->getCapability('LOGINDISABLED')) { |
| | | $this->setError(self::ERROR_BAD, "Login disabled by IMAP server"); |
| | | $this->close(); |
| | | $this->closeConnection(); |
| | | return false; |
| | | } |
| | | // replace AUTH with CRAM-MD5 for backward compat. |
| | |
| | | return true; |
| | | } |
| | | |
| | | // Close connection |
| | | $this->close(); |
| | | $this->closeConnection(); |
| | | |
| | | return false; |
| | | } |
| | |
| | | return ($this->fp && $this->logged) ? true : false; |
| | | } |
| | | |
| | | function close() |
| | | function closeConnection() |
| | | { |
| | | if ($this->putLine($this->nextTag() . ' LOGOUT')) { |
| | | $this->readReply(); |
| | |
| | | $this->fp = false; |
| | | } |
| | | |
| | | /** |
| | | * Executes SELECT command (if mailbox is already not in selected state) |
| | | * |
| | | * @param string $mailbox Mailbox name |
| | | * |
| | | * @return boolean True on success, false on error |
| | | * @access public |
| | | */ |
| | | function select($mailbox) |
| | | { |
| | | if (!strlen($mailbox)) { |
| | |
| | | } |
| | | } |
| | | |
| | | $this->data['READ-WRITE'] = $this->resultcode != 'READ-ONLY'; |
| | | |
| | | $this->selected = $mailbox; |
| | | return true; |
| | | } |
| | |
| | | } |
| | | |
| | | /** |
| | | * Executes STATUS comand |
| | | * Executes STATUS command |
| | | * |
| | | * @param string $mailbox Mailbox name |
| | | * @param array $items Additional requested item names. By default |
| | |
| | | return false; |
| | | } |
| | | |
| | | function checkForRecent($mailbox) |
| | | /** |
| | | * Executes EXPUNGE command |
| | | * |
| | | * @param string $mailbox Mailbox name |
| | | * @param string $messages Message UIDs to expunge |
| | | * |
| | | * @return boolean True on success, False on error |
| | | * @access public |
| | | */ |
| | | function expunge($mailbox, $messages=NULL) |
| | | { |
| | | if (!strlen($mailbox)) { |
| | | $mailbox = 'INBOX'; |
| | | if (!$this->select($mailbox)) { |
| | | return false; |
| | | } |
| | | |
| | | $this->select($mailbox); |
| | | if (!$this->data['READ-WRITE']) { |
| | | $this->setError(self::ERROR_READONLY, "Mailbox is read-only", 'EXPUNGE'); |
| | | return false; |
| | | } |
| | | |
| | | if ($this->selected == $mailbox) { |
| | | return $this->data['RECENT']; |
| | | // Clear internal status cache |
| | | unset($this->data['STATUS:'.$mailbox]); |
| | | |
| | | if ($messages) |
| | | $result = $this->execute('UID EXPUNGE', array($messages), self::COMMAND_NORESPONSE); |
| | | else |
| | | $result = $this->execute('EXPUNGE', null, self::COMMAND_NORESPONSE); |
| | | |
| | | if ($result == self::ERROR_OK) { |
| | | $this->selected = ''; // state has changed, need to reselect |
| | | return true; |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * Executes CLOSE command |
| | | * |
| | | * @return boolean True on success, False on error |
| | | * @access public |
| | | * @since 0.5 |
| | | */ |
| | | function close() |
| | | { |
| | | $result = $this->execute('CLOSE', NULL, self::COMMAND_NORESPONSE); |
| | | |
| | | if ($result == self::ERROR_OK) { |
| | | $this->selected = ''; |
| | | return true; |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * Executes SUBSCRIBE command |
| | | * |
| | | * @param string $mailbox Mailbox name |
| | | * |
| | | * @return boolean True on success, False on error |
| | | * @access public |
| | | */ |
| | | function subscribe($mailbox) |
| | | { |
| | | $result = $this->execute('SUBSCRIBE', array($this->escape($mailbox)), |
| | | self::COMMAND_NORESPONSE); |
| | | |
| | | return ($result == self::ERROR_OK); |
| | | } |
| | | |
| | | /** |
| | | * Executes UNSUBSCRIBE command |
| | | * |
| | | * @param string $mailbox Mailbox name |
| | | * |
| | | * @return boolean True on success, False on error |
| | | * @access public |
| | | */ |
| | | function unsubscribe($mailbox) |
| | | { |
| | | $result = $this->execute('UNSUBSCRIBE', array($this->escape($mailbox)), |
| | | self::COMMAND_NORESPONSE); |
| | | |
| | | return ($result == self::ERROR_OK); |
| | | } |
| | | |
| | | /** |
| | | * Executes DELETE command |
| | | * |
| | | * @param string $mailbox Mailbox name |
| | | * |
| | | * @return boolean True on success, False on error |
| | | * @access public |
| | | */ |
| | | function deleteFolder($mailbox) |
| | | { |
| | | $result = $this->execute('DELETE', array($this->escape($mailbox)), |
| | | self::COMMAND_NORESPONSE); |
| | | |
| | | return ($result == self::ERROR_OK); |
| | | } |
| | | |
| | | /** |
| | | * Removes all messages in a folder |
| | | * |
| | | * @param string $mailbox Mailbox name |
| | | * |
| | | * @return boolean True on success, False on error |
| | | * @access public |
| | | */ |
| | | function clearFolder($mailbox) |
| | | { |
| | | $num_in_trash = $this->countMessages($mailbox); |
| | | if ($num_in_trash > 0) { |
| | | $res = $this->delete($mailbox, '1:*'); |
| | | } |
| | | |
| | | if ($res) { |
| | | if ($this->selected == $mailbox) |
| | | $res = $this->close(); |
| | | else |
| | | $res = $this->expunge($mailbox); |
| | | } |
| | | |
| | | return $res; |
| | | } |
| | | |
| | | /** |
| | | * Returns count of all messages in a folder |
| | | * |
| | | * @param string $mailbox Mailbox name |
| | | * |
| | | * @return int Number of messages, False on error |
| | | * @access public |
| | | */ |
| | | function countMessages($mailbox, $refresh = false) |
| | | { |
| | | if ($refresh) { |
| | |
| | | $counts = $this->status($mailbox); |
| | | if (is_array($counts)) { |
| | | return (int) $counts['MESSAGES']; |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | /** |
| | | * Returns count of messages with \Recent flag in a folder |
| | | * |
| | | * @param string $mailbox Mailbox name |
| | | * |
| | | * @return int Number of messages, False on error |
| | | * @access public |
| | | */ |
| | | function countRecent($mailbox) |
| | | { |
| | | if (!strlen($mailbox)) { |
| | | $mailbox = 'INBOX'; |
| | | } |
| | | |
| | | $this->select($mailbox); |
| | | |
| | | if ($this->selected == $mailbox) { |
| | | return $this->data['RECENT']; |
| | | } |
| | | |
| | | return false; |
| | |
| | | $parts_count = count($a); |
| | | if ($parts_count>=6) { |
| | | for ($i=0; $i<$parts_count; $i=$i+2) { |
| | | if ($a[$i] == 'UID') |
| | | if ($a[$i] == 'UID') { |
| | | $result[$id]->uid = intval($a[$i+1]); |
| | | else if ($a[$i] == 'RFC822.SIZE') |
| | | } |
| | | else if ($a[$i] == 'RFC822.SIZE') { |
| | | $result[$id]->size = intval($a[$i+1]); |
| | | else if ($a[$i] == 'INTERNALDATE') |
| | | } |
| | | else if ($a[$i] == 'INTERNALDATE') { |
| | | $time_str = $a[$i+1]; |
| | | else if ($a[$i] == 'FLAGS') |
| | | } |
| | | else if ($a[$i] == 'FLAGS') { |
| | | $flags_str = $a[$i+1]; |
| | | } |
| | | } |
| | | |
| | | $time_str = str_replace('"', '', $time_str); |
| | |
| | | } |
| | | |
| | | // the rest of the result |
| | | preg_match('/ BODY\[HEADER.FIELDS \(.*?\)\]\s*(.*)$/s', $line, $m); |
| | | if (preg_match('/ BODY\[HEADER.FIELDS \(.*?\)\]\s*(.*)$/s', $line, $m)) { |
| | | $reslines = explode("\n", trim($m[1], '"')); |
| | | // re-parse (see below) |
| | | foreach ($reslines as $resln) { |
| | |
| | | $lines[$ln] .= (empty($lines[$ln])?'':"\n").trim($resln); |
| | | } else { |
| | | $lines[++$ln] = trim($resln); |
| | | } |
| | | } |
| | | } |
| | | } |
| | |
| | | $result[$id]->messageID = $string; |
| | | break; |
| | | case 'x-priority': |
| | | if (preg_match('/^(\d+)/', $string, $matches)) |
| | | if (preg_match('/^(\d+)/', $string, $matches)) { |
| | | $result[$id]->priority = intval($matches[1]); |
| | | } |
| | | break; |
| | | default: |
| | | if (strlen($field) > 2) |
| | | if (strlen($field) > 2) { |
| | | $result[$id]->others[$field] = $string; |
| | | } |
| | | break; |
| | | } // end switch () |
| | | } // end while () |
| | |
| | | return $result; |
| | | } |
| | | |
| | | function expunge($mailbox, $messages=NULL) |
| | | { |
| | | if (!$this->select($mailbox)) { |
| | | return false; |
| | | } |
| | | |
| | | // Clear internal status cache |
| | | unset($this->data['STATUS:'.$mailbox]); |
| | | |
| | | if ($messages) |
| | | $result = $this->execute('UID EXPUNGE', array($messages), self::COMMAND_NORESPONSE); |
| | | else |
| | | $result = $this->execute('EXPUNGE', null, self::COMMAND_NORESPONSE); |
| | | |
| | | if ($result == self::ERROR_OK) { |
| | | $this->selected = ''; // state has changed, need to reselect |
| | | return true; |
| | | } |
| | | |
| | | return false; |
| | | } |
| | | |
| | | function modFlag($mailbox, $messages, $flag, $mod) |
| | | { |
| | |
| | | } |
| | | |
| | | if (!$this->select($mailbox)) { |
| | | return false; |
| | | } |
| | | |
| | | if (!$this->data['READ-WRITE']) { |
| | | $this->setError(self::ERROR_READONLY, "Mailbox is read-only", 'STORE'); |
| | | return false; |
| | | } |
| | | |
| | |
| | | |
| | | function move($messages, $from, $to) |
| | | { |
| | | if (!$this->select($from)) { |
| | | return false; |
| | | } |
| | | |
| | | if (!$this->data['READ-WRITE']) { |
| | | $this->setError(self::ERROR_READONLY, "Mailbox is read-only", 'STORE'); |
| | | return false; |
| | | } |
| | | |
| | | $r = $this->copy($messages, $from, $to); |
| | | |
| | | if ($r) { |
| | |
| | | while ($n > 0) { |
| | | $p = strpos($str, ')', $off); |
| | | if ($p === false) { |
| | | error_log('Mismatched brackets parsing IMAP THREAD response:'); |
| | | error_log("Mismatched brackets parsing IMAP THREAD response:"); |
| | | error_log(substr($str, ($begin < 10) ? 0 : ($begin - 10), $end - $begin + 20)); |
| | | error_log(str_repeat(' ', $off - (($begin < 10) ? 0 : ($begin - 10)))); |
| | | return $node; |
| | |
| | | |
| | | if (!empty($items)) { |
| | | $result = array(); |
| | | if (in_array('COUNT', $items)) |
| | | if (in_array('COUNT', $items)) { |
| | | $result['COUNT'] = count($response); |
| | | if (in_array('MIN', $items)) |
| | | } |
| | | if (in_array('MIN', $items)) { |
| | | $result['MIN'] = !empty($response) ? min($response) : 0; |
| | | if (in_array('MAX', $items)) |
| | | } |
| | | if (in_array('MAX', $items)) { |
| | | $result['MAX'] = !empty($response) ? max($response) : 0; |
| | | if (in_array('ALL', $items)) |
| | | } |
| | | if (in_array('ALL', $items)) { |
| | | $result['ALL'] = $this->compressMessageSet($response, true); |
| | | } |
| | | |
| | | return $result; |
| | | } |
| | |
| | | $type = $mime ? 'MIME' : 'HEADER'; |
| | | |
| | | // format request |
| | | foreach($parts as $part) |
| | | foreach($parts as $part) { |
| | | $peeks[] = "BODY.PEEK[$part.$type]"; |
| | | } |
| | | |
| | | $request = "$key FETCH $id (" . implode(' ', $peeks) . ')'; |
| | | |
| | |
| | | $result = substr($line, $from, $len); |
| | | } |
| | | |
| | | if ($mode == 1) |
| | | if ($mode == 1) { |
| | | $result = base64_decode($result); |
| | | else if ($mode == 2) |
| | | } |
| | | else if ($mode == 2) { |
| | | $result = quoted_printable_decode($result); |
| | | else if ($mode == 3) |
| | | } |
| | | 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 |
| | |
| | | while ($bytes > 0) { |
| | | $line = $this->readLine(4096); |
| | | |
| | | if ($line === NULL) |
| | | if ($line === NULL) { |
| | | break; |
| | | } |
| | | |
| | | $len = strlen($line); |
| | | |
| | |
| | | return ($result == self::ERROR_OK); |
| | | } |
| | | |
| | | function deleteFolder($mailbox) |
| | | { |
| | | $result = $this->execute('DELETE', array($this->escape($mailbox)), |
| | | self::COMMAND_NORESPONSE); |
| | | |
| | | return ($result == self::ERROR_OK); |
| | | } |
| | | |
| | | function clearFolder($mailbox) |
| | | { |
| | | $num_in_trash = $this->countMessages($mailbox); |
| | | if ($num_in_trash > 0) { |
| | | $this->delete($mailbox, '1:*'); |
| | | } |
| | | return ($this->expunge($mailbox) >= 0); |
| | | } |
| | | |
| | | function subscribe($mailbox) |
| | | { |
| | | $result = $this->execute('SUBSCRIBE', array($this->escape($mailbox)), |
| | | self::COMMAND_NORESPONSE); |
| | | |
| | | return ($result == self::ERROR_OK); |
| | | } |
| | | |
| | | function unsubscribe($mailbox) |
| | | { |
| | | $result = $this->execute('UNSUBSCRIBE', array($this->escape($mailbox)), |
| | | self::COMMAND_NORESPONSE); |
| | | |
| | | return ($result == self::ERROR_OK); |
| | | } |
| | | |
| | | function append($mailbox, &$message) |
| | | { |
| | | if (!$mailbox) { |
| | |
| | | if ($this->putLine($request)) { |
| | | // Don't wait when LITERAL+ is supported |
| | | if (!$this->prefs['literal+']) { |
| | | $line = $this->readLine(512); |
| | | $line = $this->readReply(); |
| | | |
| | | if ($line[0] != '+') { |
| | | $this->parseResult($line, 'APPEND: '); |
| | |
| | | if ($this->putLine($request)) { |
| | | // Don't wait when LITERAL+ is supported |
| | | if (!$this->prefs['literal+']) { |
| | | $line = $this->readLine(512); |
| | | $line = $this->readReply(); |
| | | |
| | | if ($line[0] != '+') { |
| | | $this->parseResult($line, 'APPEND: '); |
| | |
| | | $parts = explode(' ', $quota_line); |
| | | $storage_part = array_search('STORAGE', $parts); |
| | | |
| | | if (!$storage_part) |
| | | if (!$storage_part) { |
| | | continue; |
| | | } |
| | | |
| | | $used = intval($parts[$storage_part+1]); |
| | | $total = intval($parts[$storage_part+2]); |
| | |
| | | } |
| | | |
| | | foreach ($entries as $name => $value) { |
| | | if ($value === null) |
| | | if ($value === null) { |
| | | $value = 'NIL'; |
| | | else |
| | | } |
| | | else { |
| | | $value = sprintf("{%d}\r\n%s", strlen($value), $value); |
| | | |
| | | } |
| | | $entries[$name] = $this->escape($name) . ' ' . $value; |
| | | } |
| | | |
| | |
| | | */ |
| | | function deleteMetadata($mailbox, $entries) |
| | | { |
| | | if (!is_array($entries) && !empty($entries)) |
| | | if (!is_array($entries) && !empty($entries)) { |
| | | $entries = explode(' ', $entries); |
| | | } |
| | | |
| | | if (empty($entries)) { |
| | | $this->setError(self::ERROR_COMMAND, "Wrong argument for SETMETADATA command"); |
| | | return false; |
| | | } |
| | | |
| | | foreach ($entries as $entry) |
| | | foreach ($entries as $entry) { |
| | | $data[$entry] = NULL; |
| | | } |
| | | |
| | | return $this->setMetadata($mailbox, $data); |
| | | } |
| | |
| | | $options = array_change_key_case($options, CASE_UPPER); |
| | | $opts = array(); |
| | | |
| | | if (!empty($options['MAXSIZE'])) |
| | | if (!empty($options['MAXSIZE'])) { |
| | | $opts[] = 'MAXSIZE '.intval($options['MAXSIZE']); |
| | | if (!empty($options['DEPTH'])) |
| | | } |
| | | if (!empty($options['DEPTH'])) { |
| | | $opts[] = 'DEPTH '.intval($options['DEPTH']); |
| | | } |
| | | |
| | | if ($opts) |
| | | if ($opts) { |
| | | $optlist = '(' . implode(' ', $opts) . ')'; |
| | | } |
| | | } |
| | | |
| | | $optlist .= ($optlist ? ' ' : '') . $entlist; |
| | |
| | | $attr = $entry[1]; |
| | | $value = $entry[2]; |
| | | |
| | | if ($value === null) |
| | | if ($value === null) { |
| | | $value = 'NIL'; |
| | | else |
| | | } |
| | | else { |
| | | $value = sprintf("{%d}\r\n%s", strlen($value), $value); |
| | | } |
| | | |
| | | $entries[] = sprintf('%s (%s %s)', |
| | | $this->escape($name), $this->escape($attr), $value); |
| | |
| | | for ($x=0, $len=count($attribs); $x<$len;) { |
| | | $attr = $attribs[$x++]; |
| | | $value = $attribs[$x++]; |
| | | if ($attr == 'value.priv') |
| | | if ($attr == 'value.priv') { |
| | | $res['/private' . $entry] = $value; |
| | | else if ($attr == 'value.shared') |
| | | } |
| | | else if ($attr == 'value.shared') { |
| | | $res['/shared' . $entry] = $value; |
| | | } |
| | | } |
| | | } |
| | | $last_entry = $entry; |
| | |
| | | $noresp = ($options & self::COMMAND_NORESPONSE); |
| | | $response = $noresp ? null : ''; |
| | | |
| | | if (!empty($arguments)) |
| | | if (!empty($arguments)) { |
| | | $query .= ' ' . implode(' ', $arguments); |
| | | } |
| | | |
| | | // Send command |
| | | if (!$this->putLineC($query)) { |
| | |
| | | // Parse response |
| | | do { |
| | | $line = $this->readLine(4096); |
| | | if ($response !== null) |
| | | if ($response !== null) { |
| | | $response .= $line; |
| | | } |
| | | } while (!$this->startsWith($line, $tag . ' ', true, true)); |
| | | |
| | | $code = $this->parseResult($line, $command . ': '); |
| | |
| | | $this->parseCapability($matches[1], true); |
| | | } |
| | | |
| | | // return last line only (without command tag and result) |
| | | // return last line only (without command tag, result and response code) |
| | | if ($line && ($options & self::COMMAND_LASTLINE)) { |
| | | $response = preg_replace("/^$tag (OK|NO|BAD|BYE|PREAUTH)?\s*/i", '', trim($line)); |
| | | $response = preg_replace("/^$tag (OK|NO|BAD|BYE|PREAUTH)?\s*(\[[a-z-]+\])?\s*/i", '', trim($line)); |
| | | } |
| | | |
| | | return $noresp ? $code : array($code, $response); |
| | |
| | | { |
| | | $result = ''; |
| | | $size = strlen($string); |
| | | |
| | | for ($i=0; $i<$size; $i++) { |
| | | $result .= chr(ord($string[$i]) ^ ord($string2[$i])); |
| | | } |
| | | |
| | | return $result; |
| | | } |
| | | |
| | |
| | | while ((($ts = @strtotime($date))===false) || ($ts < 0)) { |
| | | $d = explode(' ', $date); |
| | | array_pop($d); |
| | | if (!$d) break; |
| | | if (!$d) { |
| | | break; |
| | | } |
| | | $date = implode(' ', $d); |
| | | } |
| | | |
| | |
| | | */ |
| | | static function escape($string) |
| | | { |
| | | // NIL |
| | | if ($string === null) { |
| | | return 'NIL'; |
| | | } |
| | | // empty string |
| | | else if ($string === '') { |
| | | return '""'; |
| | | } |
| | | // string: special chars: SP, CTL, (, ), {, %, *, ", \, ] |
| | | else if (preg_match('/([\x00-\x20\x28-\x29\x7B\x25\x2A\x22\x5C\x5D\x7F]+)/', $string)) { |
| | | // string: special chars: SP, CTL, (, ), {, %, *, ", \, ] |
| | | return '"' . strtr($string, array('"'=>'\\"', '\\' => '\\\\')) . '"'; |
| | | } |
| | | |