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

📄 pgpsendmail.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
字号:
/*____________________________________________________________________________
	Copyright (C) 2002 PGP Corporation
	All rights reserved.

	$Id: pgpSendMail.c,v 1.10 2002/08/06 20:10:26 dallen Exp $
____________________________________________________________________________*/
#include <time.h>
#include <string.h>

#include "pgpSendMail.h"
#include "pgpMem.h"
#include "pgpMemoryMgr.h"
#include "pgpSockets.h"
#include "pgpUtilities.h"

#if PGP_WIN32
#include "pgpAsyncDNS.h"
#endif

#define kSMTPPort	25
#define kDataSize	256

enum
{
	kPGPSendMailState_Connect = 0,
	kPGPSendMailState_HELO,
	kPGPSendMailState_HELO_OK,
	kPGPSendMailState_MAIL,
	kPGPSendMailState_MAIL_OK,
	kPGPSendMailState_RCPT,
	kPGPSendMailState_RCPT_OK,
	kPGPSendMailState_DATA,
	kPGPSendMailState_DATA_START,
	kPGPSendMailState_Message,
	kPGPSendMailState_Message_OK,
	kPGPSendMailState_QUIT,
	kPGPSendMailState_QUIT_OK,
	kPGPSendMailState_Disconnect
};

#define kPGPSendMailState_Error		kPGPSendMailState_QUIT - 1


PGPError PGPSendMail(char *mailServer, char *fromName, char *fromAddress, 
			char *toAddress, char *subject, char *message)
{
	PGPMemoryMgrRef				memoryMgr = NULL;
	PGPSocketRef				socket = NULL;
	PGPSocketAddressInternet	sockAddr;
	PGPHostEntry *				hostEntry = NULL;
	PGPUInt32					inetAddress;
	PGPUInt32					index;
	PGPUInt32					msgIndex;
	PGPUInt32					messageLength;
	PGPError					err = kPGPError_NoErr;
	char						data[kDataSize];
	char *						mailMessage;
	char *						domain;
	char *						lineBegin;
	char *						lineEnd;
	char						date[256];
	char						gmtAdjust[32];
	PGPInt32					hourDiff;
	PGPInt32					minuteDiff;
	PGPInt32					state;
	PGPInt32					result = 0;
	PGPBoolean					failed;
	PGPSocketsThreadStorageRef	previousStorage;
	time_t						gmtSeconds;
	time_t						localSeconds;
	time_t						diffSeconds;
	struct tm					localTimeNow;
	struct tm					gmtTimeNow;
#if PGP_WIN32
	char						h_name[256];
	PGPAsyncHostEntryRef		asyncHostEntryRef;
#endif

	messageLength = strlen(message);

	err = PGPNewMemoryMgr(0, &memoryMgr);
	if (IsPGPError(err))
		return err;

	/* Format the Date: header */

	gmtSeconds = PGPGetStdTimeFromPGPTime(PGPGetTime());
	pgpCopyMemory(localtime(&gmtSeconds), &localTimeNow, sizeof(struct tm));
	pgpCopyMemory(gmtime(&gmtSeconds), &gmtTimeNow, sizeof(struct tm));
	localSeconds = mktime(&localTimeNow);
	gmtSeconds = mktime(&gmtTimeNow);
	strftime(date, sizeof(date), "%a, %d %b %Y %H:%M:%S ", &localTimeNow);
	if( gmtSeconds > localSeconds )
		diffSeconds = gmtSeconds - localSeconds;
	else
		diffSeconds = localSeconds - gmtSeconds;
	hourDiff = diffSeconds / 3600;
	minuteDiff = (hourDiff * 3600 - diffSeconds) / 60;
	if( gmtSeconds > localSeconds )
		hourDiff *= -1;
	sprintf(gmtAdjust, "%+03d%02d", hourDiff, minuteDiff);
	strcat(date, gmtAdjust);

	mailMessage = (char *) PGPNewData(memoryMgr, 
							(messageLength * 2) + strlen(fromName) + 13 +
							(strlen(toAddress) * 2) + 6 + 
							strlen(subject) + 11 + strlen(date) + 10, 
							kPGPMemoryMgrFlags_Clear);

	if (IsNull(mailMessage))
	{
		err = kPGPError_OutOfMemory;
		PGPFreeMemoryMgr(memoryMgr);
		return err;
	}

	sprintf(mailMessage, "From: \"%s\" <%s>\r\n", fromName, toAddress);
	msgIndex = strlen(fromName) + strlen(toAddress) + 13;
	sprintf(&(mailMessage[msgIndex]), "To: %s\r\n", toAddress);
	msgIndex += strlen(toAddress) + 6;
	sprintf(&(mailMessage[msgIndex]), "Subject: %s\r\n", subject);
	msgIndex += strlen(subject) + 11;
	sprintf(&(mailMessage[msgIndex]), "Date: %s\r\n\r\n", date);
	msgIndex += strlen(date) + 10;

	/*
		Convert message into standard SMTP message by translating
		line-ending characters to "\r\n" combination, making sure
		that any line that starts with a '.' has an extra '.' added
		to the beginning, and that "\r\n.\r\n" is added to the end
	*/

	index = 0;
	while (index < messageLength)
	{
		lineBegin = &(message[index]);
		lineEnd = strchr(lineBegin, '\r');
		if (IsNull(lineEnd))
			lineEnd = strchr(lineBegin, '\n');
		if (IsNull(lineEnd))
			break;

		if (*lineBegin == '.')
		{
			mailMessage[msgIndex] = '.';
			msgIndex++;
		}

		pgpCopyMemory(lineBegin, &(mailMessage[msgIndex]), 
			lineEnd - lineBegin + 1);
		
		index += (PGPUInt32) (lineEnd - lineBegin + 1);
		msgIndex += (PGPUInt32) (lineEnd - lineBegin + 1);
		
		pgpCopyMemory("\r\n", &(mailMessage[msgIndex]), 2);
		msgIndex += 2;
	}

	if (index < messageLength)
	{
		pgpCopyMemory(&(message[index]), &(mailMessage[msgIndex]),
			messageLength - index);

		msgIndex += messageLength - index;
		pgpCopyMemory("\r\n", &(mailMessage[msgIndex]), 2);
		msgIndex += 2;
	}

	pgpCopyMemory(".\r\n\0", &(mailMessage[msgIndex]), 4);

	PGPSocketsInit();
	PGPSocketsCreateThreadStorage(&previousStorage);

	inetAddress = PGPDottedToInternetAddress(mailServer);
	if (inetAddress != kPGPSockets_Error)
	{
#if PGP_WIN32
		err = PGPStartAsyncGetHostByAddress(inetAddress, &asyncHostEntryRef);
		if (IsntPGPError(err)) 
		{
			PGPWaitForGetHostByAddress(asyncHostEntryRef, h_name, 256);
			asyncHostEntryRef = kPGPInvalidAsyncHostEntryRef;
		}
#else
		hostEntry = PGPGetHostByAddress((char *) &inetAddress, 
						sizeof(PGPInternetAddress), 
						kPGPProtocolFamilyInternet);
#endif

		domain = mailServer;
	}
	else
	{
#if PGP_WIN32
		err = PGPStartAsyncGetHostByName(mailServer, &asyncHostEntryRef);
		if (IsntPGPError(err)) 
		{
			PGPWaitForGetHostByName(asyncHostEntryRef, &inetAddress);
			asyncHostEntryRef = kPGPInvalidAsyncHostEntryRef;
			strcpy(h_name, mailServer);
		}
#else
		hostEntry = PGPGetHostByName(mailServer);
#endif

		domain = strchr(mailServer, '@') + 1;
		if (domain == (char *) 1)
			domain = mailServer;
	}
		
	if (IsntPGPError(err) && IsNull(hostEntry))
		if (inetAddress == kPGPSockets_Error)
			err = PGPGetLastSocketsError();

	if (IsntPGPError(err))
	{
		socket = PGPOpenSocket(kPGPAddressFamilyInternet, 
					kPGPSocketTypeStream, kPGPTCPProtocol);
		
		if (IsNull(socket))
		{
			err = PGPGetLastSocketsError();
			pgpAssertNoErr(err);
		}
	}

	if (IsntPGPError(err))
	{
		sockAddr.sin_family = kPGPAddressFamilyInternet;
		sockAddr.sin_port = PGPHostToNetShort(kSMTPPort);

		/* If we were able to get the host entry, use the IP address list */
		/* from that. If not, use the IP address passed in by the caller  */

		if (IsntNull(hostEntry))
			sockAddr.sin_addr = *((PGPInternetAddress*) 
									*hostEntry->h_addr_list);
		else
			sockAddr.sin_addr = *((PGPInternetAddress*) &inetAddress);

		result = PGPConnect(socket, (PGPSocketAddress *) &sockAddr, 
					sizeof(sockAddr));

		if (result == kPGPSockets_Error)
			err = PGPGetLastSocketsError();
	}

	state = kPGPSendMailState_Connect;
	failed = FALSE;

	while (IsntPGPError(err) && (state != kPGPSendMailState_Disconnect))
	{
		switch (state)
		{
		case kPGPSendMailState_Connect:
			result = PGPReceive(socket, data, kDataSize, kPGPReceiveFlagNone);
			if (result != kPGPSockets_Error)
			{
				data[result] = 0;
				if (strncmp(data, "220", 3))
					err = kPGPError_NetworkOpFailed;
			}
			break;

		case kPGPSendMailState_HELO:
			sprintf(data, "HELO %s\r\n", domain);
			result = PGPSend(socket, data, strlen(data), kPGPSendFlagNone);
			break;

		case kPGPSendMailState_HELO_OK:
		case kPGPSendMailState_MAIL_OK:
		case kPGPSendMailState_RCPT_OK:
		case kPGPSendMailState_Message_OK:
			result = PGPReceive(socket, data, kDataSize, kPGPReceiveFlagNone);
			if (result != kPGPSockets_Error)
			{
				data[result] = 0;
				if (strncmp(data, "250", 3))
				{
					failed = TRUE;
					state = kPGPSendMailState_Error;
				}
			}
			break;

		case kPGPSendMailState_MAIL:
			sprintf(data, "MAIL FROM:<%s>\r\n", fromAddress);
			result = PGPSend(socket, data, strlen(data), kPGPSendFlagNone);
			break;

		case kPGPSendMailState_RCPT:
			sprintf(data, "RCPT TO:<%s>\r\n", toAddress);
			result = PGPSend(socket, data, strlen(data), kPGPSendFlagNone);
			break;

		case kPGPSendMailState_DATA:
			strcpy(data, "DATA\r\n");
			result = PGPSend(socket, data, strlen(data), kPGPSendFlagNone);
			break;

		case kPGPSendMailState_DATA_START:
			result = PGPReceive(socket, data, kDataSize, kPGPReceiveFlagNone);
			if (result != kPGPSockets_Error)
			{
				data[result] = 0;
				if (strncmp(data, "354", 3))
				{
					failed = TRUE;
					state = kPGPSendMailState_Error;
				}
			}
			break;

		case kPGPSendMailState_Message:
			result = PGPSend(socket, mailMessage, strlen(mailMessage), 
						kPGPSendFlagNone);
			break;

		case kPGPSendMailState_QUIT:
			strcpy(data, "QUIT\r\n");
			result = PGPSend(socket, data, strlen(data), kPGPSendFlagNone);
			break;

		case kPGPSendMailState_QUIT_OK:
			result = PGPReceive(socket, data, kDataSize, kPGPReceiveFlagNone);
			if (failed)
				err = kPGPError_NetworkOpFailed;
			break;
		}

		if (result == kPGPSockets_Error)
			err = PGPGetLastSocketsError();

		state++;
	}

	if (IsntNull(socket))
		PGPCloseSocket(socket);

	PGPSocketsDisposeThreadStorage(previousStorage);
	PGPSocketsCleanup();

	if (IsntNull(mailMessage))
		PGPFreeData(mailMessage);

	if (IsntNull(memoryMgr))
		PGPFreeMemoryMgr(memoryMgr);

	return err;
}


/*__Editor_settings____

	Local Variables:
	tab-width: 4
	End:
	vi: ts=4 sw=4
	vim: si
_____________________*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -