X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=functions%2Fimap_general.php;h=8a117dec5ef07e0e478fd562d95da6d594239822;hb=8d8da447778a43b78bc95f9601b385416ad84477;hp=a672b574e303d2a0391fb6d3554f056191323ad7;hpb=b8c285abc93c2ec5e346ba7a8af05fb87ac2b3c4;p=squirrelmail.git
diff --git a/functions/imap_general.php b/functions/imap_general.php
index a672b574..8a117dec 100755
--- a/functions/imap_general.php
+++ b/functions/imap_general.php
@@ -3,197 +3,707 @@
/**
* imap_general.php
*
- * Copyright (c) 1999-2002 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
*/
-require_once('../functions/page_header.php');
+/** Includes.. */
+require_once(SM_PATH . 'functions/page_header.php');
+require_once(SM_PATH . 'functions/auth.php');
-global $sqimap_session_id;
-$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;
+/**
+ * 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;
+
if (!$unique_id) {
- return( sprintf("A%03d", $sqimap_session_id++) );
+ return( sprintf("A%03d", $sqimap_session_id++) );
} else {
- return( sprintf("A%03d", $sqimap_session_id++) . ' UID' );
+ return( sprintf("A%03d", $sqimap_session_id++) . ' UID' );
}
}
-/*
+/**
* Both send a command and accept the result from the command.
* This is to allow proper session number handling.
*/
function sqimap_run_command_list ($imap_stream, $query, $handle_errors, &$response, &$message, $unique_id = false) {
- $sid = sqimap_session_id($unique_id);
- fputs ($imap_stream, $sid . ' ' . $query . "\r\n");
- $read = sqimap_read_data_list ($imap_stream, $sid, $handle_errors, $response, $message, $query );
- return $read;
+ 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_retrieve_imap_response ($imap_stream, $tag, $handle_errors, $response, $message, $query );
+ /* get the response and the message */
+ $message = $message[$tag];
+ $response = $response[$tag];
+ 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_run_command ($imap_stream, $query, $handle_errors, &$response, &$message, $unique_id = 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);
+ 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 {
+ 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);
- fputs ($imap_stream, $sid . ' ' . $query . "\r\n");
- $read = sqimap_read_data ($imap_stream, $sid, $handle_errors, $response, $message, $query);
- return $read;
+ $tag_uid_a = explode(' ',trim($sid));
+ $tag = $tag_uid_a[0];
+ $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) {
+ $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;
+ // array_chunk would also do the job but it's supported from php > 4.2
+ $aQueryChunks = array();
+ $iLoops = floor($iQueryCount / $iChunkSize);
+
+ if ($iLoops * $iChunkSize != $iQueryCount) ++$iLoops;
+
+ if (!function_exists('array_chunk')) { // arraychunk replacement
+ 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;
+ }
+ } else {
+ $aQueryChunks = array_chunk($aQueryList,$iChunkSize,true);
+ }
-/*
- * custom fgets function. gets a line from IMAP
- * no matter how big it may be
- */
+ for ($i=0;$i<$iLoops;++$i) {
+ $aQuery = $aQueryChunks[$i];
+ foreach($aQuery as $tag => $query) {
+ fputs($imap_stream,$query);
+ $aResults[$tag] = false;
+ }
+ foreach($aQuery as $tag => $query) {
+ 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)) {
+ $aResults[$returned_tag] = $aResponse[0];
+ } else {
+ $aResults[$returned_tag] = $aResponse;
+ }
+ $aServerResponse[$returned_tag] = $response[$returned_tag];
+ $aServerMessage[$returned_tag] = $message[$returned_tag];
+ }
+ }
+ }
+ }
+ return $aResults;
+}
+/**
+ * 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;
$results = '';
- while (strpos($read, "\n") === false) {
+ $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 {
+ // see php bug 24033. They changed fread behaviour %$^&$%
+ $iBufferSize = 7800; // multiple of 78 in case of base64 decoding.
+ }
+ if ($iSize < $iBufferSize) {
+ $iBufferSize = $iSize;
+ }
+
+ $iRetrieved = 0;
+ $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;
+ }
+ if ($sReadRem != '') {
+ $sRead = $sReadRem . $sRead;
+ $sReadRem = '';
+ }
+
+ if ($filter && $sRead != '') {
+ // in case the filter is base64 decoding we return a remainder
+ $sReadRem = $filter($sRead);
+ }
+ if ($outputstream && $sRead != '') {
+ if (is_resource($outputstream)) {
+ fwrite($outputstream,$sRead);
+ } else if ($outputstream == 'php://stdout') {
+ echo $sRead;
+ }
+ }
+ if ($no_return) {
+ $sRead = '';
+ } else {
+ $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 '