\n" .
_("ERROR : No available imapstream.") .
"\n";
error_box($string,$color);
return false;
}
}
function sqimap_run_command ($imap_stream, $query, $handle_errors, &$response,
&$message, $unique_id = false,$filter=false,
$outputstream=false,$no_return=false) {
if ($imap_stream) {
$sid = sqimap_session_id($unique_id);
fputs ($imap_stream, $sid . ' ' . $query . "\r\n");
$tag_uid_a = explode(' ',trim($sid));
$tag = $tag_uid_a[0];
$read = sqimap_read_data ($imap_stream, $tag, $handle_errors, $response,
$message, $query,$filter,$outputstream,$no_return);
/* retrieve the response and the message */
$response = $response[$tag];
$message = $message[$tag];
if (!empty($read[$tag])) {
return $read[$tag][0];
} else {
return $read[$tag];
}
} else {
global $squirrelmail_language, $color;
set_up_language($squirrelmail_language);
require_once(SM_PATH . 'functions/display_messages.php');
$string = "\n" .
_("ERROR : No available imapstream.") .
"\n";
error_box($string,$color);
return false;
}
}
function sqimap_prepare_pipelined_query($new_query,&$tag,&$aQuery,$unique_id) {
$sid = sqimap_session_id($unique_id);
$tag_uid_a = explode(' ',trim($sid));
$tag = $tag_uid_a[0];
$query = $sid . ' '.$new_query."\n";
$aQuery[$tag] = $query;
}
function sqimap_run_pipelined_command ($imap_stream, $aQuery, $handle_errors,
&$aServerResponse, &$aServerMessage, $unique_id = false,
$filter=false,$outputstream=false,$no_return=false) {
$aResponse = false;
foreach($aQuery as $tag => $query) {
fputs($imap_stream,$query);
$aResults[$tag] = false;
}
foreach($aQuery as $tag => $query) {
if (!$aResults[$tag]) {
$aReturnedResponse = sqimap_read_data_list ($imap_stream, $tag,
$handle_errors, $response, $message, $query,
$filter,$outputstream,$no_return);
foreach ($aReturnedResponse as $returned_tag => $aResponse) {
$aResults[$returned_tag] = $aResponse;
$aServerResponse[$returned_tag] = $response[$returned_tag];
$aServerMessage[$returned_tag] = $message[$returned_tag];
}
}
}
}
/*
* custom fgets function. gets a line from IMAP
* no matter how big it may be
*/
function sqimap_fgets($imap_stream) {
$read = '';
$buffer = 4096;
$results = '';
$offset = 0;
while (strpos($results, "\r\n", $offset) === false) {
if (!($read = fgets($imap_stream, $buffer))) {
/* this happens in case of an error */
/* reset $results because it's useless */
$results = false;
break;
}
if ( $results != '' ) {
$offset = strlen($results) - 1;
}
$results .= $read;
}
return $results;
}
function sqimap_fread($imap_stream,$iSize,$filter=false,
$outputstream=false, $no_return=false) {
if (!$filter || !$outputstream) {
$iBufferSize = $iSize;
} else {
$iBufferSize = 62400; // multiple of 78 in case of base64 decoding.
}
$iRet = $iSize - $iBufferSize;
$iRetrieved = 0;
$i = 0;
$results = $sReadRem = '';
$bFinished = $bBufferSizeAdapted = $bBufferIsOk = false;
while (($iRetrieved < ($iSize - $iBufferSize))) {
$sRead = fread($imap_stream,$iBufferSize);
if (!$sRead) {
$results = false;
break;
}
$iRetrieved += $iBufferSize;
if ($filter) {
// in case line-endings do not appear at position 78 we adapt the buffersize so we can base64 decode on the fly
if (!$bBufferSizeAdapted) {
$i = strpos($sRead,"\n");
if ($i) {
++$i;
$iFragments = floor($iBufferSize / $i);
$iNewBufferSize = $iFragments * $i;
$iRemainder = $iNewBufferSize + $i - $iBufferSize;
if ($iNewBufferSize == $iBufferSize) {
$bBufferIsOk = true;
$iRemainder = 0;
$iNewBufferSize = $iBufferSize;
$bBufferSizeAdapted = true;
}
if (!$bBufferIsOk && ($iRemainder + $iBufferSize) < $iSize) {
$sReadRem = fread($imap_stream,$iRemainder);
} else if (!$bBufferIsOk) {
$sReadRem = fread($imap_stream,$iSize - $iBufferSize);
$bFinished = true;
}
if (!$sReadRem && $sReadRem !== '') {
$results = false;
break;
}
$iBufferSize = $iNewBufferSize;
$bBufferSizeAdapted = true;
} else {
$sReadRem = fread($imap_stream,$iSize - $iBufferSize);
$bFinished = true;
if (!$sReadRem) {
$results = false;
break;
}
}
$sRead .= $sReadRem;
$iRetrieved += $iRemainder;
unset($sReadRem);
}
$filter($sRead);
}
if ($outputstream) {
if (is_resource($outputstream)) {
fwrite($outputstream,$sRead);
} else if ($outputstream == 'php://stdout') {
echo $sRead;
}
}
if ($no_return) {
$sRead = '';
}
$results .= $sRead;
}
if (!$results && !$bFinished) {
$sRead = fread($imap_stream,($iSize - ($iRetrieved)));
if ($filter) {
$filter($sRead);
}
if ($outputstream) {
if (is_resource($outputstream)) {
fwrite($outputstream,$sRead);
} else if ($outputstream == 'php://stdout') { // FIXME
echo $sRead;
}
}
if ($no_return) {
$sRead = '';
}
$results .= $sRead;
}
return $results;
}
/*
* Reads the output from the IMAP stream. If handle_errors is set to true,
* this will also handle all errors that are received. If it is not set,
* the errors will be sent back through $response and $message
*/
function sqimap_read_data_list ($imap_stream, $tag, $handle_errors,
&$response, &$message, $query = '',
$filter = false, $outputstream = false, $no_return = false) {
global $color, $squirrelmail_language;
$read = '';
if (!is_array($message)) $message = array();
if (!is_array($response)) $response = array();
$resultlist = array();
$data = array();
$read = sqimap_fgets($imap_stream);
$i = 0;
while ($read) {
$char = $read{0};
switch ($char)
{
case '+':
default:
$read = sqimap_fgets($imap_stream);
break;
case $tag{0}:
{
/* get the command */
$arg = '';
$i = strlen($tag)+1;
$s = substr($read,$i);
if (($j = strpos($s,' ')) || ($j = strpos($s,"\n"))) {
$arg = substr($s,0,$j);
}
$found_tag = substr($read,0,$i-1);
if ($arg && $found_tag==$tag) {
switch ($arg)
{
case 'OK':
case 'BAD':
case 'NO':
case 'BYE':
case 'PREAUTH':
$response[$found_tag] = $arg;
$message[$found_tag] = trim(substr($read,$i+strlen($arg)));
if (!empty($data)) {
$resultlist[] = $data;
}
$aResponse[$tag] = $resultlist;
break 3; /* switch switch while */
default:
/* this shouldn't happen */
$response[$found_tag] = $arg;
$message[$found_tag] = trim(substr($read,$i+strlen($arg)));
if (!empty($data)) {
$resultlist[] = $data;
}
$aResponse[$found_tag] = $resultlist;
break 3; /* switch switch while */
}
} elseif($found_tag !== $tag) {
/* not the tag we are looking for, continue */
if (!empty($data)) {
$resultlist[] = $data;
}
$aResponse[$found_tag] = $resultlist;
$resultlist = $data = array();
$read = sqimap_fgets($imap_stream);
if ($read === false) { /* error */
break 3; /* switch switch while */
}
break;
}
} // end case $tag{0}
case '*':
{
if (preg_match('/^\*\s\d+\sFETCH/',$read)) {
/* check for literal */
$s = substr($read,-3);
$fetch_data = array();
do { /* outer loop, continue until next untagged fetch
or tagged reponse */
do { /* innerloop for fetching literals. with this loop
we prohibid that literal responses appear in the
outer loop so we can trust the untagged and
tagged info provided by $read */
if ($s === "}\r\n") {
$j = strrpos($read,'{');
$iLit = substr($read,$j+1,-3);
$fetch_data[] = $read;
$sLiteral = sqimap_fread($imap_stream,$iLit,$filter,$outputstream,$no_return);
if ($sLiteral === false) { /* error */
break 4; /* while while switch while */
}
/* backwards compattibility */
$aLiteral = explode("\n", $sLiteral);
/* release not neaded data */
unset($sLiteral);
foreach ($aLiteral as $line) {
$fetch_data[] = $line ."\n";
}
/* release not neaded data */
unset($aLiteral);
/* next fgets belongs to this fetch because
we just got the exact literalsize and there
must follow data to complete the response */
$read = sqimap_fgets($imap_stream);
if ($read === false) { /* error */
break 4; /* while while switch while */
}
$fetch_data[] = $read;
} else {
$fetch_data[] = $read;
}
/* retrieve next line and check in the while
statements if it belongs to this fetch response */
$read = sqimap_fgets($imap_stream);
if ($read === false) { /* error */
break 4; /* while while switch while */
}
/* check for next untagged reponse and break */
if ($read{0} == '*') break 2;
$s = substr($read,-3);
} while ($s === "}\r\n");
$s = substr($read,-3);
} while ($read{0} !== '*' &&
substr($read,0,strlen($tag)) !== $tag);
$resultlist[] = $fetch_data;
/* release not neaded data */
unset ($fetch_data);
} else {
$s = substr($read,-3);
do {
if ($s === "}\r\n") {
$j = strrpos($read,'{');
$iLit = substr($read,$j+1,-3);
$data[] = $read;
$sLiteral = fread($imap_stream,$iLit);
if ($sLiteral === false) { /* error */
$read = false;
break 3; /* while switch while */
}
$data[] = $sLiteral;
$fetch_data[] = sqimap_fgets($imap_stream);
} else {
$data[] = $read;
}
$read = sqimap_fgets($imap_stream);
if ($read === false) {
break 3; /* while switch while */
} else if ($read{0} == '*') {
break;
}
$s = substr($read,-3);
} while ($s === "}\r\n");
break 1;
}
break;
} // end case '*'
} // end switch
} // end while
/* error processing in case $read is false */
if ($read === false) {
unset($data);
set_up_language($squirrelmail_language);
require_once(SM_PATH . 'functions/display_messages.php');
$string = "\n" .
_("ERROR : Connection dropped by imap-server.") .
"
\n" .
_("Query:") . ' '.
htmlspecialchars($query) . '
' . "
\n";
error_box($string,$color);
exit;
}
/* Set $resultlist array */
if (!empty($data)) {
//$resultlist[] = $data;
}
elseif (empty($resultlist)) {
$resultlist[] = array();
}
/* Return result or handle errors */
if ($handle_errors == false) {
return $aResponse;
return( $resultlist );
}
switch ($response[$tag])
{
case 'OK':
return $aResponse;
break;
case 'NO':
/* ignore this error from M$ exchange, it is not fatal (aka bug) */
if (strstr($message, 'command resulted in') === false) {
set_up_language($squirrelmail_language);
require_once(SM_PATH . 'functions/display_messages.php');
$string = "\n" .
_("ERROR : Could not complete request.") .
"
\n" .
_("Query:") . ' ' .
htmlspecialchars($query) . '
' .
_("Reason Given: ") .
htmlspecialchars($message[$tag]) . "
\n";
error_box($string,$color);
echo '