⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smtp.c

📁 在嵌入式linux下发送邮件的SMTP客户端程序。基于mips平台可直接使用
💻 C
📖 第 1 页 / 共 4 页
字号:
	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 + -