From 5c300c60ad0679960c4d9001f3637d4cd7ce04c5 Mon Sep 17 00:00:00 2001 From: stekkel Date: Thu, 3 Jul 2003 11:45:02 +0000 Subject: [PATCH] Hopefully fixed pipelined responses, I did something stupid and didn't test out of order reponses. Now it works. In imap_mailbox te array with mailbox objects wasn't create correctly. It contained double entries. That's fixed too. git-svn-id: https://svn.code.sf.net/p/squirrelmail/code/trunk/squirrelmail@5198 7612ce4b-ef26-0410-bec9-ea0150e637f0 --- functions/imap_general.php | 78 +++++++------- functions/imap_mailbox.php | 205 +++++++++++++++++++------------------ 2 files changed, 142 insertions(+), 141 deletions(-) diff --git a/functions/imap_general.php b/functions/imap_general.php index f8034018..3cbf3c7b 100755 --- a/functions/imap_general.php +++ b/functions/imap_general.php @@ -69,7 +69,7 @@ function sqimap_run_command ($imap_stream, $query, $handle_errors, &$response, /* retrieve the response and the message */ $response = $response[$tag]; $message = $message[$tag]; - + if (!empty($read[$tag])) { return $read[$tag][0]; } else { @@ -96,9 +96,9 @@ function sqimap_prepare_pipelined_query($new_query,&$tag,&$aQuery,$unique_id) { 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 @@ -112,18 +112,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 +134,18 @@ function sqimap_run_pipelined_command ($imap_stream, $aQueryList, $handle_errors fputs($imap_stream,$query); $aResults[$tag] = false; } - +// $aQuery = array_reverse($aQuery,true); foreach($aQuery as $tag => $query) { - if (!$aResults[$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]; } @@ -283,9 +283,9 @@ function sqimap_read_data_list($imap_stream, $tag, $handle_errors, _("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:
'. + '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 ''; @@ -308,7 +308,7 @@ function sqimap_retrieve_imap_response($imap_stream, $tag, $handle_errors, $resultlist = array(); $data = array(); $read = sqimap_fgets($imap_stream); - $i = 0; + $i = $k = 0; while ($read) { $char = $read{0}; switch ($char) @@ -328,7 +328,7 @@ function sqimap_retrieve_imap_response($imap_stream, $tag, $handle_errors, $arg = substr($s,0,$j); } $found_tag = substr($read,0,$i-1); - if ($arg && $found_tag==$tag) { + if ($found_tag) { switch ($arg) { case 'OK': @@ -341,8 +341,12 @@ function sqimap_retrieve_imap_response($imap_stream, $tag, $handle_errors, if (!empty($data)) { $resultlist[] = $data; } - $aResponse[$tag] = $resultlist; - break 3; /* switch switch while */ + $aResponse[$found_tag] = $resultlist; + $data = $resultlist = array(); + if ($found_tag == $tag) { + break 3; /* switch switch while */ + } + break; default: /* this shouldn't happen */ $response[$found_tag] = $arg; @@ -351,21 +355,17 @@ function sqimap_retrieve_imap_response($imap_stream, $tag, $handle_errors, $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 */ + $data = $resultlist = array(); + if ($found_tag == $tag) { + break 3; /* switch switch while */ + } } - break; } + $read = sqimap_fgets($imap_stream); + if ($read === false) { /* error */ + break 3; /* switch switch while */ + } + break; } // end case $tag{0} case '*': @@ -450,7 +450,7 @@ function sqimap_retrieve_imap_response($imap_stream, $tag, $handle_errors, $s = substr($read,-3); } while ($s === "}\r\n"); break 1; - } + } break; } // end case '*' } // end switch diff --git a/functions/imap_mailbox.php b/functions/imap_mailbox.php index e212d97a..223456d9 100755 --- a/functions/imap_mailbox.php +++ b/functions/imap_mailbox.php @@ -394,9 +394,9 @@ function sqimap_mailbox_parse ($line, $line_lsub) { $boxesall[$g]['flags'] = array(); if (isset($line[$g])) { ereg("\(([^)]*)\)",$line[$g],$regs); - // FIXME Flags do contain the \ character. \NoSelect \NoInferiors - // and $MDNSent <= last one doesn't have the \ - // It's better to follow RFC3501 instead of using our own naming. + // FIXME Flags do contain the \ character. \NoSelect \NoInferiors + // and $MDNSent <= last one doesn't have the \ + // It's better to follow RFC3501 instead of using our own naming. $flags = trim(strtolower(str_replace('\\', '',$regs[1]))); if ($flags) { $boxesall[$g]['flags'] = explode(' ', $flags); @@ -462,24 +462,24 @@ function sqimap_mailbox_option_list($imap_stream, $show_selected = 0, $folder_sk continue; } $lowerbox = strtolower($box); - // mailboxes are casesensitive => inbox.sent != inbox.Sent - // nevermind, to many dependencies this should be fixed! - + // mailboxes are casesensitive => inbox.sent != inbox.Sent + // nevermind, to many dependencies this should be fixed! + if (strtolower($box) == 'inbox') { // inbox is special and not casesensitive $box2 = _("INBOX"); } else { - switch ($shorten_box_names) - { - case 2: /* delimited, style = 2 */ + switch ($shorten_box_names) + { + case 2: /* delimited, style = 2 */ $box2 = str_replace('  ', '. ', $boxes_part['formatted']); - break; + break; case 1: /* indent, style = 1 */ $box2 = $boxes_part['formatted']; - break; + break; default: /* default, long names, style = 0 */ $box2 = str_replace(' ', ' ', imap_utf7_decode_local($boxes_part['unformatted-disp'])); - break; - } + break; + } } if ($show_selected != 0 && in_array($lowerbox, $show_selected) ) { $mbox_options .= '' . "\n"; @@ -523,14 +523,14 @@ function sqimap_mailbox_list($imap_stream) { /* * Workaround for mailboxes returned as literal * Doesn't work if the mailbox name is multiple lines - * (larger then fgets buffer) + * (larger then fgets buffer) */ if (isset($lsub_ary[$i + 1]) && substr($lsub_ary[$i],-3) == "}\r\n") { - if (ereg("^(\\* [A-Z]+.*)\\{[0-9]+\\}([ \n\r\t]*)$", + if (ereg("^(\\* [A-Z]+.*)\\{[0-9]+\\}([ \n\r\t]*)$", $lsub_ary[$i], $regs)) { - $i++; - $lsub_ary[$i] = $regs[1] . '"' . addslashes(trim($lsub_ary[$i])) . '"' . $regs[2]; - } + $i++; + $lsub_ary[$i] = $regs[1] . '"' . addslashes(trim($lsub_ary[$i])) . '"' . $regs[2]; + } } $temp_mailbox_name = find_mailbox_name($lsub_ary[$i]); $sorted_lsub_ary[] = $temp_mailbox_name; @@ -538,20 +538,20 @@ function sqimap_mailbox_list($imap_stream) { $inbox_subscribed = true; } } - /* remove duplicates */ - $sorted_lsub_ary = array_unique($sorted_lsub_ary); + /* remove duplicates */ + $sorted_lsub_ary = array_unique($sorted_lsub_ary); - /* natural sort mailboxes */ + /* natural sort mailboxes */ if (isset($sorted_lsub_ary)) { usort($sorted_lsub_ary, 'user_strcasecmp'); } - /* - * The LSUB response doesn't provide us information about \Noselect - * mail boxes. The LIST response does, that's why we need to do a LIST - * call to retrieve the flags for the mailbox + /* + * The LSUB response doesn't provide us information about \Noselect + * mail boxes. The LIST response does, that's why we need to do a LIST + * call to retrieve the flags for the mailbox * Note: according RFC2060 an imap server may provide \NoSelect flags in the LSUB response. * in other words, we cannot rely on it. - */ + */ $sorted_list_ary = array(); for ($i=0; $i < count($sorted_lsub_ary); $i++) { if (substr($sorted_lsub_ary[$i], -1) == $delimiter) { @@ -567,10 +567,10 @@ function sqimap_mailbox_list($imap_stream) { /* Another workaround for literals */ if (isset($read[1]) && substr($read[1],-3) == "}\r\n") { - if (ereg("^(\\* [A-Z]+.*)\\{[0-9]+\\}([ \n\r\t]*)$", + if (ereg("^(\\* [A-Z]+.*)\\{[0-9]+\\}([ \n\r\t]*)$", $read[0], $regs)) { - $read[0] = $regs[1] . '"' . addslashes(trim($read[1])) . '"' . $regs[2]; - } + $read[0] = $regs[1] . '"' . addslashes(trim($read[1])) . '"' . $regs[2]; + } } if (isset($read[0])) { @@ -589,11 +589,11 @@ function sqimap_mailbox_list($imap_stream) { true, $response, $message); /* Another workaround for literals */ if (isset($inbox_ary[1]) && substr($inbox_ary[0],-3) == "}\r\n") { - if (ereg("^(\\* [A-Z]+.*)\\{[0-9]+\\}([ \n\r\t]*)$", + if (ereg("^(\\* [A-Z]+.*)\\{[0-9]+\\}([ \n\r\t]*)$", $inbox_ary[0], $regs)) { - $inbox_ary[0] = $regs[1] . '"' . addslashes(trim($inbox_ary[1])) . + $inbox_ary[0] = $regs[1] . '"' . addslashes(trim($inbox_ary[1])) . '"' . $regs[2]; - } + } } $sorted_list_ary[] = $inbox_ary[0]; $sorted_lsub_ary[] = find_mailbox_name($inbox_ary[0]); @@ -606,12 +606,12 @@ function sqimap_mailbox_list($imap_stream) { /* Find INBOX */ $cnt = count($boxesall); - $used = array_pad($used,$cnt,false); + $used = array_pad($used,$cnt,false); for($k = 0; $k < $cnt; ++$k) { if (strtolower($boxesall[$k]['unformatted']) == 'inbox') { $boxesnew[] = $boxesall[$k]; $used[$k] = true; - break; + break; } } /* List special folders and their subfolders, if requested. */ @@ -621,8 +621,8 @@ function sqimap_mailbox_list($imap_stream) { $boxesnew[] = $boxesall[$k]; $used[$k] = true; } - } - } + } + } /* Rest of the folders */ for($k = 0; $k < $cnt; $k++) { @@ -779,28 +779,28 @@ function sqimap_mailbox_tree($imap_stream) { } $sorted_lsub_ary[] = array ('mbx' => $mbx, 'noselect' => $noselect); } - // FIX ME this requires a config setting inside conf.pl instead of checking on server type + // FIX ME this requires a config setting inside conf.pl instead of checking on server type if ($imap_server_type == "uw") { - $aQuery = array(); - $aTag = array(); - // prepare an array with queries - foreach ($sorted_lsub_ary as $aMbx) { - $mbx = $aMbx['mbx']; - $query = "LIST \"\" \"$mbx\""; + $aQuery = array(); + $aTag = array(); + // prepare an array with queries + foreach ($sorted_lsub_ary as $aMbx) { + $mbx = $aMbx['mbx']; + $query = "LIST \"\" \"$mbx\""; sqimap_prepare_pipelined_query($query,$tag,$aQuery,false); - $aTag[$tag] = $mbx; - } - $sorted_lsub_ary = array(); - // execute all the queries at once - $aResponse = sqimap_run_pipelined_command ($imap_stream, $aQuery, false, $aServerResponse, $aServerMessage); - foreach($aTag as $tag => $mbx) { - if ($aServerResponse[$tag] == 'OK') { - $sResponse = implode('', $aResponse[$tag]); - $noselect = check_is_noselect($sResponse); - $sorted_lsub_ary[] = array ('mbx' => $mbx, 'noselect' => $noselect); - } - } - $cnt = count($sorted_lsub_ary); + $aTag[$tag] = $mbx; + } + $sorted_lsub_ary = array(); + // execute all the queries at once + $aResponse = sqimap_run_pipelined_command ($imap_stream, $aQuery, false, $aServerResponse, $aServerMessage); + foreach($aTag as $tag => $mbx) { + if ($aServerResponse[$tag] == 'OK') { + $sResponse = implode('', $aResponse[$tag]); + $noselect = check_is_noselect($sResponse); + $sorted_lsub_ary[] = array ('mbx' => $mbx, 'noselect' => $noselect); + } + } + $cnt = count($sorted_lsub_ary); } $sorted_lsub_ary = array_values($sorted_lsub_ary); @@ -900,11 +900,12 @@ function sqimap_utf7_decode_mbx_tree(&$mbx_tree) { function sqimap_tree_to_ref_array(&$mbx_tree,&$aMbxs) { + if ($mbx_tree) $aMbxs[] =& $mbx_tree; if ($mbx_tree->mbxs) { $iCnt = count($mbx_tree->mbxs); for ($i=0;$i<$iCnt;++$i) { - $aMbxs[] =& sqimap_tree_to_ref_array($mbx_tree->mbxs[$i],$aMbxs); + sqimap_tree_to_ref_array($mbx_tree->mbxs[$i],$aMbxs); } } } @@ -935,66 +936,66 @@ function sqimap_get_status_mbx_tree($imap_stream,&$mbx_tree) { if($unseen_notify == 3) { $cnt = count($aMbxs); for($i=0;$i<$cnt;++$i) { - $oMbx =& $aMbxs[$i]; - if (!$oMbx->is_noselect) { + $oMbx =& $aMbxs[$i]; + if (!$oMbx->is_noselect) { $mbx = $oMbx->mailboxname_full; - if ($unseen_type == 2 || - ($move_to_trash && $oMbx->mailboxname_full == $trash_folder)) { - $query = "STATUS \"$mbx\" (MESSAGES UNSEEN)"; - } else { - $query = "STATUS \"$mbx\" (UNSEEN)"; - } + if ($unseen_type == 2 || + ($move_to_trash && $oMbx->mailboxname_full == $trash_folder)) { + $query = "STATUS \"$mbx\" (MESSAGES UNSEEN)"; + } else { + $query = "STATUS \"$mbx\" (UNSEEN)"; + } sqimap_prepare_pipelined_query($query,$tag,$aQuery,false); - } else { - $oMbx->unseen = $oMbx->total = false; - $tag = false; - } - $oMbx->tag = $tag; - $aMbxs[$i] =& $oMbx; + } else { + $oMbx->unseen = $oMbx->total = false; + $tag = false; + } + $oMbx->tag = $tag; + $aMbxs[$i] =& $oMbx; } // execute all the queries at once $aResponse = sqimap_run_pipelined_command ($imap_stream, $aQuery, false, $aServerResponse, $aServerMessage); $cnt = count($aMbxs); for($i=0;$i<$cnt;++$i) { - $oMbx =& $aMbxs[$i]; - $tag = $oMbx->tag; - if ($tag && $aServerResponse[$tag] == 'OK') { - $sResponse = implode('', $aResponse[$tag]); + $oMbx =& $aMbxs[$i]; + $tag = $oMbx->tag; + if ($tag && $aServerResponse[$tag] == 'OK') { + $sResponse = implode('', $aResponse[$tag]); if (preg_match('/UNSEEN\s+([0-9]+)/i', $sResponse, $regs)) { $oMbx->unseen = $regs[1]; } if (preg_match('/MESSAGES\s+([0-9]+)/i', $sResponse, $regs)) { $oMbx->total = $regs[1]; - } - } - unset($oMbx->tag); - } + } + } + unset($oMbx->tag); + } } else if ($unseen_notify == 2) { // INBOX only $cnt = count($aMbxs); for($i=0;$i<$cnt;++$i) { - $oMbx =& $aMbxs[$i]; - if (strtoupper($oMbx->mailboxname_full) == 'INBOX' || - ($move_to_trash && $oMbx->mailboxname_full == $trash_folder)) { - if ($unseen_type == 2 || - ($oMbx->mailboxname_full == $trash_folder && $move_to_trash)) { - $aStatus = sqimap_status_messages($imap_stream,$oMbx->mailboxname_full); - $oMbx->unseen = $aStatus['UNSEEN']; - $oMbx->total = $aStatus['MESSAGES']; - } else { - $oMbx->unseen = sqimap_unseen_messages($imap_stream,$oMbx->mailboxname_full); - } - $aMbxs[$i] =& $oMbx; - if (!$move_to_trash && $trash_folder) { - break; - } else { - // trash comes after INBOX - if ($oMbx->mailboxname_full == $trash_folder) { - break; - } - } - } - } - } + $oMbx =& $aMbxs[$i]; + if (strtoupper($oMbx->mailboxname_full) == 'INBOX' || + ($move_to_trash && $oMbx->mailboxname_full == $trash_folder)) { + if ($unseen_type == 2 || + ($oMbx->mailboxname_full == $trash_folder && $move_to_trash)) { + $aStatus = sqimap_status_messages($imap_stream,$oMbx->mailboxname_full); + $oMbx->unseen = $aStatus['UNSEEN']; + $oMbx->total = $aStatus['MESSAGES']; + } else { + $oMbx->unseen = sqimap_unseen_messages($imap_stream,$oMbx->mailboxname_full); + } + $aMbxs[$i] =& $oMbx; + if (!$move_to_trash && $trash_folder) { + break; + } else { + // trash comes after INBOX + if ($oMbx->mailboxname_full == $trash_folder) { + break; + } + } + } + } + } } ?> -- 2.25.1