#!/usr/bin/perl -w
#
#    GotMail - perl script to get mail from hotmail mailboxes.
#    Copyright (C) 2000-2003 Peter Hawkins <peterhawkins@ozemail.com.au>
#    Copyright (C) 2005 Jon Phillips <jon@rejon.org>
#    Copyright (C) 2005 Michael Ziegler.
#    Copyright (C) 2005-2006 Jos De Laender <jos.de_laender@pandora.be>
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 2 of the License, or
#    (at your option) any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with this program; if not, write to the Free Software
#    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#    -----------------------------------------------------------------------
#
#    Currently maintained by Jon Phillips <jon@rejon.org> and 
#    John Fruetel <jfruetel@hotmail.com> 
#
#    Peter Hawkins and Paul Cannon are no longer involved with the 
#    development of this software.
#

require 5.004;

eval "use Mail::SpamAssassin;";
#    Currently maintained by Jon Phillips <jon@rejon.org> and 
#    John Fruetel <jfruetel@hotmail.com> 
#
#    Peter Hawkins and Paul Cannon are no longer involved with the 
#    development of this software.
#
use English;
use URI::Escape;
use POSIX qw(tmpnam);
use FileHandle;
use strict;

# Signal handlers:
$SIG{INT} = $SIG{TERM} =
	sub {
		my($text) = @_;
		print STDERR "gotmail died with message: $text\n";
		print STDERR "Exiting abnormally, cleaning temp files.\n";
		doCleanTempFiles();
		exit(1);
	};

# Hide command line in a "ps" listing;
$0 = '[ gotmail getting new messages ]';
# This is not great security. The command line can still be found by other
# users. I recommend using a ~/.gotmailrc file, so that curl will be passed
# the username and password via private temporary files.

# Don't allow others to read our temp files
my($oldumask) = umask(077);

# Constants...
my($tmp_headers) = tmpnam()."gotmail_headers".$$;
my($tmp_cookies) = tmpnam()."gotmail_cookies".$$;
my($tmp_formdata) = tmpnam()."gotmail_form".$$;
my($tmp_curl_stderr) = tmpnam()."gotmail_curlstderr".$$;

# use constant 0.9.0 => "CVS (Run make)";

my($gotmail_version) = "0.9.0"; # hack to get in version number
my($gotmail_date) = "2005-06-16";

# JDLA
# Language constants as function of the language code 

my $current_language = "EN" ; # English is of course (duh) the default.

my %lc_trashcan = (
    'DA' => 'Papirkurv',                # Dansk, Danish
    'DE' => 'Gelschte Nachrichten',    # Deutsch, German
    'EN' => 'Trash Can',                # English, English
    'ES' => 'Papelera',                 # Espaol, Spanish
    'FR' => 'Messages supprims',       # Franais, French
    'IT' => 'Cestino',                  # Italiano, Italian
    'NL' => 'Prullenbak',               # Nederlands, Dutch
    'NO' => 'Papirkurv',                # Norsk, Norwegian
    'BR' => 'Lixeira',                  # Portugus, Portuguese (Brasil)
    'FI' => 'Roskakori',                # Suomi, Finnish
    'SV' => 'Papperskorgen'             # Svenska, Swedish
);

my %lc_nextpage = (
    'DA' => 'Nste side',               # Dansk, Danish
    'DE' => 'Nchste Seite',            # Deutsch, German
    'EN' => 'Next Page',                # English, English
    'ES' => 'Pgina siguiente',         # Espaol, Spanish
    'FR' => 'Page suivante',            # Franais, French
    'IT' => 'Pagina successiva',        # Italiano, Italian
    'NL' => 'Volgende',                 # Nederlands, Dutch
    'NO' => 'Neste side',               # Norsk, Norwegian
    'BR' => 'Prxima pgina',           # Portugus, Portuguese (Brasil)
    'FI' => 'Seuraava sivu',		        # Suomi, Finnish
    'SV' => 'Nsta sida'                # Svenska, Swedish
);
  

# If need more system types then add as more integers
use constant OS_TYPE_UNIX   =>  0;
use constant OS_TYPE_WIN32  =>  1;

# default os is unix...but this is checked with the function doCheckOS()
my($os_type) = OS_TYPE_UNIX;

# 0 will be the default for hotmail.com
my(@domains) = ("hotmail.com",
		            "msn.com",
                "charter.com",
                "compaq.net",
                "hotmail.co.jp",
                "hotmail.co.uk",
                "hotmail.de",
                "hotmail.fr",
                "hotmail.it",
                "messengeruser.com",
                "passport.com",
                "webtv.net");

# Some option dependent variables
my($conf_proxy)="";
my($conf_proxy_auth)="";
my($login) = "";
my($password) = "";
my($domain) = 'hotmail.com';
my($resend_address) = "";
my($conf_file) = "";
my(@conf_exclude_folders) = ();
my(@conf_folders) = ();
my($conf_folder_directory) = "";
my($conf_only_get_new_messages) = 0;
my($conf_mark_messages_as_read) = 0;
my($conf_delete_messages_after_download) = 0;
my($conf_move_messages_after_download) = "";
my($conf_sendmail) = "";
my($conf_curl) = 'curl -k';
my($conf_speed_limit) = 0;
my($conf_retry_limit) = 2;
my($conf_verbosity) = -1; # -1 = silent; 0 = normal; 1 = verbose; 
my($conf_save_to_login) = 0;   # 0 = no, 1 = yes
my($conf_procmail) = 0; # 0 = no, 1 = yes
my($conf_sa) = 0; # 0 = no, 1 = yes
my($conf_onlyspamscan) = 0; # 0 = no, 1 = yes
my($conf_deletespam) = 0; # 0 = no, 1 = yes
my($conf_movespam) = "";
my($conf_spamscore) = 4.5;
my($conf_procmail_bin) = '/usr/bin/procmail';
my($conf_summary) = 0;
my($conf_procmail_option)= "";
my($conf_remove_header) = 0;  # 0 = no, 1 = yes
my($conf_downloaded) = ""; # JDLA : local file with downloaded messages.
my($conf_smtpserver);
my($conf_debug) = 0;

# Global variables...
my($host) = ""; # The name of the hotmail server we are talking to...
my($gotconfig) = 0; # Have we found a config file?
my(@cookies) = ();
my($spam_folder_id) = ""; # Id of the folder where we want to move spam
my($move_folder_id) = ""; # Id of the folder where we want to move mail
my($trashFolder) = ""; # Id of the trash can folder

# Display some text.
# First parameter : text to be displayed.
# Then a number of named parameters that are optional. 
# See %args.

sub dispText($%)
{
	my $text = shift;
	my %args = (only_if_interactive   => 0,
							only_if_debug         => 0,
							min_verbosity					=> 0,
							stderr								=> 0,
							@_);

  # stderr messages are under no circumstances suppressed.
	if ($args{'stderr'}) {
		print STDERR $text;
		return;
	}

	# stdout message at this point.

	# Filter out the ones for which the verbosity is too high.
	return if ($args{'min_verbosity'} > $conf_verbosity);

	# Filter out the debug only messages.
	return if ($args{'only_if_debug'} && (not $conf_debug) );

	# Filter out the interactive only messages.
	return if ($args{'only_if_interactive'} && (not -t STDOUT) );

	# And finally print ;-)
	print STDOUT $text;

	return;
}

# Display summary to the screen, and log it, if we are specified summary.
sub dispSummary($)
{
  if ($conf_summary) {
	my($text) = @_;

	dispText($text,only_if_interactive=>1);
	dispText($text,min_verbosity=>2);
  }
}
# Various utility functions
# Can take the stderr parameter.
sub dispIntroText(%)
{
	my %args = (stderr=>0,@_);
	my $text = 
	  "\n".
	  "Gotmail v".$gotmail_version."    Copyright (C) 2000-2003 Peter Hawkins\n".
		"Gotmail comes with ABSOLUTELY NO WARRANTY.\n".
		"This is free software, and you are welcome to redistribute it\n".
		"under certain conditions; see the file COPYING for details.\n\n".
		'CVS ident: $Id: gotmail.in 112 2006-07-17 13:05:43Z kartar $' . "\n\n".
    "Running at ".localtime(time)." for user $login\n\n";
	dispText($text,%args);
}

sub dispVersionText()
{
	my $text = 
	  "Version information: Gotmail v ".  $gotmail_version.
		"   Date: ".  $gotmail_date.  "\n";
  dispText($text,min_verbosity=>-1);
}


# 
# JDLA : This hash of arrays describes the options.
# The key is the canonical option name as used on command line or 
# in configuration file.
# The value is an array with three entries :
#   - Symbolic name for parameter of the configuration item. "" if none.
#   - Subroutine to be called when having detected this option. The value
#     of the parameter is the argument of the subroutine.
#   - An explanation that describes the argument (and used for showing the
#     usage)
#     
#     

my %options = (

  'usage' => 
	  ["",\&dispUsageAndExit,
     "Display this screen"],

  'version' => 
	  ["",\&dispVersionText,
     "Display version information"],

  'config-file' => 
	  ["<file>",sub {},
     "Specify config file. Defaults to ~/.gotmailrc ."],

  'username' => 
	  ["<name>",sub {$login = shift;},
     "Specify your hotmail username (REQUIRED)"],

  'password' => 
	  ["<pass>",sub {$password = shift;},
     "Specify your hotmail password (REQUIRED)"],

  'domain' => 
	  ["<domain>",sub {$domain = shift;},
     "Specify your domain"],

  'proxy' => 
	  ["<host:port>",sub {$conf_proxy = shift;},
     "Specify an HTTP proxy to use in host:port format."],

  'proxy-auth' => 
	  ["<user:pass>",sub {$conf_proxy_auth = shift;},
     "Specify authentication details for the HTTP proxy."],

  'smtpserver' => 
	  ["<server>",sub {$conf_smtpserver = shift;},
     "Specify SMTP server. Will not use sendmail."],

  'forwarding-email' => 
	  ["<address>",sub {$resend_address = shift;},
     "Specify an email address to forward to. Otherwise saved to disk."],

  'exclude-folders' => 
	  ["\"folders\"",
		 sub {
			my $arg = shift; 
			@conf_exclude_folders = map {
			 	s/^"|"$//g;     # Remove leading, trailing quotes.
                                s/^\s+|\s+$//g; # Remove leading, trailing whitespace.
                                $_;             # The last value in the map{} construct is its return value. 
                        } split(/,/, $arg);     # Split on commas.
		 },
     "Do not get these folders (listed in quotes as in \"Inbox, Bulk Mail\")"],

  'folders' =>
    ["\"folders\"",
		 sub {
			my $arg = shift; 
			@conf_folders = map { 
				s/^"|"$//g;	# Remove leading, trailing quotes.
				s/^\s+|\s+$//g;	# Remove leading, trailing whitespace.
				$_;		# The last value in the map{} construct is placed in @conf_folders
			} split(/,/, $arg);	# Split on commas.
		 },
     "Only get these folders (optionally listed in quotes as in \"Inbox, Bulk Mail\")"],

  'folder-directory' =>
    ["/my/dir",sub {$conf_folder_directory = shift;},
     "Download messages in this directory"],

  'downloaded' =>
    ["<file>",sub {$conf_downloaded = shift;},
     "Local database of downloaded messages"],

  'only-new' =>
    ["",sub {$conf_only_get_new_messages = 1;},
     "Only unread messages will be retrieved"],

  'mark-messages-as-read' =>
    ["",sub {$conf_mark_messages_as_read = 1;},
     "Messages will be marked as read once downloaded"],

  'delete' =>
    ["",sub {$conf_delete_messages_after_download = 1;},
     "Messages will be deleted after download"],
		 
  'move' =>
    ["<folder>",sub {$conf_move_messages_after_download = shift;},
     "Messages will be moved to this folder after download"],

  'retry-limit' =>
    ["<max_tries>",sub {$conf_retry_limit = shift;},
     "Maximum number of attempts to download a message"],

  'speed-limit' =>
    ["",sub {$conf_speed_limit = 1;},
     "Throttle back rate of giving messages to sendmail"],

  'save-to-login' =>
    ["",sub {$conf_save_to_login = 1;},
     "Save to folder-dir/username for Inbox and folder-dir/username-foldername for others"],

  'use-procmail' =>
    ["",sub {$conf_procmail = 1;},
     "Send all messages only to procmail."],

  'procmail-bin' =>
    ["<path>",sub {$conf_procmail_bin = shift; $conf_procmail = 1;},
     "Use this as procmail. Defaults to /usr/bin/procmail and implies --use-procmail."],

  'procmail-option' =>
    ["<opt>",sub {$conf_procmail_option = shift;},
     "Pass options through to procmail."],

  'curl-bin' =>
    ["<path>",sub {$conf_curl = shift;},
     "Specify the path to the cURL executable if not in path"],

  'silent' =>
    ["",sub {$conf_verbosity = -1;},
     "Do not print messages"],

  'verbose' =>
    ["",sub {$conf_verbosity = 2;},
     "Verbosely print messages"],

  'verbosity' =>
    ["<value>",sub {$conf_verbosity = shift;},
     "Explicitly specify verbosity level."],

  'debug' =>
    ["",sub {$conf_debug = 1; $conf_verbosity=100;},
     "Print debug output."],

  'use-sa' =>
    ["",sub {$conf_sa = 1;},
     "Use SpamAssassin to ignore spam."],

  'delete-spam' =>
    ["",sub {$conf_deletespam = 1;},
     "Delete spam from server when using SpamAssassin."],

  'move-spam' =>
    ["<folder>",sub {$conf_movespam = shift;},
     "Move spam to this folder."],

  'spam-score' =>
    ["<value>",sub {$conf_spamscore =shift;},
     "SpamAssassin score that's considerd spam. Defaults to 4.5."],

  'onlyspamscan' =>
    ["",sub {$conf_onlyspamscan = 1},
     "Only fetch mails for scanning spam. No local saves or distribution."],

  'summary' =>
    ["",sub {$conf_summary = 1},
     "Print the number of messages received one line per folder"],

  'remove-header' =>
    ["",sub {$conf_remove_header = 1;},
     "Automatically remove X-Message-Info header to not trigger X_MESSAGE_INFO rule."]
 );

