/**
 * Selects a mailbox for header retrieval.
 * Cache control for message headers is embedded.
 *
 * @param resource $imapConnection imap socket handle
 * @param string   $mailbox mailbox to select and retrieve message headers from
 * @param array    $aConfig array with system config settings and incoming vars
 * @param array    $aProps mailbox specific properties
 * @return array   $aMailbox mailbox array with all relevant information
 * @author Marc Groot Koerkamp
 */
function sqm_api_mailbox_select($imapConnection, $mailbox, $aConfig, $aProps)
{
    /**
     * NB: retrieve this from the session before accessing this function
     * and make sure you write it back at the end of the script after
     * the aMailbox var is added so that the headers are added to the cache
     */
    global $mailbox_cache;
    /**
     * In case the properties arrays are empty set the defaults.
     */
    $aDefaultMbxPref = array();
    //                          MBX_PREF_SORT => 0,
    //                          MBX_PREF_LIMIT => 15,
    //                          MBX_PREF_AUTO_EXPUNGE => 0,
    //                          MBX_PREF_INTERNALDATE => 0
    //                           );
    /* array_merge doesn't work with integers as keys */
    //    foreach ($aDefaultMbxPref as $key => $value) {
    //        if (!isset($aProps[$key])) {
    //            $aProps[$key] = $value;
    //        }
    //    }
    $aDefaultConfigProps = array('allow_server_sort' => sqimap_capability($imapConnection, 'SORT'), 'user' => false, 'setindex' => 0, 'max_cache_size' => SQM_MAX_MBX_IN_CACHE);
    $aConfig = array_merge($aDefaultConfigProps, $aConfig);
    $iSetIndx = $aConfig['setindex'];
    $aMbxResponse = sqimap_mailbox_select($imapConnection, $mailbox);
    if ($mailbox_cache) {
        if (isset($mailbox_cache[$mailbox])) {
            $aCachedMailbox = $mailbox_cache[$mailbox];
        } else {
            $aCachedMailbox = false;
        }
        /* cleanup cache */
        if (count($mailbox_cache) > $aConfig['max_cache_size'] - 1) {
            $aTime = array();
            foreach ($mailbox_cache as $cachedmailbox => $aVal) {
                $aTime[$aVal['TIMESTAMP']] = $cachedmailbox;
            }
            if (ksort($aTime, SORT_NUMERIC)) {
                for ($i = 0, $iCnt = count($mailbox_cache); $i < $iCnt - $aConfig['max_cache_size']; ++$i) {
                    $sOldestMbx = array_shift($aTime);
                    /**
                     * Remove only the UIDSET and MSG_HEADERS from cache because those can
                     * contain large amounts of data.
                     */
                    if (isset($mailbox_cache[$sOldestMbx]['UIDSET'])) {
                        $mailbox_cache[$sOldestMbx]['UIDSET'] = false;
                    }
                    if (isset($mailbox_cache[$sOldestMbx]['MSG_HEADERS'])) {
                        $mailbox_cache[$sOldestMbx]['MSG_HEADERS'] = false;
                    }
                }
            }
        }
    } else {
        $aCachedMailbox = false;
    }
    /**
     * Deal with imap servers that do not return the required UIDNEXT or
     * UIDVALIDITY response
     * from a SELECT call (since rfc 3501 it's required).
     */
    if (!isset($aMbxResponse['UIDNEXT']) || !isset($aMbxResponse['UIDVALIDITY'])) {
        $aStatus = sqimap_status_messages($imapConnection, $mailbox, array('UIDNEXT', 'UIDVALIDITY'));
        $aMbxResponse['UIDNEXT'] = $aStatus['UIDNEXT'];
        $aMbxResponse['UIDVALIDTY'] = $aStatus['UIDVALIDITY'];
    }
    $aMailbox['UIDSET'][$iSetIndx] = false;
    $aMailbox['ID'] = false;
    $aMailbox['SETINDEX'] = $iSetIndx;
    if ($aCachedMailbox) {
        /**
         * Validate integrity of cached data
         */
        if ($aCachedMailbox['EXISTS'] == $aMbxResponse['EXISTS'] && $aMbxResponse['EXISTS'] && $aCachedMailbox['UIDVALIDITY'] == $aMbxResponse['UIDVALIDITY'] && $aCachedMailbox['UIDNEXT'] == $aMbxResponse['UIDNEXT'] && isset($aCachedMailbox['SEARCH'][$iSetIndx]) && (!isset($aConfig['search']) || $aCachedMailbox['SEARCH'][$iSetIndx] == $aConfig['search'])) {
            if (isset($aCachedMailbox['MSG_HEADERS'])) {
                $aMailbox['MSG_HEADERS'] = $aCachedMailbox['MSG_HEADERS'];
            }
            $aMailbox['ID'] = $aCachedMailbox['ID'];
            if (isset($aCachedMailbox['UIDSET'][$iSetIndx]) && $aCachedMailbox['UIDSET'][$iSetIndx]) {
                if (isset($aProps[MBX_PREF_SORT]) && $aProps[MBX_PREF_SORT] != $aCachedMailbox['SORT']) {
                    $newsort = $aProps[MBX_PREF_SORT];
                    $oldsort = $aCachedMailbox['SORT'];
                    /**
                     * If it concerns a reverse sort we do not need to invalidate
                     * the cached sorted UIDSET, a reverse is sufficient.
                     */
                    if ($newsort % 2 && $newsort + 1 == $oldsort || !($newsort % 2) && $newsort - 1 == $oldsort) {
                        $aMailbox['UIDSET'][$iSetIndx] = array_reverse($aCachedMailbox['UIDSET'][$iSetIndx]);
                    } else {
                        $server_sort_array = false;
                        $aMailbox['MSG_HEADERS'] = false;
                        $aMailbox['ID'] = false;
                    }
                    // store the new sort value in the mailbox pref
                    if ($aConfig['user']) {
                        // FIXME, in ideal situation, we write back the
                        // prefs at the end of the script
                        setUserPref($aConfig['user'], "pref_{$mailbox}", serialize($aProps));
                    }
                } else {
                    $aMailbox['UIDSET'][$iSetIndx] = $aCachedMailbox['UIDSET'][$iSetIndx];
                }
            }
        }
    }
    /**
     * Restore the offset in the paginator if no new offset is provided.
     */
    if (isset($aMailbox['UIDSET'][$iSetIndx]) && !isset($aConfig['offset']) && $aCachedMailbox['OFFSET']) {
        $aMailbox['OFFSET'] = $aCachedMailbox['OFFSET'];
        $aMailbox['PAGEOFFSET'] = $aCachedMailbox['PAGEOFFSET'];
    } else {
        $aMailbox['OFFSET'] = isset($aConfig['offset']) && $aConfig['offset'] ? $aConfig['offset'] - 1 : 0;
        $aMailbox['PAGEOFFSET'] = isset($aConfig['offset']) && $aConfig['offset'] ? $aConfig['offset'] : 1;
    }
    /**
     * Restore the showall value no new showall value is provided.
     */
    if (isset($aMailbox['UIDSET'][$iSetIndx]) && !isset($aConfig['showall']) && isset($aCachedMailbox['SHOWALL'][$iSetIndx]) && $aCachedMailbox['SHOWALL'][$iSetIndx]) {
        $aMailbox['SHOWALL'][$iSetIndx] = $aCachedMailbox['SHOWALL'][$iSetIndx];
    } else {
        $aMailbox['SHOWALL'][$iSetIndx] = isset($aConfig['showall']) && $aConfig['showall'] ? 1 : 0;
    }
    if (!isset($aProps[MBX_PREF_SORT]) && isset($aCachedMailbox['SORT'])) {
        $aMailbox['SORT'] = $aCachedMailbox['SORT'];
    } else {
        $aMailbox['SORT'] = isset($aProps[MBX_PREF_SORT]) ? $aProps[MBX_PREF_SORT] : 0;
    }
    if (!isset($aProps[MBX_PREF_LIMIT]) && isset($aCachedMailbox['LIMIT'])) {
        $aMailbox['LIMIT'] = $aCachedMailbox['LIMIT'];
    } else {
        $aMailbox['LIMIT'] = isset($aProps[MBX_PREF_LIMIT]) ? $aProps[MBX_PREF_LIMIT] : 15;
    }
    if (!isset($aProps[MBX_PREF_INTERNALDATE]) && isset($aCachedMailbox['INTERNALDATE'])) {
        $aMailbox['INTERNALDATE'] = $aCachedMailbox['INTERNALDATE'];
    } else {
        $aMailbox['INTERNALDATE'] = isset($aProps[MBX_PREF_INTERNALDATE]) ? $aProps[MBX_PREF_INTERNALDATE] : false;
    }
    if (!isset($aProps[MBX_PREF_AUTO_EXPUNGE]) && isset($aCachedMailbox['AUTO_EXPUNGE'])) {
        $aMailbox['AUTO_EXPUNGE'] = $aCachedMailbox['AUTO_EXPUNGE'];
    } else {
        $aMailbox['AUTO_EXPUNGE'] = isset($aProps[MBX_PREF_AUTO_EXPUNGE]) ? $aProps[MBX_PREF_AUTO_EXPUNGE] : false;
    }
    if (!isset($aConfig['allow_thread_sort']) && isset($aCachedMailbox['ALLOW_THREAD'])) {
        $aMailbox['ALLOW_THREAD'] = $aCachedMailbox['ALLOW_THREAD'];
    } else {
        $aMailbox['ALLOW_THREAD'] = isset($aConfig['allow_thread_sort']) ? $aConfig['allow_thread_sort'] : false;
    }
    if (!isset($aConfig['search']) && isset($aCachedMailbox['SEARCH'][$iSetIndx])) {
        $aMailbox['SEARCH'][$iSetIndx] = $aCachedMailbox['SEARCH'][$iSetIndx];
    } else {
        $aMailbox['SEARCH'][$iSetIndx] = isset($aConfig['search']) ? $aConfig['search'] : 'ALL';
    }
    if (!isset($aConfig['charset']) && isset($aCachedMailbox['CHARSET'][$iSetIndx])) {
        $aMailbox['CHARSET'][$iSetIndx] = $aCachedMailbox['CHARSET'][$iSetIndx];
    } else {
        $aMailbox['CHARSET'][$iSetIndx] = isset($aConfig['charset']) ? $aConfig['charset'] : 'US-ASCII';
    }
    $aMailbox['NAME'] = $mailbox;
    $aMailbox['EXISTS'] = $aMbxResponse['EXISTS'];
    $aMailbox['SEEN'] = isset($aMbxResponse['SEEN']) ? $aMbxResponse['SEEN'] : $aMbxResponse['EXISTS'];
    $aMailbox['RECENT'] = isset($aMbxResponse['RECENT']) ? $aMbxResponse['RECENT'] : 0;
    $aMailbox['UIDVALIDITY'] = $aMbxResponse['UIDVALIDITY'];
    $aMailbox['UIDNEXT'] = $aMbxResponse['UIDNEXT'];
    $aMailbox['PERMANENTFLAGS'] = $aMbxResponse['PERMANENTFLAGS'];
    $aMailbox['RIGHTS'] = $aMbxResponse['RIGHTS'];
    /* decide if we are thread sorting or not */
    if (!$aMailbox['ALLOW_THREAD']) {
        if ($aMailbox['SORT'] & SQSORT_THREAD) {
            $aMailbox['SORT'] -= SQSORT_THREAD;
        }
    }
    if ($aMailbox['SORT'] & SQSORT_THREAD) {
        $aMailbox['SORT_METHOD'] = 'THREAD';
        $aMailbox['THREAD_INDENT'] = $aCachedMailbox['THREAD_INDENT'];
    } else {
        if (isset($aConfig['allow_server_sort']) && $aConfig['allow_server_sort']) {
            $aMailbox['SORT_METHOD'] = 'SERVER';
            $aMailbox['THREAD_INDENT'] = false;
        } else {
            $aMailbox['SORT_METHOD'] = 'SQUIRREL';
            $aMailbox['THREAD_INDENT'] = false;
        }
    }
    /* set a timestamp for cachecontrol */
    $aMailbox['TIMESTAMP'] = time();
    return $aMailbox;
}
function sqimap_get_delimiter($imap_stream = false)
{
    global $sqimap_delimiter, $optional_delimiter;
    /* Use configured delimiter if set */
    if (!empty($optional_delimiter) && $optional_delimiter != 'detect') {
        return $optional_delimiter;
    }
    /* Do some caching here */
    if (!$sqimap_delimiter) {
        if (sqimap_capability($imap_stream, 'NAMESPACE')) {
            /*
             * According to something that I can't find, this is supposed to work on all systems
             * OS: This won't work in Courier IMAP.
             * OS: According to rfc2342 response from NAMESPACE command is:
             * OS: * NAMESPACE (PERSONAL NAMESPACES) (OTHER_USERS NAMESPACE) (SHARED NAMESPACES)
             * OS: We want to lookup all personal NAMESPACES...
             */
            $read = sqimap_run_command($imap_stream, 'NAMESPACE', true, $a, $b);
            if (eregi('\\* NAMESPACE +(\\( *\\(.+\\) *\\)|NIL) +(\\( *\\(.+\\) *\\)|NIL) +(\\( *\\(.+\\) *\\)|NIL)', $read[0], $data)) {
                if (eregi('^\\( *\\((.*)\\) *\\)', $data[1], $data2)) {
                    $pn = $data2[1];
                }
                $pna = explode(')(', $pn);
                while (list($k, $v) = each($pna)) {
                    $lst = explode('"', $v);
                    if (isset($lst[3])) {
                        $pn[$lst[1]] = $lst[3];
                    } else {
                        $pn[$lst[1]] = '';
                    }
                }
            }
            $sqimap_delimiter = $pn[0];
        } else {
            fputs($imap_stream, ". LIST \"INBOX\" \"\"\r\n");
            $read = sqimap_read_data($imap_stream, '.', true, $a, $b);
            $quote_position = strpos($read[0], '"');
            $sqimap_delimiter = substr($read[0], $quote_position + 1, 1);
        }
    }
    return $sqimap_delimiter;
}
/**
 * This function loops through a group of messages in the mailbox
 * and shows them to the user.
 *
 * @param resource $imapConnection
 * @param array    $aMailbox associative array with mailbox related vars
 * @param array    $aProps
 * @param int      $iError error code, 0 is no error
 */
