|
|
@ -2028,7 +2028,7 @@ class rcube_imap_generic
|
|
|
|
$request = "$key $cmd $message_set (" . implode(' ', $fields) . ")";
|
|
|
|
$request = "$key $cmd $message_set (" . implode(' ', $fields) . ")";
|
|
|
|
|
|
|
|
|
|
|
|
if (!$this->putLine($request)) {
|
|
|
|
if (!$this->putLine($request)) {
|
|
|
|
$this->setError(self::ERROR_COMMAND, "Unable to send command: $request");
|
|
|
|
$this->setError(self::ERROR_COMMAND, "Failed to send $cmd command");
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -2355,15 +2355,15 @@ class rcube_imap_generic
|
|
|
|
$result = array();
|
|
|
|
$result = array();
|
|
|
|
|
|
|
|
|
|
|
|
$key = $this->nextTag();
|
|
|
|
$key = $this->nextTag();
|
|
|
|
$request = $key . ($is_uid ? ' UID' : '') . " FETCH $message_set ";
|
|
|
|
$cmd = ($is_uid ? 'UID ' : '') . 'FETCH';
|
|
|
|
$request .= "(" . implode(' ', $query_items) . ")";
|
|
|
|
$request = "$key $cmd $message_set (" . implode(' ', $query_items) . ")";
|
|
|
|
|
|
|
|
|
|
|
|
if ($mod_seq !== null && $this->hasCapability('CONDSTORE')) {
|
|
|
|
if ($mod_seq !== null && $this->hasCapability('CONDSTORE')) {
|
|
|
|
$request .= " (CHANGEDSINCE $mod_seq" . ($vanished ? " VANISHED" : '') .")";
|
|
|
|
$request .= " (CHANGEDSINCE $mod_seq" . ($vanished ? " VANISHED" : '') .")";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!$this->putLine($request)) {
|
|
|
|
if (!$this->putLine($request)) {
|
|
|
|
$this->setError(self::ERROR_COMMAND, "Unable to send command: $request");
|
|
|
|
$this->setError(self::ERROR_COMMAND, "Failed to send $cmd command");
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -2714,7 +2714,7 @@ class rcube_imap_generic
|
|
|
|
|
|
|
|
|
|
|
|
// send request
|
|
|
|
// send request
|
|
|
|
if (!$this->putLine($request)) {
|
|
|
|
if (!$this->putLine($request)) {
|
|
|
|
$this->setError(self::ERROR_COMMAND, "Unable to send command: $request");
|
|
|
|
$this->setError(self::ERROR_COMMAND, "Failed to send UID FETCH command");
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -2782,14 +2782,15 @@ class rcube_imap_generic
|
|
|
|
|
|
|
|
|
|
|
|
// format request
|
|
|
|
// format request
|
|
|
|
$key = $this->nextTag();
|
|
|
|
$key = $this->nextTag();
|
|
|
|
$request = $key . ($is_uid ? ' UID' : '') . " FETCH $id ($fetch_mode.PEEK[$part]$partial)";
|
|
|
|
$cmd = ($is_uid ? 'UID ' : '') . 'FETCH';
|
|
|
|
|
|
|
|
$request = "$key $cmd $id ($fetch_mode.PEEK[$part]$partial)";
|
|
|
|
$result = false;
|
|
|
|
$result = false;
|
|
|
|
$found = false;
|
|
|
|
$found = false;
|
|
|
|
$initiated = true;
|
|
|
|
$initiated = true;
|
|
|
|
|
|
|
|
|
|
|
|
// send request
|
|
|
|
// send request
|
|
|
|
if (!$this->putLine($request)) {
|
|
|
|
if (!$this->putLine($request)) {
|
|
|
|
$this->setError(self::ERROR_COMMAND, "Unable to send command: $request");
|
|
|
|
$this->setError(self::ERROR_COMMAND, "Failed to send $cmd command");
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -2990,65 +2991,66 @@ class rcube_imap_generic
|
|
|
|
$request .= ' ' . ($binary ? '~' : '') . '{' . $len . ($literal_plus ? '+' : '') . '}';
|
|
|
|
$request .= ' ' . ($binary ? '~' : '') . '{' . $len . ($literal_plus ? '+' : '') . '}';
|
|
|
|
|
|
|
|
|
|
|
|
// send APPEND command
|
|
|
|
// send APPEND command
|
|
|
|
if ($this->putLine($request)) {
|
|
|
|
if (!$this->putLine($request)) {
|
|
|
|
// Do not wait when LITERAL+ is supported
|
|
|
|
$this->setError(self::ERROR_COMMAND, "Failed to send APPEND command");
|
|
|
|
if (!$literal_plus) {
|
|
|
|
return false;
|
|
|
|
$line = $this->readReply();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ($line[0] != '+') {
|
|
|
|
// Do not wait when LITERAL+ is supported
|
|
|
|
$this->parseResult($line, 'APPEND: ');
|
|
|
|
if (!$literal_plus) {
|
|
|
|
return false;
|
|
|
|
$line = $this->readReply();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if ($line[0] != '+') {
|
|
|
|
|
|
|
|
$this->parseResult($line, 'APPEND: ');
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
foreach ($msg as $msg_part) {
|
|
|
|
foreach ($msg as $msg_part) {
|
|
|
|
// file pointer
|
|
|
|
// file pointer
|
|
|
|
if (is_resource($msg_part)) {
|
|
|
|
if (is_resource($msg_part)) {
|
|
|
|
rewind($msg_part);
|
|
|
|
rewind($msg_part);
|
|
|
|
while (!feof($msg_part) && $this->fp) {
|
|
|
|
while (!feof($msg_part) && $this->fp) {
|
|
|
|
$buffer = fread($msg_part, $chunk_size);
|
|
|
|
$buffer = fread($msg_part, $chunk_size);
|
|
|
|
$this->putLine($buffer, false);
|
|
|
|
$this->putLine($buffer, false);
|
|
|
|
}
|
|
|
|
|
|
|
|
fclose($msg_part);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// string
|
|
|
|
fclose($msg_part);
|
|
|
|
else {
|
|
|
|
}
|
|
|
|
$size = strlen($msg_part);
|
|
|
|
// string
|
|
|
|
|
|
|
|
else {
|
|
|
|
|
|
|
|
$size = strlen($msg_part);
|
|
|
|
|
|
|
|
|
|
|
|
// Break up the data by sending one chunk (up to 512k) at a time.
|
|
|
|
// Break up the data by sending one chunk (up to 512k) at a time.
|
|
|
|
// This approach reduces our peak memory usage
|
|
|
|
// This approach reduces our peak memory usage
|
|
|
|
for ($offset = 0; $offset < $size; $offset += $chunk_size) {
|
|
|
|
for ($offset = 0; $offset < $size; $offset += $chunk_size) {
|
|
|
|
$chunk = substr($msg_part, $offset, $chunk_size);
|
|
|
|
$chunk = substr($msg_part, $offset, $chunk_size);
|
|
|
|
if (!$this->putLine($chunk, false)) {
|
|
|
|
if (!$this->putLine($chunk, false)) {
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (!$this->putLine('')) { // \r\n
|
|
|
|
if (!$this->putLine('')) { // \r\n
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
do {
|
|
|
|
do {
|
|
|
|
$line = $this->readLine();
|
|
|
|
$line = $this->readLine();
|
|
|
|
} while (!$this->startsWith($line, $key, true, true));
|
|
|
|
} while (!$this->startsWith($line, $key, true, true));
|
|
|
|
|
|
|
|
|
|
|
|
// Clear internal status cache
|
|
|
|
// Clear internal status cache
|
|
|
|
unset($this->data['STATUS:'.$mailbox]);
|
|
|
|
unset($this->data['STATUS:'.$mailbox]);
|
|
|
|
|
|
|
|
|
|
|
|
if ($this->parseResult($line, 'APPEND: ') != self::ERROR_OK)
|
|
|
|
if ($this->parseResult($line, 'APPEND: ') != self::ERROR_OK) {
|
|
|
|
return false;
|
|
|
|
return false;
|
|
|
|
else if (!empty($this->data['APPENDUID']))
|
|
|
|
|
|
|
|
return $this->data['APPENDUID'];
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
|
|
|
|
$this->setError(self::ERROR_COMMAND, "Unable to send command: $request");
|
|
|
|
if (!empty($this->data['APPENDUID'])) {
|
|
|
|
|
|
|
|
return $this->data['APPENDUID'];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
@ -3707,7 +3709,10 @@ class rcube_imap_generic
|
|
|
|
|
|
|
|
|
|
|
|
// Send command
|
|
|
|
// Send command
|
|
|
|
if (!$this->putLineC($query, true, ($options & self::COMMAND_ANONYMIZED))) {
|
|
|
|
if (!$this->putLineC($query, true, ($options & self::COMMAND_ANONYMIZED))) {
|
|
|
|
$this->setError(self::ERROR_COMMAND, "Unable to send command: $query");
|
|
|
|
preg_match('/^[A-Z0-9]+ ((UID )?[A-Z]+)/', $query, $matches);
|
|
|
|
|
|
|
|
$cmd = $matches[1] ?: 'UNKNOWN';
|
|
|
|
|
|
|
|
$this->setError(self::ERROR_COMMAND, "Failed to send $cmd command");
|
|
|
|
|
|
|
|
|
|
|
|
return $noresp ? self::ERROR_COMMAND : array(self::ERROR_COMMAND, '');
|
|
|
|
return $noresp ? self::ERROR_COMMAND : array(self::ERROR_COMMAND, '');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|