# Alternative short options (-) on the command line.

my %short_options = (
	'?' => 'usage',
	'c' => 'config-file',
	'u' => 'username',
	'p' => 'password',
	'd' => 'domain',
	's' => 'smtpserver',
	'f' => 'forwarding-email',
	'v' => 'verbose',
);

# Alternative names for the options.

my %option_aliases = (
	'help' => 'usage',
	'user' => 'username',
	'pass' => 'password',
	'forward' => 'forwarding-email',
	'folder_dir' => 'folder-directory',
	'folder-dir' => 'folder-directory',
	'folder_directory' => 'folder-directory',
	'onlynew' => 'only-new',
	'mark-read' => 'mark-messages-as-read',
	'markread' => 'mark-messages-as-read',
	'retrylimit' => 'retry-limit',
	'speedlimit' => 'speed-limit',
	'nodownload' => 'onlyspamscan',
);

# This is only called in error conditions. Output will go to stderr.
sub dispUsageAndExit()
{
	dispIntroText(stderr=>1);
	dispText("Usage:\ngotmail [OPTIONS...]\n".  "\nOptions:\n",stderr=>1);
	
	my %already_shown_options = ();

	foreach my $short_option (sort keys %short_options) {
		my $option = $short_options{$short_option};
		my $parameter   = $options{$option}[0];
		my $explanation = $options{$option}[2];

		my $explanation1 = $explanation;
		my $explanation2 = "";
		if (length($explanation)>40) {
		  my $place_to_split = rindex($explanation," ",40);
		  $explanation2 = substr($explanation,$place_to_split+1);
		  $explanation1 = substr($explanation,0,$place_to_split);
		}

		my $text = " -$short_option, --$option ";
		$text .= "$parameter" if $parameter;
		my $finaltext;
		if ($explanation2) {
	    $finaltext = sprintf("%-35s%-50s\n%-35s%-50s\n",$text,$explanation1,"",$explanation2);
		} else {
	    $finaltext = sprintf("%-35s%-50s\n",$text,$explanation1);
		}
		dispText($finaltext,stderr=>1);
		$already_shown_options{$option} = 1;
	}

	foreach my $option (sort keys %options) {
		next if $already_shown_options{$option};
		my $parameter   = $options{$option}[0];
		my $explanation = $options{$option}[2];

		my $explanation1 = $explanation;
		my $explanation2 = "";
		if (length($explanation)>40) {
		  my $place_to_split = rindex($explanation," ",40);
		  $explanation2 = substr($explanation,$place_to_split+1);
		  $explanation1 = substr($explanation,0,$place_to_split);
		}

		my $text = " --$option ";
		$text .= "$parameter" if $parameter;
		my $finaltext;
		if ($explanation2) {
	    $finaltext = sprintf("%-35s%-50s\n%-35s%-50s\n",$text,$explanation1,"",$explanation2);
		} else {
	    $finaltext = sprintf("%-35s%-50s\n",$text,$explanation1);
		}
		dispText($finaltext,stderr=>1);
	}
	exit(1);
}

# Parse ~/.gotmailrc
#
# Inserted code to parse ~/.gotmailrc
# This *should* hopefully be a little secure than specifying your
# username and password on the command line.
# parseArgs() is called afterwards, so you can override any settings.
# Thanks to Patrick Froede
#    and also to Tim Dijkstra. -pik-

sub parseConfig {
	if ("@ARGV" =~ /(\s|^)(-c|--config-file)\ ([\w\.~\/\-\@]*)(\s|$)/i) {
		$conf_file = $3;
		if (! -r $conf_file) {
			die "Config file <$conf_file> is not readable!\n";
		}
	} elsif ($ENV{"HOME"}) {
		$conf_file = $ENV{"HOME"} . "/.gotmailrc";
	} else {
		if ($ENV{"HOMEDRIVE"} && $ENV{"HOMEPATH"} && 
			  (-e $ENV{"HOMEDRIVE"} . $ENV{"HOMEPATH"} . ".gotmailrc") ) {
			# Using w2k environment variables.
			$conf_file = $ENV{"HOMEDRIVE"} . $ENV{"HOMEPATH"} . ".gotmailrc";
		} elsif (-e "/.gotmailrc") {
			# Try root directory
			$conf_file = "/.gotmailrc";
		} else {
			# Or try current directory
			$conf_file = "./.gotmailrc";
		}
	}

	# Open the config file, otherwise bail out of this subroutine
	open(RCFILE, $conf_file) || return;

	# Parse the file
	while (<RCFILE>) {
		my $line = $_;
		next if ($line =~ /^#/); # Comment.
		next if ($line =~ /^\s*$/); # Empty line.
		if (not $line =~ m/^([a-zA-Z0-9-_]+)/) {
			dispText("Wrong configuration line : '$_'\n",stderr=>1);
			dispUsageAndExit();
		}
		my $option  = $1;
		if (exists $option_aliases{$option}) {
		  $option = $option_aliases{$option};
		}
		if (not exists $options{$option}) {
			  dispText("Wrong configuration line : '$_' (illegal option)\n",stderr=>1);
				dispUsageAndExit();
	  }
		my $option_value = "";
		$line = $'; # The remaining of the line.
		if ($options{$option}[0]) { 
			# value expected
			if (not $line =~ m/\s*=\s*\S+/) {
			  dispText("Wrong configuration line : '$_' (no value)\n",stderr=>1);
				dispUsageAndExit();
			}

			# Remove equals sign and leading, trailing whitespace.
			$line =~ s/=//;		
			$line =~ s/^\s+|\s+$//g;

			$option_value = $line;
		}
		$options{$option}[1]($option_value); # Call of associated sub.
	}

	# Make a note that we obtained some configs from the options file
	$gotconfig = 1;
	close(RCFILE);
}

# Parse the command line
sub parseArgs()
{
	# If we have a config file, we don't care if there aren't any arguments...
	if (!@ARGV && ($gotconfig == 0)) {
		dispUsageAndExit();
	}

	while(@ARGV) {
		my($element)=shift(@ARGV);
		my $option;
		if ($element =~ /^-([a-zA-Z\?])/) {
			if (not exists $short_options{$1}) {
				dispText("Wrong option : '$element'\n",stderr=>1);
				dispUsageAndExit();
			} else {
				$option = $short_options{$1};
			}
		} elsif ($element =~ /^--(\S+)/) {
			$option = $1;
		  if (exists $option_aliases{$option}) {
		    $option = $option_aliases{$option};
		  }
		  if (not exists $options{$option}) {
			  dispText("Wrong option : '$element'\n",stderr=>1);
				dispUsageAndExit();
			}
		} else {
			dispText("Wrong option : '$element'\n",stderr=>1);
			dispUsageAndExit();
		}
		my $option_value = "";
		if ($options{$option}[0]) { 
			# value expected
		  $element = shift(@ARGV);
			if (not $element =~ m/(\S+)/) {
			  dispText("Wrong option : '$element' (no value)\n",stderr=>1);
				dispUsageAndExit();
			}
			$option_value = $element;
		}
		$options{$option}[1]($option_value); # Call of associated sub.
	}

	if (($login eq "") || ($password eq ""))
	{
		dispText("A username and password are REQUIRED.\n",stderr=>1);
		dispUsageAndExit();
	}
	if ($login =~ m/@/)
	{
		dispText(
			"The username should not contain a domain such as \@hotmail.com\n".
			"The latter should be specified with the --domain switch\n"
			,stderr=>1);
		dispUsageAndExit();
	}
}

# Clean up any temporary files
sub doCleanTempFiles()
{
	if (-e $tmp_headers) {
		unlink($tmp_headers)
		  or warn "Could not unlink tmp header: $!\n";
	}
	if (-e $tmp_cookies) {
		unlink($tmp_cookies)
		  or warn "Could not unlink tmp cookie: $!\n";
	}
	if (-e $tmp_formdata) {
		unlink($tmp_formdata)
		  or warn "Could not unlink tmp formdata: $!\n";
	}
	if (-e $tmp_curl_stderr) {
		unlink($tmp_curl_stderr)
		  or warn "Could not unlink tmp curlstderr: $!\n";
	}
}

sub doCleanOtherFiles()
{
}

# Check all the required programs are installed.
sub doCheckPrograms()
{
	dispText("System version is: ".$OSNAME."\n",min_verbosity=>2);
	# $PERL_VERSION and $^V seem to be broken
	dispText("Perl version is:   ".$]."\n",min_verbosity=>2);
	dispText("Curl version is:   ".`$conf_curl --version`."\n",min_verbosity=>2);

	# Try looking for sendmail in a few common places.
	$conf_sendmail = "sendmail";
	if (-x "/usr/sbin/sendmail") {
		$conf_sendmail = "/usr/sbin/sendmail";
	}	elsif (-x "/usr/lib/sendmail") {
		$conf_sendmail = "/usr/lib/sendmail"
	}
	$conf_sendmail .= " -i";

	# Make sure procmail is there.
	if ((! -x $conf_procmail_bin) and $conf_procmail) {
		die "Procmail binary at \"$conf_procmail_bin\" can't be run. Aborting";
	}

	# If we're doing spam detection, make sure SpamAssassin is installed
  if ($conf_sa) {
    eval "use Mail::SpamAssassin;";
		if ($@) {
      die("Spam detection specified but SpamAssassin not installed.  Aborting");
		}
	}
}

# Grep any cookies from the header file into the cookies file.
sub parseHeaders()
{
	my $redirector = "";
	my($in) = new FileHandle "< $tmp_headers" || return;

	while (<$in>) {
		if (m/^Location: (\S+)\s/) {
			$redirector = $1;
		}
	}
	close($in);

	return $redirector;
}

# Fetch a given page using curl
#
# The parameters taken are the URL, any data to be posted in a POST,
# whether we are to follow HTTP redirects, whether we should send and
# receive cookies, and whether we should only get the headers for this
# page and not the body.
sub getPage($$$$$)
{
	my($url, $params, $follow_forward, $cookies, $headers_only) = @_;

	if ($url =~ m/http:\/\/(\S+?)\//i) {
		$host = $1;
	}

	dispText("FETCH: $url\n",min_verbosity=>2);

	# Set up the options string...
	my($options) = "";
	if ($conf_proxy) { $options .= "--proxy ". $conf_proxy . " "; }
	if ($conf_proxy_auth) { $options .= "--proxy-user ". $conf_proxy_auth . " "; }
	if ($cookies != 0) { $options .= "-b $tmp_cookies -c $tmp_cookies " }
#	if ($cookies != 0) { $options .= "-b $tmp_cookies " }
	if ($params ne "") { $options .= "--data \"$params\" " }
	if ($headers_only) { $options .= "-I " }
	# Curl is put silent (but with error output) when not interactive or low verbosity.
	if ( (not -t STDOUT) || ($conf_verbosity <= 1) ) { $options .= "-s -S " }
	if ($conf_debug) { $options .= "-v " }

	# Get rid of any trailing space on options.. Just for neatness.
	$options =~ s/ $//;
    
	my($cmdline);
	
	# JDLA curl outputs info via stderr. Catched in file and appended
	# to stdout output in debug mode.
	
	if ( OS_TYPE_WIN32 == $os_type ) {
		$cmdline =
		"$conf_curl --stderr $tmp_curl_stderr \"$url\" $options -i -m 600 -D $tmp_headers" .
		" -A \"Mozilla/4.73 [en] (Win98; I)\"";
	} else {
		$cmdline = 
		"$conf_curl --stderr $tmp_curl_stderr \'$url\' $options -i -m 600 -D $tmp_headers" .
		" -A \"Mozilla/4.73 [en] (Win98; I)\"";
	}
    
	dispText("command line: $cmdline\n",only_if_debug=>1);

	my $tries = 1;
	my @tmp_page = ();
	while (!@tmp_page && $tries <= $conf_retry_limit) {
		dispText("Trying [$tries/$conf_retry_limit]...\n",min_verbosity=>2);
		$tries++;
		@tmp_page = `$cmdline`;
		# Copy output.
		foreach my $line (@tmp_page) { dispText($line,only_if_debug=>1) };
		open (CURL_STDERR,"$tmp_curl_stderr") || 
		  die "Could not open $tmp_curl_stderr : $!";
		# Copy curl stderr.
		dispText("\nstderr of curl :\n",only_if_debug=>1);
		while(<CURL_STDERR>) {
			my $line = $_;
			my $password_to_blank = uri_escape($password, "^A-Za-z");
			$line =~ s/$password_to_blank/**PASSWORD**/g;
		  dispText("$line",only_if_debug=>1);
		}
		close(CURL_STDERR);
	}
	if (!@tmp_page && !$headers_only && $tries >= $conf_retry_limit) {
		&doCleanTempFiles;
		die("An error was encountered getting the page. Command was $cmdline");
	}

	my $redir = parseHeaders();

	# If we have been asked to follow Location: headers
	if ($follow_forward) {
		if ($redir ne "") {
      if ($redir !~ m/^http.*/i) {
        if ($url =~ m/(http?:\/\/[^\/]+)\//i) {
          $redir = $1 . $redir;
        }
      }
			dispText("Following redirect to $redir\n",min_verbosity=>2);
			return &getPage($redir, "", $follow_forward, $cookies, $headers_only);
		}
	}
	return @tmp_page;
}