function showMessagesForMailbox($imapConnection, &$aMailbox, $aProps, &$iError)
{
    global $PHP_SELF;
    global $boxes, $show_copy_buttons;
    $highlight_list = isset($aProps['config']['highlight_list']) ? $aProps['config']['highlight_list'] : false;
    $fancy_index_highlite = isset($aProps['config']['fancy_index_highlite']) ? $aProps['config']['fancy_index_highlite'] : true;
    $aColumnsDesc = isset($aProps['columns']) ? $aProps['columns'] : false;
    $iAccount = isset($aProps['account']) ? (int) $aProps['account'] : 0;
    $sMailbox = isset($aProps['mailbox']) ? $aProps['mailbox'] : false;
    $sTargetModule = isset($aProps['module']) ? $aProps['module'] : 'read_body';
    $show_flag_buttons = isset($aProps['config']['show_flag_buttons']) ? $aProps['config']['show_flag_buttons'] : true;
    /* allows to control copy button in function call. If array key is not set, code follows user preferences */
    if (isset($aProps['config']['show_copy_buttons'])) {
        $show_copy_buttons = $aProps['config']['show_copy_buttons'];
    }
    $lastTargetMailbox = isset($aProps['config']['lastTargetMailbox']) ? $aProps['config']['lastTargetMailbox'] : '';
    $aOrder = array_keys($aProps['columns']);
    $trash_folder = isset($aProps['config']['trash_folder']) && $aProps['config']['trash_folder'] ? $aProps['config']['trash_folder'] : false;
    $sent_folder = isset($aProps['config']['sent_folder']) && $aProps['config']['sent_folder'] ? $aProps['config']['sent_folder'] : false;
    $draft_folder = isset($aProps['config']['draft_folder']) && $aProps['config']['draft_folder'] ? $aProps['config']['draft_folder'] : false;
    $page_selector = isset($aProps['config']['page_selector']) ? $aProps['config']['page_selector'] : false;
    $page_selector_max = isset($aProps['config']['page_selector_max']) ? $aProps['config']['page_selector_max'] : 10;
    $color = $aProps['config']['color'];
    /*
     * Form ID
     */
    static $iFormId;
    if (!isset($iFormId)) {
        $iFormId = 1;
    } else {
        ++$iFormId;
    }
    // store the columns to fetch so we can pick them up in read_body
    // where we validate the cache.
    calcFetchColumns($aMailbox, $aProps);
    $iError = fetchMessageHeaders($imapConnection, $aMailbox);
    if ($iError) {
        return array();
    } else {
        $aMessages = prepareMessageList($aMailbox, $aProps);
    }
    $iSetIndx = $aMailbox['SETINDEX'];
    $iLimit = $aMailbox['SHOWALL'][$iSetIndx] ? $aMailbox['EXISTS'] : $aMailbox['LIMIT'];
    $iEnd = $aMailbox['PAGEOFFSET'] + ($iLimit - 1) < $aMailbox['EXISTS'] ? $aMailbox['PAGEOFFSET'] + $iLimit - 1 : $aMailbox['EXISTS'];
    $iNumberOfMessages = $aMailbox['TOTAL'][$iSetIndx];
    $iEnd = min($iEnd, $iNumberOfMessages);
    $php_self = $PHP_SELF;
    $urlMailbox = urlencode($aMailbox['NAME']);
    if (preg_match('/^(.+)\\?.+$/', $php_self, $regs)) {
        $source_url = $regs[1];
    } else {
        $source_url = $php_self;
    }
    $baseurl = $source_url . '?mailbox=' . urlencode($aMailbox['NAME']) . '&amp;account=' . $aMailbox['ACCOUNT'] . (strpos($source_url, 'src/search.php') ? '&amp;smtoken=' . sm_generate_security_token() : '');
    $where = urlencode($aMailbox['SEARCH'][$iSetIndx][0]);
    $what = urlencode($aMailbox['SEARCH'][$iSetIndx][1]);
    $baseurl .= '&amp;where=' . $where . '&amp;what=' . $what;
    /* build thread sorting links */
    $newsort = $aMailbox['SORT'];
    if (sqimap_capability($imapConnection, 'THREAD')) {
        if ($aMailbox['SORT'] & SQSORT_THREAD) {
            $newsort -= SQSORT_THREAD;
            $thread_name = _("Unthread View");
        } else {
            $thread_name = _("Thread View");
            $newsort = $aMailbox['SORT'] + SQSORT_THREAD;
        }
        $thread_link_uri = $baseurl . '&amp;srt=' . $newsort . '&amp;startMessage=1';
    } else {
        $thread_link_uri = '';
        $thread_name = '';
    }
    $sort = $aMailbox['SORT'];
    /* FIX ME ADD CHECKBOX CONTROL. No checkbox => no buttons */
    /* future admin control over displayable buttons */
    $aAdminControl = array('markFlagged' => 1, 'markUnflagged' => 1, 'markRead' => 1, 'markUnread' => 1, 'forward' => 1, 'delete' => 1, 'undeleteButton' => 1, 'bypass_trash' => 1, 'expungeButton' => 1, 'moveButton' => 1, 'copyButton' => 1);
    /* user prefs control */
    $aUserControl = array('markFlagged' => $show_flag_buttons, 'markUnflagged' => $show_flag_buttons, 'markRead' => 1, 'markUnread' => 1, 'forward' => 1, 'delete' => 1, 'undeleteButton' => 1, 'bypass_trash' => 1, 'expungeButton' => 1, 'moveButton' => 1, 'copyButton' => $show_copy_buttons);
    $showDelete = $aMailbox['RIGHTS'] != 'READ-ONLY' && in_array('\\deleted', $aMailbox['PERMANENTFLAGS'], true) ? true : false;
    $showByPassTrash = $aMailbox['AUTO_EXPUNGE'] && $aMailbox['RIGHTS'] != 'READ-ONLY' && in_array('\\deleted', $aMailbox['PERMANENTFLAGS'], true) && $trash_folder ? true : false;
    //
    $showUndelete = !$aMailbox['AUTO_EXPUNGE'] && $aMailbox['RIGHTS'] != 'READ-ONLY' && in_array('\\deleted', $aMailbox['PERMANENTFLAGS'], true) ? true : false;
    $showMove = $aMailbox['RIGHTS'] != 'READ-ONLY' ? true : false;
    $showExpunge = !$aMailbox['AUTO_EXPUNGE'] && $aMailbox['RIGHTS'] != 'READ-ONLY' && in_array('\\deleted', $aMailbox['PERMANENTFLAGS'], true) ? true : false;
    /* Button options that depend on IMAP server and selected folder */
    $aImapControl = array('markUnflagged' => in_array('\\flagged', $aMailbox['PERMANENTFLAGS'], true), 'markFlagged' => in_array('\\flagged', $aMailbox['PERMANENTFLAGS'], true), 'markRead' => in_array('\\seen', $aMailbox['PERMANENTFLAGS'], true), 'markUnread' => in_array('\\seen', $aMailbox['PERMANENTFLAGS'], true), 'forward' => 1, 'delete' => $showDelete, 'undeleteButton' => $showUndelete, 'bypass_trash' => $showByPassTrash, 'expungeButton' => $showExpunge, 'moveButton' => $showMove, 'copyButton' => 1);
    /* Button strings */
    $aButtonStrings = array('markFlagged' => _("Flag"), 'markUnflagged' => _("Unflag"), 'markRead' => _("Read"), 'markUnread' => _("Unread"), 'forward' => _("Forward"), 'delete' => _("Delete"), 'undeleteButton' => _("Undelete"), 'bypass_trash' => _("Bypass Trash"), 'expungeButton' => _("Expunge"), 'moveButton' => _("Move"), 'copyButton' => _("Copy"));
    /* Button access keys */
    global $accesskey_mailbox_flag, $accesskey_mailbox_unflag, $accesskey_mailbox_read, $accesskey_mailbox_unread, $accesskey_mailbox_forward, $accesskey_mailbox_delete, $accesskey_mailbox_undelete, $accesskey_mailbox_bypass_trash, $accesskey_mailbox_expunge, $accesskey_mailbox_move, $accesskey_mailbox_copy, $accesskey_mailbox_move_to;
    $aButtonAccessKeys = array('markFlagged' => $accesskey_mailbox_flag, 'markUnflagged' => $accesskey_mailbox_unflag, 'markRead' => $accesskey_mailbox_read, 'markUnread' => $accesskey_mailbox_unread, 'forward' => $accesskey_mailbox_forward, 'delete' => $accesskey_mailbox_delete, 'undeleteButton' => $accesskey_mailbox_undelete, 'bypass_trash' => $accesskey_mailbox_bypass_trash, 'expungeButton' => $accesskey_mailbox_expunge, 'moveButton' => $accesskey_mailbox_move, 'copyButton' => $accesskey_mailbox_copy);
    /**
     * Register buttons in order to an array
     * The key is the "name", the first element of the value array is the "value", second argument is the type.
     */
    $aFormElements = array();
    foreach ($aAdminControl as $k => $v) {
        if ($v & $aUserControl[$k] & $aImapControl[$k]) {
            switch ($k) {
                case 'markFlagged':
                case 'markUnflagged':
                case 'markRead':
                case 'markUnread':
                case 'delete':
                case 'undeleteButton':
                case 'expungeButton':
                case 'forward':
                    $aFormElements[$k] = array('value' => $aButtonStrings[$k], 'type' => 'submit', 'accesskey' => isset($aButtonAccessKeys[$k]) ? $aButtonAccessKeys[$k] : 'NONE');
                    break;
                case 'bypass_trash':
                    $aFormElements[$k] = array('value' => $aButtonStrings[$k], 'type' => 'checkbox', 'accesskey' => isset($aButtonAccessKeys[$k]) ? $aButtonAccessKeys[$k] : 'NONE');
                    break;
                case 'moveButton':
                case 'copyButton':
                    $aFormElements['targetMailbox'] = array('options_list' => sqimap_mailbox_option_list($imapConnection, array(strtolower($lastTargetMailbox)), 0, $boxes), 'type' => 'select', 'accesskey' => $accesskey_mailbox_move_to);
                    $aFormElements['mailbox'] = array('value' => $aMailbox['NAME'], 'type' => 'hidden');
                    $aFormElements['startMessage'] = array('value' => $aMailbox['PAGEOFFSET'], 'type' => 'hidden');
                    $aFormElements[$k] = array('value' => $aButtonStrings[$k], 'type' => 'submit', 'accesskey' => isset($aButtonAccessKeys[$k]) ? $aButtonAccessKeys[$k] : 'NONE');
                    break;
            }
        }
        $aFormElements['account'] = array('value' => $iAccount, 'type' => 'hidden');
    }
    do_hook('message_list_controls', $aFormElements);
    /*
     * This is the beginning of the message list table.
     * It wraps around all messages
     */
    $safe_name = preg_replace("/[^0-9A-Za-z_]/", '_', $aMailbox['NAME']);
    $form_name = "FormMsgs" . $safe_name;
    //if (!sqgetGlobalVar('align',$align,SQ_SESSION)) {
    $align = array('left' => 'left', 'right' => 'right');
    //}
    //sm_print_r($align);
    /* finally set the template vars */
    // FIXME, before we support multiple templates we must review the names of the vars
    // BUMP!
    $aTemplate['color'] = $color;
    $aTemplate['form_name'] = "FormMsgs" . $safe_name;
    $aTemplate['form_id'] = 'mbx_' . $iFormId;
    $aTemplate['page_selector'] = $page_selector;
    $aTemplate['page_selector_max'] = $page_selector_max;
    $aTemplate['messagesPerPage'] = $aMailbox['LIMIT'];
    $aTemplate['showall'] = $aMailbox['SHOWALL'][$iSetIndx];
    $aTemplate['end_msg'] = $iEnd;
    $aTemplate['align'] = $align;
    $aTemplate['iNumberOfMessages'] = $iNumberOfMessages;
    $aTemplate['aOrder'] = $aOrder;
    $aTemplate['aFormElements'] = $aFormElements;
    $aTemplate['sort'] = $sort;
    $aTemplate['pageOffset'] = $aMailbox['PAGEOFFSET'];
    $aTemplate['baseurl'] = $baseurl;
    $aTemplate['aMessages'] =& $aMessages;
    $aTemplate['trash_folder'] = $trash_folder;
    $aTemplate['sent_folder'] = $sent_folder;
    $aTemplate['draft_folder'] = $draft_folder;
    $aTemplate['thread_link_uri'] = $thread_link_uri;
    $aTemplate['thread_name'] = $thread_name;
    $aTemplate['php_self'] = str_replace('&', '&amp;', $php_self);
    $aTemplate['mailbox'] = $sMailbox;
    //FIXME: javascript_on is always assigned to the template object in places like init.php; is there some reason to reassign it here?  is there some chance that it was changed?  if not, please remove this line!
    $aTemplate['javascript_on'] = isset($aProps['config']['javascript_on']) ? $aProps['config']['javascript_on'] : false;
    $aTemplate['enablesort'] = isset($aProps['config']['enablesort']) ? $aProps['config']['enablesort'] : false;
    $aTemplate['icon_theme'] = isset($aProps['config']['icon_theme']) ? $aProps['config']['icon_theme'] : false;
    $aTemplate['use_icons'] = isset($aProps['config']['use_icons']) ? $aProps['config']['use_icons'] : false;
    $aTemplate['alt_index_colors'] = isset($aProps['config']['alt_index_colors']) ? $aProps['config']['alt_index_colors'] : false;
    $aTemplate['fancy_index_highlite'] = $fancy_index_highlite;
    /**
     * Set up sort possibilities; one could argue that this is best
     * placed in the template, but most template authors won't understand
     * or need to understand it, so some advanced templates can override 
     * it if they do something different.
     */
    if (!($aTemplate['sort'] & SQSORT_THREAD) && $aTemplate['enablesort']) {
        $aTemplate['aSortSupported'] = array(SQM_COL_SUBJ => array(SQSORT_SUBJ_ASC, SQSORT_SUBJ_DESC), SQM_COL_DATE => array(SQSORT_DATE_DESC, SQSORT_DATE_ASC), SQM_COL_INT_DATE => array(SQSORT_INT_DATE_DESC, SQSORT_INT_DATE_ASC), SQM_COL_FROM => array(SQSORT_FROM_ASC, SQSORT_FROM_DESC), SQM_COL_TO => array(SQSORT_TO_ASC, SQSORT_TO_DESC), SQM_COL_CC => array(SQSORT_CC_ASC, SQSORT_CC_DESC), SQM_COL_SIZE => array(SQSORT_SIZE_ASC, SQSORT_SIZE_DESC));
    } else {
        $aTemplate['aSortSupported'] = array();
    }
    /**
     * Figure out which columns should serve as labels for checkbox:
     * we try to grab the two columns before and after the checkbox,
     * except the subject column, since it is the link that opens
     * the message view
     *
     * if $javascript_on is set, then the highlighting code takes
     * care of this; just skip it
     *
     * This code also might be more appropriate in a template file, but
     * we are moving this complex stuff out of the way of template 
     * authors; advanced template sets are always free to override
     * the resultant values.
     *
     */
    $show_label_columns = array();
    $index_order_part = array();
    if (!($aTemplate['javascript_on'] && $aTemplate['fancy_index_highlite'])) {
        $get_next_two = 0;
        $last_order_part = 0;
        $last_last_order_part = 0;
        foreach ($aTemplate['aOrder'] as $index_order_part) {
            if ($index_order_part == SQM_COL_CHECK) {
                $get_next_two = 1;
                if ($last_last_order_part != SQM_COL_SUBJ) {
                    $show_label_columns[] = $last_last_order_part;
                }
                if ($last_order_part != SQM_COL_SUBJ) {
                    $show_label_columns[] = $last_order_part;
                }
            } else {
                if ($get_next_two > 0 && $get_next_two < 3 && $index_order_part != SQM_COL_SUBJ) {
                    $show_label_columns[] = $index_order_part;
                    $get_next_two++;
                }
            }
            $last_last_order_part = $last_order_part;
            $last_order_part = $index_order_part;
        }
    }
    $aTemplate['show_label_columns'] = $show_label_columns;
    return $aTemplate;
}
Example #4
0
}
$base_uri = sqm_baseuri();
/*
 * In case the last session was not terminated properly, make sure
 * we get a new one.
 */
