181 lines
4.4 KiB
C++
181 lines
4.4 KiB
C++
#ifndef EMAIL_SENDER__H_
|
|
#define EMAIL_SENDER__H_
|
|
|
|
#ifdef _WIN32
|
|
#pragma once
|
|
#endif
|
|
|
|
|
|
class HEmailSender : public HThread
|
|
{
|
|
public:
|
|
HEmailSender(const HString & strIp, u_short nPort, const HString & strSubject, const HString & strMessage, const HString & strFrom, const HStrList & listTo)
|
|
: HThread(true)
|
|
{
|
|
HLOGF(HLOG_INFO5, "INFO, EmailSender, new, %s, %d, %s, %s, %s\n", strIp.psz(), nPort, strFrom.psz(), strSubject.psz(), strMessage.psz());
|
|
|
|
m_strIp = strIp;
|
|
m_nPort = nPort;
|
|
m_strSubject = strSubject;
|
|
m_strMessage = strMessage;
|
|
m_strFrom = strFrom;
|
|
m_listTo = listTo;
|
|
|
|
Begin();
|
|
}
|
|
|
|
~HEmailSender() {}
|
|
|
|
bool SendCompleteSize(SOCKET sock, const char * pszPacket, size_t nPacketSize)
|
|
{
|
|
HLOGF(HLOG_ERROR, "[TRACE], EmailSender, tx, %s", pszPacket);
|
|
|
|
off_t nSentSize;
|
|
const char * pszPacketOffset = pszPacket;
|
|
while (nPacketSize > 0)
|
|
{
|
|
nSentSize = send(sock, pszPacketOffset, nPacketSize, 0);
|
|
if (nSentSize <= 0)
|
|
{
|
|
HLOG(HLOG_ERROR, "[ERROR], EmailSender, Failed to send.\n");
|
|
return false;
|
|
}
|
|
|
|
nPacketSize -= nSentSize;
|
|
pszPacketOffset += nSentSize;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool RecvCompleteResponse(SOCKET sock)
|
|
{
|
|
int nRecvSize;
|
|
char pBuffer[8192];
|
|
char * pBufferOffset = pBuffer;
|
|
for (;;)
|
|
{
|
|
nRecvSize = recv(sock, pBufferOffset, 8191, 0);
|
|
if (nRecvSize <= 0 || (pBuffer[0] != '2' && pBuffer[0] != '3')) // '2' is error return
|
|
break;
|
|
|
|
pBufferOffset[nRecvSize] = '\0';
|
|
|
|
if (strstr(pBuffer, "\r\n"))
|
|
{
|
|
HLOGF(HLOG_ERROR, "[TRACE], EmailSender, rx, %s", pBuffer);
|
|
return true;
|
|
}
|
|
|
|
pBufferOffset += nRecvSize;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void Main()
|
|
{
|
|
// send message /////////////////////////////////////
|
|
SOCKET sockClient;
|
|
|
|
// create socket
|
|
sockClient = socket(AF_INET, SOCK_STREAM, 0);
|
|
if (sockClient == INVALID_SOCKET)
|
|
{
|
|
HLOG(HLOG_ERROR, "[ERROR], EmailSender, Failed to socket()\n");
|
|
return;
|
|
}
|
|
|
|
// set destination address
|
|
struct sockaddr_in sai;
|
|
memset(&sai, '\0', sizeof(struct sockaddr_in));
|
|
|
|
sai.sin_addr.s_addr = inet_addr(m_strIp);
|
|
sai.sin_family = AF_INET;
|
|
sai.sin_port = htons(m_nPort);
|
|
|
|
HLOG(HLOG_INFO5, "INFO, EmailSender, Trying to connect...\n");
|
|
|
|
if (connect(sockClient, (struct sockaddr *)&sai, sizeof(struct sockaddr)) == SOCKET_ERROR)
|
|
{
|
|
HLOGF(HLOG_ERROR, "[ERROR], EmailSender, connect timeout. socket = %d\n", sockClient);
|
|
return;
|
|
}
|
|
|
|
HLOG(HLOG_INFO5, "INFO, EmailSender, Connected\n");
|
|
|
|
//HELO 14.34.59.93
|
|
//MAIL FROM: sender@nate.com
|
|
//RCPT TO: comicgum@nate.com
|
|
//DATA
|
|
//From: tester<sender@nate.com>
|
|
//To: comicgum<comicgum@nate.com>
|
|
//Subject: test subject
|
|
//Test Message...
|
|
//.
|
|
//QUIT
|
|
|
|
size_t nSendSize;
|
|
char szCommand[16384];
|
|
|
|
if (RecvCompleteResponse(sockClient) == false)
|
|
return;
|
|
|
|
nSendSize = sprintf(szCommand, "HELO %s\r\n", m_strIp.psz()); // SMTP server address
|
|
if (SendCompleteSize(sockClient, szCommand, nSendSize) == false || RecvCompleteResponse(sockClient) == false)
|
|
return;
|
|
|
|
nSendSize = sprintf(szCommand, "MAIL FROM: %s\r\n", m_strFrom.psz()); // sender email address
|
|
if (SendCompleteSize(sockClient, szCommand, nSendSize) == false || RecvCompleteResponse(sockClient) == false)
|
|
return;
|
|
|
|
HString strTo;
|
|
HStrList::iterator iter = m_listTo.begin();
|
|
for (;;)
|
|
{
|
|
nSendSize = sprintf(szCommand, "RCPT TO: %s\r\n", iter->psz()); // return email address
|
|
if (SendCompleteSize(sockClient, szCommand, nSendSize) == false || RecvCompleteResponse(sockClient) == false)
|
|
return;
|
|
|
|
strTo += iter->psz();
|
|
|
|
if (++iter == m_listTo.end())
|
|
break;
|
|
|
|
strTo += ",";
|
|
}
|
|
|
|
nSendSize = sprintf(szCommand, "DATA\r\n"); // messgae start
|
|
if (SendCompleteSize(sockClient, szCommand, nSendSize) == false || RecvCompleteResponse(sockClient) == false)
|
|
return;
|
|
|
|
nSendSize = sprintf(szCommand, //"%s\r\n",
|
|
"From: LibProxy3<%s>\r\n"
|
|
"To: %s\r\n"
|
|
"Subject: %s\r\n"
|
|
"%s\r\n.\r\n", m_strFrom.psz(), strTo.psz(), m_strSubject.psz(), m_strMessage.psz()); // message
|
|
if (SendCompleteSize(sockClient, szCommand, nSendSize) == false || RecvCompleteResponse(sockClient) == false)
|
|
return;
|
|
|
|
nSendSize = sprintf(szCommand, "QUIT\r\n"); // end
|
|
if (SendCompleteSize(sockClient, szCommand, nSendSize) == false || RecvCompleteResponse(sockClient) == false)
|
|
return;
|
|
|
|
#ifdef _WIN32
|
|
closesocket(sockClient);
|
|
#else
|
|
closesocket(sockClient);
|
|
#endif
|
|
}
|
|
|
|
protected:
|
|
HString m_strIp;
|
|
u_short m_nPort;
|
|
HString m_strSubject;
|
|
HString m_strMessage;
|
|
HString m_strFrom;
|
|
HStrList m_listTo;
|
|
};
|
|
|
|
#endif // EMAIL_SENDER__H_
|