Add info option widget type
[squirrelmail.git] / functions / imap_mailbox.php
index e9f9d6a48cd3a5684be0882934bdbb49d0d36478..56f814aeae8544fbe503c7d8ce84642f3b94e318 100755 (executable)
@@ -5,7 +5,7 @@
  *
  * This implements all functions that manipulate mailboxes
  *
- * @copyright © 1999-2006 The SquirrelMail Project Team
+ * @copyright © 1999-2007 The SquirrelMail Project Team
  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  * @version $Id$
  * @package squirrelmail
@@ -233,7 +233,7 @@ function isSpecialMailbox($box,$include_subs=true) {
              isDraftMailbox($box,$include_subs) );
 
     if ( !$ret ) {
-        $ret = boolean_hook_function('special_mailbox',$box,1);
+        $ret = boolean_hook_function('special_mailbox', $box, 1);
     }
     return $ret;
 }
@@ -360,12 +360,30 @@ function sqimap_mailbox_exists ($imap_stream, $mailbox, $mailboxlist=null) {
  * @since 1.0 or older
  */
 function sqimap_mailbox_select ($imap_stream, $mailbox) {
-    // FIX ME: WHAAAA DO NOT USE "None" for something that does not exist. Use false or NULL instead
-    if ($mailbox == 'None') {
+    if (empty($mailbox)) {
         return;
     }
+
     // cleanup $mailbox in order to prevent IMAP injection attacks
     $mailbox = str_replace(array("\r","\n"), array("",""),$mailbox);
+
+    /**
+     * Default UW IMAP server configuration allows to access other files
+     * on server. $imap_server_type is not checked because interface can
+     * be used with 'other' or any other server type setting. $mailbox
+     * variable can be modified in any script that uses variable from GET
+     * or POST. This code blocks all standard SquirrelMail IMAP API requests
+     * that use mailbox with full path (/etc/passwd) or with ../ characters
+     * in path (../../etc/passwd)
+     */
+    if (strstr($mailbox, '../') || substr($mailbox, 0, 1) == '/') {
+        global $oTemplate;
+        error_box(sprintf(_("Invalid mailbox name: %s"),htmlspecialchars($mailbox)));
+        sqimap_logout($imap_stream);
+        $oTemplate->display('footer.tpl');
+        die();
+    }
+
     $read = sqimap_run_command($imap_stream, 'SELECT ' . sqimap_encode_mailbox_name($mailbox),
                                true, $response, $message);
     $result = array();
@@ -467,7 +485,8 @@ function sqimap_mailbox_delete ($imap_stream, $mailbox) {
             // subscribe again
             sqimap_subscribe ($imap_stream, $mailbox);
         } else {
-            do_hook_function('rename_or_delete_folder', $args = array($mailbox, 'delete', ''));
+            $temp = array(&$mailbox, 'delete', '');
+            do_hook('rename_or_delete_folder', $temp);
             removePref($data_dir, $username, "thread_$mailbox");
             removePref($data_dir, $username, "collapse_folder_$mailbox");
         }
@@ -522,7 +541,8 @@ function sqimap_mailbox_rename( $imap_stream, $old_name, $new_name ) {
         sqimap_subscribe($imap_stream, $new_name.$postfix);
         setPref($data_dir, $username, 'thread_'.$new_name.$postfix, $oldpref_thread);
         setPref($data_dir, $username, 'collapse_folder_'.$new_name.$postfix, $oldpref_collapse);
-        do_hook_function('rename_or_delete_folder',$args = array($old_name, 'rename', $new_name));
+        $temp = array(&$old_name, 'rename', &$new_name);
+        do_hook('rename_or_delete_folder', $temp);
         $l = strlen( $old_name ) + 1;
         $p = 'unformatted';
 
@@ -548,8 +568,8 @@ function sqimap_mailbox_rename( $imap_stream, $old_name, $new_name ) {
                 }
                 setPref($data_dir, $username, 'thread_'.$new_sub, $oldpref_thread);
                 setPref($data_dir, $username, 'collapse_folder_'.$new_sub, $oldpref_collapse);
-                do_hook_function('rename_or_delete_folder',
-                                 $args = array($box[$p], 'rename', $new_sub));
+                $temp = array(&$box[$p], 'rename', &$new_sub);
+                do_hook('rename_or_delete_folder', $temp);
             }
         }
     }
@@ -651,26 +671,13 @@ function sqimap_mailbox_parse ($line) {
 }
 
 /**
- * Returns list of options (to be echoed into select statement
- * based on available mailboxes and separators
- * Caller should surround options with <select ...> </select> and
- * any formatting.
- * @param stream $imap_stream imap connection resource to query for mailboxes
- * @param array $show_selected array containing list of mailboxes to pre-select (0 if none)
- * @param array $folder_skip array of folders to keep out of option list (compared in lower)
- * @param $boxes list of already fetched boxes (for places like folder panel, where
- *            you know these options will be shown 3 times in a row.. (most often unset).
- * @param string $flag (since 1.4.1) flag to check for in mailbox flags, used to filter out mailboxes.
- *           'noselect' by default to remove unselectable mailboxes.
- *           'noinferiors' used to filter out folders that can not contain subfolders.
- *           NULL to avoid flag check entirely.
- *           NOTE: noselect and noiferiors are used internally. The IMAP representation is
- *                 \NoSelect and \NoInferiors
- * @param boolean $use_long_format (since 1.4.1) override folder display preference and always show full folder name.
- * @return string html formated mailbox selection options
- * @since 1.3.2
+ * Returns an array of mailboxes available.  Separated from sqimap_mailbox_option_list()
+ * below for template development.
+ * 
+ * @author Steve Brown
+ * @since 1.5.2
  */
-function sqimap_mailbox_option_list($imap_stream, $show_selected = 0, $folder_skip = 0, $boxes = 0,
+function sqimap_mailbox_option_array($imap_stream, $folder_skip = 0, $boxes = 0,
                                     $flag = 'noselect', $use_long_format = false ) {
     global $username, $data_dir, $translate_special_folders, $sent_folder, 
         $trash_folder, $draft_folder;
@@ -681,13 +688,14 @@ function sqimap_mailbox_option_list($imap_stream, $show_selected = 0, $folder_sk
     if ( $use_long_format ) {
         $shorten_box_names = 0;
     } else {
-        $shorten_box_names = getPref($data_dir, $username, 'mailbox_select_style', SMPREF_OFF);
+        $shorten_box_names = getPref($data_dir, $username, 'mailbox_select_style', SMPREF_MAILBOX_SELECT_INDENTED);
     }
 
     if ($boxes == 0) {
         $boxes = sqimap_mailbox_list($imap_stream);
     }
 
+    $a = array();
     foreach ($boxes as $boxes_part) {
         if ($flag == NULL || (is_array($boxes_part['flags'])
                       && !in_array($flag, $boxes_part['flags']))) {
@@ -705,7 +713,7 @@ function sqimap_mailbox_option_list($imap_stream, $show_selected = 0, $folder_sk
             } else {
                 switch ($shorten_box_names)
                 {
-                  case 2:   /* delimited, style = 2 */
+                  case SMPREF_MAILBOX_SELECT_DELIMITED:
                       if ($translate_special_folders && $boxes_part['unformatted-dm']==$sent_folder) {
                           /*
                            * calculate pad level from number of delimiters. do it inside if control in order 
@@ -726,7 +734,7 @@ function sqimap_mailbox_option_list($imap_stream, $show_selected = 0, $folder_sk
                           $box2 = str_replace('&amp;nbsp;&amp;nbsp;', '.&nbsp;', htmlspecialchars($boxes_part['formatted']));
                       }
                     break;
-                  case 1:   /* indent, style = 1 */
+                  case SMPREF_MAILBOX_SELECT_INDENTED:
                       if ($translate_special_folders && $boxes_part['unformatted-dm']==$sent_folder) {
                           $pad = str_pad('',12 * (count(explode($delimiter,$boxes_part['unformatted-dm']))-1),'&nbsp;&nbsp;');
                           $box2 = $pad . _("Sent");
@@ -745,14 +753,58 @@ function sqimap_mailbox_option_list($imap_stream, $show_selected = 0, $folder_sk
                     break;
                 }
             }
-            if ($show_selected != 0 && in_array($lowerbox, $show_selected) ) {
-                $mbox_options .= '<option value="' . htmlspecialchars($box) .'" selected="selected">'.$box2.'</option>' . "\n";
-            } else {
-                $mbox_options .= '<option value="' . htmlspecialchars($box) .'">'.$box2.'</option>' . "\n";
+            
+            $a[htmlspecialchars($box)] = $box2;
+        }
+    }
+    
+    return $a;
+}
+
+/**
+ * Returns list of options (to be echoed into select statement
+ * based on available mailboxes and separators
+ * Caller should surround options with <select ...> </select> and
+ * any formatting.
+ * @param stream $imap_stream imap connection resource to query for mailboxes
+ * @param array $show_selected array containing list of mailboxes to pre-select (0 if none)
+ * @param array $folder_skip array of folders to keep out of option list (compared in lower)
+ * @param $boxes list of already fetched boxes (for places like folder panel, where
+ *            you know these options will be shown 3 times in a row.. (most often unset).
+ * @param string $flag (since 1.4.1) flag to check for in mailbox flags, used to filter out mailboxes.
+ *           'noselect' by default to remove unselectable mailboxes.
+ *           'noinferiors' used to filter out folders that can not contain subfolders.
+ *           NULL to avoid flag check entirely.
+ *           NOTE: noselect and noiferiors are used internally. The IMAP representation is
+ *                 \NoSelect and \NoInferiors
+ * @param boolean $use_long_format (since 1.4.1) override folder display preference and always show full folder name.
+ * @return string html formated mailbox selection options
+ * @since 1.3.2
+ */
+function sqimap_mailbox_option_list($imap_stream, $show_selected = 0, $folder_skip = 0, $boxes = 0,
+                                    $flag = 'noselect', $use_long_format = false ) {
+    global $username, $data_dir, $translate_special_folders, $sent_folder, 
+        $trash_folder, $draft_folder;
+
+    $boxes = sqimap_mailbox_option_array($imap_stream, $folder_skip, $boxes, $flag, $use_long_format);
+    
+    $str = '';
+    foreach ($boxes as $value=>$option) {
+        $lowerbox = strtolower(htmlspecialchars($value));
+        $sel = false;
+        if ($show_selected != 0) {
+            reset($show_selected);
+            while (!$sel && (list($x, $val) = each($show_selected))) {
+                if (strtolower($value) == strtolower(htmlspecialchars($val))) {
+                    $sel = true;
+                }
             }
         }
+        
+        $str .= '<option value="'. $value .'"'. ($sel ? ' selected="selected"' : '').'>'. $option ."</option>\n";
     }
-    return $mbox_options;
+    
+    return $str;
 }
 
 /**
@@ -1330,7 +1382,7 @@ function sqimap_get_status_mbx_tree($imap_stream,&$mbx_tree) {
          {
               $hook_status['MAILBOX']=$oMbx->mailboxname_full;
               $hook_status['CALLER']='sqimap_get_status_mbx_tree'; // helps w/ debugging
-              do_hook_function('folder_status',$hook_status);
+              do_hook('folder_status', $hook_status);
          }
     }
 }