X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=functions%2Fimap_general.php;h=3c812805b4c31d0babc35bee1023fdba16be9f2d;hb=d741b4ec5c3f87af5e3bff946a69ee4a1c1b00a2;hp=6b6826edc793949e30d4499e06fcb3070bc341b2;hpb=52c8b5852d7461e27027e622787598ede391718f;p=squirrelmail.git
diff --git a/functions/imap_general.php b/functions/imap_general.php
index 6b6826ed..3c812805 100755
--- a/functions/imap_general.php
+++ b/functions/imap_general.php
@@ -3,24 +3,30 @@
/**
* imap_general.php
*
- * Copyright (c) 1999-2003 The SquirrelMail Project Team
+ * Copyright (c) 1999-2004 The SquirrelMail Project Team
* Licensed under the GNU GPL. For full terms see the file COPYING.
*
* This implements all functions that do general imap functions.
*
- * $Id$
+ * @version $Id$
+ * @package squirrelmail
+ * @subpackage imap
*/
+/** Includes.. */
require_once(SM_PATH . 'functions/page_header.php');
require_once(SM_PATH . 'functions/auth.php');
-global $sqimap_session_id;
-$sqimap_session_id = 1;
+/**
+ * Generates a new session ID by incrementing the last one used;
+ * this ensures that each command has a unique ID.
+ * @param bool unique_id
+ * @return string IMAP session id of the form 'A000'.
+ */
+function sqimap_session_id($unique_id = FALSE) {
+ static $sqimap_session_id = 1;
-/* Sets an unique session id in order to avoid simultanous sessions crash. */
-function sqimap_session_id($unique_id = false) {
- global $data_dir, $username, $sqimap_session_id;
if (!$unique_id) {
return( sprintf("A%03d", $sqimap_session_id++) );
} else {
@@ -28,7 +34,7 @@ function sqimap_session_id($unique_id = false) {
}
}
-/*
+/**
* Both send a command and accept the result from the command.
* This is to allow proper session number handling.
*/
@@ -38,7 +44,7 @@ function sqimap_run_command_list ($imap_stream, $query, $handle_errors, &$respon
fputs ($imap_stream, $sid . ' ' . $query . "\r\n");
$tag_uid_a = explode(' ',trim($sid));
$tag = $tag_uid_a[0];
- $read = sqimap_read_data_list ($imap_stream, $tag, $handle_errors, $response, $message, $query );
+ $read = sqimap_retrieve_imap_response ($imap_stream, $tag, $handle_errors, $response, $message, $query );
/* get the response and the message */
$message = $message[$tag];
$response = $response[$tag];
@@ -66,10 +72,15 @@ function sqimap_run_command ($imap_stream, $query, $handle_errors, &$response,
$read = sqimap_read_data ($imap_stream, $tag, $handle_errors, $response,
$message, $query,$filter,$outputstream,$no_return);
+ if (empty($read)) { //Imap server dropped its connection
+ $response = '';
+ $message = '';
+ return false;
+ }
/* retrieve the response and the message */
$response = $response[$tag];
$message = $message[$tag];
-
+
if (!empty($read[$tag])) {
return $read[$tag][0];
} else {
@@ -86,25 +97,29 @@ function sqimap_run_command ($imap_stream, $query, $handle_errors, &$response,
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";
+ $query = $sid . ' '.$new_query."\r\n";
$aQuery[$tag] = $query;
}
function sqimap_run_pipelined_command ($imap_stream, $aQueryList, $handle_errors,
&$aServerResponse, &$aServerMessage, $unique_id = false,
- $filter=false,$outputstream=false,$no_return=false) {
-
+ $filter=false,$outputstream=false,$no_return=false) {
$aResponse = false;
+
/*
Do not fire all calls at once to the imap-server but split the calls up
in portions of $iChunkSize. If we do not do that I think we misbehave as
IMAP client or should handle BYE calls if the IMAP-server drops the
connection because the number of queries is to large. This isn't tested
but a wild guess how it could work in the field.
+
+ After testing it on Exchange 2000 we discovered that a chunksize of 32
+ was quicker then when we raised it to 128.
*/
$iQueryCount = count($aQueryList);
$iChunkSize = 32;
@@ -112,18 +127,18 @@ function sqimap_run_pipelined_command ($imap_stream, $aQueryList, $handle_errors
$aQueryChunks = array();
$iLoops = floor($iQueryCount / $iChunkSize);
- if ($iLoops * $iChunkSize !== $iQueryCount) ++$iLoops;
+ if ($iLoops * $iChunkSize != $iQueryCount) ++$iLoops;
if (!function_exists('array_chunk')) { // arraychunk replacement
- reset($aQueryList);
+ reset($aQueryList);
for($i=0;$i<$iLoops;++$i) {
- for($j=0;$j<$iChunkSize;++$j) {
- $key = key($aQueryList);
- $aTmp[$key] = $aQueryList[$key];
- if (next($aQueryList) === false) break;
- }
- $aQueryChunks[] = $aTmp;
- }
+ for($j=0;$j<$iChunkSize;++$j) {
+ $key = key($aQueryList);
+ $aTmp[$key] = $aQueryList[$key];
+ if (next($aQueryList) === false) break;
+ }
+ $aQueryChunks[] = $aTmp;
+ }
} else {
$aQueryChunks = array_chunk($aQueryList,$iChunkSize,true);
}
@@ -134,18 +149,17 @@ function sqimap_run_pipelined_command ($imap_stream, $aQueryList, $handle_errors
fputs($imap_stream,$query);
$aResults[$tag] = false;
}
-
foreach($aQuery as $tag => $query) {
- if (!$aResults[$tag]) {
- $aReturnedResponse = sqimap_read_data_list ($imap_stream, $tag,
+ if ($aResults[$tag] == false) {
+ $aReturnedResponse = sqimap_retrieve_imap_response ($imap_stream, $tag,
$handle_errors, $response, $message, $query,
$filter,$outputstream,$no_return);
foreach ($aReturnedResponse as $returned_tag => $aResponse) {
- if (!empty($aResponse)) {
+ if (!empty($aResponse)) {
$aResults[$returned_tag] = $aResponse[0];
- } else {
- $aResults[$returned_tag] = $aResponse;
- }
+ } else {
+ $aResults[$returned_tag] = $aResponse;
+ }
$aServerResponse[$returned_tag] = $response[$returned_tag];
$aServerMessage[$returned_tag] = $message[$returned_tag];
}
@@ -155,11 +169,12 @@ function sqimap_run_pipelined_command ($imap_stream, $aQueryList, $handle_errors
return $aResults;
}
-/*
- * custom fgets function. gets a line from IMAP
- * no matter how big it may be
+/**
+ * Custom fgets function: gets a line from the IMAP-server,
+ * no matter how big it may be.
+ * @param stream imap_stream the stream to read from
+ * @return string a line
*/
-
function sqimap_fgets($imap_stream) {
$read = '';
$buffer = 4096;
@@ -185,62 +200,47 @@ function sqimap_fread($imap_stream,$iSize,$filter=false,
if (!$filter || !$outputstream) {
$iBufferSize = $iSize;
} else {
- $iBufferSize = 62400; // multiple of 78 in case of base64 decoding.
+ // see php bug 24033. They changed fread behaviour %$^&$%
+ $iBufferSize = 7800; // multiple of 78 in case of base64 decoding.
+ }
+ if ($iSize < $iBufferSize) {
+ $iBufferSize = $iSize;
}
- $iRet = $iSize - $iBufferSize;
$iRetrieved = 0;
- $i = 0;
- $results = $sReadRem = '';
- $bFinished = $bBufferSizeAdapted = $bBufferIsOk = false;
- while (($iRetrieved < ($iSize - $iBufferSize))) {
+ $results = '';
+ $sRead = $sReadRem = '';
+ // NB: fread can also stop at end of a packet on sockets.
+ while ($iRetrieved < $iSize) {
$sRead = fread($imap_stream,$iBufferSize);
+ $iLength = strlen($sRead);
+ $iRetrieved += $iLength ;
+ $iRemaining = $iSize - $iRetrieved;
+ if ($iRemaining < $iBufferSize) {
+ $iBufferSize = $iRemaining;
+ }
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);
- }
+ if ($sReadRem) {
+ $sRead = $sReadRem . $sRead;
+ $sReadRem = '';
+ }
+ if (substr($sRead,-1) !== "\n") {
+ $i = strrpos($sRead,"\n");
+ if ($i !== false && $iRetrieved<$iSize) {
+ ++$i;
+ $sReadRem = substr($sRead,$i);
+ $sRead = substr($sRead,0,$i);
+ } else if ($iLength && $iRetrieved<$iSize) { // linelength > received buffer
+ $sReadRem = $sRead;
+ $sRead = '';
+ }
+ }
+ if ($filter && $sRead) {
$filter($sRead);
}
- if ($outputstream) {
+ if ($outputstream && $sRead) {
if (is_resource($outputstream)) {
fwrite($outputstream,$sRead);
} else if ($outputstream == 'php://stdout') {
@@ -249,48 +249,85 @@ function sqimap_fread($imap_stream,$iSize,$filter=false,
}
if ($no_return) {
$sRead = '';
- }
- $results .= $sRead;
- }
- if (!$results && !$bFinished) {
- $sRead = fread($imap_stream,($iSize - ($iRetrieved)));
- if ($filter) {
- $filter($sRead);
+ } else {
+ $results .= $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;
}
+/**
+ * Obsolete function, inform plugins that use it
+ * @deprecated use sqimap_run_command or sqimap_run_command_list instead
+ */
+function sqimap_read_data_list($imap_stream, $tag, $handle_errors,
+ &$response, &$message, $query = '') {
+ global $color, $squirrelmail_language;
+ set_up_language($squirrelmail_language);
+ require_once(SM_PATH . 'functions/display_messages.php');
+ $string = "\n" .
+ _("ERROR : Bad function call.") .
+ "
\n" .
+ _("Reason:") . ' '.
+ 'There is a plugin installed which make use of the
' .
+ 'SquirrelMail internal function sqimap_read_data_list.
'.
+ 'Please adapt the installed plugin and let it use
'.
+ 'sqimap_run_command or sqimap_run_command_list instead
'.
+ 'The following query was issued:
'.
+ htmlspecialchars($query) . '
' . "
\n";
+ error_box($string,$color);
+ echo '