switched from PracticalSocket to libasio
[anytun.git] / src / Sockets / SmtpdSocket.h
blobd884d051ab653da1029b772ba7c179ffaf77bac8
1 /**
2 ** \file SmtpdSocket.h
3 ** \date 2007-05-10
4 ** \author grymse@alhem.net
5 **/
6 /*
7 Copyright (C) 2007 Anders Hedstrom
9 This program is free software; you can redistribute it and/or
10 modify it under the terms of the GNU General Public License
11 as published by the Free Software Foundation; either version 2
12 of the License, or (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #ifndef _SOCKETS_SmtpdSocket_H
24 #define _SOCKETS_SmtpdSocket_H
26 #include "sockets-config.h"
27 #include <string>
28 #include "TcpSocket.h"
30 #ifdef SOCKETS_NAMESPACE
31 namespace SOCKETS_NAMESPACE {
32 #endif
35 /** Smtp server base class. */
36 class SmtpdSocket : public TcpSocket
38 protected:
39 typedef enum {
40 SMTP_NO_HELLO,
41 SMTP_NAME_TOO_LONG,
42 SMTP_DOMAIN_TOO_LONG,
43 SMTP_QUIT
44 } reason_t;
46 public:
47 class EmailAddress {
48 public:
49 EmailAddress(const std::string& str_in)
51 std::string str = str_in;
52 size_t i = str.find("<");
53 if (i != std::string::npos)
54 str = str.substr(i + 1);
55 i = str.find("@");
56 if (i != std::string::npos)
58 m_name = str.substr(0, i);
59 str = str.substr(i + 1);
60 i = str.find(">");
61 if (i != std::string::npos)
62 str = str.substr(0, i);
63 m_domain = str;
65 while (m_name.size() && m_name[m_name.size() - 1] == ' ')
66 m_name.resize(m_name.size() - 1);
67 while (m_domain.size() && m_domain[m_domain.size() - 1] == ' ')
68 m_domain.resize(m_domain.size() - 1);
69 while (m_name.size() && m_name[0] == ' ')
70 m_name = m_name.substr(1);
71 while (m_domain.size() && m_domain[0] == ' ')
72 m_domain = m_domain.substr(1);
73 m_top = m_domain;
75 for (size_t i = 0; i < m_domain.size(); i++)
77 if (m_domain[i] == '.')
79 m_sub = m_top;
80 m_top = m_domain.substr(i + 1);
86 const std::string& GetName() const { return m_name; }
87 const std::string& GetDomain() const { return m_domain; }
88 const std::string& GetTopDomain() const { return m_top; }
89 const std::string& GetSubDomain() const { return m_sub; }
91 std::string ToString() const { return m_name + "@" + m_domain; }
93 private:
94 std::string m_name;
95 std::string m_domain;
96 std::string m_top;
97 std::string m_sub;
100 public:
101 SmtpdSocket(ISocketHandler&);
103 void OnAccept();
104 void OnLine(const std::string&);
106 /** \return 'false' to abort */
107 virtual bool OnHello(const std::string& domain) = 0;
109 /** \return 'false' to abort */
110 virtual bool OnMailFrom(const EmailAddress& addr) = 0;
112 /** \return 'false' to abort */
113 virtual bool OnRcptTo(const EmailAddress& addr) = 0;
115 virtual void OnHeader(const std::string& key, const std::string& value) = 0;
117 virtual void OnHeaderComplete() = 0;
119 virtual void OnData(const std::string& line) = 0;
121 /** \return 'false' if message write failed (message will probably be resent) */
122 virtual bool OnDataComplete() = 0;
124 virtual void OnRset() = 0;
126 virtual void OnAbort(reason_t) = 0;
128 virtual void OnNotSupported(const std::string& cmd, const std::string& arg) = 0;
130 private:
131 bool m_hello; // we need HELO or EHLO first of all
132 bool m_data;
133 bool m_header;
134 std::string m_header_line;
138 #ifdef SOCKETS_NAMESPACE
139 } // namespace SOCKETS_NAMESPACE {
140 #endif
142 #endif // _SOCKETS_SmtpdSocket_H