# Do the HotMail login process - log in until we have the URL of the inbox.
sub doLogin()
{
	dispText("Getting hotmail index page...\n",min_verbosity=>2);
	my(@index_page);     ## This will have the login page.

	@index_page = getPage("http://www.hotmail.com/", "", 1, 1, 0);
	my($page) = join("", @index_page);

	## @index_page is now an intermediate page which checks if you
	## have javascript enabled or not!! This code invokes the form
  ## on that page to get you to the login/password page.
	if($page =~ m/<form.*((hiddenform)|(fmHF)).*action=\"(\S+)\".*>/i) {
    my $action = $4;

		## This processing happens only for the "new" hotmail structure.
		dispText("Processing java check....\n",min_verbosity=>2);
		my($inp);      ## This var will store all the input fields.
		while($page =~ m/<\s*input\s+.*name=\"(\S+)\"(\s+id="\S+")?\s+value=\"(\S*)\"/) {
			## Get rid of the input field we processed.
			$page = $';
			$inp .= "$1=" . uri_escape($3) . "\&";
		}
		## Get rid of the last "&"
		$inp =~ s/&$//g;

		my($FORMFILE) = new FileHandle "> $tmp_formdata" ||
			die "Couldn't open formdata file: $!\n";

		print $FORMFILE ("$inp");
		close($FORMFILE);
		my($params) = "\@$tmp_formdata";

		## Hopefully this should get us to the correct index page.
		@index_page = getPage($action, $params, 1, 1, 0);
		$page = join "", @index_page;
	}

	# Find the form "ACTION" parameter...
	my($login_script);
  my($login_new) = 0;

  # Old - multiple forms for multiple domains
	if ($page =~ m/<form.*hotmail_com.*action=\"(\S+)\".*>/i) {
		$login_script = $1;
	}
  # New - heavy javascript
	elsif ($page =~ m/<form.*f1.*action=\"(\S+)\".*>/i) {
		$login_script = $1;
		$login_new = 1;
	}
  # Very old - simple form
	elsif ($page =~ m/<form.*action=\"(\S+)\".*>/i) {
		$login_script = $1;
	}
  else {
		&doCleanTempFiles;
		die "Page doesn't contain any form action field!\n";
  }

	my($FORMFILE) = new FileHandle "> $tmp_formdata" ||
	                        die "Couldn't open formdata file: $!\n";

  if( $login_new ) {
		dispText("Using New Login...\n",min_verbosity=>2);

    ## The actual action of the form is replace by javascript
    ## (authentication depends on the domain of your user id).
    ## and arguments are appended in javascript
		if( $page =~ m/g_DO\["\Q$domain\E"\]\s*=\s*"([^"]+)\"/ ) {
			$login_script = $1;
			#dispText( "g_DO=$1\n" );
		}
		if( $page =~ m/g_QS\s*=\s*"([^"]+)\"/ ) {
			$login_script .= index($login_script,'?') >= 0 ? '&' : '?';
			$login_script .= $1;
			#dispText( "g_QS=$1\n" );
		}

    ## Get (or calculate) the hidden fields of the form 
		my ( $PPFT, $PPSX, $PwdPad );
    {
			if( $page =~ m/<\s*input\s+.*name=\"PPFT\"(\s+id="\S+")?\s+value=\"(\S*)\"/ ) {
				$PPFT = $2;
				#dispText( "PPFT=$PPFT\n" );
			}
			if( $page =~ m/<\s*input\s+.*name=\"PPSX\"(\s+id="\S+")?\s+value=\"(\S*)\"/ ) {
				$PPSX = $2;
				#dispText( "PPSX=$PPSX\n" );
			}
			{
				my $Padding = "IfYouAreReadingThisYouHaveTooMuchFreeTime";
				$PwdPad = substr( $Padding, 0, length($Padding)-length($password) ); 
				#dispText( "PwdPad=$PwdPad\n" );
			}
		}

		print $FORMFILE ("PPSX=$PPSX" .
										 "\&PwdPad=$PwdPad" .
										 "\&login=" . uri_escape($login . '@' . $domain, "^A-Za-z") .
										 "\&passwd=" . uri_escape($password, "^A-Za-z") .
										 "\&SI=" . uri_escape( '    Sign In    ' ) . 
										 "\&LoginOptions=3" .
										 "\&PPFT=" . uri_escape( $PPFT ) );
  } else {
		dispText("Using Old Login...\n",min_verbosity=>2);
		my($ctnum) = "";
		if ($page =~ m/ct=([0-9]+)/i) {
			$ctnum = uri_escape($1);
		}
		print $FORMFILE ("login=" . uri_escape($login, "^A-Za-z") .
										 "\&passwd=" . uri_escape($password, "^A-Za-z") .
										 "\&svc=mail\&mspp_shared=1" .
										 "\&domain=" . uri_escape($domain) .
										 "\&RemoteDAPost=https://login.msnia.passport.com/ppsecure/post.asp" .
										 "\&sec=share\&curmbox=ACTIVE\&js=yes\&_lang=EN" .
										 "\&beta=0\&ishotmail=1\&id=2\&fs=1" .
										 "\&cb=_lang%3dEN%26country%3dUS\&ct=$ctnum");
  }

	close $FORMFILE;
	my($params) = "\@$tmp_formdata";

	dispText("Logging in...\n");
	my(@login_page) = getPage($login_script, $params, 1, 1, 0);
	$page = join "", @login_page;

	# Find where they are sending us now...
	my($redirect_location) = "";

