Logo
~Sockets~
~Examples~
~Contact~


SmtpdSocket Class Reference

Smtp server base class. More...

#include <SmtpdSocket.h>

Inheritance diagram for SmtpdSocket:
Collaboration diagram for SmtpdSocket:

List of all members.


Public Member Functions

 SmtpdSocket (ISocketHandler &)
void OnAccept ()
 Called when an incoming connection has been completed.
void OnLine (const std::string &)
 Callback fires when a socket in line protocol has read one full line.
virtual bool OnHello (const std::string &domain)=0
virtual bool OnMailFrom (const EmailAddress &addr)=0
virtual bool OnRcptTo (const EmailAddress &addr)=0
virtual void OnHeader (const std::string &key, const std::string &value)=0
virtual void OnHeaderComplete ()=0
virtual void OnData (const std::string &line)=0
virtual bool OnDataComplete ()=0
virtual void OnRset ()=0
virtual void OnAbort (reason_t)=0
virtual void OnNotSupported (const std::string &cmd, const std::string &arg)=0

Protected Types

enum  reason_t { SMTP_NO_HELLO, SMTP_NAME_TOO_LONG, SMTP_DOMAIN_TOO_LONG, SMTP_QUIT }

Private Attributes

bool m_hello
bool m_data
bool m_header
std::string m_header_line

Classes

class  EmailAddress

Detailed Description

Smtp server base class.

Definition at line 46 of file SmtpdSocket.h.


Member Enumeration Documentation

enum SmtpdSocket::reason_t [protected]

Enumerator:
SMTP_NO_HELLO 
SMTP_NAME_TOO_LONG 
SMTP_DOMAIN_TOO_LONG 
SMTP_QUIT 

Definition at line 49 of file SmtpdSocket.h.

00049                      {
00050                 SMTP_NO_HELLO,
00051                 SMTP_NAME_TOO_LONG,
00052                 SMTP_DOMAIN_TOO_LONG,
00053                 SMTP_QUIT
00054         } reason_t;


Constructor & Destructor Documentation

SmtpdSocket::SmtpdSocket ( ISocketHandler h  ) 

Definition at line 41 of file SmtpdSocket.cpp.

References TcpSocket::SetLineProtocol().

00042 :TcpSocket(h)
00043 ,m_hello(false)
00044 ,m_data(false)
00045 ,m_header(false)
00046 {
00047         SetLineProtocol();
00048 }


Member Function Documentation

void SmtpdSocket::OnAccept (  )  [virtual]

Called when an incoming connection has been completed.

Reimplemented from Socket.

Definition at line 51 of file SmtpdSocket.cpp.

References TcpSocket::Send().

00052 {
00053         Send("220 ESMTP; \r\n");
00054 }

void SmtpdSocket::OnLine ( const std::string &  line  )  [virtual]

Callback fires when a socket in line protocol has read one full line.

Parameters:
line Line read

Reimplemented from TcpSocket.

Definition at line 57 of file SmtpdSocket.cpp.

References Parse::getrest(), Parse::getword(), m_data, m_header, m_header_line, m_hello, OnAbort(), OnData(), OnDataComplete(), OnHeader(), OnHeaderComplete(), OnHello(), OnMailFrom(), OnNotSupported(), OnRcptTo(), OnRset(), TcpSocket::Send(), Socket::SetCloseAndDelete(), SMTP_DOMAIN_TOO_LONG, SMTP_NAME_TOO_LONG, SMTP_NO_HELLO, SMTP_QUIT, Utility::ToLower(), and Utility::ToUpper().

