?? smtp.c
字號(hào):
//===================================================================
// Asoka USA Corporation
// 文件名 :SMTP.cpp
// 作 者 :charlie(劉翔)
// 版 本 :
// 完成日期:2006-01-08
// 說(shuō) 明 :此文件是用來(lái)實(shí)現(xiàn)SMTP協(xié)議處理
// 其 它 :
// 函數(shù)列表: Data
// Mail
// Connect
// ......
//
//
// 歷史記錄:
// 作者:
// 修改內(nèi)容:
//
// 2. ...
//////////////////////////////////////////////////////////////////////////
// SMTP.cpp: implementation of the CSMTP class.
//
//////////////////////////////////////////////////////////////////////
#include "SMTP.h"
#include "Base64Coder.h"
#include <malloc.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/un.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <dirent.h>
#include <memory.h>
#include <unistd.h>
#include <netdb.h>
BOOL Mail(SMTP struMail);
char* GetHost();
void SetHost(char* Host);
//發(fā)送DATA命令信息
BOOL Data(SMTP struMail);
//// 發(fā)送TO命令信息
BOOL SetTo(SMTP struMail);
//發(fā)送MAIL命令信息
BOOL MailCMD(char* from);
//和SMTP服務(wù)器斷開(kāi)連接
BOOL Disconnect();
//和SMTP服務(wù)器進(jìn)行連接
//BOOL Connect();
// 該函數(shù)是通過(guò)擴(kuò)展SMTP會(huì)話(huà)方式連接服務(wù)器的
BOOL ConnectSrvSMTP(const char* pszLocalName, const char* pszUsername, const char* pszPassword);
// 使用AUTH LOGIN命令協(xié)商登錄,即需要對(duì)用戶(hù)名進(jìn)行編碼
BOOL AuthLogin(const char* pszUsername, const char* pszPassword);
//檢查指定命令的響應(yīng)信息
BOOL ReadCommandResponse(int nExpectedCode);
//檢查郵件服務(wù)器的詳細(xì)響應(yīng)信息
BOOL ReadResponse(char* pszBuffer, int nInitialBufSize, char* pszTerminator, int nExpectedCode, char** ppszOverFlowBuffer, int nGrowBy);
char* GetError(char* Response);
//檢查郵件服務(wù)器的響應(yīng)信息
BOOL CheckResponse(int Type);
BOOL ProcedureCMD(int Type, char* buf);
char* T2A(char* lp);
//獲取文件的內(nèi)容信息
char* GetFileBody(char* strFileName, int* nBodySize);
//獲取附件的頭信息
char* GetAttachmentHeader(int* nHeaderSize, char* strFileName);
//發(fā)送指定信息的郵件
BOOL SendMailInfo(SMTP struMail);
//發(fā)送郵件的附件信息
BOOL SendAttachment(SMTP struMail);
//發(fā)送附件的尾信息
char* GetFooter(int* nFooterSize);
//發(fā)送郵件頭信息
BOOL SendMIMEHead(SMTP struMail);
//MIME信息中需要增加郵件頭中的MIME信息
BOOL GetMIMEHead(char* strMIMEHeadInfo);
//發(fā)送郵件的郵件頭信息
BOOL SendHeader(SMTP struMail);
//判斷是否是帶附件的郵件
void ISMIME(SMTP struMail);
//檢查郵件信息的合法性
BOOL CheckMailInfo(SMTP struMail);
//設(shè)置郵件的發(fā)送人信息
void SetSenderName(SMTP* struMail, char* strSenderName);
//對(duì)SUBJECT信息進(jìn)行編碼處理
char* EnSubJectCodeString(char* sText);
//對(duì)郵件體BODY信息進(jìn)行編碼處理
void EnBodyCodeString(char* sText, char* strEncode);
//初始化SMTP信息
void Initialize(SMTP *EmailSMTP);
//設(shè)置附件的文件信息
void SetFile(SMTP* struMail, char* strFileName);
//設(shè)置郵件的標(biāo)題信息
void SetMailSubject(SMTP* struMail, char* strMailSubject);
//設(shè)置郵件的正文信息
void SetMailText(SMTP* struMail, char* strMailText);
//設(shè)置用戶(hù)的帳號(hào)信息
void SetUSERID(SMTP* struMail, char* strUSERID);
//設(shè)置用戶(hù)的密碼信息
void SetPWD(SMTP* struMail, char* strPWD);
//設(shè)置郵件的SMPT服務(wù)器信息
void SetSMTPServer(SMTP* struMail, char* strSMTPServer);
//設(shè)置郵件的目的址信息
void SetSendTo(SMTP* struMail, char* strSendTo);
//設(shè)置郵件的源地址信息
void SetSendFrom(SMTP* struMail, char* strSendFrom);
//對(duì)指定的字符串進(jìn)行BASE64編碼
void EnCodeString(char* strSoure,char* strEnCode);
BOOL IsSameWeek(char* strWeek, int weekly);
//根據(jù)Quoted printable編碼規(guī)則對(duì)數(shù)據(jù)進(jìn)行編碼處理
void QuotedPrintableEncode(char* sText, char* strEncode);
char HexDigit(int nDigit);
char* substr(char* pstrChar, int iBegin, int nLength);
//查找指定字符串
int find(char* pstrChar, const char* strSoure);
//查詢(xún)函數(shù)
int rfind(char* strData, const char* strSoure);
BOOL Create();
BOOL ConnectServer(const char* pszHostAddress, int nPort);
BOOL ConnectSvr(const struct sockaddr* lpSockAddr, int nSockAddrLen);
BOOL SendDate(const char* pszBuf, int nBuf);
void CloseSocket();
int Receive(char* pszBuf, int nBuf);
//BOOL IsReadable(BOOL bReadible);
static BOOL g_bMIME = TFALSE;
static int g_hSocket = -1;
static int g_NoOfTo = 0; //發(fā)送的目的地址的個(gè)數(shù)
static char g_ErrorMessage[128];
static char g_Host[128]; //主機(jī)信息
static int g_nLastCommandResponseCode = 0;
static char g_sLastCommandResponse[128];
static int g_dwTimeout = 0; //超時(shí)時(shí)間
static BOOL g_bConnected = TFALSE;
static char g_strBoundary[128]; //Boundary信息,MIME中定義的數(shù)據(jù)
static char g_strEncode[128]; //編碼方式,MIME中定義的數(shù)據(jù)
static char g_stCharset[128]; //charset信息,MIME中定義的數(shù)據(jù)
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
void Initialize(SMTP *EmailSMTP)
{
//重新初始化全局變量
g_NoOfTo = 0;
g_dwTimeout = 120; //超時(shí)時(shí)間設(shè)置為120秒
g_bMIME = TFALSE;
g_bConnected = TFALSE;
memset(g_strBoundary, 0, 128);
memset(g_strEncode, 0, 128);
memset(g_stCharset, 0, 128);
strcpy(g_strBoundary, "18ac0781-9ae4-4a2a-b5f7-5479635efb6b");
strcpy(g_strEncode ,"base64");
strcpy(g_stCharset, "gb2312");
g_hSocket = -1;
//初始化SMTP結(jié)構(gòu)
memset(EmailSMTP->m_strFile, 0, 128);
memset(EmailSMTP->m_strSendFrom, 0, 64);
memset(EmailSMTP->m_strSendTo, 0, 64);
memset(EmailSMTP->m_strSMTPServer, 0, 64);
memset(EmailSMTP->m_strPWD, 0, 64);
memset(EmailSMTP->m_strUSERID, 0, 64);
memset(EmailSMTP->m_strMailText, 0, 64);
memset(EmailSMTP->m_strMailSubject, 0, 64);
memset(EmailSMTP->m_strSenderName, 0, 64);
}
char* T2A(char* lp)
{
return lp;
}
// 讀取主機(jī)信息
char* GetHost( )
{
return g_Host;
}
//設(shè)置主機(jī)信息
void SetHost(char* Host)
{
memset(g_Host, 0, 128);
strcpy(g_Host, Host);
}
//連接SMTP服務(wù)器
BOOL ConnectSMTP(SMTP struMail)
{
// printf("begin Connect!\n");
//char* From= NULL;
//char* strtemp = NULL;
//char* Host = NULL;
//int nPos = 0;
char sHostName[100];
BOOL bConnectOk = TFALSE;
//char* strUsername = NULL;
//char* strPassword = NULL;
/*
nPos = find(struMail.m_strSendFrom, "@");
From = substr(struMail.m_strSendFrom, 0, nPos);
strcat(From, struMail.m_strSMTPServer);
*/
// SMTP端口默認(rèn)是25
if (!ConnectServer(struMail.m_strSMTPServer, 25))
{
strcpy(g_ErrorMessage, "Server cannot be connected");
printf("Server cannot be connected!\n");
return TFALSE;
}
else
{
// printf("Connect successfully!\n");
//檢查返回的值是否是220
if(CheckResponse(CONNECTION_CHECK) == TFALSE)
{
return TFALSE;
}
//獲得本地機(jī)器名
memset(sHostName, 0, 100);
gethostname(sHostName, sizeof(sHostName));
// 進(jìn)行下一步連接,即進(jìn)行SMTP會(huì)話(huà),采用鑒權(quán)方式進(jìn)行會(huì)話(huà)
bConnectOk = ConnectSrvSMTP(sHostName, struMail.m_strUSERID , struMail.m_strPWD );
if(bConnectOk == TFALSE)
{
printf("ConnectESMTP fail!\n");
return TFALSE;
}
return TTRUE;
}
}
// 該函數(shù)是通過(guò)擴(kuò)展SMTP會(huì)話(huà)方式連接服務(wù)器的
BOOL ConnectSrvSMTP(const char* pszLocalName, const char* pszUsername, const char* pszPassword)
{
char sBuf[128];
char* pszData = NULL;
BOOL bLoginOk = TFALSE;
int nCmdLength = 0;
//驗(yàn)證參數(shù)
if((pszLocalName == NULL) || (pszUsername == NULL)|| (pszPassword == NULL))
{
return TFALSE;
}
//發(fā)送EHLO命令
memset(sBuf, 0, 128);
strcpy(sBuf, "EHLO ");
strcat(sBuf, pszLocalName);
strcat(sBuf, "\r\n");
pszData = T2A(sBuf);
nCmdLength = strlen(pszData);
if (!SendDate(pszData, nCmdLength))
{
return TFALSE;
}
//檢查Hello命令的響應(yīng) 250
if(CheckResponse(HELLO_CHECK)==TFALSE)
{
return TFALSE;
}
//進(jìn)行帳號(hào)密碼驗(yàn)證
bLoginOk = AuthLogin(pszUsername, pszPassword);
if(bLoginOk == TFALSE)
{
return TFALSE;
}
return bLoginOk;
}
// 使用AUTH LOGIN命令協(xié)商登錄,即需要對(duì)用戶(hù)名進(jìn)行編碼
BOOL AuthLogin(const char* pszUsername, const char* pszPassword)
{
char sBuf[128];
int nCmdLength = 0;
char* pszData = NULL;
char* temp = NULL;
char* pTmp = NULL;
char* sLastCommandString = NULL;
char* pszLastCommandString = NULL;
Base64Coder Coder;
Base64Coder CoderPWD;
//驗(yàn)證參數(shù)
if((pszUsername == NULL)|| (pszPassword == NULL))
{
return TFALSE;
}
//發(fā)送AUTH LOGIN命令
temp = (char*)malloc(100);
//檢查分配內(nèi)存是否成功
if(temp == NULL)
{
return TFALSE;
}
memset(sBuf, 0, 128);
strcpy(sBuf, "AUTH LOGIN\r\n");
pszData = T2A(sBuf);
nCmdLength = strlen(pszData);
if (!SendDate(pszData, nCmdLength))
{
printf("An unexpected error occurred while sending the AUTH command\n");
free(temp);
temp = NULL;
return TFALSE;
}
//初始化
//檢查Hello命令的響應(yīng) 334
if (!ReadCommandResponse(334))
{
printf("Server does not support AUTH LOGIN!\n");
free(temp);
temp = NULL;
return TFALSE;
}
else
{
//發(fā)送base64編碼后的用戶(hù)名
sLastCommandString = (char*)malloc(1024);
if(sLastCommandString == NULL)
{
free(temp);
temp = NULL;
return TFALSE;
}
strcpy(sLastCommandString , g_sLastCommandResponse);
//需要進(jìn)行數(shù)據(jù)測(cè)試
sLastCommandString = substr(sLastCommandString, 4, strlen(sLastCommandString) -4);
pszLastCommandString = T2A(sLastCommandString);
Base64CoderInit(&Coder);
_Init(&Coder);
Decode(&Coder, pszLastCommandString);
if (strcmp(DecodedMessage(Coder), "Username:") == 0)
{
Encode(&Coder, T2A((char*)pszUsername));
memset(temp, 0, 100);
sprintf(temp, "%s\r\n", EncodedMessage(Coder));
strcpy(sBuf, (const char*)temp);
pszData = T2A((char*)sBuf);
nCmdLength = strlen(pszData);
if (!SendDate(pszData, nCmdLength))
{
printf("An unexpected error occurred while sending the username\n");
free(sLastCommandString);
sLastCommandString = NULL;
free(temp);
temp = NULL;
return TFALSE;
}
}
else
{
printf("An unexpected request received when expecting username request");
free(sLastCommandString);
sLastCommandString = NULL;
free(temp);
temp = NULL;
return TFALSE;
}
}
//重新分配內(nèi)存資源
free(sLastCommandString);
sLastCommandString = NULL;
sLastCommandString = (char*)malloc(1024);
if(sLastCommandString == NULL)
{
return TFALSE;
}
//檢查返回用戶(hù)名返回碼
if (!ReadCommandResponse(334))
{
printf("Server did not response correctly to AUTH LOGIN username field!\n");
free(sLastCommandString);
sLastCommandString = NULL;
free(temp);
temp = NULL;
return TFALSE;
}
else
{
//發(fā)送密碼到服務(wù)器
memset(sLastCommandString, 0, 1024);
strcpy(sLastCommandString, g_sLastCommandResponse);
pTmp = substr(sLastCommandString, 4, strlen(sLastCommandString) -4);
pszLastCommandString = T2A(pTmp);
Base64CoderInit(&CoderPWD);
_Init(&CoderPWD);
Decode(&CoderPWD, pszLastCommandString);
if (strcmp(DecodedMessage(CoderPWD), "Password:") == 0)
{
Encode(&CoderPWD, T2A((char*)pszPassword));
memset(temp, 0, 100);
sprintf(temp, "%s\r\n", EncodedMessage(CoderPWD));
strcpy(sBuf, (const char*)temp);
pszData = T2A(sBuf);
nCmdLength = strlen(pszData);
if (!SendDate(pszData, nCmdLength))
{
printf("An unexpected error occurred while sending the password\n");
free(sLastCommandString);
sLastCommandString = NULL;
free(temp);
temp = NULL;
return TFALSE;
}
//檢查是否成功
if (!ReadCommandResponse(235))
{
printf("AUTH LOGIN authentication was unsuccessful\n");
free(sLastCommandString);
sLastCommandString = NULL;
free(temp);
temp = NULL;
return TFALSE;
}
// printf("Test Password successfully!\n");
}
else
{
printf("An unexpected request received when expecting password request\n");
free(sLastCommandString);
sLastCommandString = NULL;
free(temp);
temp = NULL;
return TFALSE;
}
}
free(sLastCommandString);
sLastCommandString = NULL;
free(temp);
temp = NULL;
return TTRUE;
}
// 發(fā)送"QUIT"命令到SMTP服務(wù)器:
BOOL Disconnect()
{
char buf[256];
memset(buf, 0, 256);
sprintf (buf, "QUIT \r\n");
//發(fā)送QUIT命令
if(SendDate(buf, strlen (buf)) == TFALSE)
{
return TFALSE;
}
//檢查是否正常退出
if (CheckResponse(QUIT_CHECK) == TFALSE)
{
return TFALSE;
}
else
{
return TTRUE;
}
}
// 發(fā)送"MAIL" 命令到SMTP服務(wù)器:
BOOL MailCMD(char* from)
{
char buf[256];
memset(buf, 0, 256);
sprintf(buf, "MAIL FROM:<%s>\r\n", from);
//發(fā)送MAIL命令
if(SendDate(buf, strlen (buf)) == TFALSE)
{
return TFALSE;
}
//檢查MAIL命令是否正常處理
if (CheckResponse(MAIL_CHECK) == TFALSE)
{
return TFALSE;
}
else
{
return TTRUE;
}
}
// 發(fā)送TO命令信息
BOOL SetTo(SMTP struMail)
{
char buf[256];
memset(buf, 0, 256);
sprintf (buf, "RCPT TO:<%s>\r\n", struMail.m_strSendTo);
//發(fā)送TO命令
if(SendDate(buf, strlen (buf)) == TFALSE)
{
return TFALSE;
}
//檢查T(mén)O命令是否正常處理
if (CheckResponse(RCPT_CHECK) == TFALSE)
{
return TFALSE;
}
return TTRUE;
}
// 發(fā)送"DATA" 命令到 SMTP 服務(wù)器:
//進(jìn)行擴(kuò)展,可以發(fā)送文件
BOOL Data(SMTP struMail)
{
char buf[256];
//char* Subject = NULL;
//char* Body = NULL;
//char* strFileName = NULL;
memset(buf, 0, 256);
//發(fā)送DATA命令
sprintf(buf, "DATA\r\n");
SendDate(buf, strlen (buf));
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -