PageRenderTime 45ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/Pw.Elka.TIN/Server/Source Files/Components/SmtpLayer/CSmtp.cpp

https://gitlab.com/mmudel/pw.elka.tin.mailer
C++ | 987 lines | 706 code | 152 blank | 129 comment | 88 complexity | efe97356585d4890126dcc38e4439c36 MD5 | raw file
  1. #define _CRT_SECURE_NO_WARNINGS
  2. #define _WINSOCK_DEPRECATED_NO_WARNINGS
  3. #include "../../../Header Files/Components/SmtpLayer/SmtpLayer.h"
  4. #include <Ws2tcpip.h>
  5. /// DESCRIPTION: Constructor of CSmtp class.
  6. /// RETURNS: none
  7. CSmtp::CSmtp()
  8. {
  9. m_iXPriority = XPRIORITY_NORMAL;
  10. m_iSMTPSrvPort = 0;
  11. /// Initialize WinSock
  12. WSADATA wsaData;
  13. WORD wVer = MAKEWORD(2,2);
  14. if (WSAStartup(wVer,&wsaData) != NO_ERROR)
  15. throw ECSmtp(ECSmtp::WSA_STARTUP);
  16. if (LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 )
  17. {
  18. WSACleanup();
  19. throw ECSmtp(ECSmtp::WSA_VER);
  20. }
  21. if((RecvBuf = new char[BUFFER_SIZE]) == NULL)
  22. throw ECSmtp(ECSmtp::LACK_OF_MEMORY);
  23. if((SendBuf = new char[BUFFER_SIZE]) == NULL)
  24. throw ECSmtp(ECSmtp::LACK_OF_MEMORY);
  25. }
  26. /// DESCRIPTION: Destructor of CSmtp class.
  27. /// RETURNS: none
  28. CSmtp::~CSmtp()
  29. {
  30. if(SendBuf)
  31. {
  32. delete[] SendBuf;
  33. SendBuf = NULL;
  34. }
  35. if(RecvBuf)
  36. {
  37. delete[] RecvBuf;
  38. RecvBuf = NULL;
  39. }
  40. WSACleanup();
  41. }
  42. /// DESCRIPTION: New recipient data is added i.e.: email and name. .
  43. /// ARGUMENTS: const char *email - mail of the recipient
  44. /// const char *name - name of the recipient
  45. /// RETURNS: void
  46. void CSmtp::AddRecipient(const char *email, const char *name)
  47. {
  48. if(!email)
  49. throw ECSmtp(ECSmtp::UNDEF_RECIPIENT_MAIL);
  50. Recipient recipient;
  51. recipient.Mail.insert(0,email);
  52. name!=NULL ? recipient.Name.insert(0,name) : recipient.Name.insert(0,"");
  53. Recipients.insert(Recipients.end(), recipient);
  54. }
  55. /// DESCRIPTION: Adds new line in a message.
  56. /// ARGUMENTS: const char *Text - text of the new line
  57. /// RETURNS: void
  58. void CSmtp::AddMsgLine(const char* Text)
  59. {
  60. MsgBody.insert(MsgBody.end(),Text);
  61. }
  62. /// DESCRIPTION: Deletes specified line in text message.. .
  63. /// ARGUMENTS: unsigned int Line - line to be delete
  64. /// RETURNS: void
  65. void CSmtp::DelMsgLine(unsigned int Line)
  66. {
  67. if(Line > MsgBody.size())
  68. throw ECSmtp(ECSmtp::OUT_OF_MSG_RANGE);
  69. MsgBody.erase(MsgBody.begin()+Line);
  70. }
  71. /// DESCRIPTION: Deletes all recipients. .
  72. /// RETURNS: void
  73. void CSmtp::DelRecipients()
  74. {
  75. Recipients.clear();
  76. }
  77. /// DESCRIPTION: Deletes message text.
  78. /// ARGUMENTS: void
  79. void CSmtp::DelMsgLines()
  80. {
  81. MsgBody.clear();
  82. }
  83. /// DESCRIPTION: New recipient data is added i.e.: email and name. .
  84. /// ARGUMENTS: const char *email - mail of the bcc-recipient
  85. /// const char *name - name of the bccc-recipient
  86. /// RETURNS: void
  87. void CSmtp::ModMsgLine(unsigned int Line,const char* Text)
  88. {
  89. if(Text)
  90. {
  91. if(Line > MsgBody.size())
  92. throw ECSmtp(ECSmtp::OUT_OF_MSG_RANGE);
  93. MsgBody.at(Line) = std::string(Text);
  94. }
  95. }
  96. /// DESCRIPTION: Sending the mail.
  97. /// ARGUMENTS: none
  98. /// RETURNS: void
  99. void CSmtp::Send()
  100. {
  101. unsigned int i, rcpt_count;
  102. char *FileBuf = NULL, *FileName = NULL;
  103. FILE* hFile = NULL;
  104. // unsigned long int FileSize,TotalSize,MsgPart;
  105. bool bAccepted;
  106. // ***** CONNECTING TO SMTP SERVER *****
  107. // connecting to remote host:
  108. if( (hSocket = ConnectRemoteServer(m_sSMTPSrvName.c_str(), m_iSMTPSrvPort)) == INVALID_SOCKET )
  109. throw ECSmtp(ECSmtp::WSA_INVALID_SOCKET);
  110. bAccepted = false;
  111. do
  112. {
  113. ReceiveData();
  114. switch(SmtpXYZdigits())
  115. {
  116. case 220:
  117. bAccepted = true;
  118. break;
  119. default:
  120. throw ECSmtp(ECSmtp::SERVER_NOT_READY);
  121. }
  122. }while(!bAccepted);
  123. // EHLO <SP> <domain> <CRLF>
  124. sprintf(SendBuf,"EHLO %s\r\n",GetLocalHostName()!=NULL ? m_sLocalHostName.c_str() : "domain");
  125. SendData();
  126. bAccepted = false;
  127. do
  128. {
  129. ReceiveData();
  130. switch(SmtpXYZdigits())
  131. {
  132. case 250:
  133. bAccepted = true;
  134. break;
  135. default:
  136. throw ECSmtp(ECSmtp::COMMAND_EHLO);
  137. }
  138. }while(!bAccepted);
  139. // AUTH <SP> LOGIN <CRLF>
  140. strcpy(SendBuf,"AUTH LOGIN\r\n");
  141. SendData();
  142. bAccepted = false;
  143. do
  144. {
  145. ReceiveData();
  146. switch(SmtpXYZdigits())
  147. {
  148. case 250:
  149. break;
  150. case 334:
  151. //std::cout << "czeka na login";
  152. bAccepted = true;
  153. break;
  154. default:
  155. throw ECSmtp(ECSmtp::COMMAND_AUTH_LOGIN);
  156. }
  157. }while(!bAccepted);
  158. // send login:
  159. if(!m_sLogin.size())
  160. throw ECSmtp(ECSmtp::UNDEF_LOGIN);
  161. sprintf(SendBuf,"%s\r\n", this->m_sLogin.c_str());
  162. SendData();
  163. bAccepted = false;
  164. do
  165. {
  166. ReceiveData();
  167. switch(SmtpXYZdigits())
  168. {
  169. case 334:
  170. bAccepted = true;
  171. break;
  172. default:
  173. throw ECSmtp(ECSmtp::UNDEF_XYZ_RESPONSE);
  174. }
  175. }while(!bAccepted);
  176. // send password:
  177. if(!m_sPassword.size())
  178. throw ECSmtp(ECSmtp::UNDEF_PASSWORD);
  179. sprintf(SendBuf,"%s\r\n", this->m_sPassword.c_str() );
  180. SendData();
  181. bAccepted = false;
  182. do
  183. {
  184. ReceiveData();
  185. switch(SmtpXYZdigits())
  186. {
  187. case 235:
  188. bAccepted = true;
  189. break;
  190. case 334:
  191. break;
  192. case 535:
  193. throw ECSmtp(ECSmtp::BAD_LOGIN_PASS);
  194. default:
  195. throw ECSmtp(ECSmtp::UNDEF_XYZ_RESPONSE);
  196. }
  197. }while(!bAccepted);
  198. // SENDING E-MAIL
  199. // MAIL <SP> FROM:<reverse-path> <CRLF>
  200. if(!m_sMailFrom.size())
  201. throw ECSmtp(ECSmtp::UNDEF_MAIL_FROM);
  202. sprintf(SendBuf,"MAIL FROM:<%s>\r\n",m_sMailFrom.c_str());
  203. SendData();
  204. bAccepted = false;
  205. do
  206. {
  207. ReceiveData();
  208. switch(SmtpXYZdigits())
  209. {
  210. case 250:
  211. bAccepted = true;
  212. break;
  213. default:
  214. throw ECSmtp(ECSmtp::COMMAND_MAIL_FROM);
  215. }
  216. }while(!bAccepted);
  217. // RCPT <SP> TO:<forward-path> <CRLF>
  218. if(!(rcpt_count = Recipients.size()))
  219. throw ECSmtp(ECSmtp::UNDEF_RECIPIENTS);
  220. for(i=0;i<Recipients.size();i++)
  221. {
  222. sprintf(SendBuf,"RCPT TO:<%s>\r\n",(Recipients.at(i).Mail).c_str());
  223. SendData();
  224. bAccepted = false;
  225. do
  226. {
  227. ReceiveData();
  228. switch(SmtpXYZdigits())
  229. {
  230. case 250:
  231. bAccepted = true;
  232. break;
  233. default:
  234. rcpt_count--;
  235. }
  236. }while(!bAccepted);
  237. }
  238. if(rcpt_count <= 0)
  239. throw ECSmtp(ECSmtp::COMMAND_RCPT_TO);
  240. // DATA <CRLF>
  241. strcpy(SendBuf,"DATA\r\n");
  242. SendData();
  243. bAccepted = false;
  244. do
  245. {
  246. ReceiveData();
  247. switch(SmtpXYZdigits())
  248. {
  249. case 354:
  250. bAccepted = true;
  251. break;
  252. case 250:
  253. break;
  254. default:
  255. throw ECSmtp(ECSmtp::COMMAND_DATA);
  256. }
  257. }while(!bAccepted);
  258. // send header(s)
  259. FormatHeader(SendBuf);
  260. SendData();
  261. // send text message
  262. if(GetMsgLines())
  263. {
  264. for(i=0;i<GetMsgLines();i++)
  265. {
  266. sprintf(SendBuf,"%s\r\n",GetMsgLineText(i));
  267. SendData();
  268. }
  269. }
  270. else
  271. {
  272. sprintf(SendBuf,"%s\r\n"," ");
  273. SendData();
  274. }
  275. // <CRLF> . <CRLF>
  276. strcpy(SendBuf,"\r\n.\r\n");
  277. SendData();
  278. bAccepted = false;
  279. do
  280. {
  281. ReceiveData();
  282. switch(SmtpXYZdigits())
  283. {
  284. case 250:
  285. bAccepted = true;
  286. break;
  287. default:
  288. throw ECSmtp(ECSmtp::MSG_BODY_ERROR);
  289. }
  290. }while(!bAccepted);
  291. // ***** CLOSING CONNECTION *****
  292. // QUIT <CRLF>
  293. strcpy(SendBuf,"QUIT\r\n");
  294. SendData();
  295. bAccepted = false;
  296. do
  297. {
  298. ReceiveData();
  299. switch(SmtpXYZdigits())
  300. {
  301. case 221:
  302. bAccepted = true;
  303. break;
  304. default:
  305. throw ECSmtp(ECSmtp::COMMAND_QUIT);
  306. }
  307. }while(!bAccepted);
  308. closesocket(hSocket);
  309. hSocket = NULL;
  310. std::cout << "Message succesfully sent. \n";
  311. }
  312. /// DESCRIPTION: Connecting to the service running on the remote server.
  313. /// ARGUMENTS: const char *server - service name
  314. /// const unsigned short port - service port
  315. /// RETURNS: socket of the remote service
  316. SOCKET CSmtp::ConnectRemoteServer(const char *szServer,const unsigned short nPort_)
  317. {
  318. unsigned short nPort = 0;
  319. LPSERVENT lpServEnt;
  320. SOCKADDR_IN sockAddr;
  321. unsigned long ul = 1;
  322. fd_set fdwrite,fdexcept;
  323. timeval timeout;
  324. int res = 0;
  325. timeout.tv_sec = TIME_IN_SEC;
  326. timeout.tv_usec = 0;
  327. SOCKET hSocket = INVALID_SOCKET;
  328. if((hSocket = socket(PF_INET, SOCK_STREAM,0)) == INVALID_SOCKET)
  329. throw ECSmtp(ECSmtp::WSA_INVALID_SOCKET);
  330. if(nPort_ != 0)
  331. nPort = htons(nPort_);
  332. else
  333. {
  334. lpServEnt = getservbyname("mail", 0);
  335. if (lpServEnt == NULL)
  336. nPort = htons(25);
  337. else
  338. nPort = lpServEnt->s_port;
  339. }
  340. sockAddr.sin_family = AF_INET;
  341. sockAddr.sin_port = nPort;
  342. //inet_pton(AF_INET, szServer , &sockAddr.sin_addr.s_addr); alternatywnie
  343. //if(( sockAddr.sin_addr.s_addr ) == INADDR_NONE)
  344. if ((sockAddr.sin_addr.s_addr = inet_addr(szServer)) == INADDR_NONE)
  345. {
  346. LPHOSTENT host;
  347. host = gethostbyname(szServer);
  348. if (host)
  349. {
  350. memcpy(&sockAddr.sin_addr, host->h_addr_list[0], host->h_length);
  351. }
  352. else
  353. {
  354. closesocket(hSocket);
  355. throw ECSmtp(ECSmtp::WSA_GETHOSTBY_NAME_ADDR);
  356. }
  357. }
  358. // start non-blocking mode for socket:
  359. if(ioctlsocket(hSocket,FIONBIO, (unsigned long*)&ul) == SOCKET_ERROR)
  360. {
  361. closesocket(hSocket);
  362. throw ECSmtp(ECSmtp::WSA_IOCTLSOCKET);
  363. }
  364. if(connect(hSocket,(LPSOCKADDR)&sockAddr,sizeof(sockAddr)) == SOCKET_ERROR)
  365. {
  366. if(WSAGetLastError() != WSAEWOULDBLOCK)
  367. {
  368. closesocket(hSocket);
  369. throw ECSmtp(ECSmtp::WSA_CONNECT);
  370. }
  371. }
  372. else
  373. return hSocket;
  374. while(true)
  375. {
  376. FD_ZERO(&fdwrite);
  377. FD_ZERO(&fdexcept);
  378. FD_SET(hSocket,&fdwrite);
  379. FD_SET(hSocket,&fdexcept);
  380. if((res = select(hSocket+1,NULL,&fdwrite,&fdexcept,&timeout)) == SOCKET_ERROR)
  381. {
  382. closesocket(hSocket);
  383. throw ECSmtp(ECSmtp::WSA_SELECT);
  384. }
  385. if(!res)
  386. {
  387. closesocket(hSocket);
  388. throw ECSmtp(ECSmtp::SELECT_TIMEOUT);
  389. }
  390. if(res && FD_ISSET(hSocket,&fdwrite))
  391. break;
  392. if(res && FD_ISSET(hSocket,&fdexcept))
  393. {
  394. closesocket(hSocket);
  395. throw ECSmtp(ECSmtp::WSA_SELECT);
  396. }
  397. } // while
  398. FD_CLR(hSocket,&fdwrite);
  399. FD_CLR(hSocket,&fdexcept);
  400. return hSocket;
  401. }
  402. /// DESCRIPTION: Converts three letters from RecvBuf to the number.
  403. /// ARGUMENTS: none
  404. /// RETURNS: integer number
  405. int CSmtp::SmtpXYZdigits()
  406. {
  407. assert(RecvBuf);
  408. if(RecvBuf == NULL)
  409. return 0;
  410. return (RecvBuf[0]-'0')*100 + (RecvBuf[1]-'0')*10 + RecvBuf[2]-'0';
  411. }
  412. /// DESCRIPTION: Prepares a header of the message.
  413. /// ARGUMENTS: char* header - formated header string
  414. /// RETURNS: void
  415. void CSmtp::FormatHeader(char* header)
  416. {
  417. char month[][4] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
  418. size_t i;
  419. std::string to;
  420. std::string cc;
  421. time_t rawtime;
  422. struct tm* timeinfo;
  423. // date/time check
  424. if(time(&rawtime) > 0)
  425. timeinfo = localtime(&rawtime);
  426. else
  427. throw ECSmtp(ECSmtp::TIME_ERROR);
  428. // check for at least one recipient
  429. if(Recipients.size())
  430. {
  431. for (i=0;i<Recipients.size();i++)
  432. {
  433. if(i > 0)
  434. to.append(",");
  435. to += Recipients[i].Name;
  436. to.append("<");
  437. to += Recipients[i].Mail;
  438. to.append(">");
  439. }
  440. }
  441. else
  442. throw ECSmtp(ECSmtp::UNDEF_RECIPIENTS);
  443. // Date: <SP> <dd> <SP> <mon> <SP> <yy> <SP> <hh> ":" <mm> ":" <ss> <SP> <zone> <CRLF>
  444. sprintf(header,"Date: %d %s %d %d:%d:%d\r\n", timeinfo->tm_mday,
  445. month[timeinfo->tm_mon],
  446. timeinfo->tm_year+1900,
  447. timeinfo->tm_hour,
  448. timeinfo->tm_min,
  449. timeinfo->tm_sec);
  450. // From: <SP> <sender> <SP> "<" <sender-email> ">" <CRLF>
  451. if(!m_sMailFrom.size())
  452. throw ECSmtp(ECSmtp::UNDEF_MAIL_FROM);
  453. strcat(header,"From: ");
  454. if(m_sNameFrom.size())
  455. strcat(header, m_sNameFrom.c_str());
  456. strcat(header," <");
  457. if(m_sNameFrom.size())
  458. strcat(header,m_sMailFrom.c_str());
  459. else
  460. strcat(header,"mail@domain.com");
  461. strcat(header, ">\r\n");
  462. // X-Mailer: <SP> <xmailer-app> <CRLF>
  463. if(m_sXMailer.size())
  464. {
  465. strcat(header,"X-Mailer: ");
  466. strcat(header, m_sXMailer.c_str());
  467. strcat(header, "\r\n");
  468. }
  469. // Reply-To: <SP> <reverse-path> <CRLF>
  470. if(m_sReplyTo.size())
  471. {
  472. strcat(header, "Reply-To: ");
  473. strcat(header, m_sReplyTo.c_str());
  474. strcat(header, "\r\n");
  475. }
  476. // X-Priority: <SP> <number> <CRLF>
  477. switch(m_iXPriority)
  478. {
  479. case XPRIORITY_HIGH:
  480. strcat(header,"X-Priority: 2 (High)\r\n");
  481. break;
  482. case XPRIORITY_NORMAL:
  483. strcat(header,"X-Priority: 3 (Normal)\r\n");
  484. break;
  485. case XPRIORITY_LOW:
  486. strcat(header,"X-Priority: 4 (Low)\r\n");
  487. break;
  488. default:
  489. strcat(header,"X-Priority: 3 (Normal)\r\n");
  490. }
  491. // To: <SP> <remote-user-mail> <CRLF>
  492. strcat(header,"To: ");
  493. strcat(header, to.c_str());
  494. strcat(header, "\r\n");
  495. // Subject: <SP> <subject-text> <CRLF>
  496. if(!m_sSubject.size())
  497. strcat(header, "Subject: ");
  498. else
  499. {
  500. strcat(header, "Subject: ");
  501. strcat(header, m_sSubject.c_str());
  502. }
  503. strcat(header, "\r\n");
  504. }
  505. /// DESCRIPTION: Receives a row terminated '\n'.
  506. /// ARGUMENTS: none
  507. /// RETURNS: void
  508. void CSmtp::ReceiveData()
  509. {
  510. int res,i = 0;
  511. fd_set fdread;
  512. timeval time;
  513. time.tv_sec = TIME_IN_SEC;
  514. time.tv_usec = 0;
  515. assert(RecvBuf);
  516. if(RecvBuf == NULL)
  517. throw ECSmtp(ECSmtp::RECVBUF_IS_EMPTY);
  518. while(1)
  519. {
  520. FD_ZERO(&fdread);
  521. FD_SET(hSocket,&fdread);
  522. if((res = select(hSocket+1, &fdread, NULL, NULL, &time)) == SOCKET_ERROR)
  523. {
  524. FD_CLR(hSocket,&fdread);
  525. throw ECSmtp(ECSmtp::WSA_SELECT);
  526. }
  527. if(!res)
  528. {
  529. //timeout
  530. FD_CLR(hSocket,&fdread);
  531. throw ECSmtp(ECSmtp::SERVER_NOT_RESPONDING);
  532. }
  533. if(res && FD_ISSET(hSocket,&fdread))
  534. {
  535. if(i >= BUFFER_SIZE)
  536. {
  537. FD_CLR(hSocket,&fdread);
  538. throw ECSmtp(ECSmtp::LACK_OF_MEMORY);
  539. }
  540. if(recv(hSocket,&RecvBuf[i++],1,0) == SOCKET_ERROR)
  541. {
  542. FD_CLR(hSocket,&fdread);
  543. throw ECSmtp(ECSmtp::WSA_RECV);
  544. }
  545. if(RecvBuf[i-1]=='\n')
  546. {
  547. RecvBuf[i] = '\0';
  548. break;
  549. }
  550. }
  551. }
  552. FD_CLR(hSocket,&fdread);
  553. }
  554. /// DESCRIPTION: Sends data from SendBuf buffer.
  555. /// ARGUMENTS: none
  556. /// RETURNS: void
  557. void CSmtp::SendData()
  558. {
  559. int idx = 0,res,nLeft = strlen(SendBuf);
  560. fd_set fdwrite;
  561. timeval time;
  562. time.tv_sec = TIME_IN_SEC;
  563. time.tv_usec = 0;
  564. assert(SendBuf);
  565. if(SendBuf == NULL)
  566. throw ECSmtp(ECSmtp::SENDBUF_IS_EMPTY);
  567. while(1)
  568. {
  569. FD_ZERO(&fdwrite);
  570. FD_SET(hSocket,&fdwrite);
  571. if((res = select(hSocket+1,NULL,&fdwrite,NULL,&time)) == SOCKET_ERROR)
  572. {
  573. FD_CLR(hSocket,&fdwrite);
  574. throw ECSmtp(ECSmtp::WSA_SELECT);
  575. }
  576. if(!res)
  577. {
  578. //timeout
  579. FD_CLR(hSocket,&fdwrite);
  580. throw ECSmtp(ECSmtp::SERVER_NOT_RESPONDING);
  581. }
  582. if(res && FD_ISSET(hSocket,&fdwrite))
  583. {
  584. if(nLeft > 0)
  585. {
  586. if((res = send(hSocket,&SendBuf[idx],nLeft,0)) == SOCKET_ERROR)
  587. {
  588. FD_CLR(hSocket,&fdwrite);
  589. throw ECSmtp(ECSmtp::WSA_SEND);
  590. }
  591. if(!res)
  592. break;
  593. nLeft -= res;
  594. idx += res;
  595. }
  596. else
  597. break;
  598. }
  599. }
  600. FD_CLR(hSocket,&fdwrite);
  601. }
  602. /// DESCRIPTION: Returns local host name.
  603. /// ARGUMENTS: none
  604. /// RETURNS: socket of the remote service
  605. const char* CSmtp::GetLocalHostName() const
  606. {
  607. char* str = NULL;
  608. if((str = new char[255]) == NULL)
  609. throw ECSmtp(ECSmtp::LACK_OF_MEMORY);
  610. if(gethostname(str,255) == SOCKET_ERROR)
  611. {
  612. delete[] str;
  613. throw ECSmtp(ECSmtp::WSA_HOSTNAME);
  614. }
  615. delete[] str;
  616. return m_sLocalHostName.c_str();
  617. }
  618. /// DESCRIPTION: Returns the number of recipents.
  619. /// ARGUMENTS: none
  620. /// RETURNS: number of recipents
  621. unsigned int CSmtp::GetRecipientCount() const
  622. {
  623. return Recipients.size();
  624. }
  625. /// DESCRIPTION: Returns m_pcReplyTo string.
  626. /// ARGUMENTS: none
  627. /// RETURNS: m_sReplyTo string
  628. const char* CSmtp::GetReplyTo() const
  629. {
  630. return m_sReplyTo.c_str();
  631. }
  632. /// DESCRIPTION: Returns m_pcMailFrom string.
  633. /// ARGUMENTS: none
  634. /// RETURNS: m_sMailFrom string
  635. const char* CSmtp::GetMailFrom() const
  636. {
  637. return m_sMailFrom.c_str();
  638. }
  639. /// DESCRIPTION: Returns m_pcNameFrom string.
  640. /// ARGUMENTS: none
  641. /// RETURNS: m_sNameFrom string
  642. const char* CSmtp::GetSenderName() const
  643. {
  644. return m_sNameFrom.c_str();
  645. }
  646. /// DESCRIPTION: Returns m_pcSubject string.
  647. /// ARGUMENTS: none
  648. /// RETURNS: m_sSubject string
  649. const char* CSmtp::GetSubject() const
  650. {
  651. return m_sSubject.c_str();
  652. }
  653. /// DESCRIPTION: Returns m_pcXMailer string.
  654. /// ARGUMENTS: none
  655. /// RETURNS: m_pcXMailer string
  656. const char* CSmtp::GetXMailer() const
  657. {
  658. return m_sXMailer.c_str();
  659. }
  660. /// DESCRIPTION: Returns m_iXPriority string.
  661. /// ARGUMENTS: none
  662. /// RETURNS: CSmptXPriority m_pcXMailer
  663. CSmptXPriority CSmtp::GetXPriority() const
  664. {
  665. return m_iXPriority;
  666. }
  667. const char* CSmtp::GetMsgLineText(unsigned int Line) const
  668. {
  669. if(Line > MsgBody.size())
  670. throw ECSmtp(ECSmtp::OUT_OF_MSG_RANGE);
  671. return MsgBody.at(Line).c_str();
  672. }
  673. unsigned int CSmtp::GetMsgLines() const
  674. {
  675. return MsgBody.size();
  676. }
  677. /// DESCRIPTION: Setting priority of the message.
  678. /// ARGUMENTS: CSmptXPriority priority - priority of the message ( XPRIORITY_HIGH,
  679. /// XPRIORITY_NORMAL, XPRIORITY_LOW)
  680. /// RETURNS: none
  681. void CSmtp::SetXPriority(CSmptXPriority priority)
  682. {
  683. m_iXPriority = priority;
  684. }
  685. /// DESCRIPTION: Setting the return address.
  686. /// ARGUMENTS: const char *ReplyTo - return address
  687. /// RETURNS: none
  688. void CSmtp::SetReplyTo(const char *ReplyTo)
  689. {
  690. m_sReplyTo.erase();
  691. m_sReplyTo.insert(0,ReplyTo);
  692. }
  693. /// DESCRIPTION: Setting sender's mail.
  694. /// ARGUMENTS: const char *EMail - sender's e-mail
  695. /// RETURNS: none
  696. void CSmtp::SetSenderMail(const char *EMail)
  697. {
  698. m_sMailFrom.erase();
  699. m_sMailFrom.insert(0,EMail);
  700. }
  701. /// DESCRIPTION: Setting sender's name.
  702. /// ARGUMENTS: const char *Name - sender's name
  703. /// RETURNS: none
  704. void CSmtp::SetSenderName(const char *Name)
  705. {
  706. m_sNameFrom.erase();
  707. m_sNameFrom.insert(0,Name);
  708. }
  709. /// DESCRIPTION: Setting subject of the message.
  710. /// ARGUMENTS: const char *Subject - subject of the message
  711. /// RETURNS: none
  712. void CSmtp::SetSubject(const char *Subject)
  713. {
  714. m_sSubject.erase();
  715. m_sSubject.insert(0,Subject);
  716. }
  717. /// DESCRIPTION: Setting the name of program which is sending the mail.
  718. /// ARGUMENTS: const char *XMailer - programe name
  719. /// RETURNS: none
  720. void CSmtp::SetXMailer(const char *XMailer)
  721. {
  722. m_sXMailer.erase();
  723. m_sXMailer.insert(0,XMailer);
  724. }
  725. /// DESCRIPTION: Setting the login of SMTP account's owner.
  726. /// ARGUMENTS: const char *Login - login of SMTP account's owner
  727. /// RETURNS: none
  728. void CSmtp::SetLogin(const char *Login)
  729. {
  730. m_sLogin.erase();
  731. m_sLogin.insert(0,Login);
  732. }
  733. /// DESCRIPTION: Setting the password of SMTP account's owner.
  734. /// ARGUMENTS: const char *Password - password of SMTP account's owner
  735. /// RETURNS: none
  736. void CSmtp::SetPassword(const char *Password)
  737. {
  738. m_sPassword.erase();
  739. m_sPassword.insert(0,Password);
  740. }
  741. /// DESCRIPTION: Setting the SMTP service name and port.
  742. /// ARGUMENTS: const char* SrvName - SMTP service name
  743. /// const unsigned short SrvPort - SMTO service port
  744. /// RETURNS: none
  745. void CSmtp::SetSMTPServer(const char* SrvName,const unsigned short SrvPort)
  746. {
  747. m_iSMTPSrvPort = SrvPort;
  748. m_sSMTPSrvName.erase();
  749. m_sSMTPSrvName.insert(0,SrvName);
  750. }
  751. /// DESCRIPTION: Returns the string for specified error code.
  752. /// ARGUMENTS: CSmtpError ErrorId - error code
  753. /// RETURNS: error string
  754. std::string ECSmtp::GetErrorText() const
  755. {
  756. switch(ErrorCode)
  757. {
  758. case ECSmtp::CSMTP_NO_ERROR:
  759. return "";
  760. case ECSmtp::WSA_STARTUP:
  761. return "Unable to initialise winsock2";
  762. case ECSmtp::WSA_VER:
  763. return "Wrong version of the winsock2";
  764. case ECSmtp::WSA_SEND:
  765. return "Function send() failed";
  766. case ECSmtp::WSA_RECV:
  767. return "Function recv() failed";
  768. case ECSmtp::WSA_CONNECT:
  769. return "Function connect failed";
  770. case ECSmtp::WSA_GETHOSTBY_NAME_ADDR:
  771. return "Unable to determine remote server";
  772. case ECSmtp::WSA_INVALID_SOCKET:
  773. return "Invalid winsock2 socket";
  774. case ECSmtp::WSA_HOSTNAME:
  775. return "Function hostname() failed";
  776. case ECSmtp::WSA_IOCTLSOCKET:
  777. return "Function ioctlsocket() failed";
  778. case ECSmtp::BAD_IPV4_ADDR:
  779. return "Improper IPv4 address";
  780. case ECSmtp::UNDEF_MSG_HEADER:
  781. return "Undefined message header";
  782. case ECSmtp::UNDEF_MAIL_FROM:
  783. return "Undefined mail sender";
  784. case ECSmtp::UNDEF_SUBJECT:
  785. return "Undefined message subject";
  786. case ECSmtp::UNDEF_RECIPIENTS:
  787. return "Undefined at least one reciepent";
  788. case ECSmtp::UNDEF_RECIPIENT_MAIL:
  789. return "Undefined recipent mail";
  790. case ECSmtp::UNDEF_LOGIN:
  791. return "Undefined user login";
  792. case ECSmtp::UNDEF_PASSWORD:
  793. return "Undefined user password";
  794. case ECSmtp::COMMAND_MAIL_FROM:
  795. return "Server returned error after sending MAIL FROM";
  796. case ECSmtp::COMMAND_EHLO:
  797. return "Server returned error after sending EHLO";
  798. case ECSmtp::COMMAND_AUTH_LOGIN:
  799. return "Server returned error after sending AUTH LOGIN";
  800. case ECSmtp::COMMAND_DATA:
  801. return "Server returned error after sending DATA";
  802. case ECSmtp::COMMAND_QUIT:
  803. return "Server returned error after sending QUIT";
  804. case ECSmtp::COMMAND_RCPT_TO:
  805. return "Server returned error after sending RCPT TO";
  806. case ECSmtp::MSG_BODY_ERROR:
  807. return "Error in message body";
  808. case ECSmtp::CONNECTION_CLOSED:
  809. return "Server has closed the connection";
  810. case ECSmtp::SERVER_NOT_READY:
  811. return "Server is not ready";
  812. case ECSmtp::SERVER_NOT_RESPONDING:
  813. return "Server not responding";
  814. case ECSmtp::FILE_NOT_EXIST:
  815. return "File not exist";
  816. case ECSmtp::MSG_TOO_BIG:
  817. return "Message is too big";
  818. case ECSmtp::BAD_LOGIN_PASS:
  819. return "Bad login or password";
  820. case ECSmtp::UNDEF_XYZ_RESPONSE:
  821. return "Undefined xyz SMTP response";
  822. case ECSmtp::LACK_OF_MEMORY:
  823. return "Lack of memory";
  824. case ECSmtp::TIME_ERROR:
  825. return "time() error";
  826. case ECSmtp::RECVBUF_IS_EMPTY:
  827. return "RecvBuf is empty";
  828. case ECSmtp::SENDBUF_IS_EMPTY:
  829. return "SendBuf is empty";
  830. case ECSmtp::OUT_OF_MSG_RANGE:
  831. return "Specified line number is out of message size";
  832. default:
  833. return "Undefined error id";
  834. }
  835. }