00058 {
00059         if (m_data)
00060         {
00061                 if (m_header)
00062                 {
00063                         if (!line.size())
00064                         {
00065                                 if (m_header_line.size())
00066                                 {
00067                                         Parse pa(m_header_line, ":");
00068                                         std::string key = pa.getword();
00069                                         OnHeader(key, pa.getrest());
00070                                 }
00071                                 m_header = false;
00072                                 OnHeaderComplete();
00073                         }
00074                         else
00075                         if (line[0] == ' ' || line[0] == '\t')
00076                         {
00077                                 m_header_line += line;
00078                         }
00079                         else
00080                         {
00081                                 if (m_header_line.size())
00082                                 {
00083                                         Parse pa(m_header_line, ":");
00084                                         std::string key = pa.getword();
00085                                         OnHeader(key, pa.getrest());
00086                                 }
00087                                 m_header_line = line;
00088                         }
00089                 }
00090                 else
00091                 if (line == ".")
00092                 {
00093                         m_data = false;
00094                         if (OnDataComplete())
00095                                 Send("250 OK\r\n");
00096                         else
00097                                 Send("550 Failed\r\n");
00098                 }
00099                 else
00100                 if (line.size() && line[0] == '.')
00101                 {
00102                         OnData(line.substr(1));
00103                 }
00104                 else
00105                 {
00106                         OnData(line);
00107                 }
00108                 return;
00109         }
00110         Parse pa(line);
00111         std::string cmd = Utility::ToUpper(pa.getword());
00112 
00113         if (cmd == "EHLO")
00114         {
00115                 if (!OnHello(pa.getrest()))
00116                 {
00117                         Send("550 Failed\r\n");
00118                 }
00119                 else
00120                 {
00121                         m_hello = true;
00122                         Send("250 mail.alhem.net\r\n");
00123                 }
00124         }
00125         else
00126         if (cmd == "HELO")
00127         {
00128                 if (!OnHello(pa.getrest()))
00129                 {
00130                         Send("550 Failed\r\n");
00131                 }
00132                 else
00133                 {
00134                         m_hello = true;
00135                         Send("250 mail.alhem.net\r\n");
00136                 }
00137         }
00138         else
00139         if (!m_hello)
00140         {
00141                 OnAbort(SMTP_NO_HELLO);
00142                 SetCloseAndDelete();
00143         }
00144         else
00145         if (cmd == "MAIL") // mail from:
00146         {
00147                 Parse pa(line, ":");
00148                 pa.getword(); // 'mail'
00149                 pa.getword(); // 'from'
00150                 std::string email = Utility::ToLower(pa.getrest());
00151 
00152                 EmailAddress addr( email );
00153                 if (addr.GetName().size() > 64)
00154                 {
00155                         OnAbort(SMTP_NAME_TOO_LONG);
00156                         Send("500 Name too long.\r\n");
00157                         return;
00158                 }
00159                 if (addr.GetDomain().size() > 64)
00160                 {
00161                         OnAbort(SMTP_DOMAIN_TOO_LONG);
00162                         Send("500 Domain too long.\r\n");
00163                         return;
00164                 }
00165 
00166                 if (!OnMailFrom( addr ))
00167                 {
00168                         Send("550 Failed\r\n");
00169                 }
00170                 else
00171                 {
00172                         Send("250 OK\r\n");
00173                 }
00174         }
00175         else
00176         if (cmd == "RCPT") // rcpt to:
00177         {
00178                 Parse pa(line, ":");
00179                 pa.getword(); // 'rcpt'
00180                 pa.getword(); // 'to'
00181                 std::string email = Utility::ToLower(pa.getrest());
00182                 // %! reject based on user / domain?
00183                 EmailAddress addr( email );
00184 
00185                 if (addr.GetName().size() > 64)
00186                 {
00187                         OnAbort(SMTP_NAME_TOO_LONG);
00188                         Send("500 Name too long.\r\n");
00189                         return;
00190                 }
00191                 if (addr.GetDomain().size() > 64)
00192                 {
00193                         OnAbort(SMTP_DOMAIN_TOO_LONG);
00194                         Send("500 Domain too long.\r\n");
00195                         return;
00196                 }
00197 
00198                 if (!OnRcptTo( addr ))
00199                 {
00200                         Send("553 Failed\r\n");
00201                 }
00202                 else
00203                 {
00204                         Send("250 OK\r\n");
00205                 }
00206         }
00207         else
00208         if (cmd == "DATA")
00209         {
00210                 Send("354 Enter mail, end with \".\" on a line by itself\r\n");
00211                 m_data = true;
00212                 m_header = false;
00213         }
00214         else
00215         if (cmd == "RSET")
00216         {
00217                 m_data = false;
00218                 m_header = false;
00219                 OnRset();
00220                 Send("250 OK\r\n"); // %! ???
00221         }
00222         else
00223         if (cmd == "QUIT")
00224         {
00225                 OnAbort(SMTP_QUIT);
00226                 Send("221 Bye Bye\r\n");
00227                 SetCloseAndDelete();
00228         }
00229         else
00230         if (cmd == "NOOP")
00231         {
00232                 Send("250 OK\r\n");
00233         }
00234         else
00235         {
00236                 OnNotSupported(cmd, pa.getrest());
00237         }
00238 }

virtual bool SmtpdSocket::OnHello ( const std::string &  domain  )  [pure virtual]

Returns:
'false' to abort

Referenced by OnLine().

virtual bool SmtpdSocket::OnMailFrom ( const EmailAddress addr  )  [pure virtual]

Returns:
'false' to abort

Referenced by OnLine().

virtual bool SmtpdSocket::OnRcptTo ( const EmailAddress addr  )  [pure virtual]

Returns:
'false' to abort

Referenced by OnLine().

virtual void SmtpdSocket::OnHeader ( const std::string &  key,
const std::string &  value 
) [pure virtual]

Referenced by OnLine().

virtual void SmtpdSocket::OnHeaderComplete (  )  [pure virtual]

Referenced by OnLine().

virtual void SmtpdSocket::OnData ( const std::string &  line  )  [pure virtual]

Referenced by OnLine().

virtual bool SmtpdSocket::OnDataComplete (  )  [pure virtual]

Returns:
'false' if message write failed (message will probably be resent)

Referenced by OnLine().

virtual void SmtpdSocket::OnRset (  )  [pure virtual]

Referenced by OnLine().

virtual void SmtpdSocket::OnAbort ( reason_t   )  [pure virtual]

Referenced by OnLine().

virtual void SmtpdSocket::OnNotSupported ( const std::string &  cmd,
const std::string &  arg 
) [pure virtual]

Referenced by OnLine().


Member Data Documentation

bool SmtpdSocket::m_hello [private]

Definition at line 141 of file SmtpdSocket.h.

Referenced by OnLine().

bool SmtpdSocket::m_data [private]

Definition at line 142 of file SmtpdSocket.h.

Referenced by OnLine().

bool SmtpdSocket::m_header [private]

Definition at line 143 of file SmtpdSocket.h.

Referenced by OnLine().

std::string SmtpdSocket::m_header_line [private]

Definition at line 144 of file SmtpdSocket.h.

Referenced by OnLine().


The documentation for this class was generated from the following files:
Page, code, and content Copyright (C) 2007 by Anders Hedström
Generated for C++ Sockets by  doxygen 1.4.4