Merge branch 'restructure-tree'
[TortoiseGit.git] / src / Utils / CSmtp.cpp
blob47aef42ece6ac68841a20ec381da10a5d32cba2a
1 //////////////////////////////////////////////////////////////////////
2 // Original class CFastSmtp written by
3 // christopher w. backen <immortal@cox.net>
4 // More details at: http://www.codeproject.com/KB/IP/zsmtp.aspx
5 //
6 // Modifications:
7 // 1. name of the class and some functions
8 // 2. new functions added: SendData,ReceiveData and more
9 // 3. authentication added
10 // 4. attachments added
11 // introduced by Jakub Piwowarczyk
12 // More details at: http://www.codeproject.com/KB/mcpp/CSmtp.aspx
13 //////////////////////////////////////////////////////////////////////
15 #include "CSmtp.h"
17 #pragma warning(push)
18 #pragma warning(disable:4786)
20 //////////////////////////////////////////////////////////////////////
21 // Construction/Destruction
22 //////////////////////////////////////////////////////////////////////
24 CSmtp::CSmtp()
26 // Initialize variables
27 m_oError = CSMTP_NO_ERROR;
28 m_iXPriority = XPRIORITY_NORMAL;
29 m_iSMTPSrvPort = 0;
31 m_pcLocalHostName = NULL;
32 m_pcMailFrom = NULL;
33 m_pcNameFrom = NULL;
34 m_pcSubject = NULL;
35 m_pcMsgBody = NULL;
36 m_pcXMailer = NULL;
37 m_pcReplyTo = NULL;
38 m_pcLogin = NULL;
39 m_pcPassword = NULL;
40 m_pcSMTPSrvName = NULL;
42 if((RecvBuf = new char[BUFFER_SIZE]) == NULL)
44 m_oError = CSMTP_LACK_OF_MEMORY;
45 return;
48 if((SendBuf = new char[BUFFER_SIZE]) == NULL)
50 m_oError = CSMTP_LACK_OF_MEMORY;
51 return;
54 // Initialize WinSock
55 WORD wVer = MAKEWORD(2,2);
56 if (WSAStartup(wVer,&wsaData) != NO_ERROR)
58 m_oError = CSMTP_WSA_STARTUP;
59 return;
61 if (LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )
63 m_oError = CSMTP_WSA_VER;
64 WSACleanup();
65 return;
69 CSmtp::~CSmtp()
71 // Clear vectors
72 Recipients.clear();
73 CCRecipients.clear();
74 BCCRecipients.clear();
75 Attachments.clear();
77 // Free memory
78 if (m_pcLocalHostName)
79 delete[] m_pcLocalHostName;
80 if (m_pcMailFrom)
81 delete[] m_pcMailFrom;
82 if (m_pcNameFrom)
83 delete[] m_pcNameFrom;
84 if (m_pcSubject)
85 delete[] m_pcSubject;
86 if (m_pcMsgBody)
87 delete[] m_pcMsgBody;
88 if (m_pcXMailer)
89 delete[] m_pcXMailer;
90 if (m_pcReplyTo)
91 delete[] m_pcReplyTo;
92 if (m_pcLogin)
93 delete[] m_pcLogin;
94 if (m_pcPassword)
95 delete[] m_pcPassword;
96 if(SendBuf)
97 delete[] SendBuf;
98 if(RecvBuf)
99 delete[] RecvBuf;
101 // Cleanup
102 WSACleanup();
105 //////////////////////////////////////////////////////////////////////
106 // Methods
107 //////////////////////////////////////////////////////////////////////
109 bool CSmtp::AddAttachment(const char *path)
111 std::string str(path);
112 Attachments.insert(Attachments.end(),str);
113 return true;
116 bool CSmtp::AddRecipient(const char *email, const char *name)
118 assert(email);
120 if(!email)
122 m_oError = CSMTP_UNDEF_RECIPENT_MAIL;
123 return false;
126 Recipent recipent;
127 recipent.Mail.insert(0,email);
128 name!=NULL ? recipent.Name.insert(0,name) : recipent.Name.insert(0,"");
130 Recipients.insert(Recipients.end(), recipent);
132 return true;
135 bool CSmtp::AddCCRecipient(const char *email, const char *name)
137 assert(email);
139 if(!email)
141 m_oError = CSMTP_UNDEF_RECIPENT_MAIL;
142 return false;
145 Recipent recipent;
146 recipent.Mail.insert(0,email);
147 name!=NULL ? recipent.Name.insert(0,name) : recipent.Name.insert(0,"");
149 CCRecipients.insert(CCRecipients.end(), recipent);
151 return true;
154 bool CSmtp::AddBCCRecipient(const char *email, const char *name)
156 assert(email);
158 if(!email)
160 m_oError = CSMTP_UNDEF_RECIPENT_MAIL;
161 return false;
164 Recipent recipent;
165 recipent.Mail.insert(0,email);
166 name!=NULL ? recipent.Name.insert(0,name) : recipent.Name.insert(0,"");
168 BCCRecipients.insert(BCCRecipients.end(), recipent);
170 return true;
173 bool CSmtp::Send()
175 unsigned int i,rcpt_count,res,FileId;
176 char *FileBuf = NULL, *FileName = NULL;
177 FILE* hFile = NULL;
178 unsigned long int FileSize,TotalSize,MsgPart;
180 // ***** CONNECTING TO SMTP SERVER *****
182 assert(m_pcSMTPSrvName);
184 // connecting to remote host:
185 if( (hSocket = ConnectRemoteServer(m_pcSMTPSrvName, m_iSMTPSrvPort)) == INVALID_SOCKET )
187 m_oError = CSMTP_WSA_INVALID_SOCKET;
188 return false;
190 Sleep(DELAY_IN_MS);
191 if(!ReceiveData())
192 return false;
194 switch(SmtpXYZdigits())
196 case 220:
197 break;
198 default:
199 m_oError = CSMTP_SERVER_NOT_READY;
200 return false;
203 // EHLO <SP> <domain> <CRLF>
204 sprintf(SendBuf,"EHLO %s\r\n",GetLocalHostName()!=NULL ? m_pcLocalHostName : "domain");
205 if(!SendData())
206 return false;
207 Sleep(DELAY_IN_MS);
208 if(!ReceiveData())
209 return false;
211 switch(SmtpXYZdigits())
213 case 250:
214 break;
215 default:
216 m_oError = CSMTP_COMMAND_EHLO;
217 return false;
220 // AUTH <SP> LOGIN <CRLF>
221 strcpy(SendBuf,"AUTH LOGIN\r\n");
222 if(!SendData())
223 return false;
224 Sleep(DELAY_IN_MS);
225 if(!ReceiveData())
226 return false;
228 switch(SmtpXYZdigits())
230 case 334:
231 break;
232 default:
233 m_oError = CSMTP_COMMAND_AUTH_LOGIN;
234 return false;
237 // send login:
238 if(!m_pcLogin)
240 m_oError = CSMTP_UNDEF_LOGIN;
241 return false;
243 std::string encoded_login = base64_encode(reinterpret_cast<const unsigned char*>(m_pcLogin),strlen(m_pcLogin));
244 sprintf(SendBuf,"%s\r\n",encoded_login.c_str());
245 if(!SendData())
246 return false;
247 Sleep(DELAY_IN_MS);
248 if(!ReceiveData())
249 return false;
251 switch(SmtpXYZdigits())
253 case 334:
254 break;
255 default:
256 m_oError = CSMTP_UNDEF_XYZ_RESPOMSE;
257 return false;
260 // send password:
261 if(!m_pcPassword)
263 m_oError = CSMTP_UNDEF_PASSWORD;
264 return false;
266 std::string encoded_password = base64_encode(reinterpret_cast<const unsigned char*>(m_pcPassword),strlen(m_pcPassword));
267 sprintf(SendBuf,"%s\r\n",encoded_password.c_str());
268 if(!SendData())
269 return false;
270 Sleep(DELAY_IN_MS);
271 if(!ReceiveData())
272 return false;
274 switch(SmtpXYZdigits())
276 case 235:
277 break;
278 case 535:
279 m_oError = CSMTP_BAD_LOGIN_PASS;
280 return false;
281 default:
282 m_oError = CSMTP_UNDEF_XYZ_RESPOMSE;
283 return false;
286 // ***** SENDING E-MAIL *****
288 // MAIL <SP> FROM:<reverse-path> <CRLF>
289 if(m_pcMailFrom == NULL)
291 m_oError = CSMTP_UNDEF_MAILFROM;
292 return false;
294 sprintf(SendBuf,"MAIL FROM:<%s>\r\n",m_pcMailFrom);
295 if(!SendData())
296 return false;
297 Sleep(DELAY_IN_MS);
298 if(!ReceiveData())
299 return false;
301 switch(SmtpXYZdigits())
303 case 250:
304 break;
305 default:
306 m_oError = CSMTP_COMMAND_MAIL_FROM;
307 return false;
310 // RCPT <SP> TO:<forward-path> <CRLF>
311 rcpt_count = Recipients.size();
312 for(i=0;i<Recipients.size();i++)
314 sprintf(SendBuf,"RCPT TO:<%s>\r\n",(Recipients.at(i).Mail).c_str());
315 if(!SendData())
316 return false;
317 Sleep(DELAY_IN_MS);
318 if(!ReceiveData())
319 return false;
321 switch(SmtpXYZdigits())
323 case 250:
324 break;
325 default:
326 m_oError = CSMTP_COMMAND_RCPT_TO;
327 rcpt_count--;
330 if(!rcpt_count)
331 return false;
332 for(i=0;i<CCRecipients.size();i++)
334 sprintf(SendBuf,"RCPT TO:<%s>\r\n",(CCRecipients.at(i).Mail).c_str());
335 if(!SendData())
336 return false;
337 Sleep(DELAY_IN_MS);
338 if(!ReceiveData())
339 return false;
341 for(i=0;i<BCCRecipients.size();i++)
343 sprintf(SendBuf,"RCPT TO:<%s>\r\n",(BCCRecipients.at(i).Mail).c_str());
344 if(!SendData())
345 return false;
346 Sleep(DELAY_IN_MS);
347 if(!ReceiveData())
348 return false;
351 // DATA <CRLF>
352 strcpy(SendBuf,"DATA\r\n");
353 if(!SendData())
354 return false;
355 Sleep(DELAY_IN_MS);
356 if(!ReceiveData())
357 return false;
359 switch(SmtpXYZdigits())
361 case 354:
362 break;
363 default:
364 m_oError = CSMTP_COMMAND_DATA;
365 return false;
368 // send header(s)
369 if(!FormatHeader(SendBuf))
371 m_oError = CSMTP_UNDEF_MSG_HEADER;
372 return false;
374 if(!SendData())
375 return false;
377 // send text message
378 sprintf(SendBuf,"%s\r\n",m_pcMsgBody); // NOTICE: each line ends with <CRLF>
379 if(!SendData())
380 return false;
382 // next goes attachments (if they are)
383 if((FileBuf = new char[55]) == NULL)
385 m_oError = CSMTP_LACK_OF_MEMORY;
386 return false;
388 if((FileName = new char[255]) == NULL)
390 m_oError = CSMTP_LACK_OF_MEMORY;
391 return false;
393 TotalSize = 0;
394 for(FileId=0;FileId<Attachments.size();FileId++)
396 strcpy(FileName,Attachments[FileId].c_str());
398 sprintf(SendBuf,"--%s\r\n",BOUNDARY_TEXT);
399 strcat(SendBuf,"Content-Type: application/x-msdownload; name=\"");
400 strcat(SendBuf,&FileName[Attachments[FileId].find_last_of("\\") + 1]);
401 strcat(SendBuf,"\"\r\n");
402 strcat(SendBuf,"Content-Transfer-Encoding: base64\r\n");
403 strcat(SendBuf,"Content-Disposition: attachment; filename=\"");
404 strcat(SendBuf,&FileName[Attachments[FileId].find_last_of("\\") + 1]);
405 strcat(SendBuf,"\"\r\n");
406 strcat(SendBuf,"\r\n");
408 if(!SendData())
409 return false;
411 // opening the file:
412 hFile = fopen(FileName,"rb");
413 if(hFile == NULL)
415 m_oError = CSMTP_FILE_NOT_EXIST;
416 break;
419 // checking file size:
420 FileSize = 0;
421 while(!feof(hFile))
422 FileSize += fread(FileBuf,sizeof(char),54,hFile);
423 TotalSize += FileSize;
425 // sending the file:
426 if(TotalSize/1024 > MSG_SIZE_IN_MB*1024)
427 m_oError = CSMTP_MSG_TOO_BIG;
428 else
430 fseek (hFile,0,SEEK_SET);
432 MsgPart = 0;
433 for(i=0;i<FileSize/54+1;i++)
435 res = fread(FileBuf,sizeof(char),54,hFile);
436 MsgPart ? strcat(SendBuf,base64_encode(reinterpret_cast<const unsigned char*>(FileBuf),res).c_str())
437 : strcpy(SendBuf,base64_encode(reinterpret_cast<const unsigned char*>(FileBuf),res).c_str());
438 strcat(SendBuf,"\r\n");
439 MsgPart += res + 2;
440 if(MsgPart >= BUFFER_SIZE/2)
441 { // sending part of the message
442 MsgPart = 0;
443 if(!SendData())
445 delete[] FileBuf;
446 delete[] FileName;
447 fclose(hFile);
448 return false;
452 if(MsgPart)
454 if(!SendData())
456 delete[] FileBuf;
457 delete[] FileName;
458 fclose(hFile);
459 return false;
463 fclose(hFile);
465 delete[] FileBuf;
466 delete[] FileName;
468 // sending last message block (if there is one or more attachments)
469 if(Attachments.size())
471 sprintf(SendBuf,"\r\n--%s--\r\n",BOUNDARY_TEXT);
472 if(!SendData())
473 return false;
476 // <CRLF> . <CRLF>
477 strcpy(SendBuf,"\r\n.\r\n");
478 if(!SendData())
479 return false;
480 Sleep(DELAY_IN_MS);
481 if(!ReceiveData())
482 return false;
484 switch(SmtpXYZdigits())
486 case 250:
487 break;
488 default:
489 m_oError = CSMTP_MSG_BODY_ERROR;
490 return false;
493 // ***** CLOSING CONNECTION *****
495 // QUIT <CRLF>
496 strcpy(SendBuf,"QUIT\r\n");
497 if(!SendData())
498 return false;
499 Sleep(DELAY_IN_MS);
500 if(!ReceiveData())
501 return false;
503 switch(SmtpXYZdigits())
505 case 221:
506 break;
507 default:
508 m_oError = CSMTP_COMMAND_QUIT;
509 hSocket = NULL;
510 return false;
513 closesocket(hSocket);
514 hSocket = NULL;
515 return true;
518 SOCKET CSmtp::ConnectRemoteServer(const char *server,const unsigned short port)
520 short nProtocolPort;
521 LPHOSTENT lpHostEnt;
522 LPSERVENT lpServEnt;
523 SOCKADDR_IN sockAddr;
524 SOCKET hServerSocket = INVALID_SOCKET;
525 struct in_addr addr;
527 // If the user input is an alpha name for the host, use gethostbyname()
528 // If not, get host by addr (assume IPv4)
529 if(isalpha(server[0]))
530 lpHostEnt = gethostbyname(server);
531 else
533 addr.s_addr = inet_addr(server);
534 if(addr.s_addr == INADDR_NONE)
536 m_oError = CSMTP_BAD_IPV4_ADDR;
537 return INVALID_SOCKET;
539 else
540 lpHostEnt = gethostbyaddr((char *) &addr, 4, AF_INET);
543 if(lpHostEnt != NULL)
545 if((hServerSocket = socket(PF_INET, SOCK_STREAM,0)) != INVALID_SOCKET)
547 if(port != NULL)
548 nProtocolPort = htons(port);
549 else
551 lpServEnt = getservbyname("mail", 0);
552 if (lpServEnt == NULL)
553 nProtocolPort = htons(25);
554 else
555 nProtocolPort = lpServEnt->s_port;
558 sockAddr.sin_family = AF_INET;
559 sockAddr.sin_port = nProtocolPort;
560 sockAddr.sin_addr = *((LPIN_ADDR)*lpHostEnt->h_addr_list);
561 if(connect(hServerSocket,(PSOCKADDR)&sockAddr,sizeof(sockAddr)) == SOCKET_ERROR)
563 m_oError = CSMTP_WSA_CONNECT;
564 hServerSocket = INVALID_SOCKET;
567 else
569 m_oError = CSMTP_WSA_INVALID_SOCKET;
570 return INVALID_SOCKET;
573 else
575 m_oError = CSMTP_WSA_GETHOSTBY_NAME_ADDR;
576 return INVALID_SOCKET;
579 return hServerSocket;
582 int CSmtp::SmtpXYZdigits()
584 assert(RecvBuf);
585 if(RecvBuf == NULL)
586 return 0;
587 return (RecvBuf[0]-'0')*100 + (RecvBuf[1]-'0')*10 + RecvBuf[2]-'0';
590 bool CSmtp::FormatHeader(char* header)
592 unsigned int i,s = 0;
593 char szDate[500];
594 char sztTime[500];
595 char *to = NULL;
596 char *cc = NULL;
597 char *bcc = NULL;
599 // check for at least one recipient
600 if(Recipients.size())
602 for (i=s=0;i<Recipients.size();i++)
603 s += Recipients[i].Mail.size() + Recipients[i].Name.size() + 3;
604 if (s == 0)
605 s = 1;
606 if((to = new char[s]) == NULL)
608 m_oError = CSMTP_LACK_OF_MEMORY;
609 return false;
612 to[0] = '\0';
613 for (i=0;i<Recipients.size();i++)
615 i > 0 ? strcat(to,","):strcpy(to,"");
616 strcat(to,Recipients[i].Name.c_str());
617 strcat(to,"<");
618 strcat(to,Recipients[i].Mail.c_str());
619 strcat(to,">");
622 else
624 m_oError = CSMTP_UNDEF_RECIPENTS;
625 return false;
628 if(CCRecipients.size())
630 for (i=s=0;i<CCRecipients.size();i++)
631 s += CCRecipients[i].Mail.size() + CCRecipients[i].Name.size() + 3;
632 if (s == 0)
633 s = 1;
634 if((cc = new char[s]) == NULL)
636 m_oError = CSMTP_LACK_OF_MEMORY;
637 delete[] to;
638 return false;
641 cc[0] = '\0';
642 for (i=0;i<CCRecipients.size();i++)
644 i > 0 ? strcat(cc,","):strcpy(cc,"");
645 strcat(cc,CCRecipients[i].Name.c_str());
646 strcat(cc,"<");
647 strcat(cc,CCRecipients[i].Mail.c_str());
648 strcat(cc,">");
652 if(BCCRecipients.size())
654 for (i=s=0;i<BCCRecipients.size();i++)
655 s += BCCRecipients[i].Mail.size() + BCCRecipients[i].Name.size() + 3;
656 if(s == 0)
657 s=1;
658 if((bcc = new char[s]) == NULL)
660 m_oError = CSMTP_LACK_OF_MEMORY;
661 delete[] to;
662 delete[] cc;
663 return false;
666 bcc[0] = '\0';
667 for (i=0;i<BCCRecipients.size();i++)
669 i > 0 ? strcat(bcc,","):strcpy(bcc,"");
670 strcat(bcc,BCCRecipients[i].Name.c_str());
671 strcat(bcc,"<");
672 strcat(bcc,BCCRecipients[i].Mail.c_str());
673 strcat(bcc,">");
677 // Date: <SP> <dd> <SP> <mon> <SP> <yy> <SP> <hh> ":" <mm> ":" <ss> <SP> <zone> <CRLF>
678 SYSTEMTIME st={0};
679 ::GetSystemTime(&st);
680 ::GetDateFormatA(MAKELCID(0x0409,SORT_DEFAULT),0,&st,"ddd\',\' dd MMM yyyy",szDate,sizeof(szDate));
681 ::GetTimeFormatA(MAKELCID(0x0409,SORT_DEFAULT),TIME_FORCE24HOURFORMAT,&st,"HH\':\'mm\':\'ss",sztTime,sizeof(sztTime));
682 sprintf(header,"Date: %s %s\r\n", szDate, sztTime);
684 // From: <SP> <sender> <SP> "<" <sender-email> ">" <CRLF>
685 if(m_pcMailFrom == NULL)
687 m_oError = CSMTP_UNDEF_MAILFROM;
688 delete[] to;
689 delete[] cc;
690 delete[] bcc;
691 return false;
693 strcat(header,"From: ");
694 if(m_pcNameFrom)
695 strcat(header, m_pcNameFrom);
696 strcat(header," <");
697 strcat(header,m_pcMailFrom);
698 strcat(header, ">\r\n");
700 // X-Mailer: <SP> <xmailer-app> <CRLF>
701 if (m_pcXMailer != NULL)
703 strcat(header,"X-Mailer: ");
704 strcat(header, m_pcXMailer);
705 strcat(header, "\r\n");
708 // Reply-To: <SP> <reverse-path> <CRLF>
709 if(m_pcReplyTo != NULL)
711 strcat(header, "Reply-To: ");
712 strcat(header, m_pcReplyTo);
713 strcat(header, "\r\n");
716 // X-Priority: <SP> <number> <CRLF>
717 switch(m_iXPriority)
719 case XPRIORITY_HIGH:
720 strcat(header,"X-Priority: 2 (High)\r\n");
721 break;
722 case XPRIORITY_NORMAL:
723 strcat(header,"X-Priority: 3 (Normal)\r\n");
724 break;
725 case XPRIORITY_LOW:
726 strcat(header,"X-Priority: 4 (Low)\r\n");
727 break;
728 default:
729 strcat(header,"X-Priority: 3 (Normal)\r\n");
732 // To: <SP> <remote-user-mail> <CRLF>
733 strcat(header,"To: ");
734 strcat(header, to);
735 strcat(header, "\r\n");
737 // Cc: <SP> <remote-user-mail> <CRLF>
738 if(CCRecipients.size())
740 strcat(header,"Cc: ");
741 strcat(header, cc);
742 strcat(header, "\r\n");
745 if(BCCRecipients.size())
747 strcat(header,"Bcc: ");
748 strcat(header, bcc);
749 strcat(header, "\r\n");
752 // Subject: <SP> <subject-text> <CRLF>
753 if(m_pcSubject == NULL)
755 m_oError = CSMTP_UNDEF_SUBJECT;
756 strcat(header, "Subject: ");
758 else
760 strcat(header, "Subject: ");
761 strcat(header, m_pcSubject);
763 strcat(header, "\r\n");
765 // MIME-Version: <SP> 1.0 <CRLF>
766 strcat(header,"MIME-Version: 1.0\r\n");
767 if(!Attachments.size())
768 { // no attachments
769 strcat(header,"Content-type: text/plain; charset=US-ASCII\r\n");
770 strcat(header,"Content-Transfer-Encoding: 7bit\r\n");
771 strcat(SendBuf,"\r\n");
773 else
774 { // there is one or more attachments
775 strcat(header,"Content-Type: multipart/mixed; boundary=\"");
776 strcat(header,BOUNDARY_TEXT);
777 strcat(header,"\"\r\n");
778 strcat(header,"\r\n");
779 // first goes text message
780 strcat(SendBuf,"--");
781 strcat(SendBuf,BOUNDARY_TEXT);
782 strcat(SendBuf,"\r\n");
783 strcat(SendBuf,"Content-type: text/plain; charset=US-ASCII\r\n");
784 strcat(SendBuf,"Content-Transfer-Encoding: 7bit\r\n");
785 strcat(SendBuf,"\r\n");
788 // clean up
789 delete[] to;
790 delete[] cc;
791 delete[] bcc;
793 // done
794 return true;
797 bool CSmtp::ReceiveData()
799 assert(RecvBuf);
801 int res;
803 if(RecvBuf == NULL)
804 return false;
806 if( (res = recv(hSocket,RecvBuf,BUFFER_SIZE,0)) == SOCKET_ERROR )
808 m_oError = CSMTP_WSA_RECV;
809 return false;
811 if(res == 0)
813 m_oError = CSMTP_CONNECTION_CLOSED;
814 return false;
816 RecvBuf[res] = '\0';
818 return true;
821 bool CSmtp::SendData()
823 assert(SendBuf);
825 int idx = 0,res,nLeft = strlen(SendBuf);
826 while(nLeft > 0)
828 if( res = send(hSocket,&SendBuf[idx],nLeft,0) == SOCKET_ERROR)
830 m_oError = CSMTP_WSA_SEND;
831 return false;
833 if(!res)
834 break;
835 nLeft -= res;
836 idx += res;
838 return true;
841 CSmtpError CSmtp::GetLastError()
843 return m_oError;
847 const char* const CSmtp::GetLocalHostIP()
849 in_addr *iaHost = NULL;
850 HOSTENT *pHe = NULL;
852 if (m_pcIPAddr)
853 delete[] m_pcIPAddr;
855 if(gethostname(m_pcHostName,255) != SOCKET_ERROR)
857 pHe = gethostbyname(m_pcHostName);
858 if (pHe != NULL)
860 for (int i=0;pHe->h_addr_list[i] != 0;i++)
862 iaHost = (LPIN_ADDR)pHe->h_addr_list[i];
863 m_pcIPAddr = inet_ntoa(*iaHost);
867 else
869 m_oError = CSMTP_WSA_GETHOSTBY_NAME_ADDR;
870 m_pcIPAddr = NULL;
873 return m_pcIPAddr;
877 const char* const CSmtp::GetLocalHostName()
879 if(m_pcLocalHostName)
880 delete[] m_pcLocalHostName;
881 if((m_pcLocalHostName = new char[255]) == NULL)
883 m_oError = CSMTP_LACK_OF_MEMORY;
884 return NULL;
886 if(gethostname((char FAR*)m_pcLocalHostName,255) == SOCKET_ERROR)
887 m_oError = CSMTP_WSA_HOSTNAME;
888 return m_pcLocalHostName;
891 unsigned const int CSmtp::GetBCCRecipientCount()
893 return BCCRecipients.size();
896 unsigned const int CSmtp::GetCCRecipientCount()
898 return CCRecipients.size();
901 const char* const CSmtp::GetMessageBody()
903 return m_pcMsgBody;
906 unsigned const int CSmtp::GetRecipientCount()
908 return Recipients.size();
911 const char* const CSmtp::GetReplyTo()
913 return m_pcReplyTo;
916 const char* const CSmtp::GetMailFrom()
918 return m_pcMailFrom;
921 const char* const CSmtp::GetSenderName()
923 return m_pcNameFrom;
926 const char* const CSmtp::GetSubject()
928 return m_pcSubject;
931 const char* const CSmtp::GetXMailer()
933 return m_pcXMailer;
936 CSmptXPriority CSmtp::GetXPriority()
938 return m_iXPriority;
941 void CSmtp::SetXPriority(CSmptXPriority priority)
943 m_iXPriority = priority;
946 void CSmtp::SetMessageBody(const char *body)
948 assert(body);
949 int s = strlen(body);
950 if (m_pcMsgBody)
951 delete[] m_pcMsgBody;
952 if((m_pcMsgBody = new char[s+1]) == NULL)
954 m_oError = CSMTP_LACK_OF_MEMORY;
955 return;
957 strcpy(m_pcMsgBody, body);
960 void CSmtp::SetReplyTo(const char *replyto)
962 assert(replyto);
963 int s = strlen(replyto);
964 if (m_pcReplyTo)
965 delete[] m_pcReplyTo;
966 if((m_pcReplyTo = new char[s+1]) == NULL)
968 m_oError = CSMTP_LACK_OF_MEMORY;
969 return;
971 strcpy(m_pcReplyTo, replyto);
974 void CSmtp::SetSenderMail(const char *email)
976 assert(email);
977 int s = strlen(email);
978 if (m_pcMailFrom)
979 delete[] m_pcMailFrom;
980 if((m_pcMailFrom = new char[s+1]) == NULL)
982 m_oError = CSMTP_LACK_OF_MEMORY;
983 return;
985 strcpy(m_pcMailFrom, email);
988 void CSmtp::SetSenderName(const char *name)
990 assert(name);
991 int s = strlen(name);
992 if (m_pcNameFrom)
993 delete[] m_pcNameFrom;
994 if((m_pcNameFrom = new char[s+1]) == NULL)
996 m_oError = CSMTP_LACK_OF_MEMORY;
997 return;
999 strcpy(m_pcNameFrom, name);
1002 void CSmtp::SetSubject(const char *subject)
1004 assert(subject);
1005 int s = strlen(subject);
1006 if (m_pcSubject)
1007 delete[] m_pcSubject;
1008 m_pcSubject = new char[s+1];
1009 strcpy(m_pcSubject, subject);
1012 void CSmtp::SetXMailer(const char *xmailer)
1014 assert(xmailer);
1015 int s = strlen(xmailer);
1016 if (m_pcXMailer)
1017 delete[] m_pcXMailer;
1018 if((m_pcXMailer = new char[s+1]) == NULL)
1020 m_oError = CSMTP_LACK_OF_MEMORY;
1021 return;
1023 strcpy(m_pcXMailer, xmailer);
1026 void CSmtp::SetLogin(const char *login)
1028 assert(login);
1029 int s = strlen(login);
1030 if (m_pcLogin)
1031 delete[] m_pcLogin;
1032 if((m_pcLogin = new char[s+1]) == NULL)
1034 m_oError = CSMTP_LACK_OF_MEMORY;
1035 return;
1037 strcpy(m_pcLogin, login);
1040 void CSmtp::SetPassword(const char *password)
1042 assert(password);
1043 int s = strlen(password);
1044 if (m_pcPassword)
1045 delete[] m_pcPassword;
1046 if((m_pcPassword = new char[s+1]) == NULL)
1048 m_oError = CSMTP_LACK_OF_MEMORY;
1049 return;
1051 strcpy(m_pcPassword, password);
1054 void CSmtp::SetSMTPServer(const char* SrvName,const unsigned short SrvPort)
1056 assert(SrvName);
1057 m_iSMTPSrvPort = SrvPort;
1058 int s = strlen(SrvName);
1059 if(m_pcSMTPSrvName)
1060 delete[] m_pcSMTPSrvName;
1061 if((m_pcSMTPSrvName = new char[s+1]) == NULL)
1063 m_oError = CSMTP_LACK_OF_MEMORY;
1064 return;
1066 strcpy(m_pcSMTPSrvName, SrvName);
1069 //////////////////////////////////////////////////////////////////////
1070 // Friends
1071 //////////////////////////////////////////////////////////////////////
1073 char* GetErrorText(CSmtpError ErrorId)
1075 switch(ErrorId)
1077 case CSMTP_NO_ERROR:
1078 return "";
1079 case CSMTP_WSA_STARTUP:
1080 return "Unable to initialise winsock2.";
1081 case CSMTP_WSA_VER:
1082 return "Wrong version of the winsock2.";
1083 case CSMTP_WSA_SEND:
1084 return "Function send() failed.";
1085 case CSMTP_WSA_RECV:
1086 return "Function recv() failed.";
1087 case CSMTP_WSA_CONNECT:
1088 return "Function connect failed.";
1089 case CSMTP_WSA_GETHOSTBY_NAME_ADDR:
1090 return "Functions gethostbyname() or gethostbyaddr() failed.";
1091 case CSMTP_WSA_INVALID_SOCKET:
1092 return "Invalid winsock2 socket.";
1093 case CSMTP_WSA_HOSTNAME:
1094 return "Function hostname() failed.";
1095 case CSMTP_BAD_IPV4_ADDR:
1096 return "Improper IPv4 address.";
1097 case CSMTP_UNDEF_MSG_HEADER:
1098 return "Undefined message header.";
1099 case CSMTP_UNDEF_MAILFROM:
1100 return "Undefined from is the mail.";
1101 case CSMTP_UNDEF_SUBJECT:
1102 return "Undefined message subject.";
1103 case CSMTP_UNDEF_RECIPENTS:
1104 return "Undefined at least one reciepent.";
1105 case CSMTP_UNDEF_RECIPENT_MAIL:
1106 return "Undefined recipent mail.";
1107 case CSMTP_UNDEF_LOGIN:
1108 return "Undefined user login.";
1109 case CSMTP_UNDEF_PASSWORD:
1110 return "Undefined user password.";
1111 case CSMTP_COMMAND_MAIL_FROM:
1112 return "Server returned error after sending MAIL FROM.";
1113 case CSMTP_COMMAND_EHLO:
1114 return "Server returned error after sending EHLO.";
1115 case CSMTP_COMMAND_AUTH_LOGIN:
1116 return "Server returned error after sending AUTH LOGIN.";
1117 case CSMTP_COMMAND_DATA:
1118 return "Server returned error after sending DATA.";
1119 case CSMTP_COMMAND_QUIT:
1120 return "Server returned error after sending QUIT.";
1121 case CSMTP_COMMAND_RCPT_TO:
1122 return "Server returned error after sending RCPT TO.";
1123 case CSMTP_MSG_BODY_ERROR:
1124 return "Error in message body";
1125 case CSMTP_CONNECTION_CLOSED:
1126 return "Server has closed the connection.";
1127 case CSMTP_SERVER_NOT_READY:
1128 return "Server is not ready.";
1129 case CSMTP_FILE_NOT_EXIST:
1130 return "File not exist.";
1131 case CSMTP_MSG_TOO_BIG:
1132 return "Message is too big.";
1133 case CSMTP_BAD_LOGIN_PASS:
1134 return "Bad login or password.";
1135 case CSMTP_UNDEF_XYZ_RESPOMSE:
1136 return "Undefined xyz SMTP response.";
1137 case CSMTP_LACK_OF_MEMORY:
1138 return "Lack of memory.";
1139 default:
1140 return "Undefined error id.";
1144 #pragma warning(pop)