#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 //To: comicgum //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_