📄 pgpsendmail.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 + -