Logo
~Sockets~
~Examples~
~Contact~


SMTPSocket.cpp

Go to the documentation of this file.
00001 // SMTPSocket.cpp
00002 /*
00003 Copyright (C) 2004  Anders Hedstrom
00004 
00005 This program is free software; you can redistribute it and/or
00006 modify it under the terms of the GNU General Public License
00007 as published by the Free Software Foundation; either version 2
00008 of the License, or (at your option) any later version.
00009 
00010 This program is distributed in the hope that it will be useful,
00011 but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 GNU General Public License for more details.
00014 
00015 You should have received a copy of the GNU General Public License
00016 along with this program; if not, write to the Free Software
00017 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00018 */
00019 
00020 #ifdef _WIN32
00021 #pragma warning(disable:4786)
00022 #endif
00023 //#include <assert.h>
00024 //#include <stdio.h>
00025 #ifdef _WIN32
00026 #define strcasecmp stricmp
00027 #endif
00028 
00029 #include "socket_include.h"
00030 #include "Parse.h"
00031 #include "FwdSocket.h"
00032 #include "Mailinst.h"
00033 #include "NukeHandler.h"
00034 #include "SMTPSocket.h"
00035 
00036 /*
00037 #ifdef _DEBUG
00038 #define DEB(x) x
00039 #else
00040 #define DEB(x)
00041 #endif
00042 */
00043 /*
00044 #define DEB(x) { \
00045         FILE *fil = fopen("C:\\deb.log","at"); \
00046         x; \
00047         fclose(fil); \
00048 }
00049 */
00050 #define DEB(x)
00051 
00052 
00053 SMTPSocket::SMTPSocket(ISocketHandler& h)
00054 :TcpSocket(h)
00055 ,m_remote(NULL)
00056 ,m_cmd_data(false)
00057 ,m_cmd_quit(false)
00058 {
00059         SetLineProtocol();
00060 }
00061 
00062 
00063 SMTPSocket::~SMTPSocket()
00064 {
00065         if (m_remote && Handler().Valid(m_remote) )
00066         {
00067 //              m_remote -> SetCloseAndDelete();
00068         }
00069 }
00070 
00071 
00072 void SMTPSocket::OnLine(const std::string& line)
00073 {
00074         Parse pa(line,":");
00075         std::string cmd = pa.getword();
00076 
00077         if (m_cmd_data)
00078         {
00079                 if (cmd == "From" && line.substr(0,5) == "From:" && !m_header_from.size())
00080                 {
00081                         m_header_from = pa.getrest();
00082                         printf(" %s\n",line.c_str());
00083                 }
00084                 else
00085                 if (cmd == "To" && line.substr(0,3) == "To:" && !m_header_to.size())
00086                 {
00087                         m_header_to = pa.getrest();
00088                         printf(" %s\n",line.c_str());
00089                 }
00090                 else
00091                 if (cmd == "Subject" && line.substr(0,8) == "Subject:" && !m_header_subject.size())
00092                 {
00093                         m_header_subject = pa.getrest();
00094                         printf(" %s\n",line.c_str());
00095                 }
00096                 else
00097                 if (cmd == ".")
00098                 {
00099                         if (m_fake)
00100                         {
00101                                 printf(" *** FAKE <221\n");
00102                                 Send("221 2.0.0 g2.alhem.net closing connection\r\n");
00103                         }
00104                         m_cmd_data = false;
00105                 }
00106                 m_data += line + "\r\n";
00107         }
00108         else
00109         if (!strcasecmp(cmd.c_str(), "MAIL") )
00110         {
00111                 m_cmd_mail = pa.getrest();
00112                 printf(" %s\n",line.c_str());
00113                 if (!strstr(m_cmd_mail.c_str(),"@") || !strstr(m_cmd_mail.c_str(),"."))
00114                 {
00115                         SetCloseAndDelete();
00116                 }
00117         }
00118         else
00119         if (!strcasecmp(cmd.c_str(), "RCPT") )
00120         {
00121                 m_cmd_rcpt = pa.getrest();
00122                 printf(" %s\n",line.c_str());
00123         }
00124         else
00125         if (!strcasecmp(cmd.c_str(), "DATA") )
00126         {
00127                 if (m_fake)
00128                 {
00129                         printf(" *** FAKE <354\n");
00130                         Send("354 Enter mail, end with \".\" on a line by itself\r\n");
00131                 }
00132                 m_cmd_data = true;
00133         }
00134         else
00135         if (!strcasecmp(cmd.c_str(), "QUIT") )
00136                 m_cmd_quit = true;
00137         else
00138         if (!m_cmd_data)
00139         {
00140                 printf("Command: %s\n",line.c_str());
00141         }
00142         if (m_remote && Handler().Valid(m_remote) && !m_fake)
00143         {
00144                 m_remote -> Send(line + "\r\n");
00145         }
00146         if (m_cmd_quit)
00147         {
00148                 db::Mailinst mq(*static_cast<NukeHandler&>(Handler()).GetDatabase(),
00149                         GetRemoteHostname(),
00150                         get_email(m_cmd_mail),
00151                         get_email(m_cmd_rcpt),
00152                         get_email(m_header_from),
00153                         get_email(m_header_to),
00154                         m_header_subject);
00155                 mq.save();
00156 //              printf(" %s\n %s\n",m_cmd_mail.c_str(),m_header_from.c_str());
00157 //              printf(" %s\n %s\n",m_cmd_rcpt.c_str(),m_header_to.c_str());
00158 //              printf(" %s\n",m_header_subject.c_str());
00159 //              printf("\n");
00160                 SetCloseAndDelete();
00161         }
00162 }
00163 
00164 
00165 void SMTPSocket::OnDelete()
00166 {
00167         if (m_remote && Handler().Valid(m_remote) )
00168         {
00169 //              m_remote -> SetCloseAndDelete();
00170         }
00171 }
00172 
00173 
00174 void SMTPSocket::OnAccept()
00175 {
00176         printf(" *** Remote Address: '%s'\n",GetRemoteHostname().c_str());
00177         if (Utility::isipv4(GetRemoteHostname()))
00178         {
00179                 // create a 'Spammer'
00180                 SetCloseAndDelete();
00181                 return;
00182         }
00183         m_remote = new FwdSocket(Handler());
00184         m_remote -> Open("mail.alhem.net",279);
00185         m_remote -> SetDeleteByHandler();
00186         m_remote -> SetRemote(this);
00187         Handler().Add(m_remote);
00188 }
00189 
00190 
00191 std::string SMTPSocket::get_email(const std::string& em)
00192 {
00193         char *tmp = new char[em.size() + 1];
00194         strcpy(tmp, em.c_str());
00195         char *p = strstr(tmp,"<");
00196         if (p)
00197         {
00198                 char *p2 = strstr(p,">");
00199                 if (p2)
00200                 {
00201                         *p2 = 0;
00202                         std::string str = p + 1;
00203                         delete tmp;
00204                         return str;
00205                 }
00206         }
00207         delete tmp;
00208         return em;
00209 }
00210 
00211 
Page, code, and content Copyright (C) 2006 by Anders Hedström
Generated on Mon Aug 29 20:21:47 2005 for C++ Sockets by  doxygen 1.4.4