Logo
~Sockets~
~Examples~
~Contact~


SmtpdSocket Class Reference

Smtp server base class. More...

#include <SmtpdSocket.h>

Inheritance diagram for SmtpdSocket:

Inheritance graph
[legend]
Collaboration diagram for SmtpdSocket:

Collaboration graph
[legend]
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
 
Returns:
'false' to abort

virtual bool OnMailFrom (const EmailAddress &addr)=0
 
Returns:
'false' to abort

virtual bool OnRcptTo (const EmailAddress &addr)=0
 
Returns:
'false' to abort

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
 
Returns:
'false' if message write failed (message will probably be resent)

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

00039                      {
00040                 SMTP_NO_HELLO,
00041                 SMTP_NAME_TOO_LONG,
00042                 SMTP_DOMAIN_TOO_LONG,
00043                 SMTP_QUIT
00044         } reason_t;


Constructor & Destructor Documentation

SmtpdSocket::SmtpdSocket ( ISocketHandler  ) 

Definition at line 31 of file SmtpdSocket.cpp.

References TcpSocket::SetLineProtocol().

00032 :TcpSocket(h)
00033 ,m_hello(false)
00034 ,m_data(false)
00035 ,m_header(false)
00036 {
00037         SetLineProtocol();
00038 }


Member Function Documentation

void SmtpdSocket::OnAccept (  )  [virtual]

Called when an incoming connection has been completed.

Reimplemented from Socket.

Definition at line 41 of file SmtpdSocket.cpp.

References TcpSocket::Send().

00042 {
00043         Send("220 ESMTP; \r\n");
00044 }

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

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

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

Referenced by OnLine().

bool SmtpdSocket::m_data [private]

Definition at line 132 of file SmtpdSocket.h.

Referenced by OnLine().

bool SmtpdSocket::m_header [private]

Definition at line 133 of file SmtpdSocket.h.

Referenced by OnLine().

std::string SmtpdSocket::m_header_line [private]

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