📄 pop3_client.c
字号:
else
end_detect = 0;
continue;
}
if( end_detect == 4 )
{
if(ch == '\n')
{
pop3c_changestate(POP3C_MESSAGE_RECEIVED);
return(1);
}
else
end_detect = 0;
continue;
}
}
break;
case POP3C_DELE_SENT:
if(cmd == POP3C_OK)
{
DEBUGOUT("DELE +OK by POP3 server\r\n");
pop3c_changestate(POP3C_DELE_ACKED);
return(1);
}
break;
case POP3C_QUIT_SENT:
if(cmd == POP3C_OK)
{
DEBUGOUT("QUIT +OK by POP3 server\r\n");
pop3c_changestate(POP3C_QUIT_ACKED);
return(1);
}
break;
default:
break;
}
return(1);
case TCP_EVENT_REGENERATE:
/* Send last packet again */
DEBUGOUT("POP3C is regenerating...\r\n");
switch (POP3Client.state)
{
case POP3C_USERNAME_SENT:
pop3c_senduser();
return(1);
case POP3C_PASSWORD_SENT:
pop3c_sendpassword();
return(1);
case POP3C_STAT_SENT:
pop3c_sendstat();
return(1);
case POP3C_LIST_SENT:
pop3c_sendlist(POP3Client.curmsgindex);
return(1);
case POP3C_TOP0_SENT:
pop3c_sendtop(0);
return(1);
case POP3C_RETR_SENT:
pop3c_sendretr(POP3Client.curmsgindex);
return(1);
case POP3C_DELE_SENT:
pop3c_senddele(POP3Client.curmsgindex);
return(1);
case POP3C_QUIT_SENT:
pop3c_sendquit();
return(1);
default:
return(-1);
}
break;
default:
return(-1);
}
return(-1);
}
/********************************************************************************
Function: pop3c_run
Parameters: void
Return val: void
Date: 11.9.2002
Desc: This function should be called periodically from main loop
in order to run pop3 client 'thread'.
*********************************************************************************/
void pop3c_run (void)
{
INT16 i;
/* On that function we can send data when called by main loop */
if( pop3c_init_done == 0 )
return;
if( POP3Client.state < POP3C_OPEN_REQUESTED)
return;
/* Is there timeout of some sort? */
if(check_timer(POP3Client.tmrhandle) == 0)
{
/* Yep */
tcp_abort(POP3Client.sochandle);
pop3c_changestate(POP3C_CLOSED);
/* Make user callback */
pop3c_error();
return;
}
if( POP3Client.state == POP3C_OPEN_REQUESTED)
{
/* We are on this state because user has requested connection */
/* but connection is not yet opened. */
/* Try to get TCP stack to accept our connection request */
tcp_abort(POP3Client.sochandle); /* Release old connection */
if(tcp_connect(POP3Client.sochandle, POP3Client.remip, POP3Client.remport, 0) >= 0)
pop3c_changestate(POP3C_CONNECTIONOPEN_SENT);
return;
}
if( tcp_getstate(POP3Client.sochandle) != TCP_STATE_CONNECTED )
{
return;
}
if( tcp_checksend(POP3Client.sochandle) < 0 )
return;
/* It's connected and no unacked data so try to send */
if(POP3Client.state == POP3C_SERVER_READY)
{
/* Send USER */
pop3c_senduser();
pop3c_changestate(POP3C_USERNAME_SENT);
DEBUGOUT("POP3C USER packet sent\r\n");
return;
}
if(POP3Client.state == POP3C_USERNAME_ACKED)
{
/* Send PASS */
pop3c_sendpassword();
pop3c_changestate(POP3C_PASSWORD_SENT);
DEBUGOUT("POP3C PASS packet sent\r\n");
return;
}
if(POP3Client.state == POP3C_PASSWORD_ACKED)
{
/* Send STAT */
pop3c_sendstat();
pop3c_changestate(POP3C_STAT_SENT);
DEBUGOUT("POP3C STAT packet sent\r\n");
return;
}
if(POP3Client.state == POP3C_STAT_GET)
{
/* Still messages? */
if( POP3Client.curmsgindex < POP3Client.msgtotal )
{
POP3Client.curmsgindex++;
pop3c_sendlist(POP3Client.curmsgindex);
pop3c_changestate(POP3C_LIST_SENT);
DEBUGOUT("POP3C LIST packet sent\r\n");
return;
}
/* End of messages */
pop3c_sendquit();
pop3c_changestate(POP3C_QUIT_SENT);
DEBUGOUT("POP3C QUIT packet sent\r\n");
return;
}
if(POP3Client.state == POP3C_LIST_GET)
{
/* Now we have the whole length of current message. Receive body */
pop3c_sendtop(POP3Client.curmsgindex);
pop3c_changestate(POP3C_TOP0_SENT);
DEBUGOUT("POP3C TOP packet sent\r\n");
return;
}
if(POP3Client.state == POP3C_TOP0_GET)
{
/* Offer the e-mail to sender */
if((POP3Client.curmsgtotlen + 100) > POP3Client.curmsghlen)
{
if(POP3Client.curmsgtotlen < POP3Client.curmsghlen)
i = pop3c_msgoffer(POP3Client.curmsgindex, 0, &POP3Client.from[0], &POP3Client.subject[0]);
else
i = pop3c_msgoffer(POP3Client.curmsgindex, POP3Client.curmsgtotlen - POP3Client.curmsghlen, &POP3Client.from[0], &POP3Client.subject[0]);
if( i == (-2) )
{
/* User want's the mail to be deleted directly */
pop3c_senddele(POP3Client.curmsgindex);
pop3c_changestate(POP3C_DELE_SENT);
DEBUGOUT("POP3C deleting the e-mail\r\n");
return;
}
if( i == (-1) )
{
/* User want's the mail to be left on server without reading it */
/* So goto next one */
pop3c_changestate(POP3C_STAT_GET);
return;
}
if( i >= 0 )
{
/* User wants to read and delete the mail normally */
pop3c_sendretr(POP3Client.curmsgindex);
pop3c_changestate(POP3C_RETR_SENT);
DEBUGOUT("POP3C reading the e-mail\r\n");
return;
}
return;
}
/* The mail is somehow corrupted, just delete it */
pop3c_senddele(POP3Client.curmsgindex);
pop3c_changestate(POP3C_DELE_SENT);
DEBUGOUT("POP3C deleting CORRUPTED e-mail\r\n");
return;
}
if(POP3Client.state == POP3C_MESSAGE_RECEIVED)
{
/* Delete the readed message */
pop3c_senddele(POP3Client.curmsgindex);
pop3c_changestate(POP3C_DELE_SENT);
DEBUGOUT("POP3C deleting readed e-mail\r\n");
return;
}
if(POP3Client.state == POP3C_DELE_ACKED)
{
/* Goto next one */
pop3c_changestate(POP3C_STAT_GET);
return;
}
if(POP3Client.state == POP3C_QUIT_ACKED)
{
/* Try to close TCP */
if(tcp_close(POP3Client.sochandle) >= 0)
{
pop3c_changestate(POP3C_CLOSED);
pop3c_allok();
DEBUGOUT("POP3C connection closed OK\r\n");
return;
}
/* Close is not accepted by TCP. See if timeout */
if(check_timer(POP3Client.tmrhandle) == 0)
{
/* Use brute force */
tcp_abort(POP3Client.sochandle);
pop3c_changestate(POP3C_CLOSED);
pop3c_allok();
DEBUGOUT("POP3C connection closed by ABORT\r\n");
return;
}
/* Keep trying untill timeout */
return;
}
return;
}
void pop3c_senduser (void)
{
INT8 i;
UINT8* buf;
/* Fill TCP Tx buffer with "USER " and use callback function */
/* pop3c_getusername in order to get the username */
/* that combined "USER username" to POP3 server */
buf = &OTCP_TXBUF[TCP_APP_OFFSET];
*buf++ = 'U';
*buf++ = 'S';
*buf++ = 'E';
*buf++ = 'R';
*buf++ = ' ';
i = pop3c_getusername(buf);
if(i < 0)
return;
buf += i;
/* Insert >CRLF */
*buf++ = '\r';
*buf = '\n';
tcp_send(POP3Client.sochandle, &OTCP_TXBUF[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET, i + 7);
}
void pop3c_sendpassword (void)
{
INT8 i;
UINT8* buf;
/* Fill TCP Tx buffer with "PASS " and use callback function */
/* pop3c_getpassword in order to get the password */
/* that combined "PASS password" to POP3 server */
buf = &OTCP_TXBUF[TCP_APP_OFFSET];
*buf++ = 'P';
*buf++ = 'A';
*buf++ = 'S';
*buf++ = 'S';
*buf++ = ' ';
i = pop3c_getpassword(buf);
if(i < 0)
return;
buf += i;
/* Insert >CRLF */
*buf++ = '\r';
*buf = '\n';
tcp_send(POP3Client.sochandle, &OTCP_TXBUF[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET, i + 7);
}
void pop3c_sendstat (void)
{
UINT8* buf;
/* Fill TCP Tx buffer with "STAT\r\n" and send it to POP3 server */
buf = &OTCP_TXBUF[TCP_APP_OFFSET];
*buf++ = 'S';
*buf++ = 'T';
*buf++ = 'A';
*buf++ = 'T';
*buf++ = '\r';
*buf = '\n';
tcp_send(POP3Client.sochandle, &OTCP_TXBUF[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET, 6);
}
void pop3c_sendlist (UINT16 msgnbr)
{
UINT8* buf;
INT16 i;
/* Ask LIST of given message number in order to get the total len of it */
buf = &OTCP_TXBUF[TCP_APP_OFFSET];
*buf++ = 'L';
*buf++ = 'I';
*buf++ = 'S';
*buf++ = 'T';
*buf++ = ' ';
otcp_ltoa( (UINT32)msgnbr, buf);
i = otcp_strlen(buf,40);
if(i<0)
return;
buf += i;
*buf++ = '\r';
*buf = '\n';
tcp_send(POP3Client.sochandle, &OTCP_TXBUF[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET, i + 7);
}
void pop3c_sendtop (UINT16 msgnbr)
{
UINT8* buf;
INT16 i;
/* Ask TOP msgnbr 0 in order to get the header of msg */
buf = &OTCP_TXBUF[TCP_APP_OFFSET];
*buf++ = 'T';
*buf++ = 'O';
*buf++ = 'P';
*buf++ = ' ';
otcp_ltoa( (UINT32)msgnbr, buf);
i = otcp_strlen(buf,40);
if(i<0)
return;
buf += i;
*buf++ = ' ';
*buf++ = '0';
*buf++ = '\r';
*buf = '\n';
tcp_send(POP3Client.sochandle, &OTCP_TXBUF[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET, i + 8);
}
void pop3c_sendretr (UINT16 msgnbr)
{
UINT8* buf;
INT16 i;
/* Ask RETR of given message number in order to get the message */
buf = &OTCP_TXBUF[TCP_APP_OFFSET];
*buf++ = 'R';
*buf++ = 'E';
*buf++ = 'T';
*buf++ = 'R';
*buf++ = ' ';
otcp_ltoa( (UINT32)msgnbr, buf);
i = otcp_strlen(buf,40);
if(i<0)
return;
buf += i;
*buf++ = '\r';
*buf = '\n';
tcp_send(POP3Client.sochandle, &OTCP_TXBUF[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET, i + 7);
}
void pop3c_senddele (UINT16 msgnbr)
{
UINT8* buf;
INT16 i;
/* Ask DELE of given message number in order to delete it */
buf = &OTCP_TXBUF[TCP_APP_OFFSET];
*buf++ = 'D';
*buf++ = 'E';
*buf++ = 'L';
*buf++ = 'E';
*buf++ = ' ';
otcp_ltoa( (UINT32)msgnbr, buf);
i = otcp_strlen(buf,40);
if(i<0)
return;
buf += i;
*buf++ = '\r';
*buf = '\n';
tcp_send(POP3Client.sochandle, &OTCP_TXBUF[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET, i + 7);
}
void pop3c_sendquit (void)
{
UINT8* buf;
/* Fill TCP Tx buffer with "QUIT\r\n" and send it to POP3 server */
buf = &OTCP_TXBUF[TCP_APP_OFFSET];
*buf++ = 'Q';
*buf++ = 'U';
*buf++ = 'I';
*buf++ = 'T';
*buf++ = '\r';
*buf = '\n';
tcp_send(POP3Client.sochandle, &OTCP_TXBUF[TCP_APP_OFFSET], NETWORK_TX_BUFFER_SIZE - TCP_APP_OFFSET, 6);
}
INT16 pop3c_parsestat (void)
{
/* Parse total number of messages */
UINT8 i;
UINT8 ch;
if( RECEIVE_NETWORK_B() != '+')
return(-1);
if( otcp_tolower(RECEIVE_NETWORK_B()) != 'o')
return(-1);
if( otcp_tolower(RECEIVE_NETWORK_B()) != 'k')
return(-1);
if( RECEIVE_NETWORK_B() != ' ')
return(-1);
POP3Client.msgtotal = 0;
for(i=0; i<5; i++)
{
ch = RECEIVE_NETWORK_B();
if(ch == ' ')
return(1);
if( otcp_isnumeric(ch) == 0)
return(-1);
ch = otcp_asciitohex(ch);
POP3Client.msgtotal *= 10;
POP3Client.msgtotal += ch;
}
/* If we get there the number of messages is too big */
return(-1);
}
INT16 pop3c_parselist (void)
{
/* Parse total length of current message */
UINT8 i;
UINT8 ch;
if( RECEIVE_NETWORK_B() != '+')
return(-1);
if( otcp_tolower(RECEIVE_NETWORK_B()) != 'o')
return(-1);
if( otcp_tolower(RECEIVE_NETWORK_B()) != 'k')
return(-1);
if( RECEIVE_NETWORK_B() != ' ')
return(-1);
/* Receive untill next space */
for(i=0; i<5; i++)
{
ch = RECEIVE_NETWORK_B();
if( ch == ' ')
break;
}
/* Space not found? */
if( ch != ' ')
return(-1);
POP3Client.curmsgtotlen = 0;
for(i=0; i<9; i++)
{
ch = RECEIVE_NETWORK_B();
if(ch == '\r')
return(1);
if(ch == '\n')
return(1);
if( otcp_isnumeric(ch) == 0)
return(-1);
ch = otcp_asciitohex(ch);
POP3Client.curmsgtotlen *= 10;
POP3Client.curmsgtotlen += ch;
}
/* If all OK we are NOT here */
return(-1);
}
void pop3c_changestate (UINT8 nstate)
{
init_timer(POP3Client.tmrhandle, POP3C_TOUT*TIMERTIC);
POP3Client.state = nstate;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -