📄 smtp.c
字号:
/*******************************************************************************
SMTP SOURCE CODE
BY WANGQINGLIN 2003.11.03 IN BEIJIN
********************************************************************************/
#include "func.h"
#include <stdio.h>
#include <string.h>
#include "C:\wql\tcpipsocket\tcpip.h"
#include "C:\wql\tcpipsocket\smtp.h"
#define SMTP_DOMAIN "WANGQINGLIN"
#define MAX_SMTP_S_O_L 1000
extern UINT8 xdata MY_IP[4];
CONNECTION *SMTP_SOCKET;
UINT8 SMTP_STATE = SMTP_INIT;
SMTPtype SMTP_PACKET;
UINT8 SMTP_IN[100];
UINT8 SMTP_SOCKET_O_BUF[MAX_SMTP_S_O_L];//定义了用于SMTP的SOCKET的输出缓冲区
extern void delay_long();
unsigned char Base64Table[64]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+";
//**************************************************************
// 应用程序不听的调用这个函数以便查看是否有关于SMTP的数据过来
// *************************************************************
void SMTP_tick()
{
UINT16 SMTP_IN_DATA_LEN; //收到的SMTP的数据长度
UINT8 SMTP_OUT[300]; //这里300只是暂时的,具体的长度应根据具体情况设定
if(SMTP_SOCKET ==NULL) return;
if(SMTP_SOCKET->state != STATE_ESTABLISHED) return; //not established
SMTP_IN_DATA_LEN = SOCKET_READ_INBUFFER(SMTP_SOCKET,SMTP_IN); //RECEIVED THE DATA
//if(SMTP_IN_DATA_LEN ==0) return;
if(SOCKET_GET_O_L(SMTP_SOCKET)) return; //上次的还没有发送出去,则退出
switch (SMTP_STATE)
{
case SMTP_INIT:
case SMTP_WAITFORESTAB:
case SMTP_WAITFORHELO220:
if(SMTP_IN_DATA_LEN ==0) break;
if(ch_strstr(SMTP_IN, "220") != NULL)
{
sprintf(SMTP_OUT,"HELO zhuziliangnb\r\n"); //send 'hello my_ip
SOCKET_WRITE_OUTBUFFER(SMTP_SOCKET,SMTP_OUT,strlen(SMTP_OUT));
printf("received the hello 220\n");
SMTP_STATE = SMTP_WAITFORMAIL250;
}
break;
case SMTP_WAITFORMAIL250:
if(SMTP_IN_DATA_LEN ==0) break;
if(ch_strstr(SMTP_IN, "250") != NULL)
{
sprintf(SMTP_OUT,"MAIL FROM:\"%s\"\r\n",SMTP_PACKET.FROM);
SOCKET_WRITE_OUTBUFFER(SMTP_SOCKET,SMTP_OUT,strlen(SMTP_OUT));
printf("received the peer's hello\n");
SMTP_STATE = SMTP_WAITFORRCPT250;
}
break;
case SMTP_WAITFORRCPT250:
if(SMTP_IN_DATA_LEN ==0) break;
if(ch_strstr(SMTP_IN, "250") != NULL)
{
sprintf(SMTP_OUT,"RCPT TO:<%s>\r\n",SMTP_PACKET.TO);
SOCKET_WRITE_OUTBUFFER(SMTP_SOCKET,SMTP_OUT,strlen(SMTP_OUT));
printf("received the peer's RCPT hello\n");
SMTP_STATE = SMTP_WAITFORDATA250;
}
break;
case SMTP_WAITFORDATA250:
if(SMTP_IN_DATA_LEN ==0) break;
if(ch_strstr(SMTP_IN, "250") != NULL)
{ //READY TO SEND DATA
sprintf(SMTP_OUT,"DATA\r\n");
SOCKET_WRITE_OUTBUFFER(SMTP_SOCKET,SMTP_OUT,strlen(SMTP_OUT));
printf("SEND DATA\n");
SMTP_STATE = SMTP_WAITFORDATA354;
}
break;
case SMTP_WAITFORDATA354:
if(SMTP_IN_DATA_LEN ==0) break;
if(ch_strstr(SMTP_IN, "354") != NULL)
{
sprintf(SMTP_OUT,"FROM:<%s>\r\nTO:<%s>\r\nSubject: %s\r\n\r\n",SMTP_PACKET.FROM,SMTP_PACKET.TO,SMTP_PACKET.SUBJECT);
SOCKET_WRITE_OUTBUFFER(SMTP_SOCKET,SMTP_OUT,strlen(SMTP_OUT)); //SEND THE HEAD
printf("SEND EMAIL");
SMTP_STATE = SMTP_SENDBODY; //WAIT ACK AND SEND THE END SYMBOL
}
break;
case SMTP_SENDBODY:
SOCKET_WRITE_OUTBUFFER(SMTP_SOCKET,SMTP_PACKET.MESSAGE,SMTP_PACKET.MESSAGE_LEN);
SMTP_STATE = SMTP_SENDEOM;
break;
case SMTP_SENDEOM:
sprintf(SMTP_OUT,"\r\n.\r\n");
SOCKET_WRITE_OUTBUFFER(SMTP_SOCKET,SMTP_OUT,strlen(SMTP_OUT));
printf("send end symbol");
SMTP_STATE = SMTP_WAITQUIT250;
break;
case SMTP_WAITQUIT250:
if(SMTP_IN_DATA_LEN ==0) break;
if(ch_strstr(SMTP_IN, "250") != NULL) //the server has received the valid email
{
sprintf(SMTP_OUT,"QUIT\r\n");
SOCKET_WRITE_OUTBUFFER(SMTP_SOCKET,SMTP_OUT,strlen(SMTP_OUT));
}
SMTP_STATE = SMTP_WAITDONE;
break;
case SMTP_WAITDONE:
if(SMTP_IN_DATA_LEN ==0) break;
if(ch_strstr(SMTP_IN, "221") != NULL) //the server has received the valid email
{
printf("EMAIL ok");
SOCKET_DELETE(SMTP_SOCKET);
}
SMTP_STATE = SMTP_DONE;
break;
case SMTP_DONE:
case SMTP_ERROR:
default:
break;
}
}
//*****************************************************************
//
// 创建了SMTP连接,如果返回NULL则说明已经没有了连接
//
// *************************************************
CONNECTION *Create_smtp_socket(UINT8 *SMTP_SERVER_IP)
{
SMTP_SOCKET = SOCKET_CREATE(SMTP_PORT,SMTP_SERVER_IP,14001,SMTP_SOCKET_O_BUF);
if(SMTP_SOCKET == NULL) return NULL;
SMTP_STATE = SMTP_WAITFORESTAB; //等待建立连接
return SMTP_SOCKET;
}
//*****************************************************************
// 初始化SMTP的数据包,包括向谁传,来自谁和主题、消息及其长度
void SMTP_SENDMAIL(UINT8 *TO,UINT8 *FROM,UINT8 *SUBJECT,UINT8 *MESSAGE,UINT16 MES_LEN)
{
SMTP_PACKET.TO = TO;
SMTP_PACKET.FROM = FROM;
SMTP_PACKET.SUBJECT = SUBJECT;
SMTP_PACKET.MESSAGE = MESSAGE;
SMTP_PACKET.MESSAGE_LEN = MES_LEN;
}
//*****************************************************************
//加密算法
//当需要用户名和密码时,要做加密传输
//buftoenc---需要做加密的数据存储区的指针
//bufsize ---这个存储区的大小
//encbuf ---已经加密完的数据存储区指针
// 返回值:非0表示encbuf的大小
// 0表示转换失败
unsigned int Base64Encod(char *buftoenc,int bufsize,char *encbuf)
{
int i;
int b64byte[5];
unsigned char buftemp[50];
i = 0;
//Allocate space for the temporary string
strcpy((char *)buftemp,buftoenc);
if (bufsize%3==1)
{
buftemp[bufsize]='\0';
buftemp[bufsize+1]='\0';
}
if (bufsize%3==2)buftemp[bufsize]='\0';
while (i<bufsize)
{
b64byte[0]=buftemp[i]>>2;
b64byte[1]=((buftemp[i]&3)<<4)|(buftemp[i+1]>>4);
b64byte[2]=((buftemp[i+1]&0x0F)<<2)|(buftemp[i+2]>>6);
b64byte[3]=buftemp[i+2]&0x3F;
encbuf[i+(i/3)]=Base64Table[b64byte[0]];
encbuf[i+(i/3)+1]=Base64Table[b64byte[1]];
encbuf[i+(i/3)+2]=Base64Table[b64byte[2]];
encbuf[i+(i/3)+3]=Base64Table[b64byte[3]];
i+=3;
}
if (bufsize%3==0)
return bufsize*8/6;
if (bufsize%3==1)
return((bufsize+2)*8/6)-2;
if (bufsize%3==2)
return((bufsize+1)*8/6)-1;
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -