}
-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");
- $read = sqimap_read_data ($imap_stream, $sid, $handle_errors, $response, $message, $query);
+ $read = sqimap_read_data ($imap_stream, $sid, $handle_errors, $response,
+ $message, $query,$filter,$outputstream,$no_return);
return $read;
} else {
global $squirrelmail_language, $color;
return $results;
}
+function sqimap_fread($imap_stream,$iSize,$filter=false,
+ $outputstream=false, $no_return=false) {
+ if (!$filter || !$outputstream) {
+ $iBufferSize = $iSize;
+ } else {
+ $iBufferSize = 32768;
+ }
+ $iRet = $iSize - $iBufferSize;
+ $i = 0;
+ $results = '';
+ while (($i * $iBufferSize) < $iRet) {
+ $sRead = fread($imap_stream,$iBufferSize);
+ if (!$sRead) {
+ $results = false;
+ break;
+ }
+ ++$i;
+ if ($filter) {
+ $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 !== false) {
+ $sRead = fread($imap_stream,($iSize - ($i * $iBufferSize)));
+ 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_uid, $handle_errors, &$response, &$message, $query = '') {
+function sqimap_read_data_list ($imap_stream, $tag_uid, $handle_errors,
+ &$response, &$message, $query = '',
+ $filter = false, $outputstream = false, $no_return = false) {
global $color, $squirrelmail_language;
$read = '';
$tag_uid_a = explode(' ',trim($tag_uid));
$j = strrpos($read,'{');
$iLit = substr($read,$j+1,-3);
$fetch_data[] = $read;
- $sLiteral = fread($imap_stream,$iLit);
+ $sLiteral = sqimap_fread($imap_stream,$iLit,$filter,$outputstream,$no_return);
if ($sLiteral === false) { /* error */
break 4; /* while while switch while */
}
}
}
-function sqimap_read_data ($imap_stream, $tag_uid, $handle_errors, &$response, &$message, $query = '') {
- $res = sqimap_read_data_list($imap_stream, $tag_uid, $handle_errors, $response, $message, $query);
-
+function sqimap_read_data ($imap_stream, $tag_uid, $handle_errors,
+ &$response, &$message, $query = '',
+ $filter=false,$outputstream=false,$no_return=false) {
+ $res = sqimap_read_data_list($imap_stream, $tag_uid, $handle_errors,
+ $response, $message, $query,$filter,$outputstream,$no_return);
/* sqimap_read_data should be called for one response
but since it just calls sqimap_read_data_list which
handles multiple responses we need to check for that
require_once(SM_PATH . 'functions/imap.php');
require_once(SM_PATH . 'functions/attachment_common.php');
-/* --------------------------------------------------------------------------------- */
-/* MIME DECODING */
-/* --------------------------------------------------------------------------------- */
+/* -------------------------------------------------------------------------- */
+/* MIME DECODING */
+/* -------------------------------------------------------------------------- */
/* This function gets the structure of a message and stores it in the "message" class.
* It will return this object for use with all relevant header information and
/* Do a bit of error correction. If we couldn't find the entity id, just guess
* that it is the first one. That is usually the case anyway.
*/
+
if (!$ent_id) {
$cmd = "FETCH $id BODY[]";
} else {
function mime_print_body_lines ($imap_stream, $id, $ent_id=1, $encoding) {
global $uid_support;
- $sid = sqimap_session_id($uid_support);
/* Don't kill the connection if the browser is over a dialup
* and it would take over 30 seconds to download it.
* Don“t call set_time_limit in safe mode.
if (!ini_get('safe_mode')) {
set_time_limit(0);
}
- if ($uid_support) {
- $sid_s = substr($sid,0,strpos($sid, ' '));
+ /* in case of base64 encoded attachments, do not buffer them.
+ Instead, echo the decoded attachment directly to screen */
+ if (strtolower($encoding) == 'base64') {
+ if (!$ent_id) {
+ $query = "FETCH $id BODY[]";
+ } else {
+ $query = "FETCH $id BODY[$ent_id]";
+ }
+ sqimap_run_command($imap_stream,$query,true,$response,$message,$uid_support,'sqimap_base64_decode','php://stdout',true);
} else {
- $sid_s = $sid;
+ $body = mime_fetch_body ($imap_stream, $id, $ent_id);
+ echo decodeBody($body, $encoding);
}
- $body = mime_fetch_body ($imap_stream, $id, $ent_id);
- echo decodeBody($body, $encoding);
+ /*
+ TODO, use the same method for quoted printable.
+ However, I assume that quoted printable attachments aren't that large
+ so the performancegain / memory usage drop will be minimal.
+ If we decide to add that then we need to adapt sqimap_fread because
+ we need to split te result on \n and fread doesn't stop at \n. That
+ means we also should provide $results from sqimap_fread (by ref) to
+ te function and set $no_return to false. The $filter function for
+ quoted printable should handle unsetting of $results.
+ */
+ /*
+ TODO 2: find out how we write to the output stream php://stdout. fwrite
+ doesn't work because 'php://stdout isn't a stream.
+ */
+
return;
/*
fputs ($imap_stream, "$sid FETCH $id BODY[$ent_id]\r\n");
return $attachments;
}
+function sqimap_base64_decode(&$string) {
+ $string = base64_decode($string);
+}
+
/* This function decodes the body depending on the encoding type. */
function decodeBody($body, $encoding) {
global $show_html_default;