Grammar
[squirrelmail.git] / config / conf.pl
index 95bbd8f1c16af1cbe9a8fad29a0b2145f3d368a6..65966aab54a3673508012b28e5415fb9b2f342c2 100755 (executable)
@@ -1,14 +1,14 @@
 #!/usr/bin/env perl
 # conf.pl
 #
 #!/usr/bin/env perl
 # conf.pl
 #
-# Copyright (c) 1999-2006 The SquirrelMail Project Team
+# Copyright (c) 1999-2010 The SquirrelMail Project Team
 # Licensed under the GNU GPL. For full terms see COPYING.
 #
 # A simple configure script to configure SquirrelMail
 #
 # $Id$
 ############################################################
 # Licensed under the GNU GPL. For full terms see COPYING.
 #
 # A simple configure script to configure SquirrelMail
 #
 # $Id$
 ############################################################
-$conf_pl_version = "1.4.0";
+$conf_pl_version = "1.5.0";
 
 ############################################################
 # Check what directory we're supposed to be running in, and
 
 ############################################################
 # Check what directory we're supposed to be running in, and
@@ -46,6 +46,17 @@ $dir = cwd();
 # First, lets read in the data already in there...
 ############################################################
 if ( -e "config.php" ) {
 # First, lets read in the data already in there...
 ############################################################
 if ( -e "config.php" ) {
+    # Make sure that file is readable
+    if (! -r "config.php") {
+        clear_screen();
+        print "WARNING:\n";
+        print "The file \"config/config.php\" was found, but you don't\n";
+        print "have rights to read it.\n";
+        print "\n";
+        print "Press enter to continue";
+        $ctu = <STDIN>;
+        exit;
+    }
     open( FILE, "config.php" );
     while ( $line = <FILE> ) {
         $line =~ s/^\s+//;
     open( FILE, "config.php" );
     while ( $line = <FILE> ) {
         $line =~ s/^\s+//;
@@ -70,7 +81,7 @@ if ( -e "config.php" ) {
 
     if ( $config_version ne $conf_pl_version ) {
         clear_screen();
 
     if ( $config_version ne $conf_pl_version ) {
         clear_screen();
-        print $WHT. "WARNING:\n" . $NRM;
+        print "WARNING:\n";
         print "  The file \"config/config.php\" was found, but it is for\n";
         print "  an older version of SquirrelMail. It is possible to still\n";
         print "  read the defaults from this file but be warned that many\n";
         print "  The file \"config/config.php\" was found, but it is for\n";
         print "  an older version of SquirrelMail. It is possible to still\n";
         print "  read the defaults from this file but be warned that many\n";
@@ -123,13 +134,13 @@ if ( -e "config.php" ) {
 
     if ( $config_version ne $conf_pl_version ) {
         clear_screen();
 
     if ( $config_version ne $conf_pl_version ) {
         clear_screen();
-        print $WHT. "WARNING:\n" . $NRM;
+        print "WARNING:\n";
         print "  You are trying to use a 'config_default.php' from an older\n";
         print "  version of SquirrelMail. This is HIGHLY unrecommended. You\n";
         print "  should get the 'config_default.php' that matches the version\n";
         print "  of SquirrelMail that you are running. You can get this from\n";
         print "  the SquirrelMail web page by going to the following URL:\n";
         print "  You are trying to use a 'config_default.php' from an older\n";
         print "  version of SquirrelMail. This is HIGHLY unrecommended. You\n";
         print "  should get the 'config_default.php' that matches the version\n";
         print "  of SquirrelMail that you are running. You can get this from\n";
         print "  the SquirrelMail web page by going to the following URL:\n";
-        print "      http://www.squirrelmail.org.\n";
+        print "      http://squirrelmail.org.\n";
         print "\n";
         print "Continue loading with old config_default.php (a bad idea) [y/N]? ";
         $ctu = <STDIN>;
         print "\n";
         print "Continue loading with old config_default.php (a bad idea) [y/N]? ";
         $ctu = <STDIN>;
@@ -175,19 +186,32 @@ while ( $line = <FILE> ) {
         $options[1] =~ s/\\'/'/g;
         $options[1] =~ s/\\\\/\\/g;
 
         $options[1] =~ s/\\'/'/g;
         $options[1] =~ s/\\\\/\\/g;
 
-        if ( $options[0] =~ /^theme\[[0-9]+\]\[['"]PATH['"]\]/ ) {
+        if ( $options[0] =~ /^user_themes\[[0-9]+\]\[['"]PATH['"]\]/ ) {
+            $sub = $options[0];
+            $sub =~ s/\]\[['"]PATH['"]\]//;
+            $sub =~ s/.*\[//;
+            if ( -e "../css/" ) {
+                $options[1] =~ s/^\.\.\/config/\.\.\/css/;
+            }
+            $user_theme_path[$sub] = &change_to_rel_path($options[1]);
+        } elsif ( $options[0] =~ /^user_themes\[[0-9]+\]\[['"]NAME['"]\]/ ) {
+            $sub = $options[0];
+            $sub =~ s/\]\[['"]NAME['"]\]//;
+            $sub =~ s/.*\[//;
+            $user_theme_name[$sub] = $options[1];
+        } elsif ( $options[0] =~ /^icon_themes\[[0-9]+\]\[['"]PATH['"]\]/ ) {
             $sub = $options[0];
             $sub =~ s/\]\[['"]PATH['"]\]//;
             $sub =~ s/.*\[//;
             $sub = $options[0];
             $sub =~ s/\]\[['"]PATH['"]\]//;
             $sub =~ s/.*\[//;
-            if ( -e "../themes" ) {
-                $options[1] =~ s/^\.\.\/config/\.\.\/themes/;
+            if ( -e "../images/" ) {
+                $options[1] =~ s/^\.\.\/config/\.\.\/images/;
             }
             }
-            $theme_path[$sub] = &change_to_rel_path($options[1]);
-        } elsif ( $options[0] =~ /^theme\[[0-9]+\]\[['"]NAME['"]\]/ ) {
+            $icon_theme_path[$sub] = &change_to_rel_path($options[1]);
+        } elsif ( $options[0] =~ /^icon_themes\[[0-9]+\]\[['"]NAME['"]\]/ ) {
             $sub = $options[0];
             $sub =~ s/\]\[['"]NAME['"]\]//;
             $sub =~ s/.*\[//;
             $sub = $options[0];
             $sub =~ s/\]\[['"]NAME['"]\]//;
             $sub =~ s/.*\[//;
-            $theme_name[$sub] = $options[1];
+            $icon_theme_name[$sub] = $options[1];
         } elsif ( $options[0] =~ /^aTemplateSet\[[0-9]+\]\[['"]ID['"]\]/ ) {
             $sub = $options[0];
             $sub =~ s/\]\[['"]ID['"]\]//;
         } elsif ( $options[0] =~ /^aTemplateSet\[[0-9]+\]\[['"]ID['"]\]/ ) {
             $sub = $options[0];
             $sub =~ s/\]\[['"]ID['"]\]//;
@@ -196,6 +220,18 @@ while ( $line = <FILE> ) {
                 $options[1] =~ s/^\.\.\/config/\.\.\/templates/;
             }
             $templateset_id[$sub] = $options[1];
                 $options[1] =~ s/^\.\.\/config/\.\.\/templates/;
             }
             $templateset_id[$sub] = $options[1];
+##### FIXME: This section BELOW here so old prefs files don't blow up when running conf.pl
+#####        Remove after a month or two 
+} elsif ( $options[0] =~ /^aTemplateSet\[[0-9]+\]\[['"]PATH['"]\]/ ) {
+    $sub = $options[0];
+    $sub =~ s/\]\[['"]PATH['"]\]//;
+    $sub =~ s/.*\[//;
+    if ( -e "../templates" ) {
+        $options[1] =~ s/^\.\.\/config/\.\.\/templates/;
+    }
+    $templateset_id[$sub] = $options[1];
+##### FIXME: This section ABOVE here so old prefs files don't blow up when running conf.pl
+#####        Remove after a month or two 
         } elsif ( $options[0] =~ /^aTemplateSet\[[0-9]+\]\[['"]NAME['"]\]/ ) {
             $sub = $options[0];
             $sub =~ s/\]\[['"]NAME['"]\]//;
         } elsif ( $options[0] =~ /^aTemplateSet\[[0-9]+\]\[['"]NAME['"]\]/ ) {
             $sub = $options[0];
             $sub =~ s/\]\[['"]NAME['"]\]//;
@@ -216,6 +252,11 @@ while ( $line = <FILE> ) {
             $sub =~ s/\'\]//;
             $sub =~ s/^fontsets\[\'//;
             $fontsets{$sub} = $options[1];
             $sub =~ s/\'\]//;
             $sub =~ s/^fontsets\[\'//;
             $fontsets{$sub} = $options[1];
+        } elsif ( $options[0] =~ /^theme\[[0-9]+\]\[['"]PATH|NAME['"]\]/ ) {
+            ##
+            ## $color themes are no longer supported.  Please leave this
+            ## so conf.pl doesn't barf if it encounters a $theme.
+            ##
         } elsif ( $options[0] =~ /^ldap_server\[[0-9]+\]/ ) {
             $sub = $options[0];
             $sub =~ s/\]//;
         } elsif ( $options[0] =~ /^ldap_server\[[0-9]+\]/ ) {
             $sub = $options[0];
             $sub =~ s/\]//;
@@ -318,7 +359,7 @@ while ( $line = <FILE> ) {
             $ldap_writeable[$sub] = $writeable;
             $ldap_search_tree[$sub] = $search_tree;
             $ldap_starttls[$sub] = $starttls;
             $ldap_writeable[$sub] = $writeable;
             $ldap_search_tree[$sub] = $search_tree;
             $ldap_starttls[$sub] = $starttls;
-        } elsif ( $options[0] =~ /^(data_dir|attachment_dir|theme_css|org_logo|signout_page|icon_theme_def)$/ ) {
+        } elsif ( $options[0] =~ /^(data_dir|attachment_dir|org_logo|signout_page|icon_theme_def)$/ ) {
             ${ $options[0] } = &change_to_rel_path($options[1]);
         } else {
             ${ $options[0] } = $options[1];
             ${ $options[0] } = &change_to_rel_path($options[1]);
         } else {
             ${ $options[0] } = $options[1];
@@ -327,10 +368,19 @@ while ( $line = <FILE> ) {
 }
 close FILE;
 
 }
 close FILE;
 
+# RPC template sets aren't included in user interface skin list,
+# so add the one from the config file here
+#
+if ($rpc_templateset =~ /_rpc$/) {
+    $templateset_name[$#templateset_name + 1] = $rpc_templateset;
+    $templateset_id[$#templateset_id + 1] = $rpc_templateset;
+}
+
 # FIXME: unknown introduction date
 $useSendmail = 'false'                  if ( lc($useSendmail) ne 'true' );
 $sendmail_path = "/usr/sbin/sendmail"   if ( !$sendmail_path );
 $pop_before_smtp = 'false'              if ( !$pop_before_smtp );
 # FIXME: unknown introduction date
 $useSendmail = 'false'                  if ( lc($useSendmail) ne 'true' );
 $sendmail_path = "/usr/sbin/sendmail"   if ( !$sendmail_path );
 $pop_before_smtp = 'false'              if ( !$pop_before_smtp );
+$pop_before_smtp_host = ''              if ( !$pop_before_smtp_host );
 $default_unseen_notify = 2              if ( !$default_unseen_notify );
 $default_unseen_type = 1                if ( !$default_unseen_type );
 $config_use_color = 0                   if ( !$config_use_color );
 $default_unseen_notify = 2              if ( !$default_unseen_notify );
 $default_unseen_type = 1                if ( !$default_unseen_type );
 $config_use_color = 0                   if ( !$config_use_color );
@@ -344,9 +394,7 @@ $delete_folder = 'false'                if ( !$delete_folder );
 $noselect_fix_enable = 'false'          if ( !$noselect_fix_enable );
 $frame_top = "_top"                     if ( !$frame_top );
 $provider_uri = ''                      if ( !$provider_uri );
 $noselect_fix_enable = 'false'          if ( !$noselect_fix_enable );
 $frame_top = "_top"                     if ( !$frame_top );
 $provider_uri = ''                      if ( !$provider_uri );
-$provider_name = ''                     if ( !$provider_name );
-$edit_identity = 'true'                 if ( !$edit_identity );
-$edit_name = 'true'                     if ( !$edit_name );
+$provider_name = ''                     if ( !$provider_name || $provider_name eq 'SquirrelMail');
 $no_list_for_subscribe = 'false'        if ( !$no_list_for_subscribe );
 $allow_charset_search = 'true'          if ( !$allow_charset_search );
 $allow_advanced_search = 0              if ( !$allow_advanced_search) ;
 $no_list_for_subscribe = 'false'        if ( !$no_list_for_subscribe );
 $allow_charset_search = 'true'          if ( !$allow_charset_search );
 $allow_advanced_search = 0              if ( !$allow_advanced_search) ;
@@ -359,6 +407,9 @@ $default_use_javascript_addr_book = 'false' if (! $default_use_javascript_addr_b
 
 # since 1.2.0
 $hide_sm_attributions = 'false'         if ( !$hide_sm_attributions );
 
 # since 1.2.0
 $hide_sm_attributions = 'false'         if ( !$hide_sm_attributions );
+# since 1.2.5
+$edit_identity = 'true'                 if ( !$edit_identity );
+$edit_name = 'true'                     if ( !$edit_name );
 
 # since 1.4.0
 $use_smtp_tls= 'false'                  if ( !$use_smtp_tls);
 
 # since 1.4.0
 $use_smtp_tls= 'false'                  if ( !$use_smtp_tls);
@@ -376,12 +427,22 @@ $aggressive_decoding = 'false'          if ( !$aggressive_decoding );
 # $advanced_tree = 'false'                if ( !$advanced_tree );
 $use_php_recode = 'false'               if ( !$use_php_recode );
 $use_php_iconv = 'false'                if ( !$use_php_iconv );
 # $advanced_tree = 'false'                if ( !$advanced_tree );
 $use_php_recode = 'false'               if ( !$use_php_recode );
 $use_php_iconv = 'false'                if ( !$use_php_iconv );
+$buffer_output = 'false'                if ( !$buffer_output );
 
 # since 1.5.1
 $use_icons = 'false'                    if ( !$use_icons );
 $use_iframe = 'false'                   if ( !$use_iframe );
 $lossy_encoding = 'false'               if ( !$lossy_encoding );
 $allow_remote_configtest = 'false'      if ( !$allow_remote_configtest );
 
 # since 1.5.1
 $use_icons = 'false'                    if ( !$use_icons );
 $use_iframe = 'false'                   if ( !$use_iframe );
 $lossy_encoding = 'false'               if ( !$lossy_encoding );
 $allow_remote_configtest = 'false'      if ( !$allow_remote_configtest );
+$secured_config = 'true'                if ( !$secured_config );
+$sq_https_port = 443                    if ( !$sq_https_port );
+$sq_ignore_http_x_forwarded_headers = 'true' if ( !$sq_ignore_http_x_forwarded_headers );
+
+$sm_debug_mode = 'SM_DEBUG_MODE_MODERATE' if ( !$sm_debug_mode );
+#FIXME: When this is STABLE software, remove the line above and uncomment the one below:
+#$sm_debug_mode = 'SM_DEBUG_MODE_OFF'    if ( !$sm_debug_mode );
+$sm_debug_mode = convert_debug_binary_integer_to_constants($sm_debug_mode);
+
 $addrbook_global_table = 'global_abook' if ( !$addrbook_global_table );
 $addrbook_global_writeable = 'false'    if ( !$addrbook_global_writeable );
 $addrbook_global_listing = 'false'      if ( !$addrbook_global_listing );
 $addrbook_global_table = 'global_abook' if ( !$addrbook_global_table );
 $addrbook_global_writeable = 'false'    if ( !$addrbook_global_writeable );
 $addrbook_global_listing = 'false'      if ( !$addrbook_global_listing );
@@ -395,9 +456,6 @@ $prefs_user_size = 128                  if ( !$prefs_user_size );
 $prefs_key_size = 64                    if ( !$prefs_key_size );
 $prefs_val_size = 65536                 if ( !$prefs_val_size );
 
 $prefs_key_size = 64                    if ( !$prefs_key_size );
 $prefs_val_size = 65536                 if ( !$prefs_val_size );
 
-# since 1.5.2
-$icon_theme_def = ''                                   if ( !$icon_theme_def );
-
 # add qmail-inject test here for backwards compatibility
 if ( !$sendmail_args && $sendmail_path =~ /qmail-inject/ ) {
     $sendmail_args = '';
 # add qmail-inject test here for backwards compatibility
 if ( !$sendmail_args && $sendmail_path =~ /qmail-inject/ ) {
     $sendmail_args = '';
@@ -429,12 +487,24 @@ $abook_file_line_length = 2048         if ( !$abook_file_line_length );
 $config_location_base = ''             if ( !$config_location_base );
 $smtp_sitewide_user = ''               if ( !$smtp_sitewide_user );
 $smtp_sitewide_pass = ''               if ( !$smtp_sitewide_pass );
 $config_location_base = ''             if ( !$config_location_base );
 $smtp_sitewide_user = ''               if ( !$smtp_sitewide_user );
 $smtp_sitewide_pass = ''               if ( !$smtp_sitewide_pass );
+$icon_theme_def = ''                   if ( !$icon_theme_def );
+$disable_plugins = 'false'             if ( !$disable_plugins );
+$disable_plugins_user = ''             if ( !$disable_plugins_user );
+$only_secure_cookies = 'true'          if ( !$only_secure_cookies );
+$disable_security_tokens = 'false'     if ( !$disable_security_tokens );
+$check_referrer = ''                   if ( !$check_referrer );
+$ask_user_info = 'true'                if ( !$ask_user_info );
 
 if ( $ARGV[0] eq '--install-plugin' ) {
     print "Activating plugin " . $ARGV[1] . "\n";
 
 if ( $ARGV[0] eq '--install-plugin' ) {
     print "Activating plugin " . $ARGV[1] . "\n";
-    push @plugins, $ARGV[1];
-    save_data();
-    exit(0);
+    if ( -d "../plugins/" . $ARGV[1]) {
+        push @plugins, $ARGV[1];
+        save_data();
+        exit(0);
+    } else {
+        print "No such plugin.\n";
+        exit(1);
+    }
 } elsif ( $ARGV[0] eq '--remove-plugin' ) {
     print "Removing plugin " . $ARGV[1] . "\n";
     foreach $plugin (@plugins) {
 } elsif ( $ARGV[0] eq '--remove-plugin' ) {
     print "Removing plugin " . $ARGV[1] . "\n";
     foreach $plugin (@plugins) {
@@ -445,11 +515,42 @@ if ( $ARGV[0] eq '--install-plugin' ) {
     @plugins = @newplugins;
     save_data();
     exit(0);
     @plugins = @newplugins;
     save_data();
     exit(0);
+} elsif ( $ARGV[0] eq '--update-plugins' or $ARGV[0] eq '-u') {
+    build_plugin_hook_array();
+    exit(0);
+} elsif ( $ARGV[0] eq '--help' or $ARGV[0] eq '-h') {
+    print "SquirrelMail Configuration Script\n";
+    print "Usage:\n";
+    print " * No arguments: initiates the configuration dialog\n";
+    print " * --install-plugin <plugin> : activates the specified plugin\n";
+    print " * --remove-plugin <plugin>  : deactivates the specified plugin\n";
+    print " * --update-plugins , -u     : rebuilds plugin_hooks.php according\n";
+    print "                               to plugins activated in config.php\n";
+    print " * --help , -h               : Displays this help\n";
+    print "\n";
+    exit(0);
 }
 
 }
 
+
+
+####################################################################################
+
+# used in multiple places, define once
+$list_supported_imap_servers = 
+    "    bincimap    = Binc IMAP server\n" .
+    "    courier     = Courier IMAP server\n" .
+    "    cyrus       = Cyrus IMAP server\n" .
+    "    dovecot     = Dovecot Secure IMAP server\n" .
+    "    exchange    = Microsoft Exchange IMAP server\n" .
+    "    hmailserver = hMailServer\n" .
+    "    macosx      = Mac OS X Mailserver\n" .
+    "    mercury32   = Mercury/32\n" .
+    "    uw          = University of Washington's IMAP server\n" .
+    "    gmail       = IMAP access to Google mail (Gmail) accounts\n";
+
 #####################################################################################
 if ( $config_use_color == 1 ) {
 #####################################################################################
 if ( $config_use_color == 1 ) {
-    $WHT = "\x1B[37;1m";
+    $WHT = "\x1B[1m";
     $NRM = "\x1B[0m";
 } else {
     $WHT              = "";
     $NRM = "\x1B[0m";
 } else {
     $WHT              = "";
@@ -457,6 +558,24 @@ if ( $config_use_color == 1 ) {
     $config_use_color = 2;
 }
 
     $config_use_color = 2;
 }
 
+# lists can be printed in more than one column; default is just one
+#
+$columns = 1;
+
+# try to get screen width dynamically if possible; default to 80
+# (user can override with "w#" command)
+#
+eval { require "sys/ioctl.ph" };
+if ($@
+ || !defined &TIOCGWINSZ
+ || !open(TTY, "+</dev/tty")
+ || !ioctl(TTY, &TIOCGWINSZ, $winsize='')) {
+    $screen_width = 80;
+} else {
+    ($row, $col, $xpixel, $ypixel) = unpack('S4', $winsize);
+    $screen_width = $col;
+}
+
 while ( ( $command ne "q" ) && ( $command ne "Q" ) && ( $command ne ":q" ) ) {
     clear_screen();
     print $WHT. "SquirrelMail Configuration : " . $NRM;
 while ( ( $command ne "q" ) && ( $command ne "Q" ) && ( $command ne ":q" ) ) {
     clear_screen();
     print $WHT. "SquirrelMail Configuration : " . $NRM;
@@ -471,7 +590,7 @@ while ( ( $command ne "q" ) && ( $command ne "Q" ) && ( $command ne ":q" ) ) {
         print "2.  Server Settings\n";
         print "3.  Folder Defaults\n";
         print "4.  General Options\n";
         print "2.  Server Settings\n";
         print "3.  Folder Defaults\n";
         print "4.  General Options\n";
-        print "5.  Templates\n";
+        print "5.  User Interface\n";
         print "6.  Address Books\n";
         print "7.  Message of the Day (MOTD)\n";
         print "8.  Plugins\n";
         print "6.  Address Books\n";
         print "7.  Message of the Day (MOTD)\n";
         print "8.  Plugins\n";
@@ -490,7 +609,7 @@ while ( ( $command ne "q" ) && ( $command ne "Q" ) && ( $command ne ":q" ) ) {
         print "5.  Signout Page           : $WHT$signout_page$NRM\n";
         print "6.  Top Frame              : $WHT$frame_top$NRM\n";
         print "7.  Provider link          : $WHT$provider_uri$NRM\n";
         print "5.  Signout Page           : $WHT$signout_page$NRM\n";
         print "6.  Top Frame              : $WHT$frame_top$NRM\n";
         print "7.  Provider link          : $WHT$provider_uri$NRM\n";
-        print "8.  Provider name          : $WHT$provider_name$NRM\n";
+        print "8.  Provider link text     : $WHT$provider_name$NRM\n";
 
         print "\n";
         print "R   Return to Main Menu\n";
 
         print "\n";
         print "R   Return to Main Menu\n";
@@ -563,61 +682,60 @@ while ( ( $command ne "q" ) && ( $command ne "Q" ) && ( $command ne ":q" ) ) {
         print "R   Return to Main Menu\n";
     } elsif ( $menu == 3 ) {
         print $WHT. "Folder Defaults\n" . $NRM;
         print "R   Return to Main Menu\n";
     } elsif ( $menu == 3 ) {
         print $WHT. "Folder Defaults\n" . $NRM;
-        print "1.  Default Folder Prefix         : $WHT$default_folder_prefix$NRM\n";
-        print "2.  Show Folder Prefix Option     : $WHT$show_prefix_option$NRM\n";
-        print "3.  Trash Folder                  : $WHT$trash_folder$NRM\n";
-        print "4.  Sent Folder                   : $WHT$sent_folder$NRM\n";
-        print "5.  Drafts Folder                 : $WHT$draft_folder$NRM\n";
-        print "6.  By default, move to trash     : $WHT$default_move_to_trash$NRM\n";
-        print "7.  By default, move to sent      : $WHT$default_move_to_sent$NRM\n";
-        print "8.  By default, save as draft     : $WHT$default_save_as_draft$NRM\n";
-        print "9.  List Special Folders First    : $WHT$list_special_folders_first$NRM\n";
-        print "10. Show Special Folders Color    : $WHT$use_special_folder_color$NRM\n";
-        print "11. Auto Expunge                  : $WHT$auto_expunge$NRM\n";
-        print "12. Default Sub. of INBOX         : $WHT$default_sub_of_inbox$NRM\n";
-        print "13. Show 'Contain Sub.' Option    : $WHT$show_contain_subfolders_option$NRM\n";
-        print "14. Default Unseen Notify         : $WHT$default_unseen_notify$NRM\n";
-        print "15. Default Unseen Type           : $WHT$default_unseen_type$NRM\n";
-        print "16. Auto Create Special Folders   : $WHT$auto_create_special$NRM\n";
-        print "17. Folder Delete Bypasses Trash  : $WHT$delete_folder$NRM\n";
-        print "18. Enable /NoSelect folder fix   : $WHT$noselect_fix_enable$NRM\n";
+        print "1.  Default Folder Prefix          : $WHT$default_folder_prefix$NRM\n";
+        print "2.  Show Folder Prefix Option      : $WHT$show_prefix_option$NRM\n";
+        print "3.  Trash Folder                   : $WHT$trash_folder$NRM\n";
+        print "4.  Sent Folder                    : $WHT$sent_folder$NRM\n";
+        print "5.  Drafts Folder                  : $WHT$draft_folder$NRM\n";
+        print "6.  By default, move to trash      : $WHT$default_move_to_trash$NRM\n";
+        print "7.  By default, save sent messages : $WHT$default_move_to_sent$NRM\n";
+        print "8.  By default, save as draft      : $WHT$default_save_as_draft$NRM\n";
+        print "9.  List Special Folders First     : $WHT$list_special_folders_first$NRM\n";
+        print "10. Show Special Folders Color     : $WHT$use_special_folder_color$NRM\n";
+        print "11. Auto Expunge                   : $WHT$auto_expunge$NRM\n";
+        print "12. Default Sub. of INBOX          : $WHT$default_sub_of_inbox$NRM\n";
+        print "13. Show 'Contain Sub.' Option     : $WHT$show_contain_subfolders_option$NRM\n";
+        print "14. Default Unseen Notify          : $WHT$default_unseen_notify$NRM\n";
+        print "15. Default Unseen Type            : $WHT$default_unseen_type$NRM\n";
+        print "16. Auto Create Special Folders    : $WHT$auto_create_special$NRM\n";
+        print "17. Folder Delete Bypasses Trash   : $WHT$delete_folder$NRM\n";
+        print "18. Enable /NoSelect folder fix    : $WHT$noselect_fix_enable$NRM\n";
         print "\n";
         print "R   Return to Main Menu\n";
     } elsif ( $menu == 4 ) {
         print $WHT. "General Options\n" . $NRM;
         print "\n";
         print "R   Return to Main Menu\n";
     } elsif ( $menu == 4 ) {
         print $WHT. "General Options\n" . $NRM;
-        print "1.  Data Directory              : $WHT$data_dir$NRM\n";
-        print "2.  Attachment Directory        : $WHT$attachment_dir$NRM\n";
-        print "3.  Directory Hash Level        : $WHT$dir_hash_level$NRM\n";
-        print "4.  Default Left Size           : $WHT$default_left_size$NRM\n";
-        print "5.  Usernames in Lowercase      : $WHT$force_username_lowercase$NRM\n";
-        print "6.  Allow use of priority       : $WHT$default_use_priority$NRM\n";
-        print "7.  Hide SM attributions        : $WHT$hide_sm_attributions$NRM\n";
-        print "8.  Allow use of receipts       : $WHT$default_use_mdn$NRM\n";
-        print "9.  Allow editing of identity   : $WHT$edit_identity$NRM\n";
-        print "    Allow editing of name       : $WHT$edit_name$NRM\n";
-        print "    Remove username from header : $WHT$hide_auth_header$NRM\n";
-        print "10. Disable server thread sort  : $WHT$disable_thread_sort$NRM\n";
-        print "11. Disable server-side sorting : $WHT$disable_server_sort$NRM\n";
-        print "12. Allow server charset search : $WHT$allow_charset_search$NRM\n";
-        print "13. Allow advanced search       : $WHT$allow_advanced_search$NRM\n";
-        print "14. PHP session name            : $WHT$session_name$NRM\n";
-        print "15. Time zone configuration     : $WHT$time_zone_type$NRM\n";
-        print "16. Location base               : $WHT$config_location_base$NRM\n";
+        print "1.  Data Directory               : $WHT$data_dir$NRM\n";
+        print "2.  Attachment Directory         : $WHT$attachment_dir$NRM\n";
+        print "3.  Directory Hash Level         : $WHT$dir_hash_level$NRM\n";
+        print "4.  Default Left Size            : $WHT$default_left_size$NRM\n";
+        print "5.  Usernames in Lowercase       : $WHT$force_username_lowercase$NRM\n";
+        print "6.  Allow use of priority        : $WHT$default_use_priority$NRM\n";
+        print "7.  Hide SM attributions         : $WHT$hide_sm_attributions$NRM\n";
+        print "8.  Allow use of receipts        : $WHT$default_use_mdn$NRM\n";
+        print "9.  Allow editing of identity    : $WHT$edit_identity$NRM\n";
+        print "    Allow editing of name        : $WHT$edit_name$NRM\n";
+        print "    Remove username from header  : $WHT$hide_auth_header$NRM\n";
+        print "10. Disable server thread sort   : $WHT$disable_thread_sort$NRM\n";
+        print "11. Disable server-side sorting  : $WHT$disable_server_sort$NRM\n";
+        print "12. Allow server charset search  : $WHT$allow_charset_search$NRM\n";
+        print "13. Allow advanced search        : $WHT$allow_advanced_search$NRM\n";
+        print "14. PHP session name             : $WHT$session_name$NRM\n";
+        print "15. Time zone configuration      : $WHT$time_zone_type$NRM\n";
+        print "16. Location base                : $WHT$config_location_base$NRM\n";
+        print "17. Only secure cookies if poss. : $WHT$only_secure_cookies$NRM\n";
+        print "18. Disable secure forms         : $WHT$disable_security_tokens$NRM\n";
+        print "19. Page referal requirement     : $WHT$check_referrer$NRM\n";
         print "\n";
         print "R   Return to Main Menu\n";
     } elsif ( $menu == 5 ) {
         print "\n";
         print "R   Return to Main Menu\n";
     } elsif ( $menu == 5 ) {
-        print $WHT. "Themes\n" . $NRM;
-        print "1.  Change Template set\n";
-#        for ( $count = 0 ; $count <= $#theme_name/2 ; $count++ ) {
-#            $temp_name = $theme_name[$count*2];
-#            printf "     %s%*s    %s\n", $temp_name,
-#                   40 - length($temp_name), " ",
-#                   $theme_name[($count*2)+1];
-#        }
-        print "2.  CSS File : $WHT$theme_css$NRM\n";
-        print "3.  Default font size: $WHT$default_fontsize$NRM\n";
-        print "4.  Change available font sets\n";
-        print "5.  Change Themes\n";
+        print $WHT. "User Interface\n" . $NRM;
+        print "1.  Use Icons?                   : $WHT$use_icons$NRM\n";
+#        print "3.  Default Icon Set             : $WHT$icon_theme_def$NRM\n";
+        print "2.  Default font size            : $WHT$default_fontsize$NRM\n";
+        print "3.  Manage template sets (skins)\n";
+        print "4.  Manage user themes\n";
+        print "5.  Manage font sets\n";
+        print "6.  Manage icon themes\n";
 
         print "\n";
         print "R   Return to Main Menu\n";
 
         print "\n";
         print "R   Return to Main Menu\n";
@@ -642,20 +760,35 @@ while ( ( $command ne "q" ) && ( $command ne "Q" ) && ( $command ne ":q" ) ) {
         print "\n";
         print "R   Return to Main Menu\n";
     } elsif ( $menu == 8 ) {
         print "\n";
         print "R   Return to Main Menu\n";
     } elsif ( $menu == 8 ) {
-        print $WHT. "Plugins\n" . $NRM;
+        if (lc($disable_plugins) eq 'true' && $disable_plugins_user ne '') {
+            print $WHT. "Plugins (WARNING: All plugins are currently disabled\n                  for the user \"$disable_plugins_user\"!)\n" . $NRM;
+        } elsif (lc($disable_plugins) eq 'true') {
+            print $WHT. "Plugins (WARNING: All plugins are currently disabled!)\n" . $NRM;
+        } else {
+            print $WHT. "Plugins\n" . $NRM;
+        }
         print "  Installed Plugins\n";
         print "  Installed Plugins\n";
-        $num = 0;
-        for ( $count = 0 ; $count <= $#plugins ; $count++ ) {
-            $num = $count + 1;
-            print "    $num. $plugins[$count]\n";
+        if ($columns > 1) {
+            $num = print_multi_col_list(1, $columns, $screen_width, 1, @plugins);
+        } else {
+            $num = 0;
+            for ( $count = 0 ; $count <= $#plugins ; $count++ ) {
+                $num = $count + 1;
+                $english_name = get_plugin_english_name($plugins[$count]);
+                if ( $english_name eq "" ) {
+                    print "    $WHT$num.$NRM $plugins[$count]" . get_plugin_version($plugins[$count]) . "\n";
+                } else {
+                    print "    $WHT$num.$NRM $english_name ($plugins[$count])" . get_plugin_version($plugins[$count]) . "\n";
+                }
+            }
         }
         print "\n  Available Plugins:\n";
         opendir( DIR, "../plugins" );
         }
         print "\n  Available Plugins:\n";
         opendir( DIR, "../plugins" );
-        @files          = readdir(DIR);
+        @files          = sort(readdir(DIR));
         $pos            = 0;
         @unused_plugins = ();
         for ( $i = 0 ; $i <= $#files ; $i++ ) {
         $pos            = 0;
         @unused_plugins = ();
         for ( $i = 0 ; $i <= $#files ; $i++ ) {
-            if ( -d "../plugins/" . $files[$i] && $files[$i] !~ /^\./ && $files[$i] ne "CVS" ) {
+            if ( -d "../plugins/" . $files[$i] && $files[$i] !~ /^\./ && $files[$i] ne ".svn" ) {
                 $match = 0;
                 for ( $k = 0 ; $k <= $#plugins ; $k++ ) {
                     if ( $plugins[$k] eq $files[$i] ) {
                 $match = 0;
                 for ( $k = 0 ; $k <= $#plugins ; $k++ ) {
                     if ( $plugins[$k] eq $files[$i] ) {
@@ -669,14 +802,33 @@ while ( ( $command ne "q" ) && ( $command ne "Q" ) && ( $command ne ":q" ) ) {
             }
         }
 
             }
         }
 
-        for ( $i = 0 ; $i <= $#unused_plugins ; $i++ ) {
-            $num = $num + 1;
-            print "    $num. $unused_plugins[$i]\n";
+        if ($columns > 1) {
+            $num = print_multi_col_list($num + 1, $columns, $screen_width, 1, @unused_plugins);
+        } else {
+            for ( $i = 0 ; $i <= $#unused_plugins ; $i++ ) {
+                $num = $num + 1;
+                $english_name = get_plugin_english_name($unused_plugins[$i]);
+                if ( $english_name eq "" ) {
+                    print "    $WHT$num.$NRM $unused_plugins[$i]" . get_plugin_version($unused_plugins[$i]) . "\n";
+                } else {
+                    print "    $WHT$num.$NRM $english_name ($unused_plugins[$i])" . get_plugin_version($unused_plugins[$i]) . "\n";
+                }
+            }
         }
         closedir DIR;
 
         print "\n";
         }
         closedir DIR;
 
         print "\n";
+        if (lc($disable_plugins) eq 'true' && $disable_plugins_user ne '') {
+            print "E   Enable active plugins (all plugins currently\n    disabled for the user \"$disable_plugins_user\")\n";
+        } elsif (lc($disable_plugins) eq 'true') {
+            print "E   Enable active plugins (all plugins currently\n    disabled)\n";
+        } else {
+            print "D   Disable all plugins\n";
+        }
+        print "U   Set the user for whom plugins can be disabled\n";
         print "R   Return to Main Menu\n";
         print "R   Return to Main Menu\n";
+        print "C#  List plugins in <#> number of columns\n";
+        print "W#  Change screen width to <#> (currently $screen_width)\n";
     } elsif ( $menu == 9 ) {
         print $WHT. "Database\n" . $NRM;
         print "1.  DSN for Address Book   : $WHT$addrbook_dsn$NRM\n";
     } elsif ( $menu == 9 ) {
         print $WHT. "Database\n" . $NRM;
         print "1.  DSN for Address Book   : $WHT$addrbook_dsn$NRM\n";
@@ -695,27 +847,31 @@ while ( ( $command ne "q" ) && ( $command ne "Q" ) && ( $command ne ":q" ) ) {
         print "\n";
         print "R   Return to Main Menu\n";
     } elsif ( $menu == 10 ) {
         print "\n";
         print "R   Return to Main Menu\n";
     } elsif ( $menu == 10 ) {
-    print $WHT. "Language settings\n" . $NRM;
-    print "1.  Default Language                : $WHT$squirrelmail_default_language$NRM\n";
-    print "2.  Default Charset                 : $WHT$default_charset$NRM\n";
-    print "3.  Show alternative language names : $WHT$show_alternative_names$NRM\n";
-    print "4.  Enable aggressive decoding      : $WHT$aggressive_decoding$NRM\n";
-    print "5.  Enable lossy encoding           : $WHT$lossy_encoding$NRM\n";
-    print "\n";
+        print $WHT. "Language settings\n" . $NRM;
+        print "1.  Default Language                : $WHT$squirrelmail_default_language$NRM\n";
+        print "2.  Default Charset                 : $WHT$default_charset$NRM\n";
+        print "3.  Show alternative language names : $WHT$show_alternative_names$NRM\n";
+        print "4.  Enable aggressive decoding      : $WHT$aggressive_decoding$NRM\n";
+        print "5.  Enable lossy encoding           : $WHT$lossy_encoding$NRM\n";
+        print "\n";
         print "R   Return to Main Menu\n";
     } elsif ( $menu == 11 ) {
         print "R   Return to Main Menu\n";
     } elsif ( $menu == 11 ) {
-    print $WHT. "Interface tweaks\n" . $NRM;
-    print "1.  Display html mails in iframe : $WHT$use_iframe$NRM\n";
-    print "2.  Use Icons                    : $WHT$use_icons$NRM\n";
-    print "3.  Default Icon Set             : $WHT$icon_theme_def$NRM\n";
-    print "\n";
-    print $WHT. "PHP tweaks\n" . $NRM;
-    print "4.  Use php recode functions     : $WHT$use_php_recode$NRM\n";
-    print "5.  Use php iconv functions      : $WHT$use_php_iconv$NRM\n";
-    print "\n";
-    print $WHT. "Configuration tweaks\n" . $NRM;
-    print "6.  Allow remote configtest     : $WHT$allow_remote_configtest$NRM\n";
-    print "\n";
+        print $WHT. "Interface tweaks\n" . $NRM;
+        print "1.  Display html mails in iframe : $WHT$use_iframe$NRM\n";
+        print "2.  Ask user info on first login : $WHT$ask_user_info$NRM\n";
+        print "\n";
+        print $WHT. "PHP tweaks\n" . $NRM;
+        print "4.  Use php recode functions     : $WHT$use_php_recode$NRM\n";
+        print "5.  Use php iconv functions      : $WHT$use_php_iconv$NRM\n";
+        print "6.  Buffer all output            : $WHT$buffer_output$NRM\n";
+        print "\n";
+        print $WHT. "Configuration tweaks\n" . $NRM;
+        print "7.  Allow remote configtest     : $WHT$allow_remote_configtest$NRM\n";
+        print "8.  Debug mode                  : $WHT$sm_debug_mode$NRM\n";
+        print "9.  Secured configuration mode  : $WHT$secured_config$NRM\n";
+        print "10. HTTPS port                  : $WHT$sq_https_port$NRM\n";
+        print "11. Ignore HTTP_X_FORWARDED headers: $WHT$sq_ignore_http_x_forwarded_headers$NRM\n";
+        print "\n";
         print "R   Return to Main Menu\n";
     }
     if ( $config_use_color == 1 ) {
         print "R   Return to Main Menu\n";
     }
     if ( $config_use_color == 1 ) {
@@ -755,9 +911,11 @@ while ( ( $command ne "q" ) && ( $command ne "Q" ) && ( $command ne ":q" ) ) {
             $NRM              = "";
         } else {
             $config_use_color = 1;
             $NRM              = "";
         } else {
             $config_use_color = 1;
-            $WHT              = "\x1B[37;1m";
+            $WHT              = "\x1B[1m";
             $NRM              = "\x1B[0m";
         }
             $NRM              = "\x1B[0m";
         }
+    } elsif ( $command =~ /^w([0-9]+)/ ) {
+        $screen_width = $1;
     } elsif ( $command eq "d" && $menu == 0 ) {
         set_defaults();
     } else {
     } elsif ( $command eq "d" && $menu == 0 ) {
         set_defaults();
     } else {
@@ -840,12 +998,17 @@ while ( ( $command ne "q" ) && ( $command ne "Q" ) && ( $command ne ":q" ) ) {
             elsif ( $command == 14 ) { $session_name             = command317(); }
             elsif ( $command == 15 ) { $time_zone_type           = command318(); }
             elsif ( $command == 16 ) { $config_location_base     = command_config_location_base(); }
             elsif ( $command == 14 ) { $session_name             = command317(); }
             elsif ( $command == 15 ) { $time_zone_type           = command318(); }
             elsif ( $command == 16 ) { $config_location_base     = command_config_location_base(); }
+            elsif ( $command == 17 ) { $only_secure_cookies = command319(); }
+            elsif ( $command == 18 ) { $disable_security_tokens  = command320(); }
+            elsif ( $command == 19 ) { $check_referrer           = command321(); }
         } elsif ( $menu == 5 ) {
         } elsif ( $menu == 5 ) {
-            if ( $command == 1 ) { $templateset_default = command_templates(); }
-            elsif ( $command == 2 ) { $theme_css = command42(); }
-            elsif ( $command == 3 ) { $default_fontsize = command_default_fontsize(); }
-            elsif ( $command == 4 ) { command_fontsets(); }
-            elsif ( $command == 5 ) { command41(); }
+            if ( $command == 1 )     { $use_icons      = commandB3(); }
+#            elsif ( $command == 3 )  { $icon_theme_def = command53(); }
+            elsif ( $command == 2 )  { $default_fontsize = command_default_fontsize(); }
+            elsif ( $command == 3 )  { $templateset_default = command_templates(); }
+            elsif ( $command == 4 )  { command_userThemes(); }
+            elsif ( $command == 5 )  { command_fontsets(); }
+            elsif ( $command == 6 )  { command_iconSets(); }
         } elsif ( $menu == 6 ) {
             if    ( $command == 1 ) { command61(); }
             elsif ( $command == 2 ) { command62(); }
         } elsif ( $menu == 6 ) {
             if    ( $command == 1 ) { command61(); }
             elsif ( $command == 2 ) { command62(); }
@@ -856,7 +1019,11 @@ while ( ( $command ne "q" ) && ( $command ne "Q" ) && ( $command ne ":q" ) ) {
         } elsif ( $menu == 7 ) {
             if ( $command == 1 ) { $motd = command71(); }
         } elsif ( $menu == 8 ) {
         } elsif ( $menu == 7 ) {
             if ( $command == 1 ) { $motd = command71(); }
         } elsif ( $menu == 8 ) {
-            if ( $command =~ /^[0-9]+/ ) { @plugins = command81(); }
+            if    ( $command =~ /^[0-9]+/ )    { @plugins              = command81(); }
+            elsif ( $command eq "u" )          { $disable_plugins_user = command82(); }
+            elsif ( $command eq "d" )          { $disable_plugins      = 'true'; }
+            elsif ( $command eq "e" )          { $disable_plugins      = 'false'; }
+            elsif ( $command =~ /^c([0-9]+)/ ) { $columns              = $1; }
         } elsif ( $menu == 9 ) {
             if    ( $command == 1 ) { $addrbook_dsn     = command91(); }
             elsif ( $command == 2 ) { $addrbook_table   = command92(); }
         } elsif ( $menu == 9 ) {
             if    ( $command == 1 ) { $addrbook_dsn     = command91(); }
             elsif ( $command == 2 ) { $addrbook_table   = command92(); }
@@ -877,11 +1044,15 @@ while ( ( $command ne "q" ) && ( $command ne "Q" ) && ( $command ne ":q" ) ) {
             elsif ( $command == 5 ) { $lossy_encoding                = commandA5(); }
         } elsif ( $menu == 11 ) {
             if    ( $command == 1 ) { $use_iframe     = commandB2(); }
             elsif ( $command == 5 ) { $lossy_encoding                = commandA5(); }
         } elsif ( $menu == 11 ) {
             if    ( $command == 1 ) { $use_iframe     = commandB2(); }
-            elsif ( $command == 2 ) { $use_icons      = commandB3(); }
-            elsif ( $command == 3 ) { $icon_theme_def = commandB7(); }
+            elsif ( $command == 2 ) { $ask_user_info  = command_ask_user_info(); }
             elsif ( $command == 4 ) { $use_php_recode = commandB4(); }
             elsif ( $command == 5 ) { $use_php_iconv  = commandB5(); }
             elsif ( $command == 4 ) { $use_php_recode = commandB4(); }
             elsif ( $command == 5 ) { $use_php_iconv  = commandB5(); }
-            elsif ( $command == 6 ) { $allow_remote_configtest = commandB6(); }
+            elsif ( $command == 6 ) { $buffer_output  = commandB6(); }
+            elsif ( $command == 7 ) { $allow_remote_configtest = commandB7(); }
+            elsif ( $command == 8 ) { $sm_debug_mode = commandB8(); }
+            elsif ( $command == 9 ) { $secured_config = commandB9(); }
+            elsif ( $command == 10 ) { $sq_https_port = commandB10(); }
+            elsif ( $command == 11 ) { $sq_ignore_http_x_forwarded_headers = commandB11(); }
         }
     }
 }
         }
     }
 }
@@ -926,7 +1097,7 @@ sub command2 {
     print "    to use the default logo, use ../images/sm_logo.png\n";
     print "  - To specify a logo defined outside the SquirrelMail source tree\n";
     print "    use the absolute URL the webserver would use to include the file\n";
     print "    to use the default logo, use ../images/sm_logo.png\n";
     print "  - To specify a logo defined outside the SquirrelMail source tree\n";
     print "    use the absolute URL the webserver would use to include the file\n";
-    print "    e.g. http://www.example.com/images/mylogo.gif or /images/mylogo.jpg\n";
+    print "    e.g. http://example.com/images/mylogo.gif or /images/mylogo.jpg\n";
     print "\n";
     print "[$WHT$org_logo$NRM]: $WHT";
     $new_org_logo = <STDIN>;
     print "\n";
     print "[$WHT$org_logo$NRM]: $WHT";
     $new_org_logo = <STDIN>;
@@ -1021,8 +1192,8 @@ sub command6 {
 
 # Default link to provider
 sub command7 {
 
 # Default link to provider
 sub command7 {
-    print "Here you can set the link on the right of the page.\n";
-    print "If empty, it will link to the SquirrelMail About page.\n";
+    print "Here you can set the link on the top-right of the message list.\n";
+    print "If empty, it will not be displayed.\n";
     print "\n";
     print "[$WHT$provider_uri$NRM]: $WHT";
     $new_provider_uri = <STDIN>;
     print "\n";
     print "[$WHT$provider_uri$NRM]: $WHT";
     $new_provider_uri = <STDIN>;
@@ -1036,13 +1207,13 @@ sub command7 {
 }
 
 sub command8 {
 }
 
 sub command8 {
-    print "Here you can set the name of the link on the right of the page.\n";
-    print "The default is 'SquirrelMail'\n";
+    print "Here you can set the name of the link on the top-right of the message list.\n";
+    print "The default is empty (do not display anything).'\n";
     print "\n";
     print "[$WHT$provider_name$NRM]: $WHT";
     $new_provider_name = <STDIN>;
     if ( $new_provider_name eq "\n" ) {
     print "\n";
     print "[$WHT$provider_name$NRM]: $WHT";
     $new_provider_name = <STDIN>;
     if ( $new_provider_name eq "\n" ) {
-        $new_provider_name = 'SquirrelMail';
+        $new_provider_name = '';
     } else {
         $new_provider_name =~ s/[\r\n]//g;
         $new_provider_name =~ s/^\s+$//g;
     } else {
         $new_provider_name =~ s/[\r\n]//g;
         $new_provider_name =~ s/^\s+$//g;
@@ -1064,7 +1235,7 @@ sub command11 {
     if ( $new_domain eq "\n" ) {
         $new_domain = $domain;
     } else {
     if ( $new_domain eq "\n" ) {
         $new_domain = $domain;
     } else {
-        $new_domain =~ s/[\r\n]//g;
+        $new_domain =~ s/\s//g;
     }
     return $new_domain;
 }
     }
     return $new_domain;
 }
@@ -1187,13 +1358,38 @@ sub command18a {
     $YesNo = 'n';
     $YesNo = 'y' if ( lc($pop_before_smtp) eq 'true' );
 
     $YesNo = 'n';
     $YesNo = 'y' if ( lc($pop_before_smtp) eq 'true' );
 
-    print "Use pop before SMTP (y/n) [$WHT$YesNo$NRM]: $WHT";
+    print "Use POP before SMTP (y/n) [$WHT$YesNo$NRM]: $WHT";
 
     $new_pop_before_smtp = <STDIN>;
     $new_pop_before_smtp =~ tr/yn//cd;
 
     $new_pop_before_smtp = <STDIN>;
     $new_pop_before_smtp =~ tr/yn//cd;
-    return 'true'  if ( $new_pop_before_smtp eq "y" );
-    return 'false'  if ( $new_pop_before_smtp eq "n" );
-    return $pop_before_smtp;
+    if ( $new_pop_before_smtp eq "y" ) {
+        $new_pop_before_smtp = "true";
+    } elsif ( $new_pop_before_smtp eq "n" ) {
+        $new_pop_before_smtp = "false";
+    } else {
+        $new_pop_before_smtp = $pop_before_smtp;
+    }
+
+    # if using POP before SMTP, allow setting of custom POP server address
+    if ($new_pop_before_smtp eq "true") {
+        print "$NRM\nIf the address of the POP server is not the same as\n";
+        print "your SMTP server, you may specify it here. Leave blank (to\n";
+        print "clear this, enter only spaces) to use the same address as\n";
+        print "your SMTP server.\n";
+        print "POP before SMTP server address [$WHT$pop_before_smtp_host$NRM]: $WHT";
+
+        $new_pop_before_smtp_host = <STDIN>;
+        if ( $new_pop_before_smtp_host eq "\n" ) {
+            $new_pop_before_smtp_host = $pop_before_smtp_host;
+        } elsif ($new_pop_before_smtp_host =~ /^\s+$/) {
+            $new_pop_before_smtp_host = '';
+        } else {
+            $new_pop_before_smtp_host =~ s/[\r|\n]//g;
+        }
+        $pop_before_smtp_host = $new_pop_before_smtp_host;
+    }
+
+    return $new_pop_before_smtp;
 }
 
 # imap_server_type
 }
 
 # imap_server_type
@@ -1204,14 +1400,7 @@ sub command19 {
     print "these servers.  If you would like to use them, please select your\n";
     print "IMAP server.  If you do not wish to use these work-arounds, you can\n";
     print "set this to \"other\", and none will be used.\n";
     print "these servers.  If you would like to use them, please select your\n";
     print "IMAP server.  If you do not wish to use these work-arounds, you can\n";
     print "set this to \"other\", and none will be used.\n";
-    print "    courier     = Courier IMAP server\n";
-    print "    cyrus       = Cyrus IMAP server\n";
-    print "    dovecot     = Dovecot Secure IMAP server\n";
-    print "    exchange    = Microsoft Exchange IMAP server\n";
-    print "    hmailserver = hMailServer\n";
-    print "    macosx      = Mac OS X Mailserver\n";
-    print "    mercury32   = Mercury Mail Transport System\n";
-    print "    uw          = University of Washington's IMAP server\n";
+    print $list_supported_imap_servers;
     print "\n";
     print "    other       = Not one of the above servers\n";
     print "\n";
     print "\n";
     print "    other       = Not one of the above servers\n";
     print "\n";
@@ -1361,6 +1550,7 @@ sub command112b {
                 print " ERROR TESTING\n";
                 close $sock;
             } else {
                 print " ERROR TESTING\n";
                 close $sock;
             } else {
+                $got = <$sock>;  # Discard greeting
                 print $sock "HELO $domain\r\n";
                 $got = <$sock>;  # Discard
                 print $sock "MAIL FROM:<tester\@squirrelmail.org>\r\n";
                 print $sock "HELO $domain\r\n";
                 $got = <$sock>;  # Discard
                 print $sock "MAIL FROM:<tester\@squirrelmail.org>\r\n";
@@ -1461,10 +1651,10 @@ sub command_smtp_sitewide_userpass($) {
     print "SMTP connections?";
     if ($smtp_sitewide_user ne '') {
         $default = 'y';
     print "SMTP connections?";
     if ($smtp_sitewide_user ne '') {
         $default = 'y';
-        print " [Yn]:";
+        print " [Y/n]:";
     } else {
         $default = 'n';
     } else {
         $default = 'n';
-        print " [yN]:";
+        print " [y/N]:";
     }
     $tmp=<STDIN>;
     $tmp = trim($tmp);
     }
     $tmp=<STDIN>;
     $tmp = trim($tmp);
@@ -1495,12 +1685,12 @@ sub command_smtp_sitewide_userpass($) {
             }
         } else {
             print "Invalid input. You must set username used for SMTP authentication.\n";
             }
         } else {
             print "Invalid input. You must set username used for SMTP authentication.\n";
-            print "Click any key to continue\n";
+            print "Click enter to continue\n";
             $tmp = <STDIN>;
         }
     } else {
         print "Invalid input\n";
             $tmp = <STDIN>;
         }
     } else {
         print "Invalid input\n";
-        print "Click any key to continue\n";
+        print "Click enter to continue\n";
         $tmp = <STDIN>;
     }
 }
         $tmp = <STDIN>;
     }
 }
@@ -1563,18 +1753,23 @@ sub display_use_tls($) {
 }
 
 # $encode_header_key
 }
 
 # $encode_header_key
-sub command114{
-    print "Encryption key allows to hide SquirrelMail Received: headers\n";
-    print "in outbound messages. Interface uses encryption key to encode\n";
-    print "username, remote address and proxied address, then stores encoded\n";
-    print "information in X-Squirrel-* headers.\n";
+sub command114 {
+    print "This encryption key allows the hiding of SquirrelMail Received:\n";
+    print "headers in outbound messages.  SquirrelMail uses the encryption\n";
+    print "key to encode the username, remote address, and proxied address\n";
+    print "and then stores that encoded information in X-Squirrel-* headers.\n";
     print "\n";
     print "\n";
-    print "Warning: used encryption function is not bulletproof. When used\n";
-    print "with static encryption keys, it provides only minimal security\n";
-    print "measures and information can be decoded quickly.\n";
+    print "Warning: the encryption function used to accomplish this is not\n";
+    print "bulletproof. When used with a static encryption key as it is here,\n";
+    print "it provides only minimal security and the encoded user information\n";
+    print "in the X-Squirrel-* headers can be decoded quickly by a skilled\n";
+    print "attacker.\n";
     print "\n";
     print "\n";
-    print "Encoded information can be decoded with decrypt_headers.php script\n";
-    print "from SquirrelMail contrib/ directory.\n";
+    print "When you need to inspect an email sent from your system with the\n";
+    print "X-Squirrel-* headers, you can decode the user information therein\n";
+    print "by using the decrypt_headers.php script found in the SquirrelMail\n";
+    print "contrib/ directory. You'll need the encryption key that you\n";
+    print "defined here when doing so.\n";
     print "\n";
     print "Enter encryption key: ";
     $new_encode_header_key = <STDIN>;
     print "\n";
     print "Enter encryption key: ";
     $new_encode_header_key = <STDIN>;
@@ -1642,6 +1837,25 @@ sub command81 {
     return @plugins;
 }
 
     return @plugins;
 }
 
+# disable_plugins_user
+sub command82 {
+    print "When all active plugins are disabled, they can be disabled only\n";
+    print "for the one user named here.  If left blank, plugins will be\n";
+    print "disabled for ALL users.  This setting has no effect if plugins\n";
+    print "are not disabled.\n";
+    print "\n";
+    print "This must be the exact IMAP login name for the desired user.\n";
+    print "\n";
+    print "[$WHT$disable_plugins_user$NRM]: $WHT";
+    $new_disable_plugins_user = <STDIN>;
+    if ( $new_disable_plugins_user eq "\n" ) {
+        $new_disable_plugins_user = $disable_plugins_user;
+    } else {
+        $new_disable_plugins_user =~ s/[\r\n]//g;
+    }
+    return $new_disable_plugins_user;
+}
+
 ################# FOLDERS ###################
 
 # default_folder_prefix
 ################# FOLDERS ###################
 
 # default_folder_prefix
@@ -1811,11 +2025,12 @@ sub command24a {
     return $default_move_to_trash;
 }
 
     return $default_move_to_trash;
 }
 
-# default move to sent
+# default move to sent (save sent messages)
 sub command24b {
 sub command24b {
-    print "By default, should messages get moved to the sent folder?  You\n";
-    print "can specify the default sent folder in option 4.  If this is set\n";
-    print "to false, messages will get sent and no copy will be made.\n";
+    print "By default, should copies of outgoing messages get saved in the\n";
+    print "sent folder?  You can specify the default sent folder in option 4.\n";
+    print "If this is set to false, messages will get sent and no copy will\n";
+    print "be made.\n";
     print "\n";
     print "Sent folder is currently: $sent_folder\n";
     print "\n";
     print "\n";
     print "Sent folder is currently: $sent_folder\n";
     print "\n";
@@ -1825,7 +2040,7 @@ sub command24b {
     } else {
         $default_value = "n";
     }
     } else {
         $default_value = "n";
     }
-    print "By default, move to sent (y/n) [$WHT$default_value$NRM]: $WHT";
+    print "By default, save sent messages (y/n) [$WHT$default_value$NRM]: $WHT";
     $new_show = <STDIN>;
     if ( ( $new_show =~ /^y\n/i ) || ( ( $new_show =~ /^\n/ ) && ( $default_value eq "y" ) ) ) {
         $default_move_to_sent = 'true';
     $new_show = <STDIN>;
     if ( ( $new_show =~ /^y\n/i ) || ( ( $new_show =~ /^\n/ ) && ( $default_value eq "y" ) ) ) {
         $default_move_to_sent = 'true';
@@ -1844,7 +2059,7 @@ sub command24c {
     print "Drafts folder is currently: $draft_folder\n";
     print "\n";
 
     print "Drafts folder is currently: $draft_folder\n";
     print "\n";
 
-    if ( lc($default_move_to_draft) eq 'true' ) {
+    if ( lc($default_save_as_draft) eq 'true' ) {
         $default_value = "y";
     } else {
         $default_value = "n";
         $default_value = "y";
     } else {
         $default_value = "n";
@@ -2047,7 +2262,7 @@ sub command215 {
         print "Deleting folders will bypass the trash folder and be immediately deleted\n\n";
         print "If this is not the correct value for your server,\n";
         print "please use option D on the Main Menu to configure your server correctly.\n\n";
         print "Deleting folders will bypass the trash folder and be immediately deleted\n\n";
         print "If this is not the correct value for your server,\n";
         print "please use option D on the Main Menu to configure your server correctly.\n\n";
-        print "Press any key to continue...\n";
+        print "Press enter to continue...\n";
         $new_delete = <STDIN>;
         $delete_folder = 'true';
     } else {
         $new_delete = <STDIN>;
         $delete_folder = 'true';
     } else {
@@ -2086,7 +2301,7 @@ sub command215 {
 
 #noselect fix
 sub command216 {
 
 #noselect fix
 sub command216 {
-    print "Some IMAP server allow subfolders to exist even if the parent\n";
+    print "Some IMAP servers allow subfolders to exist even if the parent\n";
     print "folders do not. This fixes some problems with the folder list\n";
     print "when this is the case, causing the /NoSelect folders to be displayed\n";
     print "\n";
     print "folders do not. This fixes some problems with the folder list\n";
     print "when this is the case, causing the /NoSelect folders to be displayed\n";
     print "\n";
@@ -2272,7 +2487,7 @@ sub command38 {
     print "";
     print "\n";
 
     print "";
     print "\n";
 
-    if ( lc($default_hide_attribution) eq 'true' ) {
+    if ( lc($hide_sm_attributions) eq 'true' ) {
         $default_value = "y";
     } else {
         $default_value = "n";
         $default_value = "y";
     } else {
         $default_value = "n";
@@ -2336,7 +2551,8 @@ sub command310 {
 }
 
 sub command311 {
 }
 
 sub command311 {
-    print "  Given that users are not allowed to modify their
+    print "$NRM";
+    print "\n  Given that users are not allowed to modify their
   email address, can they edit their full name?
 
   ";
   email address, can they edit their full name?
 
   ";
@@ -2357,17 +2573,23 @@ sub command311 {
 }
 
 sub command311b {
 }
 
 sub command311b {
-    print "  SquirrelMail adds username information to every sent email
-  in order to prevent possible sender forging when users are allowed
-  to change their email and/or full name.
+    print "$NRM";
+    print "\n  SquirrelMail adds username information to every outgoing
+  email in order to prevent possible sender forging when users are
+  allowed to change their email and/or full name.
 
 
-  You can remove user information from this header (y), if you think that
+  You can remove user information from this header (y) if you think that
   it violates privacy or security.
 
   Note: If users are allowed to change their email addresses,
   this setting will make it difficult to determine who sent what where.
   Use at your own risk.
 
   it violates privacy or security.
 
   Note: If users are allowed to change their email addresses,
   this setting will make it difficult to determine who sent what where.
   Use at your own risk.
 
+  Note: If you have defined a header encryption key in your SMTP or
+  Sendmail settings (see the \"Server Settings\" option page), this
+  setting is ignored because all user information in outgoing messages
+  is encoded.
+
   ";
 
     if ( lc($hide_auth_header) eq "true" ) {
   ";
 
     if ( lc($hide_auth_header) eq "true" ) {
@@ -2497,7 +2719,7 @@ sub command318 {
     print "See SquirrelMail documentation about format of config/timezones.php file.\n";
     print "\n";
 
     print "See SquirrelMail documentation about format of config/timezones.php file.\n";
     print "\n";
 
-    print "Used time zone configuration (0,1,2,3)? [$WHT$time_zone_type$NRM]: $WHT";
+    print "Desired time zone configuration (0,1,2,3)? [$WHT$time_zone_type$NRM]: $WHT";
     $new_time_zone_type = <STDIN>;
     if ( $new_time_zone_type =~ /^[0123]\n/i ) {
         $time_zone_type = $new_time_zone_type;
     $new_time_zone_type = <STDIN>;
     if ( $new_time_zone_type =~ /^[0123]\n/i ) {
         $time_zone_type = $new_time_zone_type;
@@ -2528,20 +2750,136 @@ sub command_config_location_base {
     return $config_location_base;
 }
 
     return $config_location_base;
 }
 
+# only_secure_cookies (since 1.5.2)
+sub command319 {
+    print "This option allows you to specify that if a user session is initiated\n";
+    print "under a secure (HTTPS, SSL-encrypted) connection, the cookies given to\n";
+    print "the browser will ONLY be transmitted via a secure connection henceforth.\n\n";
+    print "Generally this is a Good Thing, and should NOT be disabled.  However,\n";
+    print "if you intend to use the Secure Login or Show SSL Link plugins to\n";
+    print "encrypt the user login, but not the rest of the SquirrelMail session,\n";
+    print "this can be turned off.  Think twice before doing so.\n";
+    print "\n";
+
+    if ( lc($only_secure_cookies) eq 'true' ) {
+        $default_value = "y";
+    } else {
+        $default_value = "n";
+    }
+    print "Transmit cookies only on secure connection when available? (y/n) [$WHT$default_value$NRM]: $WHT";
+    $only_secure_cookies = <STDIN>;
+    if ( ( $only_secure_cookies =~ /^y\n/i ) || ( ( $only_secure_cookies =~ /^\n/ ) && ( $default_value eq "y" ) ) ) {
+        $only_secure_cookies = 'true';
+    } else {
+        $only_secure_cookies = 'false';
+    }
+    return $only_secure_cookies;
+}
+
+
+# disable_security_tokens (since 1.5.2)
+sub command320 {
+    print "This option allows you to turn off the security checks in the forms\n";
+    print "that SquirrelMail generates.  It is NOT RECOMMENDED that you disable\n";
+    print "this feature - otherwise, your users may be exposed to phishing and\n";
+    print "other attacks.\n";
+    print "Unless you know what you are doing, you should leave this set to \"NO\".\n";
+    print "\n";
+
+    if ( lc($disable_security_tokens) eq 'true' ) {
+        $default_value = "y";
+    } else {
+        $default_value = "n";
+    }
+    print "Disable secure forms? (y/n) [$WHT$default_value$NRM]: $WHT";
+    $disable_security_tokens = <STDIN>;
+    if ( ( $disable_security_tokens =~ /^y\n/i ) || ( ( $disable_security_tokens =~ /^\n/ ) && ( $default_value eq "y" ) ) ) {
+        $disable_security_tokens = 'true';
+    } else {
+        $disable_security_tokens = 'false';
+    }
+    return $disable_security_tokens;
+}
+
+
+
+# check_referrer (since 1.1.5.2)
+sub command321 {
+    print "This option allows you to enable referal checks for all page requests\n";
+    print "made to SquirrelMail.  This can help ensure that page requests came\n";
+    print "from the same server and not from an attacker's site (usually the\n";
+    print "result of a XSS or phishing attack).  To enable referal checking,\n";
+    print "this setting can be set to the domain where your SquirrelMail is\n";
+    print "being hosted (usually the same as the Domain setting under Server\n";
+    print "Settings).  For example, it could be \"example.com\", or if you\n";
+    print "use a plugin (such as Login Manager) to host SquirrelMail on more\n";
+    print "than one domain, you can set this to \"###DOMAIN###\" to tell it\n";
+    print "to use the current domain.\n";
+    print "\n";
+    print "However, in some cases (where proxy servers are in use, etc.), the\n";
+    print "domain might be different.\n";
+    print "\n";
+    print "NOTE that referal checks are not foolproof - they can be spoofed by\n";
+    print "browsers, and some browsers intentionally don't send referal\n";
+    print "information (in which case, the check is silently bypassed)\n";
+    print "\n";
+
+    print "Referal requirement? [$WHT$check_referrer$NRM]: $WHT";
+    $new_check_referrer = <STDIN>;
+    chomp($new_check_referrer);
+    $check_referrer = $new_check_referrer;
+
+    return $check_referrer;
+}
+
+
+
+sub command_userThemes {
+    print "\nDefine the user themes that you wish to use.  If you have added\n";
+    print "a theme of your own, just follow the instructions (?) about\n";
+    print "how to add them.  You can also change the default theme.\n\n";
+    
+    print "Available user themes:\n";
+    $count = 0;
+    while ( $count <= $#user_theme_name ) {
+        if ( $count == $user_theme_default ) {
+            print " *";
+        } else {
+            print "  ";
+        }
+        if ( $count < 10 ) {
+            print " ";
+        }
+        $name       = $user_theme_name[$count];
+        $num_spaces = 35 - length($name);
+        for ( $i = 0 ; $i < $num_spaces ; $i++ ) {
+            $name = $name . " ";
+        }
 
 
+        print " $count.  $name";
+        print "($user_theme_path[$count])\n";
 
 
-sub command41 {
-    print "\nDefine the themes that you wish to use.  If you have added ";
-    print "a theme of your own, just follow the instructions (?) about how to add ";
-    print "them.  You can also change the default theme.\n";
-    print "[theme] command (?=help) > ";
+        $count++;
+    }
+    
+    print "\n";
+    print ".------------------------------------.\n";
+    print "| t             (detect user themes) |\n";
+    print "| +                 (add user theme) |\n";
+    print "| - N            (remove user theme) |\n";
+    print "| m N      (mark default user theme) |\n";
+    print "| l               (list user themes) |\n";
+    print "| d                           (done) |\n";
+    print "`------------------------------------'\n";
+    
+    print "\n[user_themes] command (?=help) > ";
     $input = <STDIN>;
     $input =~ s/[\r\n]//g;
     while ( $input ne "d" ) {
         if ( $input =~ /^\s*l\s*/i ) {
             $count = 0;
     $input = <STDIN>;
     $input =~ s/[\r\n]//g;
     while ( $input ne "d" ) {
         if ( $input =~ /^\s*l\s*/i ) {
             $count = 0;
-            while ( $count <= $#theme_name ) {
-                if ( $count == $theme_default ) {
+            while ( $count <= $#user_theme_name ) {
+                if ( $count == $user_theme_default ) {
                     print " *";
                 } else {
                     print "  ";
                     print " *";
                 } else {
                     print "  ";
@@ -2549,347 +2887,629 @@ sub command41 {
                 if ( $count < 10 ) {
                     print " ";
                 }
                 if ( $count < 10 ) {
                     print " ";
                 }
-                $name       = $theme_name[$count];
+                $name       = $user_theme_name[$count];
                 $num_spaces = 35 - length($name);
                 for ( $i = 0 ; $i < $num_spaces ; $i++ ) {
                     $name = $name . " ";
                 }
 
                 print " $count.  $name";
                 $num_spaces = 35 - length($name);
                 for ( $i = 0 ; $i < $num_spaces ; $i++ ) {
                     $name = $name . " ";
                 }
 
                 print " $count.  $name";
-                print "($theme_path[$count])\n";
+                print "($user_theme_path[$count])\n";
 
                 $count++;
             }
         } elsif ( $input =~ /^\s*m\s*[0-9]+/i ) {
 
                 $count++;
             }
         } elsif ( $input =~ /^\s*m\s*[0-9]+/i ) {
-            $old_def       = $theme_default;
-            $theme_default = $input;
-            $theme_default =~ s/^\s*m\s*//;
-            if ( ( $theme_default > $#theme_name ) || ( $theme_default < 0 ) ) {
-                print "Cannot set default theme to $theme_default.  That theme does not exist.\n";
-                $theme_default = $old_def;
+            $old_def       = $user_theme_default;
+            $user_theme_default = $input;
+            $user_theme_default =~ s/^\s*m\s*//;
+            if ( ( $user_theme_default > $#user_theme_name ) || ( $user_theme_default < 0 ) ) {
+                print "Cannot set default theme to $user_theme_default.  That theme does not exist.\n";
+                $user_theme_default = $old_def;
             }
         } elsif ( $input =~ /^\s*\+/ ) {
             }
         } elsif ( $input =~ /^\s*\+/ ) {
-            print "What is the name of this theme: ";
+            print "What is the name of this theme? ";
             $name = <STDIN>;
             $name =~ s/[\r\n]//g;
             $name = <STDIN>;
             $name =~ s/[\r\n]//g;
-            $theme_name[ $#theme_name + 1 ] = $name;
-            print "Be sure to put ../themes/ before the filename.\n";
-            print "What file is this stored in (ex: ../themes/default_theme.php): ";
+            $user_theme_name[ $#user_theme_name + 1 ] = $name;
+            print "Be sure to put ../css/ before the filename.\n";
+            print "What file is this stored in (ex: ../css/my_theme/): ";
             $name = <STDIN>;
             $name =~ s/[\r\n]//g;
             $name = <STDIN>;
             $name =~ s/[\r\n]//g;
-            $theme_path[ $#theme_path + 1 ] = $name;
+            $user_theme_path[ $#user_theme_path + 1 ] = $name;
         } elsif ( $input =~ /^\s*-\s*[0-9]?/ ) {
             if ( $input =~ /[0-9]+\s*$/ ) {
                 $rem_num = $input;
                 $rem_num =~ s/^\s*-\s*//g;
                 $rem_num =~ s/\s*$//;
             } else {
         } elsif ( $input =~ /^\s*-\s*[0-9]?/ ) {
             if ( $input =~ /[0-9]+\s*$/ ) {
                 $rem_num = $input;
                 $rem_num =~ s/^\s*-\s*//g;
                 $rem_num =~ s/\s*$//;
             } else {
-                $rem_num = $#theme_name;
+                $rem_num = $#user_theme_name;
             }
             }
-            if ( $rem_num == $theme_default ) {
+            if ( $rem_num == $user_theme_default ) {
                 print "You cannot remove the default theme!\n";
             } else {
                 $count          = 0;
                 @new_theme_name = ();
                 @new_theme_path = ();
                 print "You cannot remove the default theme!\n";
             } else {
                 $count          = 0;
                 @new_theme_name = ();
                 @new_theme_path = ();
-                while ( $count <= $#theme_name ) {
+                while ( $count <= $#user_theme_name ) {
                     if ( $count != $rem_num ) {
                     if ( $count != $rem_num ) {
-                        @new_theme_name = ( @new_theme_name, $theme_name[$count] );
-                        @new_theme_path = ( @new_theme_path, $theme_path[$count] );
+                        @new_theme_name = ( @new_theme_name, $user_theme_name[$count] );
+                        @new_theme_path = ( @new_theme_path, $user_theme_path[$count] );
                     }
                     $count++;
                 }
                     }
                     $count++;
                 }
-                @theme_name = @new_theme_name;
-                @theme_path = @new_theme_path;
-                if ( $theme_default > $rem_num ) {
-                    $theme_default--;
+                @user_theme_name = @new_theme_name;
+                @user_theme_path = @new_theme_path;
+                if ( $user_theme_default > $rem_num ) {
+                    $user_theme_default--;
                 }
             }
         } elsif ( $input =~ /^\s*t\s*/i ) {
             print "\nStarting detection...\n\n";
 
                 }
             }
         } elsif ( $input =~ /^\s*t\s*/i ) {
             print "\nStarting detection...\n\n";
 
-            opendir( DIR, "../themes" );
-            @files = grep { /\.php$/i } readdir(DIR);
+            opendir( DIR, "../css" );
+            @files = sort(readdir(DIR));
             $cnt = 0;
             while ( $cnt <= $#files ) {
             $cnt = 0;
             while ( $cnt <= $#files ) {
-                $filename = "../themes/" . $files[$cnt];
-                if ( $filename ne "../themes/index.php" ) {
+                $filename = "../css/" . $files[$cnt] .'/';
+                if ( $files[$cnt] !~ /^\./ && $filename ne "../css/rtl.css" && -e $filename . "default.css" ) {
                     $found = 0;
                     $found = 0;
-                    for ( $x = 0 ; $x <= $#theme_path ; $x++ ) {
-                        if ( $theme_path[$x] eq $filename ) {
+                    for ( $x = 0 ; $x <= $#user_theme_path ; $x++ ) {
+                        if ( $user_theme_path[$x] eq $filename ) {
                             $found = 1;
                         }
                     }
                     if ( $found != 1 ) {
                             $found = 1;
                         }
                     }
                     if ( $found != 1 ) {
-                        print "** Found theme: $filename\n";
-                        print "   What is its name? ";
+                        print "** Found user theme: $filename\n";
+                        $def = $files[$cnt];
+                        $def =~ s/_/ /g;
+                        $def = lc($def);
+                        #$def =~ s/(^\w+)/ucfirst $1/eg;
+                        #$def =~ s/(\s+)(\w+)/$1 . ucfirst $2/eg;
+                        $def =~ s/(^\w+)|(\s+)(\w+)/ucfirst $1 . $2 . ucfirst $3/eg;
+                        print "   What is its name? [$def]: ";
                         $nm = <STDIN>;
                         $nm = <STDIN>;
-                        $nm =~ s/[\n\r]//g;
-                        $theme_name[ $#theme_name + 1 ] = $nm;
-                        $theme_path[ $#theme_path + 1 ] = $filename;
+                        $nm =~ s/^\s+|\s+$|[\n\r]//g;
+                        if ( $nm eq '' ) { $nm = $def; }
+                        $user_theme_name[ $#user_theme_name + 1 ] = $nm;
+                        $user_theme_path[ $#user_theme_path + 1 ] = $filename;
                     }
                 }
                 $cnt++;
             }
             print "\n";
                     }
                 }
                 $cnt++;
             }
             print "\n";
-            for ( $cnt = 0 ; $cnt <= $#theme_path ; $cnt++ ) {
-                $filename = $theme_path[$cnt];
-                if ( !( -e $filename ) ) {
+            for ( $cnt = 0 ; $cnt <= $#user_theme_path ; $cnt++ ) {
+                $filename = $user_theme_path[$cnt];
+                if ( $filename != 'none' && !( -e $filename ."/default.css" ) ) {
                     print "  Removing $filename (file not found)\n";
                     $offset         = 0;
                     print "  Removing $filename (file not found)\n";
                     $offset         = 0;
-                    @new_theme_name = ();
-                    @new_theme_path = ();
-                    for ( $x = 0 ; $x < $#theme_path ; $x++ ) {
-                        if ( $theme_path[$x] eq $filename ) {
+                    @new_user_theme_name = ();
+                    @new_user_theme_path = ();
+                    for ( $x = 0 ; $x < $#user_theme_path ; $x++ ) {
+                        if ( $user_theme_path[$x] eq $filename ) {
                             $offset = 1;
                         }
                         if ( $offset == 1 ) {
                             $offset = 1;
                         }
                         if ( $offset == 1 ) {
-                            $new_theme_name[$x] = $theme_name[ $x + 1 ];
-                            $new_theme_path[$x] = $theme_path[ $x + 1 ];
+                            $new_user_theme_name[$x] = $user_theme_name[ $x + 1 ];
+                            $new_user_theme_path[$x] = $user_theme_path[ $x + 1 ];
                         } else {
                         } else {
-                            $new_theme_name[$x] = $theme_name[$x];
-                            $new_theme_path[$x] = $theme_path[$x];
+                            $new_user_theme_name[$x] = $user_theme_name[$x];
+                            $new_user_theme_path[$x] = $user_theme_path[$x];
                         }
                     }
                         }
                     }
-                    @theme_name = @new_theme_name;
-                    @theme_path = @new_theme_path;
+                    @user_theme_name = @new_user_theme_name;
+                    @user_theme_path = @new_user_theme_path;
                 }
             }
             print "\nDetection complete!\n\n";
 
             closedir DIR;
         } elsif ( $input =~ /^\s*\?\s*/ ) {
                 }
             }
             print "\nDetection complete!\n\n";
 
             closedir DIR;
         } elsif ( $input =~ /^\s*\?\s*/ ) {
-            print ".-------------------------.\n";
-            print "| t       (detect themes) |\n";
-            print "| +           (add theme) |\n";
-            print "| - N      (remove theme) |\n";
-            print "| m N      (mark default) |\n";
-            print "| l         (list themes) |\n";
-            print "| d                (done) |\n";
-            print "`-------------------------'\n";
+            print ".------------------------------------.\n";
+            print "| t             (detect user themes) |\n";
+            print "| +                 (add user theme) |\n";
+            print "| - N            (remove user theme) |\n";
+            print "| m N      (mark default user theme) |\n";
+            print "| l               (list user themes) |\n";
+            print "| d                           (done) |\n";
+            print "`------------------------------------'\n";
         }
         }
-        print "[theme] command (?=help) > ";
+        print "[user_themes] command (?=help) > ";
         $input = <STDIN>;
         $input =~ s/[\r\n]//g;
     }
 }
 
         $input = <STDIN>;
         $input =~ s/[\r\n]//g;
     }
 }
 
-sub command_templates {
-    print "\nDefine the template sets that you wish to use.  If you have added ";
-    print "a template set of your own, just follow the instructions (?) about how to add ";
-    print "them.  You can also change the default template.\n";
-
-    print "\n  Available Templates:\n";
+sub command_iconSets {
+    print "\nDefine the icon themes that you wish to use.  If you have added\n";
+    print "a theme of your own, just follow the instructions (?) about\n";
+    print "how to add them.  You can also change the default and fallback\n";
+    print "themes.  The default theme will be used when no icon theme is\n";
+    print "set by the user.  The fallback theme will be used if an icon\n";
+    print "cannot be found in the currently selected icon theme.\n\n";
+    
+    print "Available icon themes:\n\n";
 
     $count = 0;
 
     $count = 0;
-    while ( $count <= $#templateset_name ) {
-        if ( $count == $templateset_default ) {
-            print " *";
+    while ( $count <= $#icon_theme_name ) {
+        if ( $count == $icon_theme_def ) {
+            print " d";
+        } else {
+            print "  ";
+        }
+        if ( $count eq $icon_theme_fallback ) {
+            print "f ";
         } else {
             print "  ";
         }
         if ( $count < 10 ) {
             print " ";
         }
         } else {
             print "  ";
         }
         if ( $count < 10 ) {
             print " ";
         }
-        $name       = $templateset_name[$count];
+        $name       = $icon_theme_name[$count];
         $num_spaces = 35 - length($name);
         for ( $i = 0 ; $i < $num_spaces ; $i++ ) {
             $name = $name . " ";
         }
 
         print " $count.  $name";
         $num_spaces = 35 - length($name);
         for ( $i = 0 ; $i < $num_spaces ; $i++ ) {
             $name = $name . " ";
         }
 
         print " $count.  $name";
-        print "($templateset_id[$count])\n";
+        print "($icon_theme_path[$count])\n";
 
         $count++;
 
         $count++;
-   }
-
-# FIXME: what is this stuff?  it is commented out, can we just blast it?
-#    opendir( DIR, "../templates" );
-#    @files          = readdir(DIR);
-#    $pos            = 0;
-#
-#    while ( $cnt <= $#files ) {
-#        if ( -d "../templates/" . $files[$i] && $files[$i] !~ /^\./ && $files[$i] ne "CVS" ) {
-#            $filename = "../templates/" . $files[$cnt];
-#            $found = 0;
-#            for ( $x = 0 ; $x <= $#templateset_id ; $x++ ) {
-#                if ( $theme_path[$x] eq $filename ) {
-#                    $found = 1;
-#                }
-#            }
-#        }
-#        $cnt++;
-#    }
-#    for ( $i = 0 ; $i <= $#files ; $i++ ) {
-#        if ( -d "../templates/" . $files[$i] && $files[$i] !~ /^\./ && $files[$i] ne "CVS" ) {
-#            $match = 0;
-#           for ( $k = 0 ; $k <= $#aTemplateSets ; $k++ ) {
-#                if ( $aTemplateSets[$chosen] eq $files[$i] ) {
-#                    $match = 1;
-#                }
-#            }
-#           if ( $match == 0 ) {
-#                    $unused_plugins[$pos] = $files[$i];
-#                    $pos++;
-#                }
-#            }
-#    }
-#
-#    for ( $i = 0 ; $i <= $#unused_plugins ; $i++ ) {
-#        $num = $num + 1;
-#        print "    $num. $unused_plugins[$i]\n";
-#    }
-#    closedir DIR;
-
-    $menu_text = ".-------------------------------------.\n"
-               . "| t            (detect templates set) |\n"
-               . "| +                (add template set) |\n"
-               . "| - N           (remove template set) |\n"
-               . "| m N     (mark default template set) |\n"
-               . "| l              (list template sets) |\n"
-               . "| d                            (done) |\n"
-               . "|-------------------------------------|\n"
-               . "| where N is a template set number    |\n"
-               . "`-------------------------------------'\n";
+    }
+    
+    print "\n d = Default icon theme\n";
+    print " f = Fallback icon theme\n";
     print "\n";
     print "\n";
-    print $menu_text;
-    print "\n[template set] command (?=help) > ";
-
+    print ".------------------------------------.\n";
+    print "| t             (detect icon themes) |\n";
+    print "| +                 (add icon theme) |\n";
+    print "| - N            (remove icon theme) |\n";
+    print "| m N      (mark default icon theme) |\n";
+    print "| f N        (set fallback icon set) |\n";
+    print "| l               (list icon themes) |\n";
+    print "| d                           (done) |\n";
+    print "`------------------------------------'\n";
+    
+    print "\n[icon_themes] command (?=help) > ";
     $input = <STDIN>;
     $input =~ s/[\r\n]//g;
     while ( $input ne "d" ) {
     $input = <STDIN>;
     $input =~ s/[\r\n]//g;
     while ( $input ne "d" ) {
-
-        # list template sets
-        #
         if ( $input =~ /^\s*l\s*/i ) {
         if ( $input =~ /^\s*l\s*/i ) {
-# LEFT OFF HERE!  default is lost after detection.... hmmmm
-print "DEFAULT INDEX IS " . $templateset_default . "\n";
             $count = 0;
             $count = 0;
-            while ( $count <= $#templateset_name ) {
-                if ( $count == $templateset_default ) {
-                    print " *";
-                } else {
-                    print "  ";
-                }
-                if ( $count < 10 ) {
-                    print " ";
-                }
-                $name       = $templateset_name[$count];
+            print "\n";
+            while ( $count <= $#icon_theme_name ) {
+                       if ( $count == $icon_theme_def ) {
+                           print " d";
+                       } else {
+                           print "  ";
+                       }
+                       if ( $count eq $icon_theme_fallback ) {
+                           print "f ";
+                       } else {
+                           print "  ";
+                       }
+                $name       = $icon_theme_name[$count];
                 $num_spaces = 35 - length($name);
                 for ( $i = 0 ; $i < $num_spaces ; $i++ ) {
                     $name = $name . " ";
                 }
 
                 print " $count.  $name";
                 $num_spaces = 35 - length($name);
                 for ( $i = 0 ; $i < $num_spaces ; $i++ ) {
                     $name = $name . " ";
                 }
 
                 print " $count.  $name";
-                print "($templateset_id[$count])\n";
+                print "($icon_theme_path[$count])\n";
 
                 $count++;
             }
 
                 $count++;
             }
-
-        # mark default template set
-        #
+                   print "\n d = Default icon theme\n";
+                   print " f = Fallback icon theme\n\n";
         } elsif ( $input =~ /^\s*m\s*[0-9]+/i ) {
         } elsif ( $input =~ /^\s*m\s*[0-9]+/i ) {
-            $old_def       = $templateset_default;
-            $templateset_default = $input;
-            $templateset_default =~ s/^\s*m\s*//;
-            if ( ( $templateset_default > $#templateset_name ) || ( $templateset_default < 0 ) ) {
-                print "Cannot set default template set to $templateset_default.  That template set does not exist.\n";
-                $templateset_default = $old_def;
+            $old_def       = $icon_theme_def;
+            $icon_theme_def = $input;
+            $icon_theme_def =~ s/^\s*m\s*//;
+            if ( ( $icon_theme_default > $#icon_theme_name ) || ( $icon_theme_default < 0 ) ) {
+                print "Cannot set default icon theme to $icon_theme_default.  That theme does not exist.\n";
+                $icon_theme_def = $old_def;
+            }
+        } elsif ( $input =~ /^\s*f\s*[0-9]+/i ) {
+            $old_fb       = $icon_theme_fallback;
+            $icon_theme_fallback = $input;
+            $icon_theme_fallback =~ s/^\s*f\s*//;
+            if ( ( $icon_theme_fallback > $#icon_theme_name ) || ( $icon_theme_fallback < 0 ) ) {
+                print "Cannot set fallback icon theme to $icon_theme_fallback.  That theme does not exist.\n";
+                $icon_theme_fallback = $old_fb;
             }
             }
-
-        # add template set
-        #
         } elsif ( $input =~ /^\s*\+/ ) {
         } elsif ( $input =~ /^\s*\+/ ) {
-            print "\nWhat is the name of this template (as shown to your users): ";
+            print "What is the name of this icon theme? ";
             $name = <STDIN>;
             $name =~ s/[\r\n]//g;
             $name = <STDIN>;
             $name =~ s/[\r\n]//g;
-            $templateset_name[ $#templateset_name + 1 ] = $name;
-            print "\n\nThe directory name should not contain any path information\n"
-                . "or slashes, and should be the name of the directory that the\n"
-                . "template set is found in within the SquirrelMail templates\n"
-                . "directory.\n\n";
-            print "What directory is this stored in (ex: default_advanced): ";
+            $icon_theme_name[ $#icon_theme_name + 1 ] = $name;
+            print "Be sure to put ../images/themes/ before the filename.\n";
+            print "What directory is this icon theme stored in (ex: ../images/themes/my_theme/)? ";
             $name = <STDIN>;
             $name =~ s/[\r\n]//g;
             $name = <STDIN>;
             $name =~ s/[\r\n]//g;
-            $templateset_id[ $#templateset_id + 1 ] = $name;
-
-        # detect template sets
-        #
+            $icon_theme_path[ $#icon_theme_path + 1 ] = $name;
+        } elsif ( $input =~ /^\s*-\s*[0-9]?/ ) {
+            if ( $input =~ /[0-9]+\s*$/ ) {
+                $rem_num = $input;
+                $rem_num =~ s/^\s*-\s*//g;
+                $rem_num =~ s/\s*$//;
+            } else {
+                $rem_num = $#icon_theme_name;
+            }
+            if ( $rem_num == $icon_theme_def ) {
+                print "You cannot remove the default icon theme!\n";
+            } elsif ( $rem_num == $icon_theme_fallback ) {
+                print "You cannot remove the fallback icon theme!\n";
+            } else {
+                $count          = 0;
+                @new_theme_name = ();
+                @new_theme_path = ();
+                while ( $count <= $#icon_theme_name ) {
+                    if ( $count != $rem_num ) {
+                        @new_theme_name = ( @new_theme_name, $icon_theme_name[$count] );
+                        @new_theme_path = ( @new_theme_path, $icon_theme_path[$count] );
+                    }
+                    $count++;
+                }
+                @icon_theme_name = @new_theme_name;
+                @icon_theme_path = @new_theme_path;
+                if ( $icon_theme_def > $rem_num ) {
+                    $icon_theme_def--;
+                }
+            }
         } elsif ( $input =~ /^\s*t\s*/i ) {
             print "\nStarting detection...\n\n";
         } elsif ( $input =~ /^\s*t\s*/i ) {
             print "\nStarting detection...\n\n";
-            opendir( DIR, "../templates" );
-            @files = readdir(DIR);
+
+            opendir( DIR, "../images/themes/" );
+            @files = sort(readdir(DIR));
             $cnt = 0;
             while ( $cnt <= $#files ) {
             $cnt = 0;
             while ( $cnt <= $#files ) {
-                if ( -d "../templates/" . $files[$cnt] && $files[$cnt] !~ /^\./ && $files[$cnt] ne "CVS" ) {
-                    $filename = $files[$cnt];
+                $filename = "../images/themes/" . $files[$cnt] .'/';
+                if ( -d "../images/themes/" . $files[$cnt] && $files[$cnt] !~ /^\./ && $files[$cnt] ne ".svn" ) {
                     $found = 0;
                     $found = 0;
-                    for ( $x = 0 ; $x <= $#templateset_id ; $x++ ) {
-                        if ( $templateset_id[$x] eq $filename ) {
+                    for ( $x = 0 ; $x <= $#icon_theme_path ; $x++ ) {
+                        if ( $icon_theme_path[$x] eq $filename ) {
                             $found = 1;
                             $found = 1;
-                            last;
                         }
                     }
                         }
                     }
-                    if ( $found != 1) {
-                        print "** Found template set: $filename\n";
-                        print "   What is it's name (as shown to your users)? ";
+                    if ( $found != 1 ) {
+                        print "** Found icon theme: $filename\n";
+                        $def = $files[$cnt];
+                        $def =~ s/_/ /g;
+                        $def = lc($def);
+                        #$def =~ s/(^\w+)/ucfirst $1/eg;
+                        #$def =~ s/(\s+)(\w+)/$1 . ucfirst $2/eg;
+                        $def =~ s/(^\w+)|(\s+)(\w+)/ucfirst $1 . $2 . ucfirst $3/eg;
+                        print "   What is its name? [$def]: ";
                         $nm = <STDIN>;
                         $nm = <STDIN>;
-                        $nm =~ s/[\n\r]//g;
-                        $templateset_id[ $#templateset_id + 1 ] = $filename;
-                        $templateset_name[ $#templateset_name + 1 ] = $nm;
-# FIXME: why are these two lines here?
-#                        $aTemplateSet[ $#templateset_name + 1 ] = $nm;
-#                        $aTemplateSet[ $#templateset_id + 1 ] = $filename;
+                        $nm =~ s/^\s+|\s+$|[\n\r]//g;
+                        if ( $nm eq '' ) { $nm = $def; }
+                        $icon_theme_name[ $#icon_theme_name + 1 ] = $nm;
+                        $icon_theme_path[ $#icon_theme_path + 1 ] = $filename;
                     }
                 }
                 $cnt++;
             }
             print "\n";
                     }
                 }
                 $cnt++;
             }
             print "\n";
-            for ( $cnt= 0 ; $cnt <= $#templateset_id ; ) {
-                $filename = $templateset_id[$cnt];
-                if ( !(-d  change_to_rel_path('SM_PATH . \'templates/' . $filename)) ) {
-                    print "  Removing \"$filename\" (template set directory not found)\n";
-                    if ( $templateset_default gt $cnt ) { $templateset_default--; }
-                    elsif ( $templateset_default eq $cnt ) { $templateset_default = 0; }
+            for ( $cnt = 0 ; $cnt <= $#icon_theme_path ; $cnt++ ) {
+                $filename = $icon_theme_path[$cnt];
+                if ( $filename ne "none" && $filename ne "template" && ! -d $filename ) {
+                    print "  Removing $filename (file not found)\n";
                     $offset         = 0;
                     $offset         = 0;
-                    @new_templateset_name = ();
-                    @new_templateset_id = ();
-                    for ( $x = 0 ; $x < $#templateset_id ; $x++ ) {
-                        if ( $templateset_id[$x] eq $filename ) {
+                    @new_icon_theme_name = ();
+                    @new_icon_theme_path = ();
+                    for ( $x = 0 ; $x < $#icon_theme_path ; $x++ ) {
+                        if ( $icon_theme_path[$x] eq $filename ) {
                             $offset = 1;
                         }
                         if ( $offset == 1 ) {
                             $offset = 1;
                         }
                         if ( $offset == 1 ) {
-                            $new_templateset_name[$x] = $templateset_name[ $x + 1 ];
-                            $new_templateset_id[$x] = $templateset_id[ $x + 1 ];
+                            $new_icon_theme_name[$x] = $icon_theme_name[ $x + 1 ];
+                            $new_icon_theme_path[$x] = $icon_theme_path[ $x + 1 ];
                         } else {
                         } else {
-                            $new_templateset_name[$x] = $templateset_name[$x];
-                            $new_templateset_id[$x] = $templateset_id[$x];
+                            $new_icon_theme_name[$x] = $icon_theme_name[$x];
+                            $new_icon_theme_path[$x] = $icon_theme_path[$x];
                         }
                     }
                         }
                     }
-                    @templateset_name = @new_templateset_name;
-                    @templateset_id = @new_templateset_id;
-                } else { $cnt++; }
+                    @icon_theme_name = @new_icon_theme_name;
+                    @icon_theme_path = @new_icon_theme_path;
+                }
             }
             print "\nDetection complete!\n\n";
 
             closedir DIR;
             }
             print "\nDetection complete!\n\n";
 
             closedir DIR;
+        } elsif ( $input =~ /^\s*\?\s*/ ) {
+            print ".------------------------------------.\n";
+            print "| t             (detect icon themes) |\n";
+            print "| +                 (add icon theme) |\n";
+            print "| - N            (remove icon theme) |\n";
+            print "| m N      (mark default icon theme) |\n";
+            print "| f N        (set fallback icon set) |\n";
+            print "| l               (list icon themes) |\n";
+            print "| d                           (done) |\n";
+            print "`------------------------------------'\n";
+        }
+        print "[icon_themes] command (?=help) > ";
+        $input = <STDIN>;
+        $input =~ s/[\r\n]//g;
+    }
+}
 
 
-        # remove template set
-        #
-        # undocumented functionality of removing last template set isn't that great
-        #} elsif ( $input =~ /^\s*-\s*[0-9]?/ ) {
-        } elsif ( $input =~ /^\s*-\s*[0-9]+/ ) {
-            if ( $input =~ /[0-9]+\s*$/ ) {
-                $rem_num = $input;
-                $rem_num =~ s/^\s*-\s*//g;
-                $rem_num =~ s/\s*$//;
-            } else {
-                $rem_num = $#templateset_name;
-            }
-            if ( $rem_num == $templateset_default ) {
-                print "You cannot remove the default template set!\n";
-            } else {
-                $count          = 0;
+sub command_templates {
+    print "\nDefine the template sets (skins) that you wish to use.  If you have added\n";
+    print "a template set of your own, just follow the instructions (?) about\n";
+    print "how to add them.  You can also change the default template.\n";
+
+    print "\n  Available Templates:\n";
+
+    $count = 0;
+    while ( $count <= $#templateset_name ) {
+        if ( $templateset_id[$count] eq $templateset_default ) {
+            print " d";
+        } else {
+            print "  ";
+        }
+        if ( $templateset_id[$count] eq $templateset_fallback ) {
+            print "f";
+        } else {
+            print " ";
+        }
+        if ( $templateset_id[$count] eq $rpc_templateset ) {
+            print "r ";
+        } else {
+            print "  ";
+        }
+        if ( $count < 10 ) {
+            print " ";
+        }
+        if ( $count < 100 ) {
+            print " ";
+        }
+        $name       = $templateset_name[$count];
+
+        # present RPC template sets differently
+        #
+        if ( $templateset_id[$count] =~ /_rpc$/ ) {
+            $name = $name . " (not shown in user interface; used for RPC interface only)";
+        } else {
+
+            $num_spaces = 35 - length($name);
+            for ( $i = 0 ; $i < $num_spaces ; $i++ ) {
+                $name = $name . " ";
+            }
+            $name = $name . "($templateset_id[$count])";
+
+        }
+
+        print " $count.  $name\n";
+
+        $count++;
+    }
+    print "\n  d = default template set\n"
+       . "  f = fallback template set\n"
+       . "  r = RPC template set\n\n";
+
+    $menu_text = ".-------------------------------------.\n"
+               . "| t             (detect template set) |\n"
+               . "| +                (add template set) |\n"
+               . "| - N           (remove template set) |\n"
+               . "| m N     (mark default template set) |\n"
+               . "| f N     (set fallback template set) |\n"
+               . "| r N          (set RPC template set) |\n"
+               . "| l        (list template sets/skins) |\n"
+               . "| d                            (done) |\n"
+               . "|-------------------------------------|\n"
+               . "| where N is a template set number    |\n"
+               . "`-------------------------------------'\n";
+    print "\n";
+    print $menu_text;
+    print "\n[template set] command (?=help) > ";
+
+    $input = <STDIN>;
+    $input =~ s/[\r\n]//g;
+    while ( $input ne "d" ) {
+
+        # list template sets
+        #
+        if ( $input =~ /^\s*l\s*/i ) {
+            $count = 0;
+            while ( $count <= $#templateset_name ) {
+                if ( $templateset_id[$count] eq $templateset_default ) {
+                    print " d";
+                } else {
+                    print "  ";
+                }
+                if ( $templateset_id[$count] eq $templateset_fallback ) {
+                    print "f";
+                } else {
+                    print " ";
+                }
+                if ( $templateset_id[$count] eq $rpc_templateset ) {
+                    print "r ";
+                } else {
+                    print "  ";
+                }
+                if ( $count < 10 ) {
+                    print " ";
+                }
+                if ( $count < 100 ) {
+                    print " ";
+                }
+                $name       = $templateset_name[$count];
+
+                # present RPC template sets differently
+                #
+                if ( $templateset_id[$count] =~ /_rpc$/ ) {
+                    $name = $name . " (not shown in user interface; used for RPC interface only)";
+                } else {
+
+                    $num_spaces = 35 - length($name);
+                    for ( $i = 0 ; $i < $num_spaces ; $i++ ) {
+                        $name = $name . " ";
+                    }
+                    $name = $name . "($templateset_id[$count])";
+
+                }
+
+                print " $count.  $name\n";
+
+                $count++;
+            }
+            print "\n  d = default template set\n"
+                . "  f = fallback template set\n"
+                . "  r = RPC template set\n\n";
+
+        # mark default template set
+        #
+        } elsif ( $input =~ /^\s*m\s*[0-9]+/i ) {
+            $old_def       = $templateset_default;
+            $input =~ s/^\s*m\s*//;
+            $templateset_default = $templateset_id[$input];
+            if ( $templateset_default =~ /^\s*$/ ) {
+                print "Cannot set default template set to $input.  That template set does not exist.\n";
+                $templateset_default = $old_def;
+            }
+            if ( $templateset_default =~ /_rpc$/ ) {
+                print "Cannot set default template set to $input.  That template set is intended for the RPC interface only.\n";
+                $templateset_default = $old_def;
+            }
+
+        # set fallback template set
+        #
+        } elsif ( $input =~ /^\s*f\s*[0-9]+/i ) {
+            $old_def       = $templateset_fallback;
+            $input =~ s/^\s*f\s*//;
+            $templateset_fallback = $templateset_id[$input];
+            if ( $templateset_fallback =~ /^\s*$/ ) {
+                print "Cannot set fallback template set to $input.  That template set does not exist.\n";
+                $templateset_fallback = $old_def;
+            }
+            if ( $templateset_fallback =~ /_rpc$/ ) {
+                print "Cannot set fallback template set to $input.  That template set is intended for the RPC interface only.\n";
+                $templateset_fallback = $old_def;
+            }
+
+        # set RPC template set
+        #
+        } elsif ( $input =~ /^\s*r\s*[0-9]+/i ) {
+            $old_def       = $rpc_templateset;
+            $input =~ s/^\s*r\s*//;
+            $rpc_templateset = $templateset_id[$input];
+            if ( $rpc_templateset =~ /^\s*$/ ) {
+                print "Cannot set RPC template set to $input.  That template set does not exist.\n";
+                $rpc_templateset = $old_def;
+            }
+            if ( $rpc_templateset !~ /_rpc$/ ) {
+                print "Cannot set fallback template set to $input.  That template set is not intended for the RPC interface.\n";
+                $rpc_templateset = $old_def;
+            }
+
+        # add template set
+        #
+        } elsif ( $input =~ /^\s*\+/ ) {
+            print "\nWhat is the name of this template (as shown to your users): ";
+            $name = <STDIN>;
+            $name =~ s/[\r\n]//g;
+            $templateset_name[ $#templateset_name + 1 ] = $name;
+            print "\n\nThe directory name should not contain any path information\n"
+                . "or slashes, and should be the name of the directory that the\n"
+                . "template set is found in within the SquirrelMail templates\n"
+                . "directory.\n\n";
+            print "What directory is this stored in (ex: default_advanced): ";
+            $name = <STDIN>;
+            $name =~ s/[\r\n]//g;
+            $templateset_id[ $#templateset_id + 1 ] = $name;
+
+        # detect template sets
+        #
+        } elsif ( $input =~ /^\s*t\s*/i ) {
+            print "\nStarting detection...\n\n";
+            opendir( DIR, "../templates" );
+            @files = sort(readdir(DIR));
+            $cnt = 0;
+            while ( $cnt <= $#files ) {
+                if ( -d "../templates/" . $files[$cnt] && $files[$cnt] !~ /^\./ && $files[$cnt] ne ".svn" ) {
+                    $filename = $files[$cnt];
+                    $found = 0;
+                    for ( $x = 0 ; $x <= $#templateset_id ; $x++ ) {
+                        if ( $templateset_id[$x] eq $filename ) {
+                            $found = 1;
+                            last;
+                        }
+                    }
+                    if ( $found != 1) {
+                        print "** Found template set: $filename\n";
+                        $def = $files[$cnt];
+
+                        # no user-friendly names needed for RPC template sets
+                        #
+                        if ( $def =~ /_rpc$/ ) {
+                            $nm = $def;
+                        } else {
+                            $def = lc($def);
+                            $def =~ s/_/ /g;
+                            #$def =~ s/(^\w+)/ucfirst $1/eg;
+                            #$def =~ s/(\s+)(\w+)/$1 . ucfirst $2/eg;
+                            $def =~ s/(^\w+)|(\s+)(\w+)/ucfirst $1 . $2 . ucfirst $3/eg;
+                            print "   What is it's name (as shown to your users)? [$def]: ";
+                            $nm = <STDIN>;
+                            $nm =~ s/^\s+|\s+$|[\n\r]//g;
+                            if ( $nm eq '' ) { $nm = $def; }
+                        }
+                        $templateset_id[ $#templateset_id + 1 ] = $filename;
+                        $templateset_name[ $#templateset_name + 1 ] = $nm;
+                    }
+                }
+                $cnt++;
+            }
+            print "\n";
+            for ( $cnt= 0 ; $cnt <= $#templateset_id ; ) {
+                $filename = $templateset_id[$cnt];
+                if ( !(-d  change_to_rel_path('SM_PATH . \'templates/' . $filename)) ) {
+                    print "  Removing \"$filename\" (template set directory not found)\n";
+                    if ( $templateset_default eq $filename ) { $templateset_default = 'default'; }
+                    if ( $templateset_fallback eq $filename ) { $templateset_fallback = 'default'; }
+                    if ( $rpc_templateset eq $filename ) { $rpc_templateset = 'default_rpc'; }
+                    $offset         = 0;
+                    @new_templateset_name = ();
+                    @new_templateset_id = ();
+                    for ( $x = 0 ; $x < $#templateset_id ; $x++ ) {
+                        if ( $templateset_id[$x] eq $filename ) {
+                            $offset = 1;
+                        }
+                        if ( $offset == 1 ) {
+                            $new_templateset_name[$x] = $templateset_name[ $x + 1 ];
+                            $new_templateset_id[$x] = $templateset_id[ $x + 1 ];
+                        } else {
+                            $new_templateset_name[$x] = $templateset_name[$x];
+                            $new_templateset_id[$x] = $templateset_id[$x];
+                        }
+                    }
+                    @templateset_name = @new_templateset_name;
+                    @templateset_id = @new_templateset_id;
+                } else { $cnt++; }
+            }
+            print "\nDetection complete!\n\n";
+
+            closedir DIR;
+
+        # remove template set
+        #
+        # undocumented functionality of removing last template set isn't that great
+        #} elsif ( $input =~ /^\s*-\s*[0-9]?/ ) {
+        } elsif ( $input =~ /^\s*-\s*[0-9]+/ ) {
+            if ( $input =~ /[0-9]+\s*$/ ) {
+                $rem_num = $input;
+                $rem_num =~ s/^\s*-\s*//g;
+                $rem_num =~ s/\s*$//;
+            } else {
+                $rem_num = $#templateset_name;
+            }
+            if ( $templateset_id[$rem_num] eq $templateset_default ) {
+                print "You cannot remove the default template set!\n";
+            } elsif ( $templateset_id[$rem_num] eq $templateset_fallback ) {
+                print "You cannot remove the fallback template set!\n";
+            } elsif ( $templateset_id[$rem_num] eq $rpc_templateset ) {
+                print "You cannot remove the RPC template set!\n";
+            } else {
+                $count          = 0;
                 @new_templateset_name = ();
                 @new_templateset_id = ();
                 while ( $count <= $#templateset_name ) {
                 @new_templateset_name = ();
                 @new_templateset_id = ();
                 while ( $count <= $#templateset_name ) {
@@ -2901,16 +3521,19 @@ print "DEFAULT INDEX IS " . $templateset_default . "\n";
                 }
                 @templateset_name = @new_templateset_name;
                 @templateset_id = @new_templateset_id;
                 }
                 @templateset_name = @new_templateset_name;
                 @templateset_id = @new_templateset_id;
-                if ( $templateset_default > $rem_num ) {
-                    $templateset_default--;
-                }
             }
 
         # help
         #
         } elsif ( $input =~ /^\s*\?\s*/ ) {
             print $menu_text;
             }
 
         # help
         #
         } elsif ( $input =~ /^\s*\?\s*/ ) {
             print $menu_text;
+
+        # command not understood
+        #
+        } else {
+            print "Command not understood\n";
         }
         }
+
         print "[template set] command (?=help) > ";
         $input = <STDIN>;
         $input =~ s/[\r\n]//g;
         print "[template set] command (?=help) > ";
         $input = <STDIN>;
         $input =~ s/[\r\n]//g;
@@ -2919,34 +3542,6 @@ print "DEFAULT INDEX IS " . $templateset_default . "\n";
 }
 
 
 }
 
 
-# Theme - CSS file
-sub command42 {
-    print "You may specify a cascading style-sheet (CSS) file to be included\n";
-    print "on each html page generated by SquirrelMail. The CSS file is useful\n";
-    print "for specifying a site-wide font. If you're not familiar with CSS\n";
-    print "files, leave this blank.\n";
-    print "\n";
-    print "To clear out an existing value, just type a space for the input.\n";
-    print "\n";
-    print "Please be aware of the following: \n";
-    print "  - Relative URLs are relative to the config dir\n";
-    print "    to use the themes directory, use ../themes/css/newdefault.css\n";
-    print "  - To specify a css file defined outside the SquirrelMail source tree\n";
-    print "    use the absolute URL the webserver would use to include the file\n";
-    print "    e.g. http://some.host.com/css/mystyle.css or /css/mystyle.css\n";
-    print "\n";
-    print "[$WHT$theme_css$NRM]: $WHT";
-    $new_theme_css = <STDIN>;
-
-    if ( $new_theme_css eq "\n" ) {
-        $new_theme_css = $theme_css;
-    } else {
-        $new_theme_css =~ s/[\r\n]//g;
-    }
-    $new_theme_css =~ s/^\s*//;
-    return $new_theme_css;
-}
-
 # sets default font size option
 sub command_default_fontsize {
     print "Enter default font size [$WHT$$default_fontsize$NRM]: $WHT";
 # sets default font size option
 sub command_default_fontsize {
     print "Enter default font size [$WHT$$default_fontsize$NRM]: $WHT";
@@ -3091,10 +3686,10 @@ sub command61 {
 
             print "First, we need to have the hostname or the IP address where\n";
             print "this LDAP server resides. Example: ldap.bigfoot.com\n";
 
             print "First, we need to have the hostname or the IP address where\n";
             print "this LDAP server resides. Example: ldap.bigfoot.com\n";
-           print "\n";
-           print "You can use any URI compatible with your LDAP library. Please\n";
+            print "\n";
+            print "You can use any URI compatible with your LDAP library. Please\n";
             print "note that StartTLS option is not compatible with ldaps and\n";
             print "note that StartTLS option is not compatible with ldaps and\n";
-           print "ldapi URIs.\n";
+            print "ldapi URIs.\n";
             print "hostname: ";
             $name = <STDIN>;
             $name =~ s/[\r\n]//g;
             print "hostname: ";
             $name = <STDIN>;
             $name =~ s/[\r\n]//g;
@@ -3833,6 +4428,30 @@ sub commandB2 {
     }
     return $use_iframe;
 }
     }
     return $use_iframe;
 }
+
+# ask user info
+sub command_ask_user_info {
+    print "New users need to supply their real name and email address to\n";
+    print "send out proper mails. When this option is enabled, a user that\n";
+    print "logs in for the first time will be redirected to the Personal\n";
+    print "Options screen and asked to supply their personal data.\n";
+    print "\n";
+
+    if ( lc($ask_user_info) eq 'true' ) {
+        $default_value = "y";
+    } else {
+        $default_value = "n";
+    }
+    print "Ask user info? (y/n) [$WHT$default_value$NRM]: $WHT";
+    $ask_user_info = <STDIN>;
+    if ( ( $ask_user_info =~ /^y\n/i ) || ( ( $ask_user_info =~ /^\n/ ) && ( $default_value eq "y" ) ) ) {
+        $ask_user_info = 'true';
+    } else {
+        $ask_user_info = 'false';
+    }
+    return $ask_user_info;
+}
+
 # use icons
 sub commandB3 {
     print "Enabling this option will cause icons to be used instead of text\n";
 # use icons
 sub commandB3 {
     print "Enabling this option will cause icons to be used instead of text\n";
@@ -3906,8 +4525,37 @@ sub commandB5 {
     return $use_php_iconv;
 }
 
     return $use_php_iconv;
 }
 
-# configtest block
+# buffer output
 sub commandB6 {
 sub commandB6 {
+    print "In some cases, buffering all output (holding it on the server until\n";
+    print "the full page is ready to send to the browser) allows more complex\n";
+    print "functionality, especially for plugins that want to add headers on hooks\n";
+    print "that are beyond the point of output having been sent to the browser\n";
+    print "otherwise.  Most plugins that need this functionality will enable it\n";
+    print "automatically on their own, but you can turn it on manually here.  You'd\n";
+    print "usually want to do this if you want to specify a custom output handler\n";
+    print "for parsing the output - you can do that by specifying a value for\n";
+    print "\$buffered_output_handler in config_local.php.  Don't forget to define\n";
+    print "a function of the same name as what \$buffered_output_handler is set to.\n";
+    print "\n";
+
+    if ( lc($buffer_output) eq 'true' ) {
+        $default_value = "y";
+    } else {
+        $default_value = "n";
+    }
+    print "Buffer all output? (y/n) [$WHT$default_value$NRM]: $WHT";
+    $buffer_output = <STDIN>;
+    if ( ( $buffer_output =~ /^y\n/i ) || ( ( $buffer_output =~ /^\n/ ) && ( $default_value eq "y" ) ) ) {
+        $buffer_output = 'true';
+    } else {
+        $buffer_output = 'false';
+    }
+    return $buffer_output;
+}
+
+# configtest block
+sub commandB7 {
     print "Enable this option if you want to check SquirrelMail configuration\n";
     print "remotely with configtest.php script.\n";
     print "\n";
     print "Enable this option if you want to check SquirrelMail configuration\n";
     print "remotely with configtest.php script.\n";
     print "\n";
@@ -3928,12 +4576,12 @@ sub commandB6 {
 }
 
 # Default Icon theme
 }
 
 # Default Icon theme
-sub commandB7 {
-       print "You may change the path to the default icon theme to be used, if icons\n";
-       print "have been enabled.  This theme will be used when an icon cannot be\n";
-       print "found in the current theme, or when no icon theme is specified.  If\n";
-       print "left blank, and icons are enabled, the default theme will be used\n";
-       print "from images/themes/default/.\n";
+sub command53 {
+    print "You may change the path to the default icon theme to be used, if icons\n";
+    print "have been enabled.  This theme will be used when an icon cannot be\n";
+    print "found in the current theme, or when no icon theme is specified.  If\n";
+    print "left blank, and icons are enabled, the default theme will be used\n";
+    print "from images/themes/default/.\n";
     print "\n";
     print "To clear out an existing value, just type a space for the input.\n";
     print "\n";
     print "\n";
     print "To clear out an existing value, just type a space for the input.\n";
     print "\n";
@@ -3954,6 +4602,171 @@ sub commandB7 {
     return $new_icon_theme_def;
 }
 
     return $new_icon_theme_def;
 }
 
+# SquirrelMail debug mode (since 1.5.2)
+sub commandB8 {
+    print "When debugging or developing SquirrelMail, you may want to increase\n";
+    print "the verbosity of certain kinds of errors, notices, and/or diagnostics.\n";
+    print "You may enable one or more of the debugging modes here.  Please make\n";
+    print "sure that you have turned off debugging if you are using SquirrelMail\n";
+    print "in a production environment.\n\n";
+
+    $input = "";
+    while ( $input ne "d\n" ) {
+        $sm_debug_mode = convert_debug_constants_to_binary_integer($sm_debug_mode);
+
+        # per include/constants.php, here are the debug mode values:
+        #
+        # 0          SM_DEBUG_MODE_OFF
+        # 1          SM_DEBUG_MODE_SIMPLE
+        # 512        SM_DEBUG_MODE_MODERATE
+        # 524288     SM_DEBUG_MODE_ADVANCED
+        # 536870912  SM_DEBUG_MODE_STRICT
+        #
+        print "\n#  Enabled?  Description\n";
+        print "---------------------------------------------------------------------\n";
+        print "0     " . ($sm_debug_mode == 0 ? "y" : " ")
+            . "      No debugging (recommended in production environments)\n";
+        print "1     " . ($sm_debug_mode & 1 ? "y" : " ")
+            . "      Simple debugging (PHP E_ERROR)\n";
+        print "2     " . ($sm_debug_mode & 512 ? "y" : " ")
+            . "      Moderate debugging (PHP E_ALL)\n";
+        print "3     " . ($sm_debug_mode & 524288 ? "y" : " ")
+            . "      Advanced debugging (PHP E_ALL plus log errors\n";
+        print "             intentionally suppressed)\n";
+        print "4     " . ($sm_debug_mode & 536870912 ? "y" : " ")
+            . "      Strict debugging (PHP E_STRICT)\n";
+        print "\n";
+    
+        print "SquirrelMail debug mode (0,1,2,3,4) or d when done? : $WHT";
+        $input = <STDIN>;
+        if ( $input eq "d\n" ) {
+            # nothing
+        } elsif ($input !~ /^[0-9]+\n$/) {
+            print "\nInvalid configuration value.\n";
+            print "\nPress enter to continue...";
+            $tmp = <STDIN>;
+        } elsif ( $input == "0\n" ) {
+            $sm_debug_mode = 0;
+        } elsif ( $input == "1\n" ) {
+            if ($sm_debug_mode & 1) {
+                $sm_debug_mode ^= 1;
+            } else {
+                $sm_debug_mode |= 1;
+            }
+        } elsif ( $input == "2\n" ) {
+            if ($sm_debug_mode & 512) {
+                $sm_debug_mode ^= 512;
+            } else {
+                $sm_debug_mode |= 512;
+            }
+        } elsif ( $input == "3\n" ) {
+            if ($sm_debug_mode & 524288) {
+                $sm_debug_mode ^= 524288;
+            } else {
+                $sm_debug_mode |= 524288;
+            }
+        } elsif ( $input == "4\n" ) {
+            if ($sm_debug_mode & 536870912) {
+                $sm_debug_mode ^= 536870912;
+            } else {
+                $sm_debug_mode |= 536870912;
+            }
+        } else {
+            print "\nInvalid configuration value.\n";
+            print "\nPress enter to continue...";
+            $tmp = <STDIN>;
+        }
+        print "\n";
+    }
+    $sm_debug_mode = convert_debug_binary_integer_to_constants($sm_debug_mode);
+    return $sm_debug_mode;
+}
+
+# Secured configuration mode (since 1.5.2)
+sub commandB9 {
+    print "This option allows you to enable \"Secured Configuration\" mode,\n";
+    print "which will guarantee that certain settings made herein will be\n";
+    print "made immutable and will not be subject to override by either friendly\n";
+    print "or unfriendly code/plugins.  Only a small number of settings herein\n";
+    print "will be used in this manner - just those that are deemed to be a\n";
+    print "potential security threat when rouge plugin or other code may be\n";
+    print "executed inside SquirrelMail.\n";
+    print "\n";
+
+    if ( lc($secured_config) eq 'true' ) {
+        $default_value = "y";
+    } else {
+        $default_value = "n";
+    }
+    print "Enable secured configuration mode? (y/n) [$WHT$default_value$NRM]: $WHT";
+    $secured_config = <STDIN>;
+    if ( ( $secured_config =~ /^y\n/i ) || ( ( $secured_config =~ /^\n/ ) && ( $default_value eq "y" ) ) ) {
+        $secured_config = 'true';
+    } else {
+        $secured_config = 'false';
+    }
+    return $secured_config;
+}
+
+# Set a (non-standard) HTTPS port
+sub commandB10 {
+    print "If you run HTTPS (SSL-secured HTTP) on a non-standard port, you should\n";
+    print "indicate that port here.  Even if you do not, SquirrelMail may still\n";
+    print "auto-detect secure connections, but it is safer and also very useful\n";
+    print "for third party plugins if you specify the port number here.\n";
+    print "\n";
+    print "Most SquirrelMail administrators will not need to use this setting\n";
+    print "because most all web servers use port 443 for HTTPS connections, and\n";
+    print "SquirrelMail assumes 443 unless something else is given here.\n";
+    print "\n";
+
+    print "Enter your HTTPS port [$sq_https_port]: ";
+    my $tmp = <STDIN>;
+    $tmp = trim($tmp);
+    # value is not modified, if user hits Enter or enters space
+    if ($tmp ne '') {
+        # make sure that input is numeric
+        if ($tmp =~ /^\d+$/) {
+            $sq_https_port = $tmp;
+        } else {
+            print "\n";
+            print "--- INPUT ERROR ---\n";
+            print "\n";
+            print "If you want to change this setting, you must enter a number.\n";
+            print "If you want to keep the original value, just press Enter.\n\n";
+            print "Press Enter to continue...";
+            $tmp = <STDIN>;
+        }
+    }
+    return $sq_https_port;
+}
+
+# Ignore HTTP_X_FORWARDED_* headers?
+sub commandB11 {
+
+    if ( lc($sq_ignore_http_x_forwarded_headers) eq 'true' ) {
+        $default_value = "y";
+    } else {
+        $default_value = "n";
+    }
+
+    print "Because HTTP_X_FORWARDED_* headers can be sent by the client and\n";
+    print "therefore possibly exploited by an outsider, SquirrelMail ignores\n";
+    print "them by default. If a proxy server or other machine sits between\n";
+    print "clients and your SquirrelMail server, you can turn this off to\n";
+    print "tell SquirrelMail to use such headers.\n";
+    print "\n";
+
+    print "Ignore HTTP_X_FORWARDED headers? (y/n) [$WHT$default_value$NRM]: $WHT";
+    $sq_ignore_http_x_forwarded_headers = <STDIN>;
+    if ( ( $sq_ignore_http_x_forwarded_headers =~ /^y\n/i ) || ( ( $sq_ignore_http_x_forwarded_headers =~ /^\n/ ) && ( $default_value eq "y" ) ) ) {
+        $sq_ignore_http_x_forwarded_headers = 'true';
+    } else {
+        $sq_ignore_http_x_forwarded_headers = 'false';
+    }
+    return $sq_ignore_http_x_forwarded_headers;
+}
+
 sub save_data {
     $tab = "    ";
     if ( open( CF, ">config.php" ) ) {
 sub save_data {
     $tab = "    ";
     if ( open( CF, ">config.php" ) ) {
@@ -3965,7 +4778,6 @@ sub save_data {
         print CF " * Created using the configure script, conf.pl\n";
         print CF " */\n";
         print CF "\n";
         print CF " * Created using the configure script, conf.pl\n";
         print CF " */\n";
         print CF "\n";
-        print CF "global \$version;\n";
 
         if ($print_config_version) {
             print CF "\$config_version = '$print_config_version';\n";
 
         if ($print_config_version) {
             print CF "\$config_version = '$print_config_version';\n";
@@ -4035,6 +4847,8 @@ sub save_data {
         # boolean
         print CF "\$pop_before_smtp        = $pop_before_smtp;\n";
         # string
         # boolean
         print CF "\$pop_before_smtp        = $pop_before_smtp;\n";
         # string
+        print CF "\$pop_before_smtp_host   = '$pop_before_smtp_host';\n";
+        # string
         print CF "\$imap_server_type       = '$imap_server_type';\n";
         # boolean
         print CF "\$invert_time            = $invert_time;\n";
         print CF "\$imap_server_type       = '$imap_server_type';\n";
         # boolean
         print CF "\$invert_time            = $invert_time;\n";
@@ -4120,6 +4934,11 @@ sub save_data {
         # string
         print CF "\$config_location_base     = '$config_location_base';\n";
         print CF "\n";
         # string
         print CF "\$config_location_base     = '$config_location_base';\n";
         print CF "\n";
+        # boolean
+        print CF "\$disable_plugins          = $disable_plugins;\n";
+        # string
+        print CF "\$disable_plugins_user     = '$disable_plugins_user';\n";
+        print CF "\n";
 
         # all plugins are strings
         for ( $ct = 0 ; $ct <= $#plugins ; $ct++ ) {
 
         # all plugins are strings
         for ( $ct = 0 ; $ct <= $#plugins ; $ct++ ) {
@@ -4128,24 +4947,60 @@ sub save_data {
         print CF "\n";
 
         # strings
         print CF "\n";
 
         # strings
-        print CF "\$theme_css = " . &change_to_SM_path($theme_css) . ";\n";
-        if ( $theme_default eq '' ) { $theme_default = '0'; }
-        print CF "\$theme_default = $theme_default;\n";
+        if ( $user_theme_default eq '' ) { $user_theme_default = '0'; }
+        print CF "\$user_theme_default = $user_theme_default;\n";
 
 
-        for ( $count = 0 ; $count <= $#theme_name ; $count++ ) {
-            print CF "\$theme[$count]['PATH'] = " . &change_to_SM_path($theme_path[$count]) . ";\n";
+        for ( $count = 0 ; $count <= $#user_theme_name ; $count++ ) {
+            if ($user_theme_path[$count] eq 'none') {
+                $path = '\'none\'';
+            } else {
+                $path = &change_to_SM_path($user_theme_path[$count]);
+            }
+            print CF "\$user_themes[$count]['PATH'] = " . $path . ";\n";
+            # escape theme name so it can contain single quotes.
+            $esc_name =  $user_theme_name[$count];
+            $esc_name =~ s/\\/\\\\/g;
+            $esc_name =~ s/'/\\'/g;
+            print CF "\$user_themes[$count]['NAME'] = '$esc_name';\n";
+        }
+        print CF "\n";
+
+        if ( $icon_theme_def eq '' ) { $icon_theme_def = '0'; }
+        print CF "\$icon_theme_def = $icon_theme_def;\n";
+        if ( $icon_theme_fallback eq '' ) { $icon_theme_fallback = '0'; }
+           print CF "\$icon_theme_fallback = $icon_theme_fallback;\n";
+           
+        for ( $count = 0 ; $count <= $#icon_theme_name ; $count++ ) {
+            $path = $icon_theme_path[$count];
+            if ($path eq 'none' || $path eq 'template') {
+                $path = "'".$path."'";
+            } else {
+                $path = &change_to_SM_path($icon_theme_path[$count]);
+            }
+            print CF "\$icon_themes[$count]['PATH'] = " . $path . ";\n";
             # escape theme name so it can contain single quotes.
             # escape theme name so it can contain single quotes.
-            $esc_name =  $theme_name[$count];
+            $esc_name =  $icon_theme_name[$count];
             $esc_name =~ s/\\/\\\\/g;
             $esc_name =~ s/'/\\'/g;
             $esc_name =~ s/\\/\\\\/g;
             $esc_name =~ s/'/\\'/g;
-            print CF "\$theme[$count]['NAME'] = '$esc_name';\n";
+            print CF "\$icon_themes[$count]['NAME'] = '$esc_name';\n";
         }
         print CF "\n";
 
         }
         print CF "\n";
 
-        if ( $templateset_default eq '' ) { $templateset_default = '0'; }
-        print CF "\$templateset_default = $templateset_default;\n";
+        if ( $templateset_default eq '' ) { $templateset_default = 'default'; }
+        print CF "\$templateset_default = '$templateset_default';\n";
+
+        if ( $templateset_fallback eq '' ) { $templateset_fallback = 'default'; }
+        print CF "\$templateset_fallback = '$templateset_fallback';\n";
+
+        if ( $rpc_templateset eq '' ) { $rpc_templateset = 'default_rpc'; }
+        print CF "\$rpc_templateset = '$rpc_templateset';\n";
 
         for ( $count = 0 ; $count <= $#templateset_name ; $count++ ) {
 
         for ( $count = 0 ; $count <= $#templateset_name ; $count++ ) {
+
+            # don't include RPC template sets
+            #
+            if ( $templateset_id[$count] =~ /_rpc$/ ) { next; }
+
             print CF "\$aTemplateSet[$count]['ID'] = '" . $templateset_id[$count] . "';\n";
             # escape theme name so it can contain single quotes.
             $esc_name =  $templateset_name[$count];
             print CF "\$aTemplateSet[$count]['ID'] = '" . $templateset_id[$count] . "';\n";
             # escape theme name so it can contain single quotes.
             $esc_name =  $templateset_name[$count];
@@ -4287,41 +5142,60 @@ sub save_data {
         print CF "\$no_list_for_subscribe = $no_list_for_subscribe;\n";
 
         # string
         print CF "\$no_list_for_subscribe = $no_list_for_subscribe;\n";
 
         # string
-        print CF "\$smtp_auth_mech = '$smtp_auth_mech';\n";
-        print CF "\$smtp_sitewide_user = '". quote_single($smtp_sitewide_user) ."';\n";
-        print CF "\$smtp_sitewide_pass = '". quote_single($smtp_sitewide_pass) ."';\n";
+        print CF "\$smtp_auth_mech        = '$smtp_auth_mech';\n";
+        print CF "\$smtp_sitewide_user    = '". quote_single($smtp_sitewide_user) ."';\n";
+        print CF "\$smtp_sitewide_pass    = '". quote_single($smtp_sitewide_pass) ."';\n";
         # string
         # string
-        print CF "\$imap_auth_mech = '$imap_auth_mech';\n";
+        print CF "\$imap_auth_mech        = '$imap_auth_mech';\n";
+        # boolean
+        print CF "\$use_imap_tls          = $use_imap_tls;\n";
         # boolean
         # boolean
-        print CF "\$use_imap_tls = $use_imap_tls;\n";
+        print CF "\$use_smtp_tls          = $use_smtp_tls;\n";
+        # string
+        print CF "\$session_name          = '$session_name';\n";
         # boolean
         # boolean
-        print CF "\$use_smtp_tls = $use_smtp_tls;\n";
+        print CF "\$only_secure_cookies     = $only_secure_cookies;\n";
+        print CF "\$disable_security_tokens = $disable_security_tokens;\n";
+
         # string
         # string
-        print CF "\$session_name = '$session_name';\n";
+        print CF "\$check_referrer          = '$check_referrer';\n";
 
         print CF "\n";
 
         # boolean
         print CF "\$use_iframe = $use_iframe;\n";
 
         print CF "\n";
 
         # boolean
         print CF "\$use_iframe = $use_iframe;\n";
-        print CF "\n";
+        # boolean
+        print CF "\$ask_user_info = $ask_user_info;\n";
         # boolean
         print CF "\$use_icons = $use_icons;\n";
         print CF "\n";
         # boolean
         print CF "\$use_icons = $use_icons;\n";
         print CF "\n";
-        # string
-        print CF "\$icon_theme_def = " . &change_to_SM_path($icon_theme_def) . ";\n";
         # boolean
         print CF "\$use_php_recode = $use_php_recode;\n";
         # boolean
         print CF "\$use_php_recode = $use_php_recode;\n";
-        print CF "\n";
         # boolean
         print CF "\$use_php_iconv = $use_php_iconv;\n";
         print CF "\n";
         # boolean
         # boolean
         print CF "\$use_php_iconv = $use_php_iconv;\n";
         print CF "\n";
         # boolean
+        print CF "\$buffer_output = $buffer_output;\n";
+        print CF "\n";
+        # boolean
         print CF "\$allow_remote_configtest = $allow_remote_configtest;\n";
         print CF "\$allow_remote_configtest = $allow_remote_configtest;\n";
+        print CF "\$secured_config = $secured_config;\n";
+        # integer
+        print CF "\$sq_https_port = $sq_https_port;\n";
+        # boolean
+        print CF "\$sq_ignore_http_x_forwarded_headers = $sq_ignore_http_x_forwarded_headers;\n";
+        # (binary) integer or constant - convert integer 
+        # values to constants before output
+        $sm_debug_mode = convert_debug_binary_integer_to_constants($sm_debug_mode);
+        print CF "\$sm_debug_mode = $sm_debug_mode;\n";
         print CF "\n";
 
         close CF;
 
         print "Data saved in config.php\n";
         print CF "\n";
 
         close CF;
 
         print "Data saved in config.php\n";
+
+        build_plugin_hook_array();
+
     } else {
         print "Error saving config.php: $!\n";
     }
     } else {
         print "Error saving config.php: $!\n";
     }
@@ -4348,15 +5222,7 @@ sub set_defaults {
     $continue = 0;
     while ( $continue != 1 ) {
         print "Please select your IMAP server:\n";
     $continue = 0;
     while ( $continue != 1 ) {
         print "Please select your IMAP server:\n";
-        print "    bincimap    = Binc IMAP server\n";
-        print "    courier     = Courier IMAP server\n";
-        print "    cyrus       = Cyrus IMAP server\n";
-        print "    dovecot     = Dovecot Secure IMAP server\n";
-        print "    exchange    = Microsoft Exchange IMAP server\n";
-        print "    hmailserver = hMailServer\n";
-        print "    macosx      = Mac OS X Mailserver\n";
-        print "    mercury32   = Mercury/32\n";
-        print "    uw          = University of Washington's IMAP server\n";
+        print $list_supported_imap_servers;
         print "\n";
         print "    quit        = Do not change anything\n";
         print "\n";
         print "\n";
         print "    quit        = Do not change anything\n";
         print "\n";
@@ -4506,6 +5372,50 @@ sub set_defaults {
             $message = "\nIf you use IMAPdir depot, you must set default folder prefix to empty string.\n";
 
             $continue = 1;
             $message = "\nIf you use IMAPdir depot, you must set default folder prefix to empty string.\n";
 
             $continue = 1;
+        } elsif ( $server eq "gmail" ) {
+            $imap_server_type               = "gmail";
+            $default_folder_prefix          = "";
+            $trash_folder                   = "[Gmail]/Trash";
+            $default_move_to_trash          = true;
+            $sent_folder                    = "[Gmail]/Sent Mail";
+            $draft_folder                   = "[Gmail]/Drafts";
+            $auto_create_special            = false;
+            $show_prefix_option             = false;
+            $default_sub_of_inbox           = false;
+            $show_contain_subfolders_option = false;
+            $delete_folder                  = true;
+            $force_username_lowercase       = false;
+            $optional_delimiter             = "/";
+            $disp_default_folder_prefix     = "<none>";
+            $domain                         = "gmail.com";
+            $imapServerAddress              = "imap.gmail.com";
+            $imapPort                       = 993;
+            $use_imap_tls                   = true;
+            $imap_auth_mech                 = "login";
+            $smtpServerAddress              = "smtp.gmail.com";
+            $smtpPort                       = 465;
+            $pop_before_smtp                = false;
+            $useSendmail                    = false;
+            $use_smtp_tls                   = true;
+            $smtp_auth_mech                 = "login";
+            $continue = 1;
+
+            # Gmail changes system folder names (Drafts, Sent, Trash) out
+            # from under you when the user changes language settings
+            $message = "\nNOTE!  When a user changes languages in Gmail's interface, the\n" 
+                     . "Drafts, Sent and Trash folder names are changed to localized\n"
+                     . "versions thereof.  To see those folders correctly in SquirrelMail,\n"
+                     . "the user should change the SquirrelMail language to match.\n"
+                     . "Moreover, SquirrelMail then needs to be told what folders to use\n"
+                     . "for Drafts, Sent and Trash in Options --> Folder Preferences.\n"
+                     . "These default settings will only correctly find the Sent, Trash\n"
+                     . "and Drafts folders if both Gmail and SquirrelMail languages are\n"
+                     . "set to English.\n\n"
+                     . "Also note that in some regions (Europe?), the default folder\n"
+                     . "names (see main menu selection 3. Folder Defaults) are different\n"
+                     . "(they may need to have the prefix \"[Google Mail]\" instead of\n"
+                     . "\"[Gmail]\") and \"Trash\" may be called \"Bin\" instead.\n";
+
         } elsif ( $server eq "quit" ) {
             $continue = 1;
         } else {
         } elsif ( $server eq "quit" ) {
             $continue = 1;
         } else {
@@ -4537,12 +5447,13 @@ sub set_defaults {
 # the SM directory tree, the SM_PATH variable will be
 # prepended to the path, if not, then the path will be
 # converted to an absolute path, e.g.
 # the SM directory tree, the SM_PATH variable will be
 # prepended to the path, if not, then the path will be
 # converted to an absolute path, e.g.
-#   '../images/logo.gif'      --> SM_PATH . 'images/logo.gif'
-#   '../../someplace/data'    --> '/absolute/path/someplace/data'
-#   'images/logo.gif'         --> SM_PATH . 'config/images/logo.gif'
-#   '/absolute/path/logo.gif' --> '/absolute/path/logo.gif'
-#   'http://whatever/'        --> 'http://whatever'
-#   $some_var/path            --> "$some_var/path"
+#   '../images/logo.gif'        --> SM_PATH . 'images/logo.gif'
+#   '../../someplace/data'      --> '/absolute/path/someplace/data'
+#   'images/logo.gif'           --> SM_PATH . 'config/images/logo.gif'
+#   '/absolute/path/logo.gif'   --> '/absolute/path/logo.gif'
+#   'C:\absolute\path\logo.gif' --> 'C:\absolute\path\logo.gif'
+#   'http://whatever/'          --> 'http://whatever'
+#   $some_var/path              --> "$some_var/path"
 sub change_to_SM_path() {
     my ($old_path) = @_;
     my $new_path = '';
 sub change_to_SM_path() {
     my ($old_path) = @_;
     my $new_path = '';
@@ -4553,7 +5464,7 @@ sub change_to_SM_path() {
     # If the path is absolute, don't bother.
     return "\'" . $old_path . "\'"  if ( $old_path eq '');
     return "\'" . $old_path . "\'"  if ( $old_path =~ /^(\/|http)/ );
     # If the path is absolute, don't bother.
     return "\'" . $old_path . "\'"  if ( $old_path eq '');
     return "\'" . $old_path . "\'"  if ( $old_path =~ /^(\/|http)/ );
-    return "\'" . $old_path . "\'"  if ( $old_path =~ /^\w:\// );
+    return "\'" . $old_path . "\'"  if ( $old_path =~ /^\w:(\\|\/)/ );
     return $old_path                if ( $old_path =~ /^\'(\/|http)/ );
     return $old_path                if ( $old_path =~ /^\'\w:\// );
     return $old_path                if ( $old_path =~ /^SM_PATH/);
     return $old_path                if ( $old_path =~ /^\'(\/|http)/ );
     return $old_path                if ( $old_path =~ /^\'\w:\// );
     return $old_path                if ( $old_path =~ /^SM_PATH/);
@@ -4671,14 +5582,11 @@ sub detect_auth_support {
 
     # So at this point, we have a response, and it is (hopefully) valid.
     if ($service eq 'SMTP') {
 
     # So at this point, we have a response, and it is (hopefully) valid.
     if ($service eq 'SMTP') {
-        if (($response =~ /^535/) or ($response =~/^502/)) {
+        if (!($response =~ /^334/)) {
             # Not supported
             print $sock $logout;
             close $sock;
             return 'NO';
             # Not supported
             print $sock $logout;
             close $sock;
             return 'NO';
-        } elsif ($response =~ /^503/) {
-            #Something went wrong
-            return undef;
         }
     } elsif ($service eq 'IMAP') {
         if ($response =~ /^A01/) {
         }
     } elsif ($service eq 'IMAP') {
         if ($response =~ /^A01/) {
@@ -4727,13 +5635,13 @@ sub check_imap_folder($) {
     if ($folder_name =~ /[\x80-\xFFFF]/) {
         print "Folder name contains 8bit characters. Configuration utility requires\n";
         print "UTF7-IMAP encoded folder names.\n";
     if ($folder_name =~ /[\x80-\xFFFF]/) {
         print "Folder name contains 8bit characters. Configuration utility requires\n";
         print "UTF7-IMAP encoded folder names.\n";
-        print "Press any key to continue...";
+        print "Press enter to continue...";
         my $tmp = <STDIN>;
         return 0;
     } elsif ($folder_name =~ /[&\*\%]/) {
         # check for ampersand and list-wildcards
         print "Folder name contains special UTF7-IMAP characters.\n";
         my $tmp = <STDIN>;
         return 0;
     } elsif ($folder_name =~ /[&\*\%]/) {
         # check for ampersand and list-wildcards
         print "Folder name contains special UTF7-IMAP characters.\n";
-        print "Are you sure that folder name is correct? (yN): ";
+        print "Are you sure that folder name is correct? (y/N): ";
         my $tmp = <STDIN>;
         $tmp = lc(trim($tmp));
         if ($tmp =~ /^y$/) {
         my $tmp = <STDIN>;
         $tmp = lc(trim($tmp));
         if ($tmp =~ /^y$/) {
@@ -4752,3 +5660,488 @@ sub quote_single($) {
     $string =~ s/\'/\\'/g;
     return $string;
 }
     $string =~ s/\'/\\'/g;
     return $string;
 }
+
+# determine a plugin's version number
+#
+# parses the setup.php file, looking for the
+# version string in the <plugin>_info() or the
+# <plugin>_version functions.
+#
+sub get_plugin_version() {
+
+    my $plugin_name = shift(@_);
+
+    $setup_file = '../plugins/' . $plugin_name . '/setup.php';
+    if ( -e "$setup_file" ) {
+        # Make sure that file is readable
+        if (! -r "$setup_file") {
+            print "\n";
+            print "WARNING:\n";
+            print "The file \"$setup_file\" was found, but you don't\n";
+            print "have rights to read it.  The plugin \"";
+            print $plugin_name . "\" may not work correctly until you fix this.\n";
+            print "\nPress enter to continue";
+            $ctu = <STDIN>;
+            print "\n";
+            next;
+        }
+
+        $version = ' ';
+# FIXME: grep the file instead of reading it into memory?
+        $whole_file = '';
+        open( FILE, "$setup_file" );
+        while ( $line = <FILE> ) {
+            $whole_file .= $line;
+        }
+        close(FILE);
+
+        # ideally, there is a version in the <plugin>_info function...
+        #
+        if ($whole_file =~ /('version'\s*=>\s*['"](.*?)['"])/) {
+            $version .= $2;
+
+        # this assumes there is only one function that returns 
+        # a static string in the setup file
+        #
+        } elsif ($whole_file =~ /(return\s*['"](.*?)['"])/) {
+            $version .= $2;
+        }
+
+        return $version;
+
+        } else {
+            print "\n";
+            print "WARNING:\n";
+            print "The file \"$setup_file\" was not found.\n";
+            print "The plugin \"" . $plugin_name;
+            print "\" may not work correctly until you fix this.\n";
+            print "\nPress enter to continue";
+            $ctu = <STDIN>;
+            print "\n";
+            next;
+        }
+
+}
+
+# determine a plugin's English name
+#
+# parses the setup.php file, looking for the
+# English name in the <plugin>_info() function.
+#
+sub get_plugin_english_name() {
+
+    my $plugin_name = shift(@_);
+
+    $setup_file = '../plugins/' . $plugin_name . '/setup.php';
+    if ( -e "$setup_file" ) {
+        # Make sure that file is readable
+        if (! -r "$setup_file") {
+            print "\n";
+            print "WARNING:\n";
+            print "The file \"$setup_file\" was found, but you don't\n";
+            print "have rights to read it.  The plugin \"";
+            print $plugin_name . "\" may not work correctly until you fix this.\n";
+            print "\nPress enter to continue";
+            $ctu = <STDIN>;
+            print "\n";
+            next;
+        }
+
+        $english_name = '';
+# FIXME: grep the file instead of reading it into memory?
+        $whole_file = '';
+        open( FILE, "$setup_file" );
+        while ( $line = <FILE> ) {
+            $whole_file .= $line;
+        }
+        close(FILE);
+
+        # the English name is in the <plugin>_info function or nothing...
+        #
+        if ($whole_file =~ /('english_name'\s*=>\s*['"](.*?)['"])/) {
+            $english_name .= $2;
+        }
+
+        return $english_name;
+
+        } else {
+            print "\n";
+            print "WARNING:\n";
+            print "The file \"$setup_file\" was not found.\n";
+            print "The plugin \"" . $plugin_name;
+            print "\" may not work correctly until you fix this.\n";
+            print "\nPress enter to continue";
+            $ctu = <STDIN>;
+            print "\n";
+            next;
+        }
+
+}
+
+# parses the setup.php files for all activated plugins and
+# builds static plugin hooks array so we don't have to load
+# ALL plugins are runtime and build the hook array on every
+# page request
+#
+# hook array is saved in config/plugin_hooks.php
+#
+# Note the $verbose variable at the top of this routine
+# can be set to zero to quiet it down.
+#
+# NOTE/FIXME: we aren't necessarily interested in writing
+#             a full-blown PHP parsing engine, so plenty
+#             of assumptions are included herein about the
+#             coding of the plugin setup files, and things
+#             like commented out curly braces or other 
+#             such oddities can break this in a bad way.
+#
+sub build_plugin_hook_array() {
+
+    $verbose = 1;
+
+    if ($verbose) {
+        print "\n\n";
+    }
+
+    if ( open( HOOKFILE, ">plugin_hooks.php" ) ) {
+        print HOOKFILE "<?php\n";
+        print HOOKFILE "\n";
+
+        print HOOKFILE "/**\n";
+        print HOOKFILE " * SquirrelMail Plugin Hook Registration File\n";
+        print HOOKFILE " * Auto-generated using the configure script, conf.pl\n";
+        print HOOKFILE " */\n";
+        print HOOKFILE "\n";
+        print HOOKFILE "global \$squirrelmail_plugin_hooks;\n";
+        print HOOKFILE "\n";
+
+PLUGIN: for ( $ct = 0 ; $ct <= $#plugins ; $ct++ ) {
+
+        if ($verbose) {
+            print "Activating plugin \"" . $plugins[$ct] . "\"...\n";
+        }
+
+        $setup_file = '../plugins/' . $plugins[$ct] . '/setup.php';
+        if ( -e "$setup_file" ) {
+            # Make sure that file is readable
+            if (! -r "$setup_file") {
+                print "\n";
+                print "WARNING:\n";
+                print "The file \"$setup_file\" was found, but you don't\n";
+                print "have rights to read it.  The plugin \"";
+                print $plugins[$ct] . "\" will not be activated until you fix this.\n";
+                print "\nPress enter to continue";
+                $ctu = <STDIN>;
+                print "\n";
+                next;
+            }
+            open( FILE, "$setup_file" );
+            $inside_init_fxn = 0;
+            $brace_count = 0;
+            while ( $line = <FILE> ) {
+
+                # throw away lines until we get to target function
+                #
+                if (!$inside_init_fxn 
+                 && $line !~ /^\s*function\s*squirrelmail_plugin_init_/i) {
+                    next;
+                } 
+                $inside_init_fxn = 1;
+
+
+                # count open braces
+                #
+                if ($line =~ /{/) {
+                    $brace_count++;
+                } 
+
+
+                # count close braces
+                #
+                if ($line =~ /}/) {
+                    $brace_count--;
+
+                    # leaving <plugin>_init() function...
+                    if ($brace_count == 0) {
+                        close(FILE);
+                        next PLUGIN;
+                    }
+
+                } 
+
+
+                # throw away lines that are not exactly one "brace set" deep
+                #
+                if ($brace_count > 1) { 
+                    next;
+                } 
+
+
+                # also not interested in lines that are not
+                # hook registration points
+                #
+                if ($line !~ /^\s*\$squirrelmail_plugin_hooks/i) {
+                    next;
+                } 
+
+
+                # if $line does not have an ending semicolon,
+                # we need to recursively read in subsequent 
+                # lines until we find one
+                while ( $line !~ /;\s*$/ ) {
+                    $line =~ s/[\n\r]\s*$//;
+                    $line .= <FILE>;
+                }
+
+
+                $line =~ s/^\s+//;
+                $line =~ s/^\$//;
+                $var = $line;
+
+                $var =~ s/=/EQUALS/;
+                if ( $var =~ /^([a-z])/i ) {
+                    @options = split ( /\s*EQUALS\s*/, $var );
+                    $options[1] =~ s/[\n\r]//g;
+                    $options[1] =~ s/[\'\"];\s*$//;
+                    $options[1] =~ s/;$//;
+                    $options[1] =~ s/^[\'\"]//;
+                    # de-escape escaped strings
+                    $options[1] =~ s/\\'/'/g;
+                    $options[1] =~ s/\\\\/\\/g;
+
+                    if ( $options[0] =~ /^squirrelmail_plugin_hooks\s*\[\s*['"]([a-z0-9 \/._*-]+)['"]\s*\]\s*\[\s*['"]([0-9a-z._-]+)['"]\s*\]/i ) {
+                        $hook_name = $1;
+                        $hooked_plugin_name = $2;
+                        # Note: if we wanted to stop plugins from registering
+                        #       a *different* plugin on a hook, we could catch
+                        #       it here, however this has actually proven to be
+                        #       a useful *feature*
+                        #if ($hooked_plugin_name ne $plugins[$ct]) {
+                        #    print "...plugin is tring to hook in under different name...\n";
+                        #}
+
+#FIXME: do we want to count the number of hook registrations for each plugin and warn if a plugin doesn't have any?
+                        # hook registration has been found!
+                        if ($verbose) {
+                            if ($hooked_plugin_name ne $plugins[$ct]) {
+                                print "   registering on hook \"" . $hook_name . "\" (as \"$hooked_plugin_name\" plugin)\n";
+                            } else {
+                                print "   registering on hook \"" . $hook_name . "\"\n";
+                            }
+                        }
+                        $line =~ s/ {2,}/ /g;
+                        $line =~ s/=/\n    =/;
+                        print HOOKFILE "\$$line";
+
+                    }
+
+                }
+
+            }
+            close(FILE);
+
+        } else {
+            print "\n";
+            print "WARNING:\n";
+            print "The file \"$setup_file\" was not found.\n";
+            print "The plugin \"" . $plugins[$ct];
+            print "\" will not be activated until you fix this.\n";
+            print "\nPress enter to continue";
+            $ctu = <STDIN>;
+            print "\n";
+            next;
+        }
+
+    }
+
+    print HOOKFILE "\n\n";
+    close(HOOKFILE);
+#    if ($verbose) {
+        print "\nDone activating plugins; registration data saved in plugin_hooks.php\n\n";
+#    }
+
+    } else {
+
+        print "\n";
+        print "WARNING:\n";
+        print "The file \"plugin_hooks.php\" was not able to be written to.\n";
+        print "No plugins will be activated until you fix this.\n";
+        print "\nPress enter to continue";
+        $ctu = <STDIN>;
+        print "\n";
+
+    }
+
+}
+
+# converts (binary) integer values that correspond 
+# to the SquirrelMail debug mode constants (see 
+# include/constants.php) into those constant strings 
+# (bitwise or'd if more than one is enabled)
+#
+# if the value passed in is not an integer, it is 
+# returned unmolested
+#
+sub convert_debug_binary_integer_to_constants() {
+
+    my ($debug_mode) = @_;
+    if ($debug_mode =~ /^[^0-9]/) {
+        return $debug_mode;
+    }
+    $debug_mode = int($debug_mode);
+    $new_debug_mode = '';
+
+    # per include/constants.php, here are their values:
+    #
+    # 0          SM_DEBUG_MODE_OFF
+    # 1          SM_DEBUG_MODE_SIMPLE
+    # 512        SM_DEBUG_MODE_MODERATE
+    # 524288     SM_DEBUG_MODE_ADVANCED
+    # 536870912  SM_DEBUG_MODE_STRICT
+    #
+    if ($debug_mode & 1) {
+        $new_debug_mode .= ' | SM_DEBUG_MODE_SIMPLE';
+    }
+    if ($debug_mode & 512) {
+        $new_debug_mode .= ' | SM_DEBUG_MODE_MODERATE';
+    }
+    if ($debug_mode & 524288) {
+        $new_debug_mode .= ' | SM_DEBUG_MODE_ADVANCED';
+    }
+    if ($debug_mode & 536870912) {
+        $new_debug_mode .= ' | SM_DEBUG_MODE_STRICT';
+    }
+
+    $new_debug_mode =~ s/^ \| //;
+    if (!$new_debug_mode) {
+        $new_debug_mode = 'SM_DEBUG_MODE_OFF';
+    }
+
+    return $new_debug_mode;
+}
+
+# converts SquirrelMail debug mode constants (see
+# include/constants.php) into their corresponding
+# (binary) integer values
+#
+# if the value passed in is an integer already, it
+# is returned unmolested
+#
+sub convert_debug_constants_to_binary_integer() {
+
+    my ($debug_mode) = @_;
+    if ($debug_mode =~ /^[0-9]/) {
+        return $debug_mode;
+    }
+    $new_debug_mode = 0;
+
+    # per include/constants.php, here are their values:
+    #
+    # 0          SM_DEBUG_MODE_OFF
+    # 1          SM_DEBUG_MODE_SIMPLE
+    # 512        SM_DEBUG_MODE_MODERATE
+    # 524288     SM_DEBUG_MODE_ADVANCED
+    # 536870912  SM_DEBUG_MODE_STRICT
+    #
+    if ($debug_mode =~ /\bSM_DEBUG_MODE_OFF\b/) {
+        $new_debug_mode = 0;
+    }
+    if ($debug_mode =~ /\bSM_DEBUG_MODE_SIMPLE\b/) {
+        $new_debug_mode |= 1;
+    }
+    if ($debug_mode =~ /\bSM_DEBUG_MODE_MODERATE\b/) {
+        $new_debug_mode |= 512;
+    }
+    if ($debug_mode =~ /\bSM_DEBUG_MODE_ADVANCED\b/) {
+        $new_debug_mode |= 524288;
+    }
+    if ($debug_mode =~ /\bSM_DEBUG_MODE_STRICT\b/) {
+        $new_debug_mode |= 536870912;
+    }
+
+    return $new_debug_mode;
+}
+
+# Function to print n column numbered lists
+#
+# WARNING: the names in the list will be truncated
+# to fit in their respective columns based on the
+# screen width and number of columns.
+#
+# Expected arguments (in this order):
+#
+#    * The start number to use for the list
+#    * The number of columns to use
+#    * The screen width
+#    * Boolean (zero/one), indicating
+#      whether or not to show item numbers
+#    * The list of strings to be shown
+#
+# Returns: The number printed on screen of the last item in the list
+#
+sub print_multi_col_list {
+    my ($num, $cols, $screen_width, $show_numbering, @list) = @_;
+    my $x;
+    my $col_cnt = 0;
+    my $row_cnt = 0;
+    my $rows;
+    my $col_width;
+    my $total = 0;
+    my @layout = ();
+    my @numbers = ();
+
+    $rows = int(@list / $cols);
+    if (@list % $cols) { $rows++; }
+    if ($show_numbering) { $col_width = int(($screen_width - 2) / $cols) - 5; }
+    else                 { $col_width = int(($screen_width - 2) / $cols) - 2; }
+
+    # build the layout array so numbers run down each column
+    #
+    for ( $x = 0; $x < @list; $x++ ) {
+
+        $layout[$row_cnt][$col_cnt] = $list[$x];
+        $numbers[$row_cnt][$col_cnt] = $num++;
+
+        # move to next column
+        #
+        if ($row_cnt == $rows - 1) {
+            $row_cnt = 0;
+            $col_cnt++;
+        }
+        else { $row_cnt++; }
+
+    }
+
+    # if we filled up fewer rows than needed, recalc column width
+    #
+    if ($rows * $col_cnt == @list) { $col_cnt--; } # loop above ended right after increment
+    if ($col_cnt + 1 < $cols) {
+        if ($show_numbering) { $col_width = int(($screen_width - 2) / ($col_cnt + 1)) - 5; }
+        else                 { $col_width = int(($screen_width - 2) / ($col_cnt + 1)) - 2; }
+    }
+
+    # print it
+    # iterate rows
+    #
+    for ( $row_cnt = 0; $row_cnt <= $rows; $row_cnt++ ) {
+
+        # indent the row
+        #
+        print " ";
+
+        # iterate columns for this row
+        #
+        for ( $col_cnt = 0; $col_cnt <= $cols; $col_cnt++ ) {
+            if ($layout[$row_cnt][$col_cnt]) {
+                print " ";
+                if ($show_numbering) { printf "$WHT% 2u.$NRM", $numbers[$row_cnt][$col_cnt]; }
+                printf " %-$col_width." . $col_width . "s", $layout[$row_cnt][$col_cnt];
+            }
+        }
+        print "\n";
+    }
+
+
+    return $num - 1;
+}
+