#!/bin/sh

HotmailTemp="/tmp/hotmole.tmp.$$"
STARTCHOP="RELATED: \[[0-9]*\]Dictionary"
ENDCHOP="1. http://go.msn.com/npl/msnp.asp"

#--------------------------------------------------------------------
# HOTMOLE v0.3 (08mar99) by Hugo Rabson (hugo.rabson@zetnet.co.uk)
# All comments are appreciated.
#
# Changes:-
# v0.3    - Handles multiple pages (page 1,page 2,page 3) on Hotmail
#         - Much better & safer trimming of emails.
#         - Email is definitely not deleted if 'mail' fails to forward it.
#           ...There was a little ambiguity in the code but it's fixed now.
#         - I've dropped the '-source' way to scan for emails.
#         - Nicer progress-reporting. More helpful error messages.
#         - Better usage of temp files and 'procedure'd calls to Lynx.
# v0.24   - Saves user's Hotmail list-of-emails as /tmp/hotmole-front-page
#           for test porpoises. Error "The requested URL /cgi/bin/redirect\
#           /cofast.cgi was not found on this server" reported. I need to
#           see hotmole-front-page if users experience errors. Thanks :)
#         - Also, new '-del' switch which will delete new incoming emails from
#           hotmail (after d/l'ing, of course).
#         - Removed 'clear' command cos it gets in the way of debugging
#         - Grabs subject from email & uses it when forwarding to local spooll
# v0.23   - Clears screen before doing anything else
# v0.22   - Improved -dump scanning for "[nn] http" lines containing
#           links to unread emails
#         - Nicer 'sending XXX to USER' message
# v0.21   - Drops "[nn][ISMAP" lines from email... It shan't drop
#           anything more vague in case it drops important stuff.
# v0.2    - Works for both -dump and -source output; it's easy
#	    to try each, by setting ListType in source code,
#         - Two user ids tried with 70+ & zero email situations;
#           in each situation, the code performs perfectly.
#--------------------------------------------------------------------


# -------------------------- PROCEDURES ----------------------------





Usage() {
    echo "
hotmole <id> <password> (-del)

Hotmole forwards emails from a user's Hotmail account to their local mail
spool. If the -del switch is used, hotmole will delete the emails from
the user's Hotmail account after forwarding them. NB: It does _not_ delete
read emails, only unread emails after forwarding.

It automatically moves from one Hotmail page to the next, forwarding all
unread email. It tries to be 'safe', and frequently checks that the
Hotmail page is formatted the way it is expected to be. (The page format
might change someday and if it does, hotmole will need to be tweaked.)

Hotmole can also check your Hotmail POP3 mailboxes if they are configured.
This is especially useful for MSN users.

    "
}



GetHotmailCgiBin() {
    HTmp=$1
    lynx -source http://www.hotmail.com > $HTmp
    res=`cat $HTmp | grep "form name=\"passwordform\" action=\"http://[0-9]*.[0-9]*.[0-9]*.[0-9]*/cgi-bin/start\" method=\"POST\"" | head -n 1 | gawk '{ split($0,output,"\""); print output[4];}'`
    if [ "$res" = "" ] ; then
	return 1
    fi
    echo $res
}


PostToCgibin() {
    HotmailAddress=$1
    CommandStr=$2
    HTmp=$3
    rm -f $3
    echo "$CommandStr" | lynx -dump -post_data $HotmailAddress > $HTmp
    return $?
}




# applies to first layout only; the tail is 'just in case'
GetEmailLocation() {
#    LinkNumber=$1 <--------- I've used $1 in code below
#    FileToScan=$2 <--------- I've used $2 in code below
    res=`cat $2 | grep "$1[.] http" | tail -n 1 | \
gawk '{ split($0,output,"?"); split(output[1],opB," "); print opB[2];}'`
    echo $res
}




# applies to first layout only; the tail is 'just in case'
GetEmailLocParams() {
# $1 -- LinkNo      $2 -- FileToScan
    res=`cat $2 | grep "$1[.] " | tail -n 1 | \
gawk '{ split($0,output,"?"); print output[2];}'`
    echo $res
}



