I have this small section of code I'm trying to get working. What I want is for it to loop for as many messages are on the server and write the text of each to a window. %temptext is what is being read into by sockread. Does it go out of this loop everytime it sockreads? I tried this code and got an endless loop saying "+OK 1 messages" in the window. Thanks.
if ($gettok(%temptext,2,32) > 0) {
echo -a you have mail
set %mailtotal $gettok(%temptext,2,32)
:GETMAIL
set %N 1
:MAILLOOP
set %loop 1
window @Email
while (%N <= %mailtotal) {
sockwrite -n $sockname retr %N
while (%temptext != .) {
aline @Email %temptext
}
inc %N
}
}
}
I have while (%temptext != .) because it sends a . after the body of the message.
You can't have a loop in the sockread event. The loop has to be done with global variables and comparisons not a while loop. Try code that I made:
usage: /getmail <server> <port> <username> <password>
alias getmail {
;1=server 2=port 3=username 4=password
;--------
set %chkADDR $1
set %chkPORT $2
set %chkUSER $3
set %chkPASS $4
;--------
set %getmail.write 0
set %getmail.state 1
if ($sock(getmail)) sockclose getmail
sockopen getmail %chkADDR %chkPORT
.timer 1 5 sockclose getmail
}
on *:SOCKREAD:getmail:{
var %s
sockread %s
tokenize 32 %s
;echo -a > $1-
if (-ERR isin $1) {
echo 4 -a ERROR: $1-
echo 4 -a %getmail.state QUIT
sockwrite -n $sockname QUIT
set %getmail.state -1
}
elseif (%getmail.state < 0) {
echo 4 -a %getmail.state Done
sockclose $sockname
}
elseif ((OK isin $1) && (!%getmail.write)) {
if (%getmail.state == 1) {
echo 3 -a USER
sockwrite -n $sockname USER %chkUSER
inc %getmail.state
}
elseif (%getmail.state == 2) {
echo 3 -a PASS
sockwrite -n $sockname PASS %chkPASS
inc %getmail.state
}
elseif (%getmail.state == 3) {
echo 3 -a STAT
sockwrite -n $sockname STAT
inc %getmail.state
}
elseif (%getmail.state == 4) {
echo 12 -a $2 $iif($2 == 1,message,messages)
if ($2 > 0) {
set %getmail.count 1
set %getmail.state 5
set %getmail.num $2
.remove mailget.tmp
echo 3 -a RETR %getmail.count
sockwrite -n $sockname RETR %getmail.count
}
else {
echo 3 -a QUIT
sockwrite -n $sockname QUIT
set %getmail.state 99
}
}
elseif (%getmail.state == 5) {
echo 7 -a Receiving %getmail.count
set %getmail.write 1
}
elseif (%getmail.state == 6) {
if (%getmail.dele < %getmail.num) {
inc %getmail.dele
echo 3 -a DELE %getmail.dele
sockwrite -n $sockname DELE %getmail.dele
}
else {
echo 3 -a QUIT
sockwrite -n $sockname QUIT
set %getmail.state 99
}
}
elseif (%getmail.state == 99) {
echo 3 -a DONE
sockclose $sockname
unset %getmail.*
}
}
elseif (%getmail.state == 5) {
if ($1- == .) {
var %getmail.ticks = $ticks
.rename mailget.tmp $+(%getmail.ticks,.txt)
echo 7 -a Received %getmail.count
echo 7 -a Saved as $+(%getmail.ticks,.txt)
set %getmail.write 0
if (%getmail.count < %getmail.num) {
inc %getmail.count
echo 3 -a RETR %getmail.count
sockwrite -n $sockname RETR %getmail.count
}
else {
set %getmail.dele 1
echo 3 -a DELE 1
sockwrite -n $sockname DELE 1
set %getmail.state 6
}
}
else {
write mailget.tmp $iif($1,$1-,$crlf)
}
}
}
The sockread event will check for existing messages then retrieve all of them and then delete all of them.
-genius_at_work
Also, if you just want to check how many messages there are, you can use this code instead:
usage: /checkmail <server> <port> <username> <password>
alias checkmail {
;1=server 2=port 3=username 4=password
;----------
set %chkmail.ADDR $1
set %chkmail.PORT $2
set %chkmail.USER $3
set %chkmail.PASS $4
;----------
set %chkmail.state 1
if ($sock(checkmail)) sockclose checkmail
sockopen checkmail %chkmail.ADDR %chkmail.PORT
}
on *:SOCKREAD:checkmail:{
var %s
sockread %s
tokenize 32 %s
; echo -s > $1-
if (OK isin $1) {
if (%chkmail.state == 1) {
echo 3 -a USER
sockwrite -n $sockname USER %chkmail.USER
}
elseif (%chkmail.state == 2) {
echo 3 -a PASS
sockwrite -n $sockname PASS %chkmail.PASS
}
elseif (%chkmail.state == 3) {
echo 3 -a STAT
sockwrite -n $sockname STAT
}
elseif (%chkmail.state == 4) {
[color:red];;; Number of messages is stored in $2 at this point only[/color]
echo 12 -a $2 $iif($2 == 1,message,messages)
echo 3 -a QUIT
sockwrite -n $sockname QUIT
}
elseif (%chkmail.state == 5) {
echo 3 -a DONE
sockclose $sockname
unset %chkmail.*
}
elseif (%chkmail.state < 1) {
echo 4 -a DONE
sockclose $sockname
unset %chkmail.*
}
else {
echo 4 -a Incompatible response at state %chkmail.state
echo 4 -a Error: $1-
sockwrite -n $sockname QUIT
set %chkmail.state -1
}
inc %chkmail.state
}
else {
echo 4 -a Unknown response at state %chkmail.state
echo 4 -a Error: $1-
sockwrite -n $sockname QUIT
set %chkmail.state -1
}
}
-genius_at_work
I'd like to try to use my own script as much as possible, since I made a dialog for it. This script was working fine to get one message until I started trying to add the part to make it retrieve more than one message if there were more. I'll show you the whole sockread event.
on 1:sockread:mail:{
sockread %temptext
if (!$window(mail)) { window @mail }
if (%temptext == +OK POP3 server ready.) { sockwrite -n $sockname user MyUserName }
if (%temptext == +OK please send PASS command) { sockwrite -n $sockname pass MyPassword }
if (%temptext == +OK MyName is welcome here) { sockwrite -n $sockname list }
if (*messages* iswm %temptext) {
sockwrite -n $sockname retr $gettok(%temptext,2,32)
sockmark mail mail
set %mailtotal $gettok(%temptext,2,32)
set %N 1
}
if ($sockerr) {
echo -a Error.
halt
}
if (%temptext) {
if ($sock(mail).mark == mail) {
while (%N <= %mailtotal) {
if (*From:* iswm %temptext) { aline @mail %temptext }
if (*Date:* iswm %temptext) { aline @mail %temptext }
if (*Subject:* iswm %temptext) { aline @mail %temptext }
if (*Message-Id:* iswm %temptext) { sockmark mail body }
}
if ($sock(mail).mark == body) {
if (*Message-Id* iswm %temptext) { echo }
elseif (%temptext == .) { echo }
else { aline @mail %temptext }
}
if (%temptext == .) && ($sock(mail).mark == body) {
sockmark mail done
inc %N
}
}
}
unset %N
unset %mailtotal
}
The code I provided can easily be modified to do what you want. You are welcome to try to get your code to work if you'd prefer, but I'm not going to waste my time debugging your code, especially since it doesn't even come close to conforming to the POP3 protocol, not to mention that it would have to be completely rewritten to get it to work anyway.
To use my code (the first code) to retrieve and load an email into a dialog, simply run the code as described above, and after this line:
.rename mailget.tmp $+(%getmail.ticks,.txt)
add this line
.timer -mo 1 10 parsemail $+(%getmail.ticks,.txt)
And then make an alias called /parsemail that reads through the given text file ($1) and loads it into the dialog however you want. You can use your existing code (with minor modifications) to recognize From:, Date:, Subject:, etc and load them into certain dialog items, and then load the body into another item.
Anyway, it's up to you.
-genius_at_work
Actually it conforms exactly to the POP3 protocol and I have it working.
Really. Try using the code you provided above on another POP3 server that uses a different daemon.
-genius_at_work