/* CheckMail.amirx 4.0 */

if ~show("L","rexxsupport.library") then
	if ~addLib("rexxsupport.library",0,-30) then
		call serr("can't find rexxsupport.library")
if ~show("L","rxsocket.library") then
	if ~addLib("rxsocket.library",0,-30) then
		call serr("can't find rxsocket.library")
if ~show("L","rmh.library") then
	if ~addLib("rmh.library",0,-30) then
		call serr("can't find rmh.library")

/*******YOU HAVE TO SET THESE!!!*******/
host  = "YOUR POP HOST NAME"
port  = 110 /* OR YOUR POP HOST PORT*/
login = "YOUR LOGIN"
pass  = "YOU PASSWORD"

/*******YOU MAY SET THESE*******/
timeout            = 120
global.normalColor = 3
global.mailColor   = 4

global.color=global.normalColor

signal on break_c
global.amirc=left(address(),6)=="AMIRC."
global.prg=ProgramName("NOEXT")

global.portName=upper(global.prg)
if show("P",global.portName) then do
	msg="address" global.portName "QUIT"
	p=global.prg
	global.prg="B"p
    call info "signalled" p "to exit."
	interpret msg
	exit
end

template="HOST/K,LOGIN/K,PASSWORD=PASS/K,PORT/K/N,TIMEOUT=TOUT/K/N,COLOR/K/N,MAILCOLOR/K/N,HELP/S"
parse arg args
if args=="?" & global.amirc then call err template

if ~ReadArgs(template) then call err Fault()

if parm.0.flag then host=parm.0.value
if parm.1.flag then login=parm.1.value
if parm.2.flag then pass=parm.2.value
if parm.3.flag then port=parm.3.value
if parm.4.flag then timeout=parm.4.value
if parm.5.flag then global.normalColor=parm.5.value
if parm.6.flag then global.mailColor=parm.6.value
global.color=global.normalColor
if parm.7.flag then call help

if port=-1 then
    if ~GetServByName("S","pop3","tcp") then port=se.ServPort
    else sin.AddrPort=110
if port<1 | port>65535 then call err "must be 1<=PORT<=65535"
if timeout<0 then call err "TIMEOUT must be non negative"

if ~OpenPort(global.portName) then call err "can't open my port"
global.ps=PortSignal(global.portName)

if timeout~=0 then do
	global.time=CreateTimer()
	global.ts=TimerSignal(global.time)
	call StartTimer(global.time,timeout)
end
else global.ts=0

global.ctrlc=2**12
global.sigbreak=or(global.ctrlc,global.ts,global.ps)
call SetSocketSignals(global.sigbreak)

call info "resolving host address..."
remote.AddrAddr=resolve(host)
if remote.AddrAddr==-1 then
	if emptyPort() | CheckSignal(global.ctrlc) then call break_c
	else if CheckSignal(global.ts) then call err "timeout"
	     else call err "host <"host"> not found"

global.sock=socket("INET","STREAM")
if global.sock<0 then call err "can't create socket"

global.sigio=2**AllocSignal()
call SetSocketSignals(global.sigbreak,global.sigio)

call IOCtlSocket(global.sock,"FIONBIO",1)
call IoctlSocket(global.sock,"FIOASYNC",1)
call SetSockOpt(global.sock,"SOCKET","EVENTMASK","CONNECT READ WRITE ERROR")
global.mask=or(global.sigbreak,global.sigio)

remote.AddrPort=port
call info "connecting..."
res=connect(global.sock,"REMOTE")
call waitev("CONNECT")

call info "loggin in..."
call waitev("READ")
call rec

call sen("USER" login)

call waitev("READ")
call rec

call sen("PASS" pass)

call waitev("READ")
call rec

call info "getting statistics..."
call sen("STAT")

call waitev("READ")
stat=rec()

num=word(stat,2)
if num>0 then do
	global.color=global.mailColor
	msg="you have" num "new mail(s) for total" word(stat,3) "bytes."
end
else msg="you have no new mail."
call info msg

call sen("QUIT")
exit

rec: procedure expose global.
	len=RecvFromUntil(global.sock,"B",256,"D0A"x)
	if len<1 then call err "error reading",1
    if word(b,1)=="-ERR" then call err "Server Error:" '['right(b,length(b)-wordindex(b,2)+1)']'
	return b

sen: procedure expose global.
parse arg string
    string=string"D0A"x
    res=send(global.sock,string)
    if res~=length(string) then call err "error sending",1
    return

waitev: procedure expose global. events.
parse arg ev
	do forever
		sigrec=Wait(global.mask)
		if emptyPort() | and(sigrec,global.ctrlc)~=0 then call break_c
		else if and(sigrec,global.ts)~=0 then call err "timeout"
		s=GetSocketEvents("EVENTS")
		if s>=0 then do
			if events.error then call err "error",1
			if events.ev then return
		end
	end
	return

info: procedure expose global.
parse arg msg
	if msg=="" then msg="F"x
    if global.amirc then "ECHO P="d2c(27)"b«"global.prg"» C="global.color msg
    else say msg
    return

err: procedure expose global.
parse arg msg,err
	if ~global.amirc then msg=global.prg":" msg
	if err==1 then
		if IsLibOn("TTCP") then more=" (error "errno()")."
		else more=" ("ErrorString(errno())")."
	else more="."
    call info msg || more
    exit

break_c: procedure expose global.
    call err "user break detected"

emptyPort: procedure expose global.
	res=0
	pkt=GetPkt(global.portName)
	do while pkt~=null()
        call reply(pkt)
		res=1
		pkt=GetPkt(global.portName)
	end
	return res~=0

help: procedure expose global.
	call info "CheckMail 3.15 (7-Jun-1998) by alfie"
	call info ""
	call info "HOST/K                    the pop3 host addr to connect"
	call info "LOGIN/K                   the user name"
	call info "PASSWORD=PASS/K           the password"
	call info "PORT/K/N,TIMEOUT=TOUT/K/N global timeout - 0 means none"
	call info "COLOR/K/N                 normal text Amirc color number"
	global.color=global.mailColor
	call info "MAILCOLOR/K/N             new-mail text Amirc color number"
	global.color=global.normalColor
	call info "HELP/S                    show this."
	call info ""
	exit
