X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=functions%2Fimap_mailbox.php;h=18af1782f7a42f8626a45d390e35f31862d99c7e;hb=c359d4a2a5c4685c7915b60b673b3872b0403838;hp=892c0f56528e739e4be1c055c90f7e180b2b3841;hpb=cc82c2b7f25b4635b52931b4682371b326cbe853;p=squirrelmail.git diff --git a/functions/imap_mailbox.php b/functions/imap_mailbox.php index 892c0f56..18af1782 100755 --- a/functions/imap_mailbox.php +++ b/functions/imap_mailbox.php @@ -24,7 +24,7 @@ global $boxesnew; */ class mailboxes { - var $mailboxname_full = '', $mailboxname_sub= '', $is_noselect = false, + var $mailboxname_full = '', $mailboxname_sub= '', $is_noselect = false, $is_noinferiors = false, $is_special = false, $is_root = false, $is_inbox = false, $is_sent = false, $is_trash = false, $is_draft = false, $mbxs = array(), $unseen = false, $total = false; @@ -79,8 +79,27 @@ function sortSpecialMbx($a, $b) { } else { $bcmp = '2' . $b->mailboxname_full; } - if ($acmp == $bcmp) return 0; - return ($acmp > $bcmp) ? 1: -1; + return user_strcasecmp($acmp, $bcmp); +} + +function compact_mailboxes_response($ary) +{ + /* + * Workaround for mailboxes returned as literal + * FIXME : Doesn't work if the mailbox name is multiple lines + * (larger then fgets buffer) + */ + for ($i = 0, $iCnt=count($ary); $i < $iCnt; $i++) { + if (isset($ary[$i + 1]) && substr($ary[$i], -3) == "}\r\n") { + if (ereg("^(\\* [A-Z]+.*)\\{[0-9]+\\}([ \n\r\t]*)$", + $ary[$i], $regs)) { + $ary[$i] = $regs[1] . '"' . addslashes(trim($ary[$i+1])) . '"' . $regs[2]; + array_splice($ary, $i+1, 2); + } + } + } + /* remove duplicates and ensure array is contiguous */ + return array_values(array_unique($ary)); } /* @@ -107,37 +126,14 @@ function find_mailbox_name($line) return ''; } -function encode_mailbox_name($what) -{ - if (ereg("[\"\\\r\n]", $what)) - return '{' . strlen($what) . "}\r\n" . $what; /* 4.3 literal form */ - return '"' . $what . '"'; /* 4.3 quoted string form */ -} - -function compact_mailboxes_response($ary) -{ - /* - * Workaround for mailboxes returned as literal - * FIXME : Doesn't work if the mailbox name is multiple lines - * (larger then fgets buffer) - */ - for ($i = 0; $i < count($ary); $i++) { - if (isset($ary[$i + 1]) && substr($ary[$i], -3) == "}\r\n") { - if (ereg("^(\\* [A-Z]+.*)\\{[0-9]+\\}([ \n\r\t]*)$", - $ary[$i], $regs)) { - $ary[$i] = $regs[1] . '"' . addslashes(trim($ary[$i+1])) . '"' . $regs[2]; - array_splice($ary, $i+1, 2); - } - } - } - /* remove duplicates and ensure array is contiguous */ - return array_values(array_unique($ary)); -} - function check_is_noselect ($lsub_line) { return preg_match("/^\* (LSUB|LIST) \([^\)]*\\\\Noselect[^\)]*\)/i", $lsub_line); } +function check_is_noinferiors ($lsub_line) { + return preg_match("/^\* (LSUB|LIST) \([^\)]*\\\\Noinferiors[^\)]*\)/i", $lsub_line); +} + /** * If $haystack is a full mailbox name, and $needle is the mailbox * separator character, returns the second last part of the full @@ -182,9 +178,6 @@ function isBoxBelow( $subbox, $parentbox ) { /* Defines special mailboxes */ function isSpecialMailbox( $box ) { - global $trash_folder, $sent_folder, $draft_folder, - $move_to_trash, $move_to_sent, $save_as_draft; - $ret = ( (strtolower($box) == 'inbox') || isTrashMailbox($box) || isSentMailbox($box) || isDraftMailbox($box) ); @@ -243,7 +236,7 @@ function sqimap_mailbox_exists ($imap_stream, $mailbox) { if (!isset($mailbox) || empty($mailbox)) { return false; } - $mbx = sqimap_run_command($imap_stream, 'LIST "" ' . encode_mailbox_name($mailbox), + $mbx = sqimap_run_command($imap_stream, 'LIST "" ' . sqimap_encode_mailbox_name($mailbox), true, $response, $message); return isset($mbx[0]); } @@ -256,7 +249,7 @@ function sqimap_mailbox_select ($imap_stream, $mailbox) { return; } - $read = sqimap_run_command($imap_stream, 'SELECT ' . encode_mailbox_name($mailbox), + $read = sqimap_run_command($imap_stream, 'SELECT ' . sqimap_encode_mailbox_name($mailbox), true, $response, $message); $result = array(); for ($i = 0, $cnt = count($read); $i < $cnt; $i++) { @@ -291,27 +284,27 @@ function sqimap_mailbox_create ($imap_stream, $mailbox, $type) { $mailbox .= $delimiter; } - $read_ary = sqimap_run_command($imap_stream, 'CREATE ' . encode_mailbox_name($mailbox), + $read_ary = sqimap_run_command($imap_stream, 'CREATE ' . sqimap_encode_mailbox_name($mailbox), true, $response, $message); sqimap_subscribe ($imap_stream, $mailbox); } /* Subscribes to an existing folder */ function sqimap_subscribe ($imap_stream, $mailbox) { - $read_ary = sqimap_run_command($imap_stream, 'SUBSCRIBE ' . encode_mailbox_name($mailbox), + $read_ary = sqimap_run_command($imap_stream, 'SUBSCRIBE ' . sqimap_encode_mailbox_name($mailbox), true, $response, $message); } /* Unsubscribes to an existing folder */ function sqimap_unsubscribe ($imap_stream, $mailbox) { - $read_ary = sqimap_run_command($imap_stream, 'UNSUBSCRIBE ' . encode_mailbox_name($mailbox), + $read_ary = sqimap_run_command($imap_stream, 'UNSUBSCRIBE ' . sqimap_encode_mailbox_name($mailbox), true, $response, $message); } /* Deletes the given folder */ function sqimap_mailbox_delete ($imap_stream, $mailbox) { global $data_dir, $username; - $read_ary = sqimap_run_command($imap_stream, 'DELETE ' . encode_mailbox_name($mailbox), + $read_ary = sqimap_run_command($imap_stream, 'DELETE ' . sqimap_encode_mailbox_name($mailbox), true, $response, $message); sqimap_unsubscribe ($imap_stream, $mailbox); do_hook_function('rename_or_delete_folder', $args = array($mailbox, 'delete', '')); @@ -342,7 +335,7 @@ function sqimap_mailbox_rename( $imap_stream, $old_name, $new_name ) { } $boxesall = sqimap_mailbox_list($imap_stream); - $cmd = 'RENAME ' . encode_mailbox_name($old_name) . ' ' . encode_mailbox_name($new_name); + $cmd = 'RENAME ' . sqimap_encode_mailbox_name($old_name) . ' ' . sqimap_encode_mailbox_name($new_name); $data = sqimap_run_command($imap_stream, $cmd, true, $response, $message); sqimap_unsubscribe($imap_stream, $old_name.$postfix); $oldpref = getPref($data_dir, $username, 'thread_'.$old_name.$postfix); @@ -374,9 +367,9 @@ function sqimap_mailbox_rename( $imap_stream, $old_name, $new_name ) { } /* - * Formats a mailbox into 4 parts for the $boxesall array + * Formats a mailbox into parts for the $boxesall array * - * The four parts are: + * The parts are: * * raw - Raw LIST/LSUB response from the IMAP server * formatted - nicely formatted folder name @@ -397,7 +390,7 @@ function sqimap_mailbox_parse ($line, $line_lsub) { } /* Count number of delimiters ($delimiter) in folder name */ - $mailbox = trim($line_lsub[$g]); + $mailbox = /*trim(*/$line_lsub[$g]/*)*/; $dm_count = substr_count($mailbox, $delimiter); if (substr($mailbox, -1) == $delimiter) { /* If name ends in delimiter, decrement count by one */ @@ -519,14 +512,14 @@ function sqimap_mailbox_option_list($imap_stream, $show_selected = 0, $folder_sk $box2 = $boxes_part['formatted']; break; default: /* default, long names, style = 0 */ - $box2 = str_replace(' ', ' ', imap_utf7_decode_local($boxes_part['unformatted-disp'])); + $box2 = str_replace(' ', ' ', htmlspecialchars(imap_utf7_decode_local($boxes_part['unformatted-disp']))); break; } } if ($show_selected != 0 && in_array($lowerbox, $show_selected) ) { - $mbox_options .= '' . "\n"; + $mbox_options .= '' . "\n"; } else { - $mbox_options .= '' . "\n"; + $mbox_options .= '' . "\n"; } } } @@ -590,7 +583,7 @@ function sqimap_mailbox_list($imap_stream) { $mbx = $sorted_lsub_ary[$i]; } $mbx = stripslashes($mbx); - $read = sqimap_run_command ($imap_stream, 'LIST "" ' . encode_mailbox_name($mbx), + $read = sqimap_run_command ($imap_stream, 'LIST "" ' . sqimap_encode_mailbox_name($mbx), true, $response, $message); $read = compact_mailboxes_response($read); if (isset($read[0])) { @@ -604,7 +597,7 @@ function sqimap_mailbox_list($imap_stream) { * we'll get it for them anyway */ if (!$inbox_subscribed) { - $inbox_ary = sqimap_run_command ($imap_stream, 'LIST "" ' . encode_mailbox_name('INBOX'), + $inbox_ary = sqimap_run_command ($imap_stream, 'LIST "" INBOX', true, $response, $message); $sorted_list_ary[] = implode('', compact_mailboxes_response($inbox_ary)); $sorted_lsub_ary[] = find_mailbox_name($inbox_ary[0]); @@ -642,6 +635,7 @@ function sqimap_mailbox_list($imap_stream) { } } } + return $boxesnew; } @@ -726,6 +720,7 @@ function sqimap_mailbox_tree($imap_stream) { $inbox_in_list = false; $inbox_subscribed = false; $noselect = false; + $noinferiors = false; require_once(SM_PATH . 'include/load_prefs.php'); @@ -738,14 +733,15 @@ function sqimap_mailbox_tree($imap_stream) { $has_inbox = false; for ($i = 0, $cnt = count($lsub_ary); $i < $cnt; $i++) { - if (preg_match("/^\*\s+LSUB\s+(.*)\"?INBOX\"?[^(\/\.)].*$/",$lsub_ary[$i])) { + if (preg_match("/^\*\s+LSUB\s+(.*)\"?INBOX\"?[^(\/\.)].*$/i",$lsub_ary[$i])) { + $lsub_ary[$i] = strtoupper($lsub_ary[$i]); $has_inbox = true; break; } } if ($has_inbox == false) { - $lsub_ary[] = '* LSUB () "' . $folder_prefix . '" INBOX'; + $lsub_ary[] = '* LSUB () NIL INBOX'; } /* @@ -761,11 +757,12 @@ function sqimap_mailbox_tree($imap_stream) { // only do the noselect test if !uw, is checked later. FIX ME see conf.pl setting if ($imap_server_type != "uw") { $noselect = check_is_noselect($lsub_ary[$i]); + $noinferiors = check_is_noinferiors($lsub_ary[$i]); } if (substr($mbx, -1) == $delimiter) { $mbx = substr($mbx, 0, strlen($mbx) - 1); } - $sorted_lsub_ary[] = array ('mbx' => $mbx, 'noselect' => $noselect); + $sorted_lsub_ary[] = array ('mbx' => $mbx, 'noselect' => $noselect, 'noinferiors' => $noinferiors); } // FIX ME this requires a config setting inside conf.pl instead of checking on server type if ($imap_server_type == "uw") { @@ -774,7 +771,7 @@ function sqimap_mailbox_tree($imap_stream) { // prepare an array with queries foreach ($sorted_lsub_ary as $aMbx) { $mbx = stripslashes($aMbx['mbx']); - sqimap_prepare_pipelined_query('LIST "" ' . encode_mailbox_name($mbx), $tag, $aQuery, false); + sqimap_prepare_pipelined_query('LIST "" ' . sqimap_encode_mailbox_name($mbx), $tag, $aQuery, false); $aTag[$tag] = $mbx; } $sorted_lsub_ary = array(); @@ -784,7 +781,8 @@ function sqimap_mailbox_tree($imap_stream) { if ($aServerResponse[$tag] == 'OK') { $sResponse = implode('', $aResponse[$tag]); $noselect = check_is_noselect($sResponse); - $sorted_lsub_ary[] = array ('mbx' => $mbx, 'noselect' => $noselect); + $noinferiors = check_is_noinferiors($sResponse); + $sorted_lsub_ary[] = array ('mbx' => $mbx, 'noselect' => $noselect, 'noinferiors' => $noinferiors); } } $cnt = count($sorted_lsub_ary); @@ -831,16 +829,28 @@ function sqimap_fill_mailbox_tree($mbx_ary, $mbxs=false,$imap_stream) { $mbx = new mailboxes(); $mailbox = $mbx_ary[$i]['mbx']; - /* @@@ FIXME @@@ + /* sent subfolders messes up using existing code as subfolders were marked, but the parents were ordered somewhere else in the list, despite having "special folders at top" option set. Need a better method than this. + */ +/* + if ($mailbox == 'INBOX') { + $mbx->is_special = true; + } elseif (stristr($trash_folder , $mailbox)) { + $mbx->is_special = true; + } elseif (stristr($sent_folder , $mailbox)) { + $mbx->is_special = true; + } elseif (stristr($draft_folder , $mailbox)) { + $mbx->is_special = true; + } switch ($mailbox) { case 'INBOX': $mbx->is_inbox = true; $mbx->is_special = true; + $mbx_ary[$i]['noselect'] = false; break; case $trash_folder: $mbx->is_trash = true; @@ -855,25 +865,14 @@ function sqimap_fill_mailbox_tree($mbx_ary, $mbxs=false,$imap_stream) { $mbx->is_special = true; break; } +*/ + $mbx->is_special |= ($mbx->is_inbox = (strtoupper($mailbox) == 'INBOX')); + $mbx->is_special |= ($mbx->is_trash = isTrashMailbox($mailbox)); + $mbx->is_special |= ($mbx->is_sent = isSentMailbox($mailbox)); + $mbx->is_special |= ($mbx->is_draft = isDraftMailbox($mailbox)); + if (!$mbx->is_special) + $mbx->is_special = do_hook_function('special_mailbox', $mailbox); - /FIXME/ - */ - - if ($mailbox == 'INBOX') { - $mbx->is_inbox = true; - $mbx->is_special = true; - } elseif (stristr($trash_folder , $mailbox)) { - $mbx->is_trash = true; - $mbx->is_special = true; - } elseif (stristr($sent_folder , $mailbox)) { - $mbx->is_sent = true; - $mbx->is_special = true; - } elseif (stristr($draft_folder , $mailbox)) { - $mbx->is_draft = true; - $mbx->is_special = true; - } - - if (isset($mbx_ary[$i]['unseen'])) { $mbx->unseen = $mbx_ary[$i]['unseen']; } @@ -882,6 +881,7 @@ function sqimap_fill_mailbox_tree($mbx_ary, $mbxs=false,$imap_stream) { } $mbx->is_noselect = $mbx_ary[$i]['noselect']; + $mbx->is_noinferiors = $mbx_ary[$i]['noinferiors']; $r_del_pos = strrpos($mbx_ary[$i]['mbx'], $delimiter); if ($r_del_pos) { @@ -955,9 +955,9 @@ function sqimap_get_status_mbx_tree($imap_stream,&$mbx_tree) { $mbx = $oMbx->mailboxname_full; if ($unseen_type == 2 || ($move_to_trash && $oMbx->mailboxname_full == $trash_folder)) { - $query = 'STATUS ' . encode_mailbox_name($mbx) . ' (MESSAGES UNSEEN)'; + $query = 'STATUS ' . sqimap_encode_mailbox_name($mbx) . ' (MESSAGES UNSEEN)'; } else { - $query = 'STATUS ' . encode_mailbox_name($mbx) . ' (UNSEEN)'; + $query = 'STATUS ' . sqimap_encode_mailbox_name($mbx) . ' (UNSEEN)'; } sqimap_prepare_pipelined_query($query,$tag,$aQuery,false); } else {