sqsession_destroy();
header('Pragma: no-cache');
/**
 * This detects if the IMAP server has logins disabled, and if so, 
 * squelches the display of the login form and puts up a message
 * explaining the situation.
 */
if ($imap_auth_mech == 'login') {
    $imap = sqimap_create_stream($imapServerAddress, $imapPort, $use_imap_tls);
    $logindisabled = sqimap_capability($imap, 'LOGINDISABLED');
    sqimap_logout($imap);
    if ($logindisabled) {
        $string = _("The IMAP server is reporting that plain text logins are disabled.") . '<br />' . _("Using CRAM-MD5 or DIGEST-MD5 authentication instead may work.") . '<br />';
        if (!$use_imap_tls) {
            $string .= _("Also, the use of TLS may allow SquirrelMail to login.") . '<br />';
        }
        $string .= _("Please contact your system administrator and report this error.");
        error_box($string, $color);
        exit;
    }
}
do_hook('login_cookie');
/* Output the javascript onload function. */
$header = "<script language=\"JavaScript\" type=\"text/javascript\">\n" . "<!--\n" . "  function squirrelmail_loginpage_onload() {\n" . "    var textElements = 0;\n" . "    for (i = 0; i < document.forms[0].elements.length; i++) {\n" . "      if (document.forms[0].elements[i].type == \"text\" || document.forms[0].elements[i].type == \"password\") {\n" . "        textElements++;\n" . "        if (textElements == " . (isset($loginname) ? 2 : 1) . ") {\n" . "          document.forms[0].elements[i].focus();\n" . "          break;\n" . "        }\n" . "      }\n" . "    }\n" . "  }\n" . "// -->\n" . "</script>\n";
if (@file_exists($theme[$theme_default]['PATH'])) {
Example #5
0
        session_regenerate_id();
        // re-send session cookie so we get the right parameters on it
        // (such as HTTPOnly, if necessary - PHP doesn't do this itself
        sqsetcookie(session_name(), session_id(), false, $base_uri);
    }
    $onetimepad = OneTimePadCreate(strlen($secretkey));
    $key = OneTimePadEncrypt($secretkey, $onetimepad);
    sqsession_register($onetimepad, 'onetimepad');
    /* remove redundant spaces */
    $login_username = trim($login_username);
    /* Verify that username and password are correct. */
    if ($force_username_lowercase) {
        $login_username = strtolower($login_username);
    }
    $imapConnection = sqimap_login($login_username, $key, $imapServerAddress, $imapPort, 0);
    $sqimap_capabilities = sqimap_capability($imapConnection);
    sqsession_register($sqimap_capabilities, 'sqimap_capabilities');
    $delimiter = sqimap_get_delimiter($imapConnection);
    sqimap_logout($imapConnection);
    sqsession_register($delimiter, 'delimiter');
    $username = $login_username;
    sqsession_register($username, 'username');
    sqsetcookie('key', $key, 0, $base_uri);
    do_hook('login_verified');
}
/* Set the login variables. */
$user_is_logged_in = true;
$just_logged_in = true;
/* And register with them with the session. */
sqsession_register($user_is_logged_in, 'user_is_logged_in');
sqsession_register($just_logged_in, 'just_logged_in');
Example #6
0
/**
 * Retrieve long text string containing semi-formatted (simple text
 * with newlines and spaces for indentation) SquirrelMail system
 * specs
 *
 * @return array A three-element array, the first element containing
 *               the string of system specs, the second one containing 
 *               a list of any warnings that may have occurred, keyed
 *               by a warning "type" (which is used to key the corrections
 *               array next), and the third element of which is a list
 *               of sub-arrays keyed by warning "type": the sub-arrays
 *               are lists of correction messages associated with the
 *               warnings.  The second and third return elements may
 *               be empty arrays if no warnings were found.
 *
 * @since 1.5.2
 *
 */
function get_system_specs()
{
    //FIXME: configtest and this plugin should be using the same code to generate the basic SM system specifications and setup detection
    global $imapServerAddress, $username, $imapPort, $imap_server_type, $use_imap_tls, $ldap_server;
    // load required libraries
    //
    include_once SM_PATH . 'functions/imap_general.php';
    $browscap = ini_get('browscap');
    if (!empty($browscap)) {
        $browser = get_browser();
    }
    $warnings = array();
    $corrections = array();
    sqgetGlobalVar('HTTP_USER_AGENT', $HTTP_USER_AGENT, SQ_SERVER);
    if (!sqgetGlobalVar('HTTP_USER_AGENT', $HTTP_USER_AGENT, SQ_SERVER)) {
        $HTTP_USER_AGENT = "Browser information is not available.";
    }
    $body_top = "My browser information:\n" . '  ' . $HTTP_USER_AGENT . "\n";
    if (isset($browser)) {
        $body_top .= "  get_browser() information (List)\n" . Show_Array((array) $browser);
    }
    $body_top .= "\nMy web server information:\n" . "  PHP Version " . phpversion() . "\n" . "  PHP Extensions (List)\n" . Show_Array(get_loaded_extensions()) . "\nSquirrelMail-specific information:\n" . "  Version:  " . SM_VERSION . "\n" . "  Plugins (List)\n" . br_show_plugins() . "\n";
    if (!empty($ldap_server[0]) && $ldap_server[0] && !extension_loaded('ldap')) {
        $warnings['ldap'] = "LDAP server defined in SquirrelMail config, " . "but the module is not loaded in PHP";
        $corrections['ldap'][] = "Reconfigure PHP with the option '--with-ldap'";
        $corrections['ldap'][] = "Then recompile PHP and reinstall";
        $corrections['ldap'][] = "-- OR --";
        $corrections['ldap'][] = "Reconfigure SquirrelMail to not use LDAP";
    }
    $body = "\nMy IMAP server information:\n" . "  Server type:  {$imap_server_type}\n";
    $imapServerAddress = sqimap_get_user_server($imapServerAddress, $username);
    $imap_stream = sqimap_create_stream($imapServerAddress, $imapPort, $use_imap_tls);
    if ($imap_stream) {
        $body .= '  Capabilities: ';
        if ($imap_capabilities = sqimap_capability($imap_stream)) {
            foreach ($imap_capabilities as $capability => $value) {
                if (is_array($value)) {
                    foreach ($value as $val) {
                        $body .= $capability . "={$val} ";
                    }
                } else {
                    $body .= $capability . (is_bool($value) ? ' ' : "={$value} ");
                }
            }
        }
        $body .= "\n";
        sqimap_logout($imap_stream);
    } else {
        $body .= "  Unable to connect to IMAP server to get information.\n";
        $warnings['imap'] = "Unable to connect to IMAP server";
        $corrections['imap'][] = "Make sure you specified the correct mail server";
        $corrections['imap'][] = "Make sure the mail server is running IMAP, not POP";
        $corrections['imap'][] = "Make sure the server responds to port {$imapPort}";
    }
    $warning_num = 0;
    if (!empty($warnings)) {
        foreach ($warnings as $key => $value) {
            if ($warning_num == 0) {
                $body_top .= "WARNINGS WERE REPORTED WITH YOUR SETUP:\n";
                $body_top = "WARNINGS WERE REPORTED WITH YOUR SETUP -- SEE BELOW\n\n{$body_top}";
            }
            $warning_num++;
            $body_top .= "\n{$value}\n";
            foreach ($corrections[$key] as $corr_val) {
                $body_top .= "  * {$corr_val}\n";
            }
        }
        $body_top .= "\n{$warning_num} warning(s) reported.\n";
        $body_top .= "----------------------------------------------\n";
    }
    $body = $body_top . $body;
    return array($body, $warnings, $corrections);
}
Example #7
0
/**
 * Gets the list of mailboxes for sqimap_maolbox_tree and sqimap_mailbox_list
 *
 * This is because both of those functions had duplicated logic, but with slightly different
 * implementations. This will make both use the same implementation, which should make it
 * easier to maintain and easier to modify in the future
 * @param stream $imap_stream imap connection resource
 * @param bool $force force a reload and ignore cache
 * @param bool $show_only_subscribed controls listing of visible or all folders
 * @param bool $session_register controls registration of retrieved data in session.
 * @return object boxesnew - array of mailboxes and their attributes
 * @since 1.5.1
 */
function sqimap_get_mailboxes($imap_stream, $force = false, $show_only_subscribed = true, $session_register = true)
{
    global $show_only_subscribed_folders, $noselect_fix_enable, $folder_prefix, $list_special_folders_first, $imap_server_type;
    $inbox_subscribed = false;
    $listsubscribed = sqimap_capability($imap_stream, 'LIST-SUBSCRIBED');
    if ($show_only_subscribed) {
        $show_only_subscribed = $show_only_subscribed_folders;
    }
    //require_once(SM_PATH . 'include/load_prefs.php');
    /**
     * There are three main listing commands we can use in IMAP:
     * LSUB        shows just the list of subscribed folders
     *            may include flags, but these are not necessarily accurate or authoratative
     *            \NoSelect has special meaning: the folder does not exist -OR- it means this
     *            folder is not subscribed but children may be
     *            [RFC-2060]
     * LIST        this shows every mailbox on the system
     *            flags are always included and are accurate and authoratative
     *            \NoSelect means folder should not be selected
     *            [RFC-2060]
     * LIST (SUBSCRIBED)    implemented with LIST-SUBSCRIBED extension
     *            this is like list but returns only subscribed folders
     *            flag meanings are like LIST, not LSUB
     *            \NonExistent means mailbox doesn't exist
     *            \PlaceHolder means parent is not valid (selectable), but one or more children are
     *            \NoSelect indeed means that the folder should not be selected
     *            IMAPEXT-LIST-EXTENSIONS-04 August 2003 B. Leiba
     */
    if (!$show_only_subscribed) {
        $lsub = 'LIST';
        $sub_cache_name = 'list_cache';
    } elseif ($listsubscribed) {
        $lsub = 'LIST (SUBSCRIBED)';
        $sub_cache_name = 'listsub_cache';
    } else {
        $lsub = 'LSUB';
        $sub_cache_name = 'lsub_cache';
    }
    // Some IMAP servers allow subfolders to exist even if the parent folders do not
    // This fixes some problems with the folder list when this is the case, causing the
    // NoSelect folders to be displayed
    if ($noselect_fix_enable) {
        $lsub_args = "{$lsub} \"{$folder_prefix}\" \"*%\"";
        $list_args = "LIST \"{$folder_prefix}\" \"*%\"";
    } else {
        $lsub_args = "{$lsub} \"{$folder_prefix}\" \"*\"";
        $list_args = "LIST \"{$folder_prefix}\" \"*\"";
    }
    // get subscribed mailbox list from cache (session)
    // if not there, then get it from the imap server and store in cache
    if (!$force) {
        sqgetGlobalVar($sub_cache_name, $lsub_cache, SQ_SESSION);
    }
    $lsub_assoc_ary = array();
    if (!empty($lsub_cache)) {
        $lsub_assoc_ary = $lsub_cache;
    } else {
        $lsub_ary = sqimap_run_command($imap_stream, $lsub_args, true, $response, $message);
        $lsub_ary = compact_mailboxes_response($lsub_ary);
        if (!empty($lsub_ary)) {
            foreach ($lsub_ary as $rawline) {
                $temp_mailbox_name = find_mailbox_name($rawline);
                $lsub_assoc_ary[$temp_mailbox_name] = $rawline;
            }
            unset($lsub_ary);
            sqsession_register($lsub_assoc_ary, $sub_cache_name);
        }
    }
    // Now to get the mailbox flags
    // The LSUB response may return \NoSelect flags, etc. but it is optional
    // according to RFC3501, and even when returned it may not be accurate
    // or authoratative. LIST will always return accurate results.
    if ($lsub == 'LIST' || $lsub == 'LIST (SUBSCRIBED)') {
        // we've already done a LIST or LIST (SUBSCRIBED)
        // and NOT a LSUB, so no need to do it again
        $list_assoc_ary = $lsub_assoc_ary;
    } else {
        // we did a LSUB so now we need to do a LIST
        // first see if it is in cache
        $list_cache_name = 'list_cache';
        if (!$force) {
            sqgetGlobalVar($list_cache_name, $list_cache, SQ_SESSION);
        }
        if (!empty($list_cache)) {
            $list_assoc_ary = $list_cache;
            // we could store this in list_cache_name but not necessary
        } else {
            // not in cache so we need to go get it from the imap server
            $list_assoc_ary = array();
            $list_ary = sqimap_run_command($imap_stream, $list_args, true, $response, $message);
            $list_ary = compact_mailboxes_response($list_ary);
            if (!empty($list_ary)) {
                foreach ($list_ary as $rawline) {
                    $temp_mailbox_name = find_mailbox_name($rawline);
                    $list_assoc_ary[$temp_mailbox_name] = $rawline;
                }
                unset($list_ary);
                sqsession_register($list_assoc_ary, $list_cache_name);
            }
        }
    }
    // If they aren't subscribed to the inbox, then add it anyway (if its in LIST)
    $inbox_subscribed = false;
    if (!empty($lsub_assoc_ary)) {
        foreach ($lsub_assoc_ary as $temp_mailbox_name => $rawline) {
            if (strtoupper($temp_mailbox_name) == 'INBOX') {
                $inbox_subscribed = true;
            }
        }
    }
    if (!$inbox_subscribed) {
        if (!empty($list_assoc_ary)) {
            foreach ($list_assoc_ary as $temp_mailbox_name => $rawline) {
                if (strtoupper($temp_mailbox_name) == 'INBOX') {
                    $lsub_assoc_ary[$temp_mailbox_name] = $rawline;
                }
            }
        }
    }
    // Now we have the raw output, we need to create an array of mailbox names we will return
    if (!$show_only_subscribed) {
        $final_folders_assoc_ary = $list_assoc_ary;
    } else {
        /**
         * only show subscribed folders
         * we need to merge the folders here... we can't trust the flags, etc. from the lsub_assoc_array
         * so we use the lsub_assoc_array as the list of folders and the values come from list_assoc_array
         */
        if (!empty($lsub_assoc_ary)) {
            foreach ($lsub_assoc_ary as $temp_mailbox_name => $rawline) {
                if (!empty($list_assoc_ary[$temp_mailbox_name])) {
                    $final_folders_assoc_ary[$temp_mailbox_name] = $list_assoc_ary[$temp_mailbox_name];
                }
            }
        }
    }
    // Now produce a flat, sorted list
    if (!empty($final_folders_assoc_ary)) {
        uksort($final_folders_assoc_ary, 'strnatcasecmp');
        foreach ($final_folders_assoc_ary as $temp_mailbox_name => $rawline) {
            $final_folders_ary[] = $rawline;
        }
    }
    // this will put it into an array we can use later
    // containing:
    // raw    - Raw LIST/LSUB response from the IMAP server
    // formatted - formatted folder name
    // unformatted - unformatted, but with the delimiter at the end removed
    // unformated-dm - folder name as it appears in raw response
    // unformatted-disp - unformatted without $folder_prefix
    // id - the array element number (0, 1, 2, etc.)
    // flags - mailbox flags
    if (!empty($final_folders_ary)) {
        $boxesall = sqimap_mailbox_parse($final_folders_ary);
    } else {
        // they have no mailboxes
        $boxesall = array();
    }
    /* Now, lets sort for special folders */
    $boxesnew = $used = array();
    /* Find INBOX */
    $cnt = count($boxesall);
    $used = array_pad($used, $cnt, false);
    $has_inbox = false;
    for ($k = 0; $k < $cnt; ++$k) {
        if (strtoupper($boxesall[$k]['unformatted']) == 'INBOX') {
            $boxesnew[] = $boxesall[$k];
            $used[$k] = true;
            $has_inbox = true;
            break;
        }
    }
    if ($has_inbox == false) {
        // do a list request for inbox because we should always show
        // inbox even if the user isn't subscribed to it.
        $inbox_ary = sqimap_run_command($imap_stream, 'LIST "" "INBOX"', true, $response, $message);
        $inbox_ary = compact_mailboxes_response($inbox_ary);
        if (count($inbox_ary)) {
            $inbox_entry = sqimap_mailbox_parse($inbox_ary);
            // add it on top of the list
            if (!empty($boxesnew)) {
                array_unshift($boxesnew, $inbox_entry[0]);
            } else {
                $boxesnew[] = $inbox_entry[0];
            }
            /* array_unshift($used,true); */
        }
    }
    /* List special folders and their subfolders, if requested. */
    if ($list_special_folders_first) {
        for ($k = 0; $k < $cnt; ++$k) {
            if (!$used[$k] && isSpecialMailbox($boxesall[$k]['unformatted'])) {
                $boxesnew[] = $boxesall[$k];
                $used[$k] = true;
            }
        }
    }
    /* Find INBOX's children */
    for ($k = 0; $k < $cnt; ++$k) {
        $isboxbelow = isBoxBelow(strtoupper($boxesall[$k]['unformatted']), 'INBOX');
        if (strtoupper($boxesall[$k]['unformatted']) == 'INBOX') {
            $is_inbox = 1;
        } else {
            $is_inbox = 0;
        }
        if (!$used[$k] && $isboxbelow && $is_inbox) {
            $boxesnew[] = $boxesall[$k];
            $used[$k] = true;
        }
    }
    /* Rest of the folders */
    for ($k = 0; $k < $cnt; $k++) {
        if (!$used[$k]) {
            $boxesnew[] = $boxesall[$k];
        }
    }
    /**
     * Don't register boxes in session, if $session_register is set to false
     * Prevents registration of sqimap_mailbox_list_all() results.
     */
    if ($session_register) {
        sqsession_register($boxesnew, 'boxesnew');
    }
    return $boxesnew;
}
/**
 * Returns sorted mailbox lists in several different ways.
 * See comment on sqimap_mailbox_parse() for info about the returned array.
 */
