+ $continue = 0;
+ while ( $continue != 1 ) {
+ print "Please select your IMAP server:\n";
+ print " cyrus = Cyrus IMAP server\n";
+ print " uw = University of Washington's IMAP server\n";
+ print " exchange = Microsoft Exchange IMAP server\n";
+ print " courier = Courier IMAP server\n";
+ print " macosx = Mac OS X Mailserver\n";
+ print " quit = Do not change anything\n";
+ print "Command >> ";
+ $server = <STDIN>;
+ $server =~ s/[\r|\n]//g;
+
+ print "\n";
+ if ( $server eq "cyrus" ) {
+ $imap_server_type = "cyrus";
+ $default_folder_prefix = "";
+ $trash_folder = "INBOX.Trash";
+ $sent_folder = "INBOX.Sent";
+ $draft_folder = "INBOX.Drafts";
+ $show_prefix_option = false;
+ $default_sub_of_inbox = true;
+ $show_contain_subfolders_option = false;
+ $optional_delimiter = ".";
+ $disp_default_folder_prefix = "<none>";
+
+ $continue = 1;
+ } elsif ( $server eq "uw" ) {
+ $imap_server_type = "uw";
+ $default_folder_prefix = "mail/";
+ $trash_folder = "Trash";
+ $sent_folder = "Sent";
+ $draft_folder = "Drafts";
+ $show_prefix_option = true;
+ $default_sub_of_inbox = false;
+ $show_contain_subfolders_option = true;
+ $optional_delimiter = "/";
+ $disp_default_folder_prefix = $default_folder_prefix;
+
+ $continue = 1;
+ } elsif ( $server eq "exchange" ) {
+ $imap_server_type = "exchange";
+ $default_folder_prefix = "";
+ $default_sub_of_inbox = true;
+ $trash_folder = "INBOX/Deleted Items";
+ $sent_folder = "INBOX/Sent Items";
+ $drafts_folder = "INBOX/Drafts";
+ $show_prefix_option = false;
+ $show_contain_subfolders_option = false;
+ $optional_delimiter = "detect";
+ $disp_default_folder_prefix = "<none>";
+
+ $continue = 1;
+ } elsif ( $server eq "courier" ) {
+ $imap_server_type = "courier";
+ $default_folder_prefix = "INBOX.";
+ $trash_folder = "Trash";
+ $sent_folder = "Sent";
+ $draft_folder = "Drafts";
+ $show_prefix_option = false;
+ $default_sub_of_inbox = false;
+ $show_contain_subfolders_option = false;
+ $optional_delimiter = ".";
+ $disp_default_folder_prefix = $default_folder_prefix;
+
+ $continue = 1;
+ } elsif ( $server eq "macosx" ) {
+ $imap_server_type = "macosx";
+ $default_folder_prefix = "INBOX/";
+ $trash_folder = "Trash";
+ $sent_folder = "Sent";
+ $draft_folder = "Drafts";
+ $show_prefix_option = false;
+ $default_sub_of_inbox = true;
+ $show_contain_subfolders_option = false;
+ $optional_delimiter = "detect";
+ $allow_charset_search = false;
+ $disp_default_folder_prefix = $default_folder_prefix;
+
+ $continue = 1;
+ } elsif ( $server eq "quit" ) {
+ $continue = 1;
+ } else {
+ $disp_default_folder_prefix = $default_folder_prefix;
+ print "Unrecognized server: $server\n";
+ print "\n";
+ }
+
+ print " imap_server_type = $imap_server_type\n";
+ print " default_folder_prefix = $disp_default_folder_prefix\n";
+ print " trash_folder = $trash_folder\n";
+ print " sent_folder = $sent_folder\n";
+ print " draft_folder = $draft_folder\n";
+ print " show_prefix_option = $show_prefix_option\n";
+ print " default_sub_of_inbox = $default_sub_of_inbox\n";
+ print "show_contain_subfolders_option = $show_contain_subfolders_option\n";
+ print " optional_delimiter = $optional_delimiter\n";
+ }
+ print "\nPress any key to continue...";
+ $tmp = <STDIN>;
+}
+
+# This subroutine corrects relative paths to ensure they
+# will work within the SM space. If the path falls within
+# 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'
+# 'images/logo.gif' --> SM_PATH . 'config/images/logo.gif'
+# '/absolute/path/logo.gif' --> '/absolute/path/logo.gif'
+# 'http://whatever/' --> 'http://whatever'
+sub change_to_SM_path() {
+ my ($old_path) = @_;
+ my $new_path = '';
+ my @rel_path;
+ my @abs_path;
+ my $subdir;
+
+ # 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 =~ /^(\$|SM_PATH)/);
+
+ # For relative paths, split on '../'
+ @rel_path = split(/\.\.\//, $old_path);
+
+ if ( $#rel_path > 1 ) {
+ # more than two levels away. Make it absolute.
+ @abs_path = split(/\//, $dir);
+ foreach $subdir (@rel_path) {
+ if ($subdir eq '') {
+ pop @abs_path;
+ } else {
+ push @abs_path, $subdir;
+ }
+ }
+ foreach $subdir (@abs_path) {
+ $new_path .= $subdir . '/';
+ }
+ } elsif ( $#rel_path > 0 ) {
+ # it's within the SM tree, prepend SM_PATH
+ $new_path = $old_path;
+ $new_path =~ s/^\.\.\//SM_PATH . \'/;
+ $new_path .= '\'';
+ } else {
+ # Last, it's a relative path without any leading '.'
+ # Prepend SM_PATH and config, since the paths are
+ # relative to the config directory
+ $new_path = "SM_PATH . \'config/" . $old_path . "\'";
+ }
+
+ return $new_path;
+}
+
+
+# Change SM_PATH to admin-friendly version, e.g.:
+# SM_PATH . 'images/logo.gif' --> '../images/logo.gif'
+# SM_PATH . 'config/some.php' --> 'some.php'
+# '/absolute/path/logo.gif' --> '/absolute/path/logo.gif'
+# 'http://whatever/' --> 'http://whatever'
+sub change_to_rel_path() {
+ my ($old_path) = @_;
+ my $new_path = $old_path;
+
+ if ( $old_path =~ /^SM_PATH/ ) {
+ $new_path =~ s/^SM_PATH . \'/\.\.\//;
+ $new_path =~ s/\.\.\/config\///;
+ }
+
+ return $new_path;
+}
+
+sub detect_auth_support {
+# Attempts to auto-detect if a specific auth mechanism is supported.
+# Called by 'command112a' and 'command112b'
+# ARGS: service-name (IMAP or SMTP), host:port, mech-name (ie. CRAM-MD5)
+
+ # Misc setup
+ use IO::Socket;
+ my $service = shift;
+ my $host = shift;
+ my $mech = shift;
+ # Sanity checks
+ if ((!defined($service)) or (!defined($host)) or (!defined($mech))) {
+ # Error - wrong # of args
+ print "BAD ARGS!\n";
+ return undef;
+ }
+
+ if ($service eq 'SMTP') {
+ $cmd = "AUTH $mech\n";
+ $logout = "QUIT\n";
+ } elsif ($service eq 'IMAP') {
+ $cmd = "A01 AUTHENTICATE $mech\n";
+ $logout = "C01 LOGOUT\n";
+ } else {
+ # unknown service - whoops.
+ return undef;
+ }
+
+ # Get this show on the road
+ my $sock=IO::Socket::INET->new($host);
+ if (!defined($sock)) {
+ # Connect failed
+ return undef;
+ }
+ my $discard = <$sock>; # Server greeting/banner - who cares..
+
+ if ($service eq 'SMTP') {
+ # Say hello first..
+ print $sock "helo $domain\n";
+ $discard = <$sock>; # Yeah yeah, you're happy to see me..
+ }
+ print $sock $cmd;
+
+ my $response = <$sock>;
+ chomp($response);
+ if (!defined($response)) {
+ return undef;
+ }
+
+ # So at this point, we have a response, and it is (hopefully) valid.
+ if ($service eq 'SMTP') {
+ if (($response =~ /^535/) or ($response =~/^502/)) {
+ # Not supported
+ close $sock;
+ return 'NO';
+ } elsif ($response =~ /^503/) {
+ #Something went wrong
+ return undef;
+ }
+ } elsif ($service eq 'IMAP') {
+ if ($response =~ /^A01/) {
+ # Not supported
+ close $sock;
+ return 'NO';
+ }
+ } else {
+ # Unknown service - this shouldn't be able to happen.
+ close $sock;
+ return undef;
+ }
+
+ # If it gets here, the mech is supported
+ print $sock "*\n"; # Attempt to cancel authentication
+ print $sock $logout; # Try to log out, but we don't really care if this fails
+ close $sock;
+ return 'YES';