--- /dev/null
+//////////////////////////////////////////////////////////////////////\r
+// Original class CFastSmtp written by \r
+// christopher w. backen <immortal@cox.net>\r
+// More details at: http://www.codeproject.com/KB/IP/zsmtp.aspx\r
+// \r
+// Modifications:\r
+// 1. name of the class and some functions\r
+// 2. new functions added: SendData,ReceiveData and more\r
+// 3. authentication added\r
+// 4. attachments added\r
+// introduced by Jakub Piwowarczyk\r
+// More details at: http://www.codeproject.com/KB/mcpp/CSmtp.aspx\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+#include "CSmtp.h"\r
+\r
+#pragma warning(push)\r
+#pragma warning(disable:4786)\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+// Construction/Destruction\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+CSmtp::CSmtp()\r
+{\r
+ // Initialize variables\r
+ m_oError = CSMTP_NO_ERROR;\r
+ m_iXPriority = XPRIORITY_NORMAL;\r
+ m_iSMTPSrvPort = 0;\r
+\r
+ m_pcLocalHostName = NULL;\r
+ m_pcMailFrom = NULL;\r
+ m_pcNameFrom = NULL;\r
+ m_pcSubject = NULL;\r
+ m_pcMsgBody = NULL;\r
+ m_pcXMailer = NULL;\r
+ m_pcReplyTo = NULL;\r
+ m_pcLogin = NULL;\r
+ m_pcPassword = NULL;\r
+ m_pcSMTPSrvName = NULL;\r
+ \r
+ if((RecvBuf = new char[BUFFER_SIZE]) == NULL)\r
+ {\r
+ m_oError = CSMTP_LACK_OF_MEMORY;\r
+ return;\r
+ }\r
+ \r
+ if((SendBuf = new char[BUFFER_SIZE]) == NULL)\r
+ {\r
+ m_oError = CSMTP_LACK_OF_MEMORY;\r
+ return;\r
+ }\r
+ \r
+ // Initialize WinSock\r
+ WORD wVer = MAKEWORD(2,2); \r
+ if (WSAStartup(wVer,&wsaData) != NO_ERROR)\r
+ {\r
+ m_oError = CSMTP_WSA_STARTUP;\r
+ return;\r
+ }\r
+ if (LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) \r
+ {\r
+ m_oError = CSMTP_WSA_VER;\r
+ WSACleanup();\r
+ return;\r
+ }\r
+}\r
+\r
+CSmtp::~CSmtp()\r
+{\r
+ // Clear vectors\r
+ Recipients.clear();\r
+ CCRecipients.clear();\r
+ BCCRecipients.clear();\r
+ Attachments.clear();\r
+\r
+ // Free memory\r
+ if (m_pcLocalHostName)\r
+ delete[] m_pcLocalHostName;\r
+ if (m_pcMailFrom)\r
+ delete[] m_pcMailFrom;\r
+ if (m_pcNameFrom)\r
+ delete[] m_pcNameFrom;\r
+ if (m_pcSubject)\r
+ delete[] m_pcSubject;\r
+ if (m_pcMsgBody)\r
+ delete[] m_pcMsgBody;\r
+ if (m_pcXMailer)\r
+ delete[] m_pcXMailer;\r
+ if (m_pcReplyTo)\r
+ delete[] m_pcReplyTo;\r
+ if (m_pcLogin)\r
+ delete[] m_pcLogin;\r
+ if (m_pcPassword)\r
+ delete[] m_pcPassword;\r
+ if(SendBuf)\r
+ delete[] SendBuf;\r
+ if(RecvBuf)\r
+ delete[] RecvBuf;\r
+ \r
+ // Cleanup\r
+ WSACleanup();\r
+}\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+// Methods\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+bool CSmtp::AddAttachment(const char *path)\r
+{\r
+ std::string str(path);\r
+ Attachments.insert(Attachments.end(),str);\r
+ return true;\r
+}\r
+\r
+bool CSmtp::AddRecipient(const char *email, const char *name)\r
+{\r
+ assert(email);\r
+ \r
+ if(!email)\r
+ {\r
+ m_oError = CSMTP_UNDEF_RECIPENT_MAIL;\r
+ return false;\r
+ }\r
+\r
+ Recipent recipent;\r
+ recipent.Mail.insert(0,email);\r
+ name!=NULL ? recipent.Name.insert(0,name) : recipent.Name.insert(0,"");\r
+\r
+ Recipients.insert(Recipients.end(), recipent);\r
+\r
+ return true; \r
+}\r
+\r
+bool CSmtp::AddCCRecipient(const char *email, const char *name)\r
+{\r
+ assert(email);\r
+ \r
+ if(!email)\r
+ {\r
+ m_oError = CSMTP_UNDEF_RECIPENT_MAIL;\r
+ return false;\r
+ }\r
+\r
+ Recipent recipent;\r
+ recipent.Mail.insert(0,email);\r
+ name!=NULL ? recipent.Name.insert(0,name) : recipent.Name.insert(0,"");\r
+\r
+ CCRecipients.insert(CCRecipients.end(), recipent);\r
+\r
+ return true;\r
+}\r
+\r
+bool CSmtp::AddBCCRecipient(const char *email, const char *name)\r
+{\r
+ assert(email);\r
+ \r
+ if(!email)\r
+ {\r
+ m_oError = CSMTP_UNDEF_RECIPENT_MAIL;\r
+ return false;\r
+ }\r
+\r
+ Recipent recipent;\r
+ recipent.Mail.insert(0,email);\r
+ name!=NULL ? recipent.Name.insert(0,name) : recipent.Name.insert(0,"");\r
+\r
+ BCCRecipients.insert(BCCRecipients.end(), recipent);\r
+\r
+ return true;\r
+}\r
+\r
+bool CSmtp::Send()\r
+{\r
+ unsigned int i,rcpt_count,res,FileId;\r
+ char *FileBuf = NULL, *FileName = NULL;\r
+ FILE* hFile = NULL;\r
+ unsigned long int FileSize,TotalSize,MsgPart;\r
+\r
+ // ***** CONNECTING TO SMTP SERVER *****\r
+\r
+ assert(m_pcSMTPSrvName);\r
+\r
+ // connecting to remote host:\r
+ if( (hSocket = ConnectRemoteServer(m_pcSMTPSrvName, m_iSMTPSrvPort)) == INVALID_SOCKET ) \r
+ {\r
+ m_oError = CSMTP_WSA_INVALID_SOCKET;\r
+ return false;\r
+ }\r
+ Sleep(DELAY_IN_MS);\r
+ if(!ReceiveData())\r
+ return false;\r
+\r
+ switch(SmtpXYZdigits())\r
+ {\r
+ case 220:\r
+ break;\r
+ default:\r
+ m_oError = CSMTP_SERVER_NOT_READY;\r
+ return false;\r
+ }\r
+\r
+ // EHLO <SP> <domain> <CRLF>\r
+ sprintf(SendBuf,"EHLO %s\r\n",GetLocalHostName()!=NULL ? m_pcLocalHostName : "domain");\r
+ if(!SendData())\r
+ return false;\r
+ Sleep(DELAY_IN_MS);\r
+ if(!ReceiveData())\r
+ return false;\r
+\r
+ switch(SmtpXYZdigits())\r
+ {\r
+ case 250:\r
+ break;\r
+ default:\r
+ m_oError = CSMTP_COMMAND_EHLO;\r
+ return false;\r
+ }\r
+\r
+ // AUTH <SP> LOGIN <CRLF>\r
+ strcpy(SendBuf,"AUTH LOGIN\r\n");\r
+ if(!SendData())\r
+ return false;\r
+ Sleep(DELAY_IN_MS);\r
+ if(!ReceiveData())\r
+ return false;\r
+\r
+ switch(SmtpXYZdigits())\r
+ {\r
+ case 334:\r
+ break;\r
+ default:\r
+ m_oError = CSMTP_COMMAND_AUTH_LOGIN;\r
+ return false;\r
+ }\r
+\r
+ // send login:\r
+ if(!m_pcLogin)\r
+ {\r
+ m_oError = CSMTP_UNDEF_LOGIN;\r
+ return false;\r
+ }\r
+ std::string encoded_login = base64_encode(reinterpret_cast<const unsigned char*>(m_pcLogin),strlen(m_pcLogin));\r
+ sprintf(SendBuf,"%s\r\n",encoded_login.c_str());\r
+ if(!SendData())\r
+ return false;\r
+ Sleep(DELAY_IN_MS);\r
+ if(!ReceiveData())\r
+ return false;\r
+\r
+ switch(SmtpXYZdigits())\r
+ {\r
+ case 334:\r
+ break;\r
+ default:\r
+ m_oError = CSMTP_UNDEF_XYZ_RESPOMSE;\r
+ return false;\r
+ }\r
+ \r
+ // send password:\r
+ if(!m_pcPassword)\r
+ {\r
+ m_oError = CSMTP_UNDEF_PASSWORD;\r
+ return false;\r
+ }\r
+ std::string encoded_password = base64_encode(reinterpret_cast<const unsigned char*>(m_pcPassword),strlen(m_pcPassword));\r
+ sprintf(SendBuf,"%s\r\n",encoded_password.c_str());\r
+ if(!SendData())\r
+ return false;\r
+ Sleep(DELAY_IN_MS);\r
+ if(!ReceiveData())\r
+ return false;\r
+\r
+ switch(SmtpXYZdigits())\r
+ {\r
+ case 235:\r
+ break;\r
+ case 535:\r
+ m_oError = CSMTP_BAD_LOGIN_PASS;\r
+ return false;\r
+ default:\r
+ m_oError = CSMTP_UNDEF_XYZ_RESPOMSE;\r
+ return false;\r
+ }\r
+\r
+ // ***** SENDING E-MAIL *****\r
+ \r
+ // MAIL <SP> FROM:<reverse-path> <CRLF>\r
+ if(m_pcMailFrom == NULL)\r
+ {\r
+ m_oError = CSMTP_UNDEF_MAILFROM;\r
+ return false;\r
+ }\r
+ sprintf(SendBuf,"MAIL FROM:<%s>\r\n",m_pcMailFrom);\r
+ if(!SendData())\r
+ return false;\r
+ Sleep(DELAY_IN_MS);\r
+ if(!ReceiveData())\r
+ return false;\r
+\r
+ switch(SmtpXYZdigits())\r
+ {\r
+ case 250:\r
+ break;\r
+ default:\r
+ m_oError = CSMTP_COMMAND_MAIL_FROM;\r
+ return false;\r
+ }\r
+\r
+ // RCPT <SP> TO:<forward-path> <CRLF>\r
+ rcpt_count = Recipients.size();\r
+ for(i=0;i<Recipients.size();i++)\r
+ {\r
+ sprintf(SendBuf,"RCPT TO:<%s>\r\n",(Recipients.at(i).Mail).c_str());\r
+ if(!SendData())\r
+ return false;\r
+ Sleep(DELAY_IN_MS);\r
+ if(!ReceiveData())\r
+ return false;\r
+\r
+ switch(SmtpXYZdigits())\r
+ {\r
+ case 250:\r
+ break;\r
+ default:\r
+ m_oError = CSMTP_COMMAND_RCPT_TO;\r
+ rcpt_count--;\r
+ }\r
+ }\r
+ if(!rcpt_count)\r
+ return false;\r
+ for(i=0;i<CCRecipients.size();i++)\r
+ {\r
+ sprintf(SendBuf,"RCPT TO:<%s>\r\n",(CCRecipients.at(i).Mail).c_str());\r
+ if(!SendData())\r
+ return false;\r
+ Sleep(DELAY_IN_MS);\r
+ if(!ReceiveData())\r
+ return false;\r
+ }\r
+ for(i=0;i<BCCRecipients.size();i++)\r
+ {\r
+ sprintf(SendBuf,"RCPT TO:<%s>\r\n",(BCCRecipients.at(i).Mail).c_str());\r
+ if(!SendData())\r
+ return false;\r
+ Sleep(DELAY_IN_MS);\r
+ if(!ReceiveData())\r
+ return false;\r
+ }\r
+ \r
+ // DATA <CRLF>\r
+ strcpy(SendBuf,"DATA\r\n");\r
+ if(!SendData())\r
+ return false;\r
+ Sleep(DELAY_IN_MS);\r
+ if(!ReceiveData())\r
+ return false;\r
+ \r
+ switch(SmtpXYZdigits())\r
+ {\r
+ case 354:\r
+ break;\r
+ default:\r
+ m_oError = CSMTP_COMMAND_DATA;\r
+ return false;\r
+ }\r
+ \r
+ // send header(s)\r
+ if(!FormatHeader(SendBuf))\r
+ {\r
+ m_oError = CSMTP_UNDEF_MSG_HEADER;\r
+ return false;\r
+ }\r
+ if(!SendData())\r
+ return false;\r
+\r
+ // send text message\r
+ sprintf(SendBuf,"%s\r\n",m_pcMsgBody); // NOTICE: each line ends with <CRLF>\r
+ if(!SendData())\r
+ return false;\r
+\r
+ // next goes attachments (if they are)\r
+ if((FileBuf = new char[55]) == NULL)\r
+ {\r
+ m_oError = CSMTP_LACK_OF_MEMORY;\r
+ return false;\r
+ }\r
+ if((FileName = new char[255]) == NULL)\r
+ {\r
+ m_oError = CSMTP_LACK_OF_MEMORY;\r
+ return false;\r
+ }\r
+ TotalSize = 0;\r
+ for(FileId=0;FileId<Attachments.size();FileId++)\r
+ {\r
+ strcpy(FileName,Attachments[FileId].c_str());\r
+\r
+ sprintf(SendBuf,"--%s\r\n",BOUNDARY_TEXT);\r
+ strcat(SendBuf,"Content-Type: application/x-msdownload; name=\"");\r
+ strcat(SendBuf,&FileName[Attachments[FileId].find_last_of("\\") + 1]);\r
+ strcat(SendBuf,"\"\r\n");\r
+ strcat(SendBuf,"Content-Transfer-Encoding: base64\r\n");\r
+ strcat(SendBuf,"Content-Disposition: attachment; filename=\"");\r
+ strcat(SendBuf,&FileName[Attachments[FileId].find_last_of("\\") + 1]);\r
+ strcat(SendBuf,"\"\r\n");\r
+ strcat(SendBuf,"\r\n");\r
+\r
+ if(!SendData())\r
+ return false;\r
+\r
+ // opening the file:\r
+ hFile = fopen(FileName,"rb");\r
+ if(hFile == NULL)\r
+ {\r
+ m_oError = CSMTP_FILE_NOT_EXIST;\r
+ break;\r
+ }\r
+ \r
+ // checking file size:\r
+ FileSize = 0;\r
+ while(!feof(hFile))\r
+ FileSize += fread(FileBuf,sizeof(char),54,hFile);\r
+ TotalSize += FileSize;\r
+\r
+ // sending the file:\r
+ if(TotalSize/1024 > MSG_SIZE_IN_MB*1024)\r
+ m_oError = CSMTP_MSG_TOO_BIG;\r
+ else\r
+ {\r
+ fseek (hFile,0,SEEK_SET);\r
+\r
+ MsgPart = 0;\r
+ for(i=0;i<FileSize/54+1;i++)\r
+ {\r
+ res = fread(FileBuf,sizeof(char),54,hFile);\r
+ MsgPart ? strcat(SendBuf,base64_encode(reinterpret_cast<const unsigned char*>(FileBuf),res).c_str())\r
+ : strcpy(SendBuf,base64_encode(reinterpret_cast<const unsigned char*>(FileBuf),res).c_str());\r
+ strcat(SendBuf,"\r\n");\r
+ MsgPart += res + 2;\r
+ if(MsgPart >= BUFFER_SIZE/2)\r
+ { // sending part of the message\r
+ MsgPart = 0;\r
+ if(!SendData())\r
+ {\r
+ delete[] FileBuf;\r
+ delete[] FileName;\r
+ fclose(hFile);\r
+ return false;\r
+ }\r
+ }\r
+ }\r
+ if(MsgPart)\r
+ {\r
+ if(!SendData())\r
+ {\r
+ delete[] FileBuf;\r
+ delete[] FileName;\r
+ fclose(hFile);\r
+ return false;\r
+ }\r
+ }\r
+ }\r
+ fclose(hFile);\r
+ }\r
+ delete[] FileBuf;\r
+ delete[] FileName;\r
+ \r
+ // sending last message block (if there is one or more attachments)\r
+ if(Attachments.size())\r
+ {\r
+ sprintf(SendBuf,"\r\n--%s--\r\n",BOUNDARY_TEXT);\r
+ if(!SendData())\r
+ return false;\r
+ }\r
+ \r
+ // <CRLF> . <CRLF>\r
+ strcpy(SendBuf,"\r\n.\r\n");\r
+ if(!SendData())\r
+ return false;\r
+ Sleep(DELAY_IN_MS);\r
+ if(!ReceiveData())\r
+ return false;\r
+\r
+ switch(SmtpXYZdigits())\r
+ {\r
+ case 250:\r
+ break;\r
+ default:\r
+ m_oError = CSMTP_MSG_BODY_ERROR;\r
+ return false;\r
+ }\r
+\r
+ // ***** CLOSING CONNECTION *****\r
+ \r
+ // QUIT <CRLF>\r
+ strcpy(SendBuf,"QUIT\r\n");\r
+ if(!SendData())\r
+ return false;\r
+ Sleep(DELAY_IN_MS);\r
+ if(!ReceiveData())\r
+ return false;\r
+\r
+ switch(SmtpXYZdigits())\r
+ {\r
+ case 221:\r
+ break;\r
+ default:\r
+ m_oError = CSMTP_COMMAND_QUIT;\r
+ hSocket = NULL;\r
+ return false;\r
+ }\r
+\r
+ closesocket(hSocket);\r
+ hSocket = NULL;\r
+ return true;\r
+}\r
+\r
+SOCKET CSmtp::ConnectRemoteServer(const char *server,const unsigned short port)\r
+{\r
+ short nProtocolPort;\r
+ LPHOSTENT lpHostEnt;\r
+ LPSERVENT lpServEnt;\r
+ SOCKADDR_IN sockAddr;\r
+ SOCKET hServerSocket = INVALID_SOCKET;\r
+ struct in_addr addr;\r
+ \r
+ // If the user input is an alpha name for the host, use gethostbyname()\r
+ // If not, get host by addr (assume IPv4)\r
+ if(isalpha(server[0]))\r
+ lpHostEnt = gethostbyname(server);\r
+ else\r
+ {\r
+ addr.s_addr = inet_addr(server);\r
+ if(addr.s_addr == INADDR_NONE) \r
+ {\r
+ m_oError = CSMTP_BAD_IPV4_ADDR;\r
+ return INVALID_SOCKET;\r
+ } \r
+ else\r
+ lpHostEnt = gethostbyaddr((char *) &addr, 4, AF_INET);\r
+ }\r
+\r
+ if(lpHostEnt != NULL)\r
+ {\r
+ if((hServerSocket = socket(PF_INET, SOCK_STREAM,0)) != INVALID_SOCKET)\r
+ {\r
+ if(port != NULL)\r
+ nProtocolPort = htons(port);\r
+ else\r
+ {\r
+ lpServEnt = getservbyname("mail", 0);\r
+ if (lpServEnt == NULL)\r
+ nProtocolPort = htons(25);\r
+ else \r
+ nProtocolPort = lpServEnt->s_port;\r
+ }\r
+ \r
+ sockAddr.sin_family = AF_INET;\r
+ sockAddr.sin_port = nProtocolPort;\r
+ sockAddr.sin_addr = *((LPIN_ADDR)*lpHostEnt->h_addr_list);\r
+ if(connect(hServerSocket,(PSOCKADDR)&sockAddr,sizeof(sockAddr)) == SOCKET_ERROR)\r
+ {\r
+ m_oError = CSMTP_WSA_CONNECT;\r
+ hServerSocket = INVALID_SOCKET;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ m_oError = CSMTP_WSA_INVALID_SOCKET;\r
+ return INVALID_SOCKET;\r
+ }\r
+ }\r
+ else\r
+ {\r
+ m_oError = CSMTP_WSA_GETHOSTBY_NAME_ADDR;\r
+ return INVALID_SOCKET;\r
+ }\r
+\r
+ return hServerSocket;\r
+}\r
+\r
+int CSmtp::SmtpXYZdigits()\r
+{\r
+ assert(RecvBuf);\r
+ if(RecvBuf == NULL)\r
+ return 0;\r
+ return (RecvBuf[0]-'0')*100 + (RecvBuf[1]-'0')*10 + RecvBuf[2]-'0';\r
+}\r
+\r
+bool CSmtp::FormatHeader(char* header)\r
+{\r
+ int i,s = 0;\r
+ TCHAR szDate[500];\r
+ TCHAR sztTime[500];\r
+ char *to = NULL;\r
+ char *cc = NULL;\r
+ char *bcc = NULL;\r
+\r
+ // check for at least one recipient\r
+ if(Recipients.size())\r
+ {\r
+ for (unsigned int i=s=0;i<Recipients.size();i++)\r
+ s += Recipients[i].Mail.size() + Recipients[i].Name.size() + 3;\r
+ if (s == 0) \r
+ s = 1;\r
+ if((to = new char[s]) == NULL)\r
+ {\r
+ m_oError = CSMTP_LACK_OF_MEMORY;\r
+ return false;\r
+ }\r
+\r
+ to[0] = '\0';\r
+ for (i=0;i<Recipients.size();i++)\r
+ {\r
+ i > 0 ? strcat(to,","):strcpy(to,"");\r
+ strcat(to,Recipients[i].Name.c_str());\r
+ strcat(to,"<");\r
+ strcat(to,Recipients[i].Mail.c_str());\r
+ strcat(to,">");\r
+ }\r
+ }\r
+ else\r
+ {\r
+ m_oError = CSMTP_UNDEF_RECIPENTS;\r
+ return false;\r
+ }\r
+\r
+ if(CCRecipients.size())\r
+ {\r
+ for (i=s=0;i<CCRecipients.size();i++)\r
+ s += CCRecipients[i].Mail.size() + CCRecipients[i].Name.size() + 3;\r
+ if (s == 0)\r
+ s = 1;\r
+ if((cc = new char[s]) == NULL)\r
+ {\r
+ m_oError = CSMTP_LACK_OF_MEMORY;\r
+ delete[] to;\r
+ return false;\r
+ }\r
+\r
+ cc[0] = '\0';\r
+ for (i=0;i<CCRecipients.size();i++)\r
+ {\r
+ i > 0 ? strcat(cc,","):strcpy(cc,"");\r
+ strcat(cc,CCRecipients[i].Name.c_str());\r
+ strcat(cc,"<");\r
+ strcat(cc,CCRecipients[i].Mail.c_str());\r
+ strcat(cc,">");\r
+ }\r
+ }\r
+\r
+ if(BCCRecipients.size())\r
+ {\r
+ for (i=s=0;i<BCCRecipients.size();i++)\r
+ s += BCCRecipients[i].Mail.size() + BCCRecipients[i].Name.size() + 3;\r
+ if(s == 0)\r
+ s=1;\r
+ if((bcc = new char[s]) == NULL)\r
+ {\r
+ m_oError = CSMTP_LACK_OF_MEMORY;\r
+ delete[] to;\r
+ delete[] cc;\r
+ return false;\r
+ }\r
+\r
+ bcc[0] = '\0';\r
+ for (i=0;i<BCCRecipients.size();i++)\r
+ {\r
+ i > 0 ? strcat(bcc,","):strcpy(bcc,"");\r
+ strcat(bcc,BCCRecipients[i].Name.c_str());\r
+ strcat(bcc,"<");\r
+ strcat(bcc,BCCRecipients[i].Mail.c_str());\r
+ strcat(bcc,">");\r
+ }\r
+ }\r
+ \r
+ // Date: <SP> <dd> <SP> <mon> <SP> <yy> <SP> <hh> ":" <mm> ":" <ss> <SP> <zone> <CRLF>\r
+ SYSTEMTIME st={0};\r
+ ::GetSystemTime(&st);\r
+ ::GetDateFormat(MAKELCID(0x0409,SORT_DEFAULT),0,&st,"ddd\',\' dd MMM yyyy",szDate,sizeof(szDate));\r
+ ::GetTimeFormat(MAKELCID(0x0409,SORT_DEFAULT),TIME_FORCE24HOURFORMAT,&st,"HH\':\'mm\':\'ss",sztTime,sizeof(sztTime));\r
+ sprintf(header,"Date: %s %s\r\n", szDate, sztTime); \r
+ \r
+ // From: <SP> <sender> <SP> "<" <sender-email> ">" <CRLF>\r
+ if(m_pcMailFrom == NULL)\r
+ {\r
+ m_oError = CSMTP_UNDEF_MAILFROM;\r
+ delete[] to;\r
+ delete[] cc;\r
+ delete[] bcc;\r
+ return false;\r
+ }\r
+ strcat(header,"From: "); \r
+ if(m_pcNameFrom)\r
+ strcat(header, m_pcNameFrom);\r
+ strcat(header," <");\r
+ strcat(header,m_pcMailFrom);\r
+ strcat(header, ">\r\n");\r
+\r
+ // X-Mailer: <SP> <xmailer-app> <CRLF>\r
+ if (m_pcXMailer != NULL)\r
+ {\r
+ strcat(header,"X-Mailer: ");\r
+ strcat(header, m_pcXMailer);\r
+ strcat(header, "\r\n");\r
+ }\r
+\r
+ // Reply-To: <SP> <reverse-path> <CRLF>\r
+ if(m_pcReplyTo != NULL)\r
+ {\r
+ strcat(header, "Reply-To: ");\r
+ strcat(header, m_pcReplyTo);\r
+ strcat(header, "\r\n");\r
+ }\r
+\r
+ // X-Priority: <SP> <number> <CRLF>\r
+ switch(m_iXPriority)\r
+ {\r
+ case XPRIORITY_HIGH:\r
+ strcat(header,"X-Priority: 2 (High)\r\n");\r
+ break;\r
+ case XPRIORITY_NORMAL:\r
+ strcat(header,"X-Priority: 3 (Normal)\r\n");\r
+ break;\r
+ case XPRIORITY_LOW:\r
+ strcat(header,"X-Priority: 4 (Low)\r\n");\r
+ break;\r
+ default:\r
+ strcat(header,"X-Priority: 3 (Normal)\r\n");\r
+ }\r
+\r
+ // To: <SP> <remote-user-mail> <CRLF>\r
+ strcat(header,"To: ");\r
+ strcat(header, to);\r
+ strcat(header, "\r\n");\r
+\r
+ // Cc: <SP> <remote-user-mail> <CRLF>\r
+ if(CCRecipients.size())\r
+ {\r
+ strcat(header,"Cc: ");\r
+ strcat(header, cc);\r
+ strcat(header, "\r\n");\r
+ }\r
+\r
+ if(BCCRecipients.size())\r
+ {\r
+ strcat(header,"Bcc: ");\r
+ strcat(header, bcc);\r
+ strcat(header, "\r\n");\r
+ }\r
+\r
+ // Subject: <SP> <subject-text> <CRLF>\r
+ if(m_pcSubject == NULL) \r
+ {\r
+ m_oError = CSMTP_UNDEF_SUBJECT;\r
+ strcat(header, "Subject: ");\r
+ }\r
+ else\r
+ {\r
+ strcat(header, "Subject: ");\r
+ strcat(header, m_pcSubject);\r
+ }\r
+ strcat(header, "\r\n");\r
+ \r
+ // MIME-Version: <SP> 1.0 <CRLF>\r
+ strcat(header,"MIME-Version: 1.0\r\n");\r
+ if(!Attachments.size())\r
+ { // no attachments\r
+ strcat(header,"Content-type: text/plain; charset=US-ASCII\r\n");\r
+ strcat(header,"Content-Transfer-Encoding: 7bit\r\n");\r
+ strcat(SendBuf,"\r\n");\r
+ }\r
+ else\r
+ { // there is one or more attachments\r
+ strcat(header,"Content-Type: multipart/mixed; boundary=\"");\r
+ strcat(header,BOUNDARY_TEXT);\r
+ strcat(header,"\"\r\n");\r
+ strcat(header,"\r\n");\r
+ // first goes text message\r
+ strcat(SendBuf,"--");\r
+ strcat(SendBuf,BOUNDARY_TEXT);\r
+ strcat(SendBuf,"\r\n");\r
+ strcat(SendBuf,"Content-type: text/plain; charset=US-ASCII\r\n");\r
+ strcat(SendBuf,"Content-Transfer-Encoding: 7bit\r\n");\r
+ strcat(SendBuf,"\r\n");\r
+ }\r
+ \r
+ // clean up\r
+ delete[] to;\r
+ delete[] cc;\r
+ delete[] bcc;\r
+ \r
+ // done \r
+ return true; \r
+}\r
+\r
+bool CSmtp::ReceiveData()\r
+{\r
+ assert(RecvBuf);\r
+\r
+ int res;\r
+\r
+ if(RecvBuf == NULL)\r
+ return false;\r
+ \r
+ if( (res = recv(hSocket,RecvBuf,BUFFER_SIZE,0)) == SOCKET_ERROR )\r
+ {\r
+ m_oError = CSMTP_WSA_RECV;\r
+ return false;\r
+ }\r
+ if(res == 0)\r
+ {\r
+ m_oError = CSMTP_CONNECTION_CLOSED;\r
+ return false;\r
+ }\r
+ RecvBuf[res] = '\0';\r
+\r
+ return true;\r
+}\r
+\r
+bool CSmtp::SendData()\r
+{\r
+ assert(SendBuf);\r
+\r
+ int idx = 0,res,nLeft = strlen(SendBuf);\r
+ while(nLeft > 0)\r
+ {\r
+ if( res = send(hSocket,&SendBuf[idx],nLeft,0) == SOCKET_ERROR)\r
+ {\r
+ m_oError = CSMTP_WSA_SEND;\r
+ return false;\r
+ }\r
+ if(!res)\r
+ break;\r
+ nLeft -= res;\r
+ idx += res;\r
+ }\r
+ return true;\r
+}\r
+\r
+CSmtpError CSmtp::GetLastError()\r
+{\r
+ return m_oError;\r
+}\r
+\r
+/*\r
+const char* const CSmtp::GetLocalHostIP()\r
+{\r
+ in_addr *iaHost = NULL;\r
+ HOSTENT *pHe = NULL;\r
+ \r
+ if (m_pcIPAddr)\r
+ delete[] m_pcIPAddr;\r
+ \r
+ if(gethostname(m_pcHostName,255) != SOCKET_ERROR)\r
+ {\r
+ pHe = gethostbyname(m_pcHostName);\r
+ if (pHe != NULL) \r
+ {\r
+ for (int i=0;pHe->h_addr_list[i] != 0;i++)\r
+ {\r
+ iaHost = (LPIN_ADDR)pHe->h_addr_list[i];\r
+ m_pcIPAddr = inet_ntoa(*iaHost);\r
+ }\r
+ } \r
+ } \r
+ else \r
+ {\r
+ m_oError = CSMTP_WSA_GETHOSTBY_NAME_ADDR;\r
+ m_pcIPAddr = NULL;\r
+ }\r
+ \r
+ return m_pcIPAddr;\r
+}\r
+*/\r
+\r
+const char* const CSmtp::GetLocalHostName() \r
+{\r
+ if(m_pcLocalHostName)\r
+ delete[] m_pcLocalHostName;\r
+ if((m_pcLocalHostName = new char[255]) == NULL)\r
+ {\r
+ m_oError = CSMTP_LACK_OF_MEMORY;\r
+ return NULL;\r
+ }\r
+ if(gethostname((char FAR*)m_pcLocalHostName,255) == SOCKET_ERROR)\r
+ m_oError = CSMTP_WSA_HOSTNAME;\r
+ return m_pcLocalHostName;\r
+}\r
+\r
+unsigned const int CSmtp::GetBCCRecipientCount()\r
+{\r
+ return BCCRecipients.size();\r
+}\r
+\r
+unsigned const int CSmtp::GetCCRecipientCount() \r
+{\r
+ return CCRecipients.size();\r
+}\r
+\r
+const char* const CSmtp::GetMessageBody() \r
+{\r
+ return m_pcMsgBody;\r
+}\r
+\r
+unsigned const int CSmtp::GetRecipientCount()\r
+{\r
+ return Recipients.size();\r
+}\r
+\r
+const char* const CSmtp::GetReplyTo() \r
+{\r
+ return m_pcReplyTo;\r
+}\r
+\r
+const char* const CSmtp::GetMailFrom() \r
+{\r
+ return m_pcMailFrom;\r
+}\r
+\r
+const char* const CSmtp::GetSenderName() \r
+{\r
+ return m_pcNameFrom;\r
+}\r
+\r
+const char* const CSmtp::GetSubject() \r
+{\r
+ return m_pcSubject;\r
+}\r
+\r
+const char* const CSmtp::GetXMailer() \r
+{\r
+ return m_pcXMailer;\r
+}\r
+\r
+CSmptXPriority CSmtp::GetXPriority()\r
+{\r
+ return m_iXPriority;\r
+}\r
+\r
+void CSmtp::SetXPriority(CSmptXPriority priority)\r
+{\r
+ m_iXPriority = priority;\r
+}\r
+\r
+void CSmtp::SetMessageBody(const char *body)\r
+{\r
+ assert(body);\r
+ int s = strlen(body);\r
+ if (m_pcMsgBody)\r
+ delete[] m_pcMsgBody;\r
+ if((m_pcMsgBody = new char[s+1]) == NULL)\r
+ {\r
+ m_oError = CSMTP_LACK_OF_MEMORY;\r
+ return;\r
+ }\r
+ strcpy(m_pcMsgBody, body); \r
+}\r
+\r
+void CSmtp::SetReplyTo(const char *replyto)\r
+{\r
+ assert(replyto);\r
+ int s = strlen(replyto);\r
+ if (m_pcReplyTo)\r
+ delete[] m_pcReplyTo;\r
+ if((m_pcReplyTo = new char[s+1]) == NULL)\r
+ {\r
+ m_oError = CSMTP_LACK_OF_MEMORY;\r
+ return;\r
+ }\r
+ strcpy(m_pcReplyTo, replyto);\r
+}\r
+\r
+void CSmtp::SetSenderMail(const char *email)\r
+{\r
+ assert(email);\r
+ int s = strlen(email);\r
+ if (m_pcMailFrom)\r
+ delete[] m_pcMailFrom;\r
+ if((m_pcMailFrom = new char[s+1]) == NULL)\r
+ {\r
+ m_oError = CSMTP_LACK_OF_MEMORY;\r
+ return;\r
+ }\r
+ strcpy(m_pcMailFrom, email); \r
+}\r
+\r
+void CSmtp::SetSenderName(const char *name)\r
+{\r
+ assert(name);\r
+ int s = strlen(name);\r
+ if (m_pcNameFrom)\r
+ delete[] m_pcNameFrom;\r
+ if((m_pcNameFrom = new char[s+1]) == NULL)\r
+ {\r
+ m_oError = CSMTP_LACK_OF_MEMORY;\r
+ return;\r
+ }\r
+ strcpy(m_pcNameFrom, name);\r
+}\r
+\r
+void CSmtp::SetSubject(const char *subject)\r
+{\r
+ assert(subject);\r
+ int s = strlen(subject);\r
+ if (m_pcSubject)\r
+ delete[] m_pcSubject;\r
+ m_pcSubject = new char[s+1];\r
+ strcpy(m_pcSubject, subject);\r
+}\r
+\r
+void CSmtp::SetXMailer(const char *xmailer)\r
+{\r
+ assert(xmailer);\r
+ int s = strlen(xmailer);\r
+ if (m_pcXMailer)\r
+ delete[] m_pcXMailer;\r
+ if((m_pcXMailer = new char[s+1]) == NULL)\r
+ {\r
+ m_oError = CSMTP_LACK_OF_MEMORY;\r
+ return;\r
+ }\r
+ strcpy(m_pcXMailer, xmailer);\r
+}\r
+\r
+void CSmtp::SetLogin(const char *login)\r
+{\r
+ assert(login);\r
+ int s = strlen(login);\r
+ if (m_pcLogin)\r
+ delete[] m_pcLogin;\r
+ if((m_pcLogin = new char[s+1]) == NULL)\r
+ {\r
+ m_oError = CSMTP_LACK_OF_MEMORY;\r
+ return;\r
+ }\r
+ strcpy(m_pcLogin, login);\r
+}\r
+\r
+void CSmtp::SetPassword(const char *password)\r
+{\r
+ assert(password);\r
+ int s = strlen(password);\r
+ if (m_pcPassword)\r
+ delete[] m_pcPassword;\r
+ if((m_pcPassword = new char[s+1]) == NULL)\r
+ {\r
+ m_oError = CSMTP_LACK_OF_MEMORY;\r
+ return;\r
+ }\r
+ strcpy(m_pcPassword, password);\r
+}\r
+\r
+void CSmtp::SetSMTPServer(const char* SrvName,const unsigned short SrvPort)\r
+{\r
+ assert(SrvName);\r
+ m_iSMTPSrvPort = SrvPort;\r
+ int s = strlen(SrvName);\r
+ if(m_pcSMTPSrvName)\r
+ delete[] m_pcSMTPSrvName;\r
+ if((m_pcSMTPSrvName = new char[s+1]) == NULL)\r
+ {\r
+ m_oError = CSMTP_LACK_OF_MEMORY;\r
+ return;\r
+ }\r
+ strcpy(m_pcSMTPSrvName, SrvName);\r
+}\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+// Friends\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+char* GetErrorText(CSmtpError ErrorId)\r
+{\r
+ switch(ErrorId)\r
+ {\r
+ case CSMTP_NO_ERROR:\r
+ return "";\r
+ case CSMTP_WSA_STARTUP:\r
+ return "Unable to initialise winsock2.";\r
+ case CSMTP_WSA_VER:\r
+ return "Wrong version of the winsock2.";\r
+ case CSMTP_WSA_SEND:\r
+ return "Function send() failed.";\r
+ case CSMTP_WSA_RECV:\r
+ return "Function recv() failed.";\r
+ case CSMTP_WSA_CONNECT:\r
+ return "Function connect failed.";\r
+ case CSMTP_WSA_GETHOSTBY_NAME_ADDR:\r
+ return "Functions gethostbyname() or gethostbyaddr() failed.";\r
+ case CSMTP_WSA_INVALID_SOCKET:\r
+ return "Invalid winsock2 socket.";\r
+ case CSMTP_WSA_HOSTNAME:\r
+ return "Function hostname() failed.";\r
+ case CSMTP_BAD_IPV4_ADDR:\r
+ return "Improper IPv4 address.";\r
+ case CSMTP_UNDEF_MSG_HEADER:\r
+ return "Undefined message header.";\r
+ case CSMTP_UNDEF_MAILFROM:\r
+ return "Undefined from is the mail.";\r
+ case CSMTP_UNDEF_SUBJECT:\r
+ return "Undefined message subject.";\r
+ case CSMTP_UNDEF_RECIPENTS:\r
+ return "Undefined at least one reciepent.";\r
+ case CSMTP_UNDEF_RECIPENT_MAIL:\r
+ return "Undefined recipent mail.";\r
+ case CSMTP_UNDEF_LOGIN:\r
+ return "Undefined user login.";\r
+ case CSMTP_UNDEF_PASSWORD:\r
+ return "Undefined user password.";\r
+ case CSMTP_COMMAND_MAIL_FROM:\r
+ return "Server returned error after sending MAIL FROM.";\r
+ case CSMTP_COMMAND_EHLO:\r
+ return "Server returned error after sending EHLO.";\r
+ case CSMTP_COMMAND_AUTH_LOGIN:\r
+ return "Server returned error after sending AUTH LOGIN.";\r
+ case CSMTP_COMMAND_DATA:\r
+ return "Server returned error after sending DATA.";\r
+ case CSMTP_COMMAND_QUIT:\r
+ return "Server returned error after sending QUIT.";\r
+ case CSMTP_COMMAND_RCPT_TO:\r
+ return "Server returned error after sending RCPT TO.";\r
+ case CSMTP_MSG_BODY_ERROR:\r
+ return "Error in message body";\r
+ case CSMTP_CONNECTION_CLOSED:\r
+ return "Server has closed the connection.";\r
+ case CSMTP_SERVER_NOT_READY:\r
+ return "Server is not ready.";\r
+ case CSMTP_FILE_NOT_EXIST:\r
+ return "File not exist.";\r
+ case CSMTP_MSG_TOO_BIG:\r
+ return "Message is too big.";\r
+ case CSMTP_BAD_LOGIN_PASS:\r
+ return "Bad login or password.";\r
+ case CSMTP_UNDEF_XYZ_RESPOMSE:\r
+ return "Undefined xyz SMTP response.";\r
+ case CSMTP_LACK_OF_MEMORY:\r
+ return "Lack of memory.";\r
+ default:\r
+ return "Undefined error id.";\r
+ }\r
+}\r
+\r
+#pragma warning(pop)\r