function sqimap_mailbox_list($imap_stream, $force = false)
{
    global $default_folder_prefix;
    if (!sqgetGlobalVar('boxesnew', $boxesnew, SQ_SESSION) || $force) {
        global $data_dir, $username, $list_special_folders_first, $folder_prefix, $trash_folder, $sent_folder, $draft_folder, $move_to_trash, $move_to_sent, $save_as_draft, $delimiter, $noselect_fix_enable, $imap_server_type;
        $inbox_in_list = false;
        $inbox_subscribed = false;
        $listsubscribed = sqimap_capability($imap_stream, 'LIST-SUBSCRIBED');
        require_once SM_PATH . 'include/load_prefs.php';
        if ($listsubscribed) {
            $lsub = 'LIST (SUBSCRIBED)';
        } else {
            $lsub = 'LSUB';
        }
        if ($noselect_fix_enable) {
            $lsub_args = "{$lsub} \"{$folder_prefix}\" \"*%\"";
        } else {
            $lsub_args = "{$lsub} \"{$folder_prefix}\" \"*\"";
        }
        /* LSUB array */
        $lsub_ary = sqimap_run_command($imap_stream, $lsub_args, true, $response, $message);
        $lsub_ary = compact_mailboxes_response($lsub_ary);
        $sorted_lsub_ary = array();
        for ($i = 0, $cnt = count($lsub_ary); $i < $cnt; $i++) {
            $temp_mailbox_name = find_mailbox_name($lsub_ary[$i]);
            $sorted_lsub_ary[] = $temp_mailbox_name;
            if (!$inbox_subscribed && strtoupper($temp_mailbox_name) == 'INBOX') {
                $inbox_subscribed = true;
            }
        }
        /* natural sort mailboxes */
        if (isset($sorted_lsub_ary)) {
            usort($sorted_lsub_ary, 'strnatcasecmp');
        }
        /*
         * 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();
        //       if (!$listsubscribed) {
        for ($i = 0; $i < count($sorted_lsub_ary); $i++) {
            if (substr($sorted_lsub_ary[$i], -1) == $delimiter) {
                $mbx = substr($sorted_lsub_ary[$i], 0, strlen($sorted_lsub_ary[$i]) - 1);
            } else {
                $mbx = $sorted_lsub_ary[$i];
            }
            $read = sqimap_run_command($imap_stream, 'LIST "" ' . sqimap_encode_mailbox_name($mbx), true, $response, $message);
            $read = compact_mailboxes_response($read);
            if (isset($read[0])) {
                $sorted_list_ary[$i] = $read[0];
            } else {
                $sorted_list_ary[$i] = '';
            }
        }
        //       }
        /*
         * Just in case they're not subscribed to their inbox,
         * we'll get it for them anyway
         */
        if (!$inbox_subscribed) {
            $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]);
        }
        $boxesall = sqimap_mailbox_parse($sorted_list_ary, $sorted_lsub_ary);
        /* Now, lets sort for special folders */
        $boxesnew = $used = array();
        /* Find INBOX */
        $cnt = count($boxesall);
        $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;
            }
        }
        /* List special folders and their subfolders, if requested. */
        if ($list_special_folders_first) {
            for ($k = 0; $k < $cnt; ++$k) {
                if (!$used[$k] && isSpecialMailbox($boxesall[$k]['unformatted'])) {
                    $boxesnew[] = $boxesall[$k];
                    $used[$k] = true;
                }
            }
        }
        /* Rest of the folders */
        for ($k = 0; $k < $cnt; $k++) {
            if (!$used[$k]) {
                $boxesnew[] = $boxesall[$k];
            }
        }
        sqsession_register($boxesnew, 'boxesnew');
    }
    return $boxesnew;
}
Example #9
0
/**
 * Returns the delimiter between mailboxes: INBOX/Test, or INBOX.Test
 * @param stream $imap_stream
 * @return string
 */
function sqimap_get_delimiter($imap_stream = false)
{
    global $sqimap_delimiter, $optional_delimiter;
    /* Use configured delimiter if set */
    if (!empty($optional_delimiter) && $optional_delimiter != 'detect') {
        return $optional_delimiter;
    }
    /* Delimiter is stored in the session from redirect.  Try fetching from there first */
    if (empty($sqimap_delimiter)) {
        sqgetGlobalVar('delimiter', $sqimap_delimiter, SQ_SESSION);
    }
    /* Do some caching here */
    if (!$sqimap_delimiter) {
        if (sqimap_capability($imap_stream, 'NAMESPACE') && ($read = sqimap_run_command($imap_stream, 'NAMESPACE', true, $a, $b)) && preg_match('/\\* NAMESPACE +(\\( *\\(.+\\) *\\)|NIL) +(\\( *\\(.+\\) *\\)|NIL) +(\\( *\\(.+\\) *\\)|NIL)/i', $read[0], $data) && preg_match('/^\\( *\\((.*)\\) *\\)/', $data[1], $data2)) {
            $pn = $data2[1];
            $pna = explode(')(', $pn);
            $delnew = array();
            while (list($k, $v) = each($pna)) {
                $lst = explode('"', $v);
                if (isset($lst[3])) {
                    $delnew[$lst[1]] = $lst[3];
                } else {
                    $delnew[$lst[1]] = '';
                }
            }
            $sqimap_delimiter = array_shift($delnew);
        } else {
            fputs($imap_stream, ". LIST \"INBOX\" \"\"\r\n");
            $read = sqimap_read_data($imap_stream, '.', true, $a, $b);
            $read = $read['.'][0];
            //sqimap_read_data() now returns a tag array of response array
            $quote_position = strpos($read[0], '"');
            $sqimap_delimiter = substr($read[0], $quote_position + 1, 1);
        }
    }
    return $sqimap_delimiter;
}