📄 smtp.c
字号:
if (CheckResponse(DATA_CHECK) == TFALSE)
{
return TFALSE;
}
else
{
//判断是否是带附件的邮件
ISMIME(struMail);
//发送邮件头信息
SendHeader(struMail);
//如果是MIME邮件,则需要增加附加的MIME信息
if(g_bMIME)
{
SendMIMEHead(struMail);
}
else
{
//发送回车换行
memset(buf, 0, 256);
sprintf (buf, "\r\n");
if(SendDate(buf, strlen(buf)) == TFALSE)
{
return TFALSE;
}
}
//发送邮件体内容
sprintf (buf, "%s", struMail.m_strMailText);
if(SendDate(buf, strlen (buf)) == TFALSE)
{
return TFALSE;
}
//发送附件内容(现在只可以发送单个文件,以后扩展可以发送文件列表)
if(g_bMIME)
{
SendAttachment(struMail);
}
//发送邮件数据结束标记
sprintf (buf, "\r\n.\r\n");
if(SendDate(buf, strlen (buf)) == TFALSE)
{
return TFALSE;
}
//检查结束符响应
if (!CheckResponse(250))
{
printf("Date command error!\n");
return TFALSE;
}
}
return TTRUE;
}
//构造邮件头信息
BOOL SendHeader(SMTP sruEmail)
{
BOOL bRet = TTRUE;
char strTemp[1024];
char* strSubEncode = NULL;
char* strMailInfo = NULL;
char* strHeadMIME = NULL;
char strTime[256];
struct tm *newtime;
time_t long_time;
char* strTimeBuf = NULL;
strMailInfo = (char*)malloc(1024);
if(strMailInfo == NULL)
{
return TFALSE;
}
//创建"FROM:"信息------"From: %s\r\n
memset(strTemp, 0, 1024);
strcpy(strTemp, sruEmail.m_strSenderName);
strcat(strTemp, " <" );
strcat(strTemp, sruEmail.m_strSendFrom);
strcat(strTemp, ">");
strcpy(strMailInfo, "From: ");
strcat(strMailInfo, strTemp);
strcat(strMailInfo, "\r\n");
//创建"To:"信息------To: %s\r\n"
strcat(strMailInfo, "To: ");
strcat(strMailInfo, sruEmail.m_strSendTo);
strcat(strMailInfo, "\r\n");
//创建主题内容,需要对主体的数据进行编码
//memset(strTemp, 0, 1024);
strSubEncode = EnSubJectCodeString(sruEmail.m_strMailSubject );
strcat(strMailInfo, "Subject: ");
strcat(strMailInfo, strSubEncode) ;
strcat(strMailInfo, "\r\n");
//创建"Date:"信息格式: Fri, 06 Jan 2006 09:02:22 +0800
// Sun May 01 20:27:01 1994
time( &long_time );
newtime = localtime( &long_time );
strTimeBuf = asctime(newtime);
strcpy(strTime, substr(strTimeBuf,0, 3));
strcat(strTime, ", ");
strcat(strTime, substr(strTimeBuf,8, 2)); //日期信息
strcat(strTime, " ");
strcat(strTime, substr(strTimeBuf, 4, 3)); //月份信息
strcat(strTime, " ");
strcat(strTime, substr(strTimeBuf, 20, 4)); //年信息
strcat(strTime, " ");
strcat(strTime, substr(strTimeBuf, 11, 8)); //时间信息
strcat(strTime, " ");
// strTime = strTime + "+0800"; //时区信息
strcat(strMailInfo, "Date: ");
strcat(strMailInfo, strTime);
strcat(strMailInfo, "\r\n");
//创建X-Mailer信息------X-Mailer: %s\r\n"
memset(strTemp, 0, 1024);
strcpy(strTemp, "AsokeMailSender");
strcat(strMailInfo, "X-Mailer: ");
strcat(strMailInfo, "X-AsokeMailSender");
strcat(strMailInfo, "\r\n");
//如果是MIME邮件,则增加MIME信息
strHeadMIME = (char*)malloc(1024);
if(g_bMIME)
{
GetMIMEHead(strHeadMIME);
strcat(strMailInfo, strHeadMIME);
}
//创建Encoding类型信息
strcat(strMailInfo, "Content-Transfer-Encoding: quoted-printable\r\n");
//创建"Reply-To:"信息------Reply-To: %s\r\n""
strcat(strMailInfo, "Reply-To: ");
strcat(strMailInfo, sruEmail.m_strSenderName);
strcat(strMailInfo, " <");
strcat(strMailInfo, sruEmail.m_strSendFrom);
strcat(strMailInfo, ">");
strcat(strMailInfo, "\r\n");
//增加定制信息
strcat(strMailInfo, "X-Program: ");
strcat(strMailInfo, "CSTMPMessageTester");
//增加结束标记
strcat(strMailInfo, "\r\n");
if(SendDate(strMailInfo, strlen(strMailInfo)) == TFALSE)
{
return TFALSE;
}
return bRet;
}
//MIME信息中需要增加邮件头中的MIME信息
BOOL GetMIMEHead(char* strMIMEHeadInfo)
{
BOOL bRet = TTRUE;
//增加必须的邮件头信息
const char* strContentType = "multipart/mixed";
//格式化字符串
char* strMIMEHead = (char*)malloc(1024);
//内存分配失败
if(strMIMEHead == NULL)
{
return TFALSE;
}
memset(strMIMEHead, 0, 1024);
sprintf(strMIMEHead, "MIME-Version: 1.0\r\nContent-Type: %s; boundary=\"%s\"\r\n", strContentType, g_strBoundary);
strcpy(strMIMEHeadInfo ,strMIMEHead);
free(strMIMEHead);
strMIMEHead = NULL;
return bRet;
}
//获取附件文件的详细信息并且进行编码处理
char* GetFileBody(char* strFileName, int* nBodySize)
{
char* pszBody = NULL;
BOOL bSuccess = TFALSE;
int dwSize = 0;
int nThisLineSize= 0;
unsigned char* pszIn = NULL;
struct stat statbuf;
FILE* infile = NULL;
char* pszEncoded = NULL;
int nEncodedSize = 0;
Base64Coder Coder;
int nInPos = 0;
int nOutPos = 0;
if (strlen(strFileName) != 0)
{
//如果是附件
//打开文件获取文件的长度
if(stat(strFileName, &statbuf) == -1)
{
return NULL;
}
else
{
dwSize = statbuf.st_size;
}
//打开文件获取文件的内容
infile = fopen(strFileName, "r" );
if (infile != NULL)
{
if (dwSize)
{
//读入文件数据
pszIn = (unsigned char*)malloc(dwSize);
//内存分配失败
if(pszIn == NULL)
{
return NULL;
}
memset(pszIn, 0, dwSize);
fread( pszIn, 1, dwSize, infile );
bSuccess = TTRUE;
if (bSuccess)
{
//编码
Base64CoderInit(&Coder);
_Init(&Coder);
EncodeBase(&Coder, (const unsigned char*)pszIn, dwSize);
//关闭输入文件
fclose(infile);
//形成编码后的发送内容
pszEncoded = EncodedMessage(Coder);
nEncodedSize = EncodedMessageSize(Coder);
*nBodySize = nEncodedSize + (((nEncodedSize/76)+1)*2) + 1;
pszBody = (char*)malloc(*nBodySize);
//内存分配失败
if(pszBody == NULL)
{
free(pszIn);
pszIn = NULL;
return NULL;
}
memset(pszBody, 0, *nBodySize);
--(*nBodySize);
while (nInPos < nEncodedSize)
{
nThisLineSize = min(nEncodedSize - nInPos, SMTP_MAXLINE);
memcpy(&pszBody[nOutPos], &pszEncoded[nInPos], nThisLineSize);
nOutPos += nThisLineSize;
memcpy(&pszBody[nOutPos], "\r\n", 2);
nOutPos += 2;
nInPos += nThisLineSize;
}
//以空字符串结束
pszBody[nOutPos] = '\0';
//删除了输入缓冲区
free(pszIn);
pszIn = NULL;
}
}
else
{
printf("No bodypart body text or filename specified!\n");
pszBody = NULL;
*nBodySize = 0;
return pszBody;
}
}
else
{
pszBody = NULL;
*nBodySize = 0;
printf("Open file fail!\n");
}
}
return pszBody;
}
//获取附件的头信息
char* GetAttachmentHeader(int* nHeaderSize, char* strFileName)
{
char* pszHeader = NULL;
char* sHeader = NULL;
//设置邮件体中文本内容和附件内容的分割信息
const char* strCharset = "iso-8859-1";
const char* strContentType = "application/octet-stream";
//根据文件的详细信息获取文件的名称
int nPos = 0;
char* strTitle = NULL;
nPos = rfind(strFileName, "/"); //linux 文件格式
//nPos = rfind(strFileName, "\\"); //windows 文件格式
strTitle = substr(strFileName, nPos+1, strlen(strFileName));
//格式化字符串
sHeader = (char*)malloc(1024);
//内存分配失败
if(sHeader == NULL)
{
return NULL;
}
memset(sHeader, 0, 1024);
sprintf(sHeader, "\r\n\r\n--%s\r\nContent-Type: %s; charset=%s; name=%s\r\nContent-Transfer-Encoding: base64\r\nContent-Disposition: attachment; filename=%s\r\n",
g_strBoundary, strContentType, strCharset, strTitle, strTitle);
//添加结束信息标记
strcat(sHeader, "\r\n");
*nHeaderSize = strlen(sHeader);
pszHeader = (char*)malloc(*nHeaderSize + 1);
//内存分配失败
if(pszHeader == NULL)
{
free(sHeader);
sHeader = NULL;
return NULL;
}
memset(pszHeader, 0, *nHeaderSize + 1);
strcpy(pszHeader, (const char*)sHeader);
//释放内存
free(sHeader);
sHeader = NULL;
return pszHeader;
}
BOOL SendAttachment(SMTP struMail)
{
BOOL bRet = TTRUE;
char* pszHeader = NULL;
int nHeaderSize = 0;
char* pszFile = NULL;
int nFileSize = 0;
char* pszFooter = NULL;
int nFooterSize = 0;
//发送附件的附件头信息
pszHeader = GetAttachmentHeader(&nHeaderSize, struMail.m_strFile);
if(pszHeader == NULL)
{
return TFALSE;
}
if (!SendDate(pszHeader, nHeaderSize))
{
if(pszHeader != NULL)
{
free(pszHeader);
pszHeader = NULL;
}
bRet = TFALSE;
}
//释放多于的内存
if(pszHeader != NULL)
{
free(pszHeader);
pszHeader = NULL;
}
//发送附件详细内容信息
pszFile = GetFileBody(struMail.m_strFile, &nFileSize);
if(pszFile == NULL )
{
return TFALSE;
}
if (!SendDate(pszFile, nFileSize))
{
if(pszFile != NULL)
{
free(pszFile);
pszFile = NULL;
}
bRet = TFALSE;
}
//释放多于的内存
if(pszFile != NULL)
{
free(pszFile);
pszFile = NULL;
}
//发送发送MIME结束部分
pszFooter = GetFooter(&nFooterSize);
if(pszFooter == NULL)
{
return TFALSE;
}
if (!SendDate(pszFooter, nFooterSize))
{
if(pszFooter != NULL)
{
free(pszFooter);
pszFooter = NULL;
}
bRet = TFALSE;
}
//释放内存信息
if(pszFooter != NULL)
{
free(pszFooter);
pszFooter = NULL;
}
return bRet;
}
char* GetFooter(int* nFooterSize)
{
char* pszFooter = NULL;
//构造MIME结束信息
char sFooter[1024];
strcpy(sFooter, "\r\n--");
strcat(sFooter, g_strBoundary);
strcat(sFooter ,"--");
*nFooterSize = strlen(sFooter);
pszFooter = (char*)malloc(*nFooterSize+1);
if(pszFooter == NULL)
{
return NULL;
}
memset(pszFooter, 0, *nFooterSize+1);
strcpy(pszFooter, sFooter);
return pszFooter;
}
//构造MIME邮件头信息
BOOL SendMIMEHead(SMTP struMail)
{
BOOL bRet = TFALSE;
char* sHeader = NULL;
const char* strContentType = "text/plain";
const char* strCharset = "gb2312";
//构造邮件头中的格式信息并且发送
const char* strFoamatMail= "This is a multi-part message in MIME format";
if (!SendDate(strFoamatMail, strlen(strFoamatMail)))
{
bRet = TFALSE;
}
//构造邮件头中的附加信息并且发送
sHeader = (char*)malloc(1024);
//内存分配失败
if(sHeader == NULL)
{
return TFALSE;
}
memset(sHeader, 0, 1024);
sprintf(sHeader, "\r\n--%s\r\nContent-Type: %s; charset=%s\r\nContent-Transfer-Encoding: quoted-printable\r\n\r\n",
g_strBoundary, strContentType, strCharset);
if (!SendDate(sHeader, strlen(sHeader)))
{
if(sHeader != NULL)
{
free(sHeader);
sHeader = NULL;
}
bRet = TFALSE;
}
//释放内存信息
if(sHeader != NULL)
{
free(sHeader);
sHeader = NULL;
}
return TTRUE;
}
//本方法检查服务器的响应:
//本方法检查服务器的响应:
BOOL CheckResponse(int Type)
{
char buf [1024];
BOOL bTimeOUt = TFALSE;
int iReceive = 0;
//////////
fd_set fdArray;
struct timeval TimeOut;
int iMaxSocket = 0;
int tpkt[4];
time_t strattime;
time_t endtime;
int lRet = -1;
//初始化数据
memset(buf, 0, 1024);
memset(tpkt, 0, sizeof(tpkt));
//等待时间
TimeOut.tv_sec = 0;
TimeOut.tv_usec = 50000; //10ms
//侦听、接收、发送数据
time( &strattime );
while (1)
{
//准备接收数组
FD_ZERO(&fdArray);
//只有一个接收socket
FD_SET(g_hSocket, &fdArray);
//超时
time( &endtime );
if ((endtime - strattime) > g_dwTimeout)
{
printf("CheckResponse command of %d have time out and the g_dwTimeout is : %d!\n", Type, g_dwTimeout);
bTimeOUt = TTRUE;
return TFALSE;
}
iMaxSocket = g_hSocket;
lRet = select(iMaxSocket+1, &fdArray, NULL, NULL, &TimeOut);
//侦听、接收、发送数据
//lRet = select(0, &fdArray, NULL, NULL, &TimeOut);
if (lRet < 0)
{
//select函数处理错误
printf("select errorin CheckResponse()");
continue;
}
//socket接收到数据
if (FD_ISSET(g_hSocket, &fdArray))
{
iReceive = Receive(buf, 1024);
if(iReceive <= 0)
{
//继续接收数据处理
continue;
}
else
{
if(ProcedureCMD(Type, buf) == TFALSE)
{
//继续接收数据处理
printf("ProcedureCMD fail and the Type is %d and buf is %s!\n", Type, buf);
continue;
}
else
{
//处理命令正确结束,跳出循环
printf("ProcedureCMD successful and the Type is %d and buf is %s!\n", Type, buf);
break;
}
}
} //接收数据处理完成 FD_ISSET(g_hSocket, &fdArray)
usleep(50);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -