The current GetLive release does not work with Hotmail any more. The code in the GetLive CVS repository has been updated, but a new version has not been released.
Below is a diff that incorporates the changes in the patches/patch-GetLive.pl file and adds instructions to the MESSAGE file to be able to get GetLive working again. Tested on i386. ok? -ME Index: Makefile =================================================================== RCS file: /cvs/ports/mail/p5-GetLive/Makefile,v retrieving revision 1.4 diff -u -p -r1.4 Makefile --- Makefile 10 Jul 2008 14:37:31 -0000 1.4 +++ Makefile 10 Nov 2008 19:42:59 -0000 @@ -3,7 +3,7 @@ COMMENT= automatically fetch hotmail.com email DISTNAME= GetLive_0_57 -PKGNAME= p5-GetLive-0.57 +PKGNAME= p5-GetLive-0.57p0 CATEGORIES= mail perl5 EXTRACT_SUFX= .tgz Index: patches/patch-GetLive_pl =================================================================== RCS file: /cvs/ports/mail/p5-GetLive/patches/patch-GetLive_pl,v retrieving revision 1.2 diff -u -p -r1.2 patch-GetLive_pl --- patches/patch-GetLive_pl 10 Jul 2008 14:37:31 -0000 1.2 +++ patches/patch-GetLive_pl 10 Nov 2008 19:42:23 -0000 @@ -1,7 +1,7 @@ $OpenBSD: patch-GetLive_pl,v 1.2 2008/07/10 14:37:31 merdely Exp $ ---- GetLive.pl.orig Sat Sep 8 14:23:33 2007 -+++ GetLive.pl Wed Oct 10 07:59:06 2007 -@@ -53,7 +53,7 @@ my $Password = ""; +--- GetLive.pl.orig Mon Nov 10 14:39:12 2008 ++++ GetLive.pl Mon Nov 10 14:41:25 2008 +@@ -65,11 +65,12 @@ my $Password = ""; my $Domain = 'hotmail.com'; my $CurlCommand = 'curl -k'; my $Verbosity = 1; # 0:Silent; 1:Normal; 2:Verbose; 10:debug; 100:heavy debug @@ -10,3 +10,274 @@ $OpenBSD: patch-GetLive_pl,v 1.2 2008/07 my $DownloadedIdsFile = ""; # Local file with Ids of already downloaded messages. my $RetryLimit = 2; my $MarkRead = "No"; # No,Yes : But never when downloaded before ! + my $Delete = "No"; # No,Yes : But never when downloaded before ! ++my $SkipTrash = "No"; # No,Yes : Do not handle the Trash folder + my $FetchOnlyUnread = "No"; # If Yes, only messages marked unread are downloaded. + # Unlike gotmail, this is completely orthogonal to the + # DownloadedIdsFile, i.e. it is the one or the other. +@@ -78,6 +79,8 @@ my $MoveToFolder = ""; # + # contains the folder to move to. This is a hook for + # autoclassifying the mail on the server, including spam filtering. + ++my $Mode = "200809"; ++ + # Quirk. MS generates unended <pre> tags. Hope this is a temporary weakness in their mind. + # (Hope makes living, we say in Dutch ...) + # If we want to allow it set this to one. Currently as of 8/9/2007 it must be accepted or the +@@ -275,7 +278,7 @@ sub ParseConfig { + } elsif ($Option =~ m/^Password$/i) { + $Password = $OptionValue; + } elsif ($Option =~ m/^Mode$/i) { +- warn "\n'Mode = ...' in the config file is ignored.\nThis version works only for 'Live' mailboxes !\n"; ++ $Mode = $OptionValue; + } elsif ($Option =~ m/^Domain$/i) { + $Domain = $OptionValue; + } elsif ($Option =~ m/^Proxy$/i) { +@@ -298,6 +301,8 @@ sub ParseConfig { + $MarkRead = $OptionValue; + } elsif ($Option =~ m/^Delete$/i) { + $Delete = $OptionValue; ++ } elsif ($Option =~ m/^SkipTrash$/i) { ++ $SkipTrash = $OptionValue; + } elsif ($Option =~ m/^MoveToFolder$/i) { + $MoveToFolder = $OptionValue; + } else { +@@ -332,6 +337,10 @@ sub ParseConfig { + Display("MarkRead should take No or Yes as argument in the configuration file.\n",stderr=>1); + DisplayUsageAndExit(); + } ++ if ($SkipTrash !~ m/^(No|Yes)$/i) { ++ Display("SkipTrash should take No or Yes as argument in the configuration file.\n",stderr=>1); ++ DisplayUsageAndExit(); ++ } + if ($Delete !~ m/^(No|Yes)$/i) { + Display("Delete should take No or Yes as argument in the configuration file.\n",stderr=>1); + DisplayUsageAndExit(); +@@ -340,6 +349,10 @@ sub ParseConfig { + Display("Delete must be 'No' when MoveToFolder is also specified in the configuration file.\n",stderr=>1); + DisplayUsageAndExit(); + } ++ if ($Mode !~ m/^(200809|200810)$/i) { ++ Display("Mode must be oneof 200809 or 200810 as argument in the configuration file.\n",stderr=>1); ++ DisplayUsageAndExit(); ++ } + } + + ######################################################################################################################## +@@ -535,7 +548,7 @@ sub Login() { + + Display("Getting hotmail index loginpage.\n", MinVerbosity =>2); + +- my ($LoginPageAsString,$GetPageUrl) = GetPage(Url => "http://mail.live.com",FollowForward => 1); ++ my ($LoginPageAsString,$GetPageUrl) = GetPage(Url => "http://mail.live.com/",FollowForward => 1); + + # We expect here a number of functions now (aug 2007) to be hidden in a javascript + # that is loaded separately. Let's load and append. +@@ -960,7 +973,7 @@ sub GetMessagesFromFolder($) { + "au=$AuthUser&". + "ptid=0"; + my $PostData = ""; +- if ($Page == 1) { ++ if ($Mode =~ m/200809/ && $Page == 1) { + $PostData = "cn=Microsoft.Msn.Hotmail.Ui.Fpp.MailBox". + "&". + "mn=GetInboxData". +@@ -971,7 +984,7 @@ sub GetMessagesFromFolder($) { + "v=1". + "&". + "mt=$MT"; +- } else { ++ } elsif ($Mode =~ m/200809/) { + $PostData = "cn=Microsoft.Msn.Hotmail.Ui.Fpp.MailBox". + "&". + "mn=GetInboxData". +@@ -979,11 +992,37 @@ sub GetMessagesFromFolder($) { + "d=true,true,{".uri_escape("\"$FolderId\"").",25,NextPage,0,Date,false,". + uri_escape("\"$pnAm\"") . "," . + uri_escape("\"$pnAd\"") . "," . +- "$Page,2,false,null,false,$ReportedNrMessages},false,null". ++ "$Page,2,false,null,false,$ReportedNrMessages},false,null". + "&". + "v=1". + "&". + "mt=$MT"; ++ } elsif ($Mode =~ m/200810/ && $Page == 1) { ++ $PostData = "cn=Microsoft.Msn.Hotmail.Ui.Fpp.MailBox". ++ "&". ++ "mn=GetInboxData". ++ "&". ++ "d=true,true,{".uri_escape("\"$FolderId\"").",0,0,Date,false,". ++ uri_escape("\"$pnAm\"") . "," . ++ uri_escape("\"$pnAd\"") . "," . ++ "$Page,2,false,%22%22,0,-1,Off},false,null". ++ "&". ++ "v=1". ++ "&". ++ "mt=$MT"; ++ } elsif ($Mode =~ m/200810/) { ++ $PostData = "cn=Microsoft.Msn.Hotmail.Ui.Fpp.MailBox". ++ "&". ++ "mn=GetInboxData". ++ "&". ++ "d=true,true,{".uri_escape("\"$FolderId\"").",NextPage,0,Date,false,". ++ uri_escape("\"$pnAm\"") . "," . ++ uri_escape("\"$pnAd\"") . "," . ++ "$Page,2,false,%22%22,$ReportedNrMessages,-1,Off},false,null". ++ "&". ++ "v=1". ++ "&". ++ "mt=$MT"; + } + + ($PageAsString,$GetPageUrl) = GetPage(Url => $Url,CurlDataArg => $PostData); +@@ -1003,8 +1042,9 @@ sub GetMessagesFromFolder($) { + + # get the ID for the trash folder + $TrashFolderId = $PageAsString; +- $TrashFolderId =~ m/sysFldrs\s*?:\s*?{\s*?trashFid\s*?:\s*?\"(.*?)\".*?}/si; ++ $TrashFolderId =~ m/sysFldrs\s*?:\s*?{.*?trashFid\s*?:\s*?\"(.*?)\".*?}/si; + $TrashFolderId = $1; ++ die "Could not find TrashFolderId." unless $TrashFolderId; + + # get the session variables as well as the request handler + $PageAsString =~ m/fppCfg\s*?:\s*?{\s*?RequestHandler\s*?:\s*?\"(.*?)\".*?SessionId\s*?:\s*?\"(.*?)\".*?AuthUser\s*?:\s*?\"(.*?)\".*?}/si; +@@ -1016,9 +1056,12 @@ sub GetMessagesFromFolder($) { + + # To start with we limit us to a MessagesArea between + # <table class="dItemListContentTable"..> ... </table..> +- if ($PageAsString !~ m/<table class=\"d?ItemListContentTable[^>]*>(.*?)<\/table/si) { ++ if ($Mode =~ m/200809/ && $PageAsString !~ m/<table class=\"d?ItemListContentTable[^>]*>(.*?)<\/table/si) { + die "Could not correctly parse the messages table."; + } ++ if ($Mode =~ m/200810/ && $PageAsString !~ m/<table class=\"d?InboxTable[^>]*>(.*?)<\/table/si) { ++ die "Could not correctly parse the messages table."; ++ } + my $MessagesArea = $1; + + # In this message area there's the body of the table containing messages. +@@ -1046,24 +1089,40 @@ sub GetMessagesFromFolder($) { + my $MessageId = $1; + my $MessageAd = $2; + +- # Goto 5th column.(to get the from) ++ # Goto column containing from info.(to get the from) + my $TdLine = ""; +- for (my $Idx=0;$Idx<4;$Idx++) { ++ my $Column = 5; ++ if ($Mode =~ m/200810/) { $Column = 4; } ++ for (my $Idx=0;$Idx<($Column-1);$Idx++) { + $MessagesArea =~ m/<td(.*?)>(.*?)<\/td\s*>/i; + $MessagesArea = $'; + $TdLine = $2; + } +- if ($TdLine !~ m/class=\"(truncate)?from\">(<[^>]+>)?(.*?)<[^>]+>/si) { +- die "Parse error for 'from'."; ++ my $From = ""; ++ if ($Mode =~ /200809/) { ++ if ($TdLine !~ m/class=\"(truncate)?from\">(<[^>]+>)?(.*?)<[^>]+>/si) { ++ die "Parse error for 'from'."; ++ } ++ $From = HtmlUnescape($3); ++ } elsif ($Mode =~ /200810/ ) { ++ if ($TdLine !~ m/(<[^>]+>)?(.*?)<[^>]+>/si) { ++ die "Parse error for 'from'."; ++ } ++ $From = HtmlUnescape($2); + } +- my $From = HtmlUnescape($3); + Display("From '$From'.\n",MinVerbosity => 10); + $MessagesFrom[$NrMessagesDetected] = $From; + + # Further to the subject column. There we pick up also the href of the message. +- $MessagesArea =~ m/<td(.*?)>(.*?)<\/td\s*>/i; +- $MessagesArea = $'; +- $TdLine = $2; ++ if ($Mode =~ /200809/) { ++ $MessagesArea =~ m/<td(.*?)>(.*?)<\/td\s*>/i; ++ $MessagesArea = $'; ++ $TdLine = $2; ++ } elsif ($Mode =~ /200810/) { ++ $MessagesArea =~ m/<td class=\"SubjectCol\">(.*?)<\/td\s*>/i; ++ $MessagesArea = $'; ++ $TdLine = $1; ++ } + if ($TdLine !~ m/<a href=\"(.*?)\"\s*>(.*?)<\/a>/si) { + die "Parse error for 'subject'."; + } +@@ -1091,11 +1150,19 @@ sub GetMessagesFromFolder($) { + Display("Search for one more page.\n",MinVerbosity => 10); + # Search for 'next page' href + my $NextPageAd = ""; +- if ($PageAsString =~ +- m/<li([^>]*)>\s*<a href=\"([^\"]+)\"[^>]*><img src=\"[^\"]*\" class=\"i_nextpage\".*?><\/a>/si) { +- $NextPageAd = $1; ++ if ($Mode =~ m/200809/) { ++ if ($PageAsString =~ ++ m/<li([^>]*)>\s*<a href=\"([^\"]+)\"[^>]*><img src=\"[^\"]*\" class=\"i_nextpage\".*?><\/a>/si) { ++ $NextPageAd = $1; ++ } ++ die "Could not find an expected next page href. Probably page structure changed." unless $NextPageAd; ++ } elsif ($Mode =~ m/200810/) { ++ if ($PageAsString =~ ++ m/<li([^>]*)>\s*<a href=\"([^\"]+)\"[^>]*><img class=\"PageNavigationNext\".*?><\/a>/si) { ++ $NextPageAd = $1; ++ } ++ die "Could not find an expected next page href. Probably page structure changed." unless $NextPageAd; + } +- die "Could not find an expected next page href. Probably page structure changed." unless $NextPageAd; + + if ($NextPageAd !~ m /pnAm=\"([^\"]*)/) { + die "Could not find pnAm in '$NextPageAd'."; +@@ -1111,7 +1178,7 @@ sub GetMessagesFromFolder($) { + Display("Next page Ad : '$pnAd'.\n",MinVerbosity => 10); + Display("Next page Am : '$pnAm'.\n",MinVerbosity => 10); + } +- } ++ } + } + + ######################################################################################################################## +@@ -1221,10 +1288,10 @@ sub GetFolders() { + # Scan the line for all folders, their href and title. + # NrFolders on the fly; + while ($FolderPageAsString =~ +- m/<td class=\"d?ManageFoldersFolderNameCol\"><a\s*href=\"([^\"]*)\"\s*>(.*?)<\/a>\s*<\/td>\s*<td class=\"d?ManageFoldersTotalCountCol[^\"]*\">(\d+)<\/td>/gc) { +- $FolderHrefs[$NrFolders] = $1; +- $FolderNames[$NrFolders] = HtmlUnescape($2); +- $FolderNrMessages[$NrFolders] = $3; ++ m/<td class=\"d?ManageFoldersFolderNameCol\"><a\s*(class=\"PrimaryTextColor\"\s*)?href=\"([^\"]*)\"\s*>(.*?)<\/a>\s*<\/td>\s*<td class=\"d?ManageFoldersTotalCountCol[^\"]*\">(\d+)<\/td>/gc) { ++ $FolderHrefs[$NrFolders] = $2; ++ $FolderNames[$NrFolders] = HtmlUnescape($3); ++ $FolderNrMessages[$NrFolders] = $4; + if ( $FolderHrefs[$NrFolders] !~ m/FolderID=([^&]*)/ ) { + die "Could not detect FolderId."; + } +@@ -1257,6 +1324,9 @@ GetFolders(); + + for (my $FolderIdx=0;$FolderIdx<$NrFolders;$FolderIdx++) { + next if (scalar keys %FoldersToProcess && not exists $FoldersToProcess{lc $FolderNames[$FolderIdx]}); ++ next if ( ($SkipTrash =~ m/^Yes$/i) && ($FolderIds[$FolderIdx] eq $TrashFolderId) ); ++ # JDLA hack. Drafts folder does not work, also not in real. Assuming 000-...-4 is the draft folder. ++ next if ( ($Mode =~ m/200810/) && ($FolderIds[$FolderIdx] =~ m/^(0|-)*4$/)); + Display("\nProcessing folder $FolderNames[$FolderIdx].\n",MinVerbosity => 1); + GetMessagesFromFolder($FolderIdx); + Display("$NrMessagesDetected/$NrMessagesUnread Messages/Unread.\n",MinVerbosity => 1); +@@ -1270,6 +1340,18 @@ exit(0); + ######################################################################################################################## + # + # $Log: GetLive.pl,v $ ++# Revision 1.46 2008/10/31 12:22:31 jdla ++# *) Bug 2208443 : Additional changes based on user feedback. ++# Mainly 'Delete' was made operational and a bug in processing ++# folders leading to no processing at all. ++# ++# Revision 1.45 2008/10/29 23:03:38 jdla ++# *) Bug 2208443 : Hotmail changes in 10/2008 solved. ++# ++# Revision 1.44 2008/08/31 20:36:08 jdla ++# *) Bug 2017097 : Messages retrieved multiple times ++# (SkipTrash option) ++# + # Revision 1.43 2008/07/05 19:55:41 jdla + # Bug 1962937 : Could not correctly parse the messages table + # (after MS started changing things again around 1/7/2008) Index: pkg/MESSAGE =================================================================== RCS file: /cvs/ports/mail/p5-GetLive/pkg/MESSAGE,v retrieving revision 1.1.1.1 diff -u -p -r1.1.1.1 MESSAGE --- pkg/MESSAGE 10 Oct 2007 15:17:49 -0000 1.1.1.1 +++ pkg/MESSAGE 10 Nov 2008 19:48:59 -0000 @@ -3,3 +3,8 @@ options. To use GetLive with SMTP as a delivery mechanism, see the scripts in ${PREFIX}/share/examples/GetLive. + +GetLive has been patched to deal with Hotmail changes. Log into Hotmail +through a browser and check the box so it never shows the changed page +again. Then, add 'mode=200810' to your config file. You may also have +to turn off 'reading panes'.