Added a EditorSocial.
[UnsignedByte.git] / src / Sockets / SmtpdSocket.cpp
blob7e9f17b14aa4fec2d9eb3628d15b151705f22ac6
1 /**
2 ** \file SmtpdSocket.cpp
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 #include "SmtpdSocket.h"
24 #include "Parse.h"
25 #include "Utility.h"
28 SmtpdSocket::SmtpdSocket(ISocketHandler& h)
29 :TcpSocket(h)
30 ,m_hello(false)
31 ,m_data(false)
32 ,m_header(false)
34 SetLineProtocol();
38 void SmtpdSocket::OnAccept()
40 Send("220 ESMTP; \r\n");
44 void SmtpdSocket::OnLine(const std::string& line)
46 if (m_data)
48 if (m_header)
50 if (!line.size())
52 if (m_header_line.size())
54 Parse pa(m_header_line, ":");
55 std::string key = pa.getword();
56 OnHeader(key, pa.getrest());
58 m_header = false;
59 OnHeaderComplete();
61 else
62 if (line[0] == ' ' || line[0] == '\t')
64 m_header_line += line;
66 else
68 if (m_header_line.size())
70 Parse pa(m_header_line, ":");
71 std::string key = pa.getword();
72 OnHeader(key, pa.getrest());
74 m_header_line = line;
77 else
78 if (line == ".")
80 m_data = false;
81 if (OnDataComplete())
82 Send("250 OK\r\n");
83 else
84 Send("550 Failed\r\n");
86 else
87 if (line.size() && line[0] == '.')
89 OnData(line.substr(1));
91 else
93 OnData(line);
95 return;
97 Parse pa(line);
98 std::string cmd = Utility::ToUpper(pa.getword());
100 if (cmd == "EHLO")
102 if (!OnHello(pa.getrest()))
104 Send("550 Failed\r\n");
106 else
108 m_hello = true;
109 Send("250 mail.alhem.net\r\n");
112 else
113 if (cmd == "HELO")
115 if (!OnHello(pa.getrest()))
117 Send("550 Failed\r\n");
119 else
121 m_hello = true;
122 Send("250 mail.alhem.net\r\n");
125 else
126 if (!m_hello)
128 OnAbort(SMTP_NO_HELLO);
129 SetCloseAndDelete();
131 else
132 if (cmd == "MAIL") // mail from:
134 Parse pa(line, ":");
135 pa.getword(); // 'mail'
136 pa.getword(); // 'from'
137 std::string email = Utility::ToLower(pa.getrest());
139 EmailAddress addr( email );
140 if (addr.GetName().size() > 64)
142 OnAbort(SMTP_NAME_TOO_LONG);
143 Send("500 Name too long.\r\n");
144 return;
146 if (addr.GetDomain().size() > 64)
148 OnAbort(SMTP_DOMAIN_TOO_LONG);
149 Send("500 Domain too long.\r\n");
150 return;
153 if (!OnMailFrom( addr ))
155 Send("550 Failed\r\n");
157 else
159 Send("250 OK\r\n");
162 else
163 if (cmd == "RCPT") // rcpt to:
165 Parse pa(line, ":");
166 pa.getword(); // 'rcpt'
167 pa.getword(); // 'to'
168 std::string email = Utility::ToLower(pa.getrest());
169 // %! reject based on user / domain?
170 EmailAddress addr( email );
172 if (addr.GetName().size() > 64)
174 OnAbort(SMTP_NAME_TOO_LONG);
175 Send("500 Name too long.\r\n");
176 return;
178 if (addr.GetDomain().size() > 64)
180 OnAbort(SMTP_DOMAIN_TOO_LONG);
181 Send("500 Domain too long.\r\n");
182 return;
185 if (!OnRcptTo( addr ))
187 Send("553 Failed\r\n");
189 else
191 Send("250 OK\r\n");
194 else
195 if (cmd == "DATA")
197 Send("354 Enter mail, end with \".\" on a line by itself\r\n");
198 m_data = true;
199 m_header = false;
201 else
202 if (cmd == "RSET")
204 m_data = false;
205 m_header = false;
206 OnRset();
207 Send("250 OK\r\n"); // %! ???
209 else
210 if (cmd == "QUIT")
212 OnAbort(SMTP_QUIT);
213 Send("221 Bye Bye\r\n");
214 SetCloseAndDelete();
216 else
217 if (cmd == "NOOP")
219 Send("250 OK\r\n");
221 else
223 OnNotSupported(cmd, pa.getrest());