# Now not needed per Chris Ebenezer's comments
#	if ($domain eq 'msn.com') {
#		if ($page =~ m/Location: (\S+)/i) {
#			$redirect_location = $1;
#		} elsif ($page =~ /unavailable/i) {
#			&doCleanTempFiles;
#			die("Hotmail is reporting that your account is temporarily " .
#			    "unavailable. Please try again later.\n");
#		}
#
#		if ($redirect_location eq "") {
#			&doCleanTempFiles;
#			die("Hotmail's page structure has changed! (msncom)\n");
#		}
#
#		my(@redirect_page) = getPage($redirect_location, "", 0, 1, 0);
#		$page = join "", @redirect_page;
#	}

	if ($page =~ m/top\.location\.replace\(\"(.*)\"\);/i) {
		$redirect_location = $1;
	} elsif ($page =~ m/window\.location\.replace\(\"(.*)\"\);/i) { 
		$redirect_location = $1; 
	} elsif ($page =~ m/meta\s*http-equiv="refresh"\s*content="0;\s*URL=([^"]+)"/i ) {
    $redirect_location = $1;
  }

	if ($redirect_location eq "") {
		&doCleanTempFiles;
		die("Hotmail's page structure has changed! (redirloc)\n");
	} elsif ($redirect_location =~ /loginerr/i) {
		&doCleanTempFiles;
		die("There was an error logging in. Please check that your " .
		    "username and password are correct.\n");
	}

	if ($redirect_location =~ m/http:\/\/([^\/]+)\/(.*)$/i) {
		$host = $1;
	} else {
		&doCleanTempFiles;
		die ("Could not parse redirect location. This could be caused by " .
         "selecting the wrong Hotmail domain or by an incorrect password " .
         "or locked account.\n");
	}

	dispText("Following redirect...\n",min_verbosity=>2);
	my(@redirect_page) = getPage($redirect_location, "", 0, 1, 0);
	$page = join "", @redirect_page;

  # JDLA : $page contains a cookie setting with the language.
  $page =~ m/^Set-Cookie:.+lang%2c(\w+)%2c/m;
  $current_language = $1;
  dispText "Detected language code '$current_language'...\n";

	# Find where the inbox is located...
	my($inbox_location);
	if ($page =~ m/Location: (\S+)/i) {
		my $inbox_loc = $1;
    if ($inbox_loc =~ m/\&RedirectLocation=(http[^\&]+)\&/i) {
      $inbox_loc = uri_unescape($1);
    }
		$inbox_loc =~ /(.+)\/dasp\/ua_info.asp\?pg=browser_limit[^&]*(&.+)/;
		$inbox_location = "$1\/HoTMail";
	} elsif ($page =~ /unavailable/i) {
		&doCleanTempFiles;
		die("Hotmail is reporting that your account is temporarily " .
		    "unavailable. Please try again later.\n");
	} else {
		&doCleanTempFiles;
		die("Hotmail's page structure has changed! (inboxloc)\n");
	}

	dispText("Going to Inbox Page: $inbox_location\n",only_if_debug=>1);
	getPage($inbox_location, "", 1, 1, 0);
	dispText("Got inbox location...\n");

	return $inbox_location;
}

sub doSaveEmail($$)
{
	my ($output, $email) = @_;

	# restore umask to whatever user had before
	umask($oldumask);
	my($OUT) = new FileHandle ">> $output";

	if (! defined ($OUT)) {
		die("Unable to open $output.");
	}

	print $OUT "$email\n";

	$OUT->close();
}

sub doResendEmail($$)
{
	my($destaddr, $email) = @_;

	my($OUT) = new FileHandle "| $conf_sendmail $destaddr";

	if (! defined ($OUT)) {
		die("Unable to open sendmail - was using $conf_sendmail $destaddr.");
	}

	# Dump the message to sendmail.
	if ($] >= 8.0) { # $] is the current perl version 
		### try and stop the Wide Character warnings
		binmode $OUT, ":utf8";
	}
	print $OUT $email;

	$OUT->close();
	if ($conf_speed_limit) { sleep(1); }
}

sub doResendSMTPEmail($$$)
{
	use Net::SMTP;
	my($destaddr, $email, $server) = @_;

	my $from = "$login\@$domain";
	if ($email =~ s/^From ([^ ]*).*\n//) {
		$from = $1;
	}

	dispText("Forwarding email to $destaddr by SMTP\n");

	my $smtp_debug = 0;
	if ($conf_verbosity == 2) {
		$smtp_debug = 1;
	}

	my $mail = Net::SMTP->new($server, Debug => $smtp_debug) or
	             die "Could not connect to SMTP server $server. $!\n";

	$mail->mail($from);
	$mail->recipient($destaddr);
	$mail->data($email);
	$mail->quit();

	if ($conf_speed_limit) { sleep(1); }
}

