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 44 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 47 of file SmtpdSocket.h.

00047                      {
00048                 SMTP_NO_HELLO,
00049                 SMTP_NAME_TOO_LONG,
00050                 SMTP_DOMAIN_TOO_LONG,
00051                 SMTP_QUIT
00052         } reason_t;


Constructor & Destructor Documentation

SmtpdSocket::SmtpdSocket ( ISocketHandler h  ) 

Definition at line 39 of file SmtpdSocket.cpp.

References TcpSocket::SetLineProtocol().

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


Member Function Documentation

void SmtpdSocket::OnAccept (  )  [virtual]

Called when an incoming connection has been completed.

Reimplemented from Socket.

Definition at line 49 of file SmtpdSocket.cpp.

References TcpSocket::Send().

00050 {
00051         Send("220 ESMTP; \r\n");
00052 }

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 55 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().

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

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 139 of file SmtpdSocket.h.

Referenced by OnLine().

bool SmtpdSocket::m_data [private]

Definition at line 140 of file SmtpdSocket.h.

Referenced by OnLine().

bool SmtpdSocket::m_header [private]

Definition at line 141 of file SmtpdSocket.h.

Referenced by OnLine().

std::string SmtpdSocket::m_header_line [private]

Definition at line 142 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