DelEmail() {
    str=`cat $1 | \
grep "\[[0-9]*\]Reply/ReplyAll/Forward[ ]*\[[0-9]*\]Delete" | head -n 1`
    if [ "$str" = "" ] ; then
	echo "Cannot find delete button - has Hotmail's email page structure changed?"
	return 1
    fi
    delbut=`echo $str | gawk '{ split($0,output,"]"); print output[5];}'`
    delnum=`echo $str | gawk '{ split($0,output,"]"); split(output[4],opB,"["); print opB[2];}'`
    if [ "$delbut" != "Delete" ] || [ "$delnum" = "" ] ; then
	echo "Del button cannot be decoded correctly."
	echo "Has Hotmail's email page structure changed, perhaps?"
	echo "(rawline=$str)"
	return 2
    fi
    butlocation=`GetEmailLocation $delnum $1`
    butparams=`GetEmailLocParams $delnum $1`
    if [ "$butlocation" != "" ] && [ "$butparams" != "" ] ; then
	echo "$butparams" | lynx -dump -post_data "$butlocation" >> /dev/null
	if [ "$?" -ne "0" ] ; then
	    echo "error deleting email from Hotmail"
	    echo "(butlocation=$butlocation)"
	    echo "(butparams=$butparams)"
	else
	    echo "That email was successfully deleted from Hotmail"
	fi
    else
	echo "Has Hotmail's email page structure changed, perhaps?"
	return 3
    fi
}



RemoveEmailChaff() {
    start=`cat $1 | grep -n "$STARTCHOP" | head -n 1 | gawk '{split($0,incoming,":"); print incoming[1];}'`
    total=`cat $1 | grep -n "" | tail -n 1 |gawk '{ split($0,incoming,":"); print incoming[1];}'`
    if [ "$start" = "" ] || [ "$total" = "" ] || \
[ "$start" = "0" ] || [ "$total" = "0" ] ; then
	echo "badly-structured email - perhaps Hotmail's format has changed?"
	echo "Forwarding whole email; no 'nice' trimming."
	cp $1 $2 -f
    else
	start=$(($start+3))
	remainder=$(($total-$start))
	cat $1 | tail -n $remainder > $2.pre
	stop=`cat $2.pre | grep -n "$ENDCHOP" | tail -n 1 | \
gawk '{ split($0,incoming,":"); print incoming[1];}'`
	if [ "$stop" != "" ] && [ "$stop" -ge "50" ] ; then
	    stop=$((stop-2))
	    cat $2.pre | head -n $stop > $2.post
	else
	    cp -f $2.pre $2.post
	fi
	cp -f $2.post $2
    fi
    rm -f $2.pre
    rm -f $2.post
}




ForwardEmail() {
    PageAddr=$1
    PageParams=$2
    OutputFile=$3
    PostToCgibin $PageAddr $PageParams $OutputFile
    res=$?
    if [ "$res" -ne "0" ] ; then
        echo "Lynx failed to grab email; therefore, it cannot be forwarded." >> /dev/stderr
    else
	subj="FW: `cat $OutputFile | grep "Subject:" | head -n 1 | \
gawk '{ print substr($0,10,length($0)-9); }'`"
        echo "Forwarding '$subj' to $USER"
	RemoveEmailChaff $OutputFile $OutputFile.after
	cat $OutputFile >> res1
	cat $OutputFile.after >> res2
	if [ ! -f "$OutputFile.after" ] ; then
	    echo "Unable to remove chaff from email"
	    echo "Sending the whole darn thing instead"
	    cp -f $OutputFile $OutputFile.after
	fi
        cat $OutputFile.after | mail $USER -s "$subj"
#	cat $OutputFile       | mail $USER -s "PRE  $subj"
        res=$?
	if [ "$res" -eq "0" ] ; then
	    if [ "$DelNew" = "YES" ] ; then
		DelEmail $OutputFile.after
	        # doesn't erase file $3; uses it to do cgi-bin stuff
	    fi
	else
	    echo "mail returned $res; possible failure to forward email"
	    if [ "$DelNew" = "YES" ] ; then
	        echo "...therefore, _not_ erased from Hotmail, just in case."
	    fi
	fi
    fi
    rm -f $OutputFile
    rm -f $OutputFile.After
}




GetPointerToNextPage() {
    HTmp=$1
    npnum=`cat $HTmp | grep "Prev Page \| \[[0-9]*\]Next Page" | tail -n 1 | gawk '{ split($0,output,"|"); split(output[2],opB,"["); split(opB[2],opC,"]"); print opC[1];}'`
    if [ "$npnum" = "" ] ; then
	echo "-99"
	return 1
    else
        butlocation=`GetEmailLocation $npnum $HTmp`
        butparams=`GetEmailLocParams $npnum $HTmp`
        if [ "$butlocation" = "" ] || [ "$butparams" = "" ] ; then
	    echo "-99"
	    return 3
	else
	    echo "$npnum"
	    return 0
	fi
    fi
}




# look for emails, assuming standard list format
ExamineHotmailPages() {
    HTmpMsg=$1
    HTmpPage="$1".page
    totalforwarded="0"
    currpage="0"
    cp -f $1 $HTmpPage;      # so, $HTmp remains truly temporary
    npnum="-1"
    totalnew=`cat $HTmpPage | grep "[0-9]* message[s], [0-9]* new" | \
head -n 1 | gawk '{ print $3; }'`
    if [ "$totalnew" = "" ] ; then
	echo "Cannot ascertain how many new emails there are."
	echo "This probably indicates failure to login."
	return
    elif [ "$totalnew" = "0" ] ; then
	echo "no new emails... sorry"
	return
    fi
    echo "$totalnew new emails to be forwarded."
    while [ "$npnum" != "STOP" ] ; do
	currpage=$(($currpage+1))
	echo "Examining page $currpage."
	for msgno in `cat $HTmpPage |grep "New \[\_\][ ]*\[[0-9]*\]" | \
gawk '{ len=length($3); end=index($3,"\]");print substr($3,2,end-2);}'` ; do
	    msglocation=`GetEmailLocation $msgno $HTmpPage`
	    msgparams=`GetEmailLocParams  $msgno $HTmpPage`
	    if [ "$msglocation" = "" ] || [ "$msgparams" = "" ] ; then
		echo "cannot call ForwardEmail - bad params for msg $msgno"
		echo "msglocation=$msglocation"
		echo "msgparams = $msgparams"
	    else
		ForwardEmail $msglocation $msgparams $HTmpMsg
		totalforwarded=$(($totalforwarded+1))
	    fi
	done
	echo "$totalforwarded / $totalnew forwarded so far."
	npnum=`GetPointerToNextPage $HTmpPage`
	res=$?
	if [ "$res" -eq "0" ] ; then
	    echo -n "Moving to page $(($currpage+1))..."
	    butlocation=`GetEmailLocation $npnum $HTmpPage`
	    butparams=`GetEmailLocParams $npnum $HTmpPage`
	    PostToCgibin $butlocation $butparams $HTmpPage ; # next page! :)
	    if [ "$?" -ne "0" ] ; then
		npnum="STOP"
		echo "Fatal Lynx error. Hotmole cannot 'turn the page'."
	    else
		echo "ok."
	    fi
	else
	    npnum="STOP"
	    if [ "$res" -eq "1" ] ; then
		echo "Page $currpage is the last page."
	    elif [ "$res" -gt "1" ] ; then
		echo "(err=$res) Has Hotmail's 'Next Page' line structure changed?"
	    fi
	fi
    done
    echo "$totalforwarded / $totalnew have been forwarded."
}





#------------------------------ MAIN -------------------------------




if [ "$#" -ne "2" ] && [ "$#" -ne "3" ] ; then
    Usage
    exit 1
fi

ID=$1
PW=$2

DelNew=NO
if [ "$#" -eq "3" ] ; then
    if [ "$3" = "-del" ] ;  then
	DelNew=YES
    else
	DelNew=NO
    fi
fi



# GET WEBPAGE ADDRESS
echo -n "Getting hotmail cgi-bin address..."
HotmailAddress=`GetHotmailCgiBin $HotmailTemp`
if [ "$?" -ne "0" ] ; then
    echo "fatal error"
    exit 1
fi
echo "ok."
echo "Hotmail's cgi-bin site is $HotmailAddress"

# LOGIN
echo -n "Logging in..."
PostToCgibin $HotmailAddress "login=$ID&passwd=$PW&frames=no" $HotmailTemp
if [ "$?" -ne "0" ] ; then
    echo "fatal error"
    exit 1
fi
echo "ok. First page has been read in."
cp $HotmailTemp /tmp/hotmole-front-page

# LIST EMAILS !
echo "Searching for emails using standard layout."
ExamineHotmailPages $HotmailTemp
echo "Exiting."

rm -f $HotmailTemp
rm -f $HotmailTemp.*
# exit 0

# ---------------------- end of file -----------------------