# Return the email message.  Actually, it returns two versions
# of the message, one with headers added and one without 
sub getEmail($$)
{
	my($url, $folder) = @_;
	my(@output) = ();

	dispText("\nGetting email message...\n");

	$url = "http://$host/$url\&raw=0";

	my(@email_page) = getPage($url, "", 1, 1, 0);

	my $emailstr = join "", @email_page;
	if ($emailstr !~ /pre/) {
		&doCleanTempFiles;
		die("Unable to download email message - $emailstr\n");
	}

	# Get everything between the <pre> </pre> tags
	@email_page = split(/<\/?pre>/, $emailstr);
	if (@email_page != 3) {
		&doCleanTempFiles;
		die("Unable to download email message - $emailstr\n");
	}
	$_ = $email_page[1];

	s/^[\s\n]*//s;

	# Strip any HTML artifacts from the message body.
	s/&lt;/</g;
	s/&gt;/>/g;
	s/&quot;/\"/g;
        s/&amp;/&/g; 

	# Add some more special headers right before the message body.
	my($gm_headers) = "X-gotmail-version: $gotmail_version\nX-gotmail-folder: $folder\nX-gotmail-user: $login\n";
	s/^$/$gm_headers/m;

	# Remove X-Message-Info header if specified
	if ($conf_remove_header) {
		s/^X-Message-Info: .*?\n//m;
	}

  # Make a copy of the message without the extra headers
  my ($noHeaders) = $_;

  # We'll try to parse out the envelope sender and date received by
	# Hotmail. Apparently, those fields are not _always_ added. If we
	# can't find good data, we'll have to make stuff up.
	my($from_addr) = "$login\@$domain";
	my($from_date) = scalar gmtime;

	# Strip "From whoever" when found on the first line- the format
	# is wrong for mbox files anyway.
	if (s/^From ([^ ]*) [^\n]*\n//s) { $from_addr = $1; }
	elsif (m/^From:[^<]*<([^>]*)>/m) { $from_addr = $1; }

	# Apply >From quoting
	s/^From ([^\n]*)\n/>From $1/gm;

	# If an mboxheader was desired, make up one
	if (m/^\t (\w+), (\d+) (\w+) (\d+) (\d+):(\d+):(\d+) ([+-]?.+)/m) {
		my($dow) = $1;
		my($mon) = $3;
		my($dom) = $2;
		my($hr) = $5;
		my($min) = $6;
		my($sec) = $7;
		my($yr) = $4;
		my($senttz) = $8;

		# Put date in mboxheader in UTC time
		$hr -= $senttz;
		while ($hr < 0) { $hr += 24; }
		while ($hr > 23) { $hr -= 24; }

		$from_date = sprintf ("%s %s %02d %02d:%02d:%02d %d",
		                      $dow, $mon, $dom, $hr, $min, $sec, $yr);
	}

	# Add an mbox-compatible header
	s/^/From $from_addr $from_date\n/;

	return ($_, $noHeaders);
}

# Get the messages from a folder called $foldername at $url
sub getFolder($$)
{
	my($foldername, $url) = @_;

	# Get the folder in newest first order
	dispText("\nLoading folder \"$foldername\" ...\n");

  # JDLA : language dependent 
  my $nextpage_string = $lc_nextpage{$current_language};

	my $page = 1;
	my $still_a_page_to_go = 1;
	my $start_line_of_nextpage_search = 0;
	my @folder = ();

	while ($still_a_page_to_go) {
		$still_a_page_to_go = 0;
	  # Get the messages in whatever order Hotmail says we should
	  push @folder,getPage("http://$host/cgi-bin/HoTMaiL?$url\&page=$page", "", 1, 1, 0);
	  for (my $line_nr=$start_line_of_nextpage_search;$line_nr<@folder;$line_nr++) {
		  if ($folder[$line_nr] =~ m/title="$nextpage_string"/) {
	      $start_line_of_nextpage_search = $line_nr + 1;
			  $still_a_page_to_go = 1;
				$page++;
				last;
			}
		}
	}

	# Redo the list on a table row by table row basis
	# XXX JDLA : I believe loop above and loop below can be
	# combined to one more efficient.
	
	my @messages;

  # Get everything that looks like a mail link
  foreach my $f (@folder) {
    while ($f =~ m/(<a href=\"javascript:G\('\/cgi-bin\/getmsg[^\"]*\">)/i) {
			push(@messages, $1);
      $f = $';
		}
  }

  # For some reason, some mails are listed more than once.
  # Sort the list of messages, then only do them once
	# JDLA : according to me this is unnecessary and confuses the newest first order ...
	# @messages = sort @messages;
	#my $oldItem = "";
	foreach my $item (@messages)
	{
    $item =~ m/<a href=\"javascript:G\('\/(cgi-bin\/getmsg\?[^\']*)'\)\">/i;
		my $msg_url = $1;

		# Since the folder is in newest first order, if we are only getting
		# new messages, and this is not a new message, we can stop here.

		if ($conf_only_get_new_messages && ($item =~ /msgread/i)) {
			next;
		}

    # JDLA
    # if conf_downloaded, we check via a local database if the message
    # is not yet downloaded. If so we skip downloading and a bunch of
    # other stuff that would be useless.

    my $have_message_already = 0;  

    if ($conf_downloaded) {
      if ($msg_url =~ m/\?msg=([^&]+)/) {
        my $id=$1;
        #print "Id:'$id'\n";

        # Look in local database if e have it already.
        if (-e $conf_downloaded) {
          open (DOWNLOADED,"$conf_downloaded") || 
            die "Could not open $conf_downloaded : $!";
          while(my $tmp_id = <DOWNLOADED>) {
            chomp ($tmp_id);
            if ($id eq $tmp_id) {
              $have_message_already = 1;
              #print "Have already $id\n";
              last;
            }
          }
        close (DOWNLOADED);
        }

        # Add it to local database if we don't have it yet.
        if (not $have_message_already) {
          # We don't have it yet. Add it to the downloaded.
          # A bit preliminary but let's take the risk.
          open (DOWNLOADED,">>$conf_downloaded") || 
            die "Could not open $conf_downloaded : $!";
          print DOWNLOADED "$id\n";
          close (DOWNLOADED);
        }
      }
    }  # if ($conf_downloaded)

    # JDLA getEmail , provided that have_message_already was not set.
    my ($Message, $msgNoHeaders);
    if (not $have_message_already) {
      ($Message, $msgNoHeaders) =getEmail($msg_url, $foldername);
				my $message_from = "";
			  if ($Message =~ m/^From: (.*)$/m) {
					$message_from = $1;
				}
				my $message_subject = "";
			  if ($Message =~ m/^Subject: (.*)$/m ) {
			    $message_subject = $1;
				}
		    dispText(" From: '$message_from'\n Subject: '$message_subject'\n",
				       min_verbosity=>1);
			}

    # Check for spam, if requested to.  Probable SPAMS are
    # not downloaded

    # JDLA : Extra check on have_message_already needed, because
    # in the case we have it already, $Message will be empty ...
    if ($conf_sa && not $have_message_already) {
      my $SpamTest = Mail::SpamAssassin -> new();

      my $MessageObject = $SpamTest -> check_message_text($Message);
      my $Score  = $MessageObject -> get_hits();

      if ($Score > $conf_spamscore) {
        if ($conf_deletespam) {
          dispText("Deleting spam...\n");
          getPage("http://$host/$msg_url\&_HMaction=MoveTo\&tobox=$trashFolder",
                  "", 1, 1, 1);
        } elsif ($conf_movespam) {
          dispText("Moving spam...\n");
          getPage("http://$host/$msg_url\&_HMaction=MoveTo\&tobox=$spam_folder_id",
                  "", 1, 1, 1);
        } else {
          dispText("Probably spam (score : $Score) : skipping...\n");
        }
        next;
      }
    }

    # If we're just scanning for spam on the server, don't download 
    if ($conf_onlyspamscan) {
      next;
    }


    # JDLA
    # All of the original code only executed if we do not have yet
    # the message.
    if (not $have_message_already) {

			# Are we resending or saving?
			if ($conf_procmail) {
				my($output) = $Message;
				dispText("Sending mail message to procmail...");
				open PR,"|" . $conf_procmail_bin." ".$conf_procmail_option;
				print PR $output;
				close PR;
				dispText("Done.\n");
			}
			elsif ($resend_address eq "") {
				my($output) = $Message;
				my($outfile) = "$conf_folder_directory/";

				if ($conf_save_to_login) {
					$outfile .= $login;
					if ($foldername ne "Inbox") {
						$outfile .= ("-" . $foldername);
					}
				} else {
					$outfile .= $foldername;
				}

				doSaveEmail($outfile, $output);
				dispText("Saving message to $outfile...\n");
			} elsif ($conf_smtpserver) {
				my($output) = $Message;
				doResendSMTPEmail($resend_address, $output, $conf_smtpserver);
			} else {
				my($output) = $msgNoHeaders;
				doResendEmail($resend_address, $output);
				dispText ("Forwarding message to $resend_address\n");
			}


      # JDLA : Marking and deleting now only active if not have_messages_already.
			# It became too slow for hotmails where the messages stay stored for
			# longer term.
			# When consistently used (downloaded and mark_read option) this should
			# give no difference.

			if ($conf_mark_messages_as_read) {
				dispText("Marking message as read...\n");
				getPage("http://$host/$msg_url", "", 1, 1, 1);
			}

			if ($conf_delete_messages_after_download) {
				dispText("Deleting message...\n");
				getPage("http://$host/$msg_url\&_HMaction=MoveTo\&tobox=$trashFolder", "", 1, 1, 1);
			} elsif ($conf_move_messages_after_download) {
				dispText("Moving message...\n");
				getPage("http://$host/$msg_url\&_HMaction=MoveTo\&tobox=$move_folder_id", "", 1, 1, 1);
      }

    } # if not HaveMessageReadAlready
	}
}

# Returns the strange Hotmail 'id' for a folder name
sub getFolderId($$$)
{
  my $host = shift;
  my $folder_index_url = shift;
  my $folder_name = shift;

  my @folder_list = getPage("http://$host/cgi-bin/folders?$folder_index_url", "", 1, 1, 0);

  # Join the page into one big string, and split it into bits that interest us
  my $onestr = join "", @folder_list;
  $onestr =~ s/\n/ /g;
  @folder_list = grep { /<td[^>]*><a\s*href=\"\/cgi-bin\/HoTMaiL\?/ }
                  split(/(<tr[^>]*>|<\/tr>)/, $onestr);

  $onestr = join "\n", @folder_list;
  foreach my $item (@folder_list) {
    if ($item =~ m/<a(.*)href=\"\/cgi-bin\/HoTMaiL\?([^\"]+)\"[ ]*>([^<]+)<\/a>/) {
      my($url) = $2;
      my($name) = $3;
      if (lc($name) eq lc($folder_name)) {
        $url =~ m/curmbox=(.*)&/;
        return($1);
      }
    }
  }
}


# Get a list of the folders we have to deal with and parse them one by one.
sub doGetFolders($)
{
	my($inbox_location) = @_;

	dispText("Loading main display...\n",min_verbosity=>2);
	if ($inbox_location !~ m/^http/) {
		$inbox_location = "http://$host/cgi-bin/".$inbox_location;
	}
	my(@inbox_page) = getPage($inbox_location, "", 1, 1, 0);

	# Ok, we have the location of the inbox. Where's the master list of folders?
	my($folder_index_url) = "";
	foreach my $item (@inbox_page) {
		if ($item =~ m/<a(.*)href=\".*(\/cgi-bin\/folders\?)(\S+)\"/i) {
			$folder_index_url = $2;
		}
	}

  dispText("\$folder_index_url->$folder_index_url\n",only_if_debug=>1);
	if ($folder_index_url eq "") {
		&doCleanTempFiles;
		die("Could not isolate folder index location\n");
	}

  # JDLA : language dependent
  my $trashcan_string = $lc_trashcan{$current_language};

  # Get the id of the trash can folder
  $trashFolder=getFolderId($host, $folder_index_url, $trashcan_string);

	if ($conf_movespam) {
    # Figure out the ID of the Spam folder
    $spam_folder_id = getFolderId($host, $folder_index_url, $conf_movespam);
    dispText("\$spam_folder_id->".$spam_folder_id."\n");
  }

	if ($conf_move_messages_after_download) {
    # Figure out the ID of the move to folder
    $move_folder_id = getFolderId($host, $folder_index_url, $conf_move_messages_after_download);
    dispText("\$move_folder_id->".$move_folder_id."\n");
  }

	# Ok let's get the folder list!
	dispText("Loading folder list...\n");
	my @folder_list = getPage("http://$host/cgi-bin/folders?", "", 1, 1, 0);

	# Join the page into one big string, and split it into bits that interest us
	my $onestr = join "", @folder_list;
	$onestr =~ s/\n/ /g;
	@folder_list = grep { /<td[^>]*><a\s*href=\"\/cgi-bin\/HoTMaiL\?/ }
	                split(/(<tr[^>]*>|<\/tr>)/, $onestr);

	foreach my $item (@folder_list) {
		if ($item =~ m/.*<a href=\"\/cgi-bin\/HoTMaiL\?(.+)\" >([^<]+)<\/a>.*/i) {
			my($url) = $1;
			my($name) = $2;

			# Establish numbers of new, unread, total mail in box - courtesy
			# of Jens Preikschat <preikschat@hotmail.com>

			# Establish total size of mail box - may be useful in the future
			# $item =~ m/<td align="right"><font class="Wf">(\w+)<\/font><\/td>/;
			# my($totalSize) = $1;

			# Establish "total number of messages" and "number of unread messages"
			# in the folder

			$item =~ m/<td align=center>(\d+)<\/td>\s*<td align=center>(\d+)<\/td>/;
			my($totalItems) = $1;
			my($unreadItems) = $2;

			if ((!$conf_only_get_new_messages) || ($unreadItems > 0)) {
				# Check that this actually _is_ a folder name, without any
				# html tags. Also makes sure we are not getting the trash
				# (it looks really stupid when we download a message, delete
				# it, and then download it again from the trash and delete
				# it into the trash yet again =)

				if ( (!($name =~ /[<>]/)) && (!($name =~ /$trashcan_string/i)) ) {
					$" = "~";
					if ((!@conf_folders || ("~@conf_folders~" =~ /~$name~/i)) && 
					    (!@conf_exclude_folders || !("~@conf_exclude_folders~" =~ /~$name~/i))) {
					  dispText ("\nProcessing Folder: \"" . $name .
						          "\", Total messages: " . $totalItems .
						          ", Unread messages: " . $unreadItems . ".\n");
                                          dispSummary ("Gotmail Messages received for account $login, folder $name: $unreadItems\n");
						getFolder($name, $url);
					}
				}
			}
		}
	}
}

# Checks the systems os and then sets this for the script to use if needed
# for specific compatiblities on different platforms.
# 
# usage: if ( OS_TYPE_WIN32 == $os_type ) {
# This is currently unused.

sub doCheckOS ()
{
	# DEFAULT is set to OS_TYPE_UNIX, and is why windows is all that is
	# checked
	if ( defined($ENV{'OS'}) && $ENV{'OS'} =~ /windows/i ) {
		$os_type = OS_TYPE_WIN32;
	}
}


doCheckOS();
parseConfig();
parseArgs();
dispIntroText();
doCheckPrograms();
doCleanOtherFiles();
my($inbox_location) = doLogin();
doGetFolders($inbox_location);
dispText("\nAll done!\n\n");
doCleanTempFiles();

exit(0);

# vim:noet:sw=2:ts=2:filetype=perl
