4 Copyright (C) 2007 Carlos Daniel Ruvalcaba Valenzuela <clsdaniel@gmail.com>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License along
17 with this program; if not, write to the Free Software Foundation, Inc.,
18 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 const int SMTP_PORT
= 12000; //25;
25 const char CRLF
[2] = {0x0D, 0x0A};
27 const int CMD_EHLO
= 1;
28 const int CMD_HELO
= 2;
29 const int CMD_MAIL
= 3;
30 const int CMD_RCPT
= 4;
31 const int CMD_DATA
= 5;
32 const int CMD_QUIT
= 6;
33 const int CMD_RSET
= 7;
34 const char KEY_END_DATA
[6] = {0x0D, 0x0A, '.', 0x0D, 0x0A, 0x00};
37 if ((v
>= 65) && (v
<= 90))
43 if ((v
>= 97) && (v
<= 122))
55 class SMTPHandler
: public ProtocolHandler
{
56 SearchTree
<int, 27, &knhash
> cmdtree
;
59 cmdtree
.Insert("EHLO", 1);
60 cmdtree
.Insert("HELO", 2);
61 cmdtree
.Insert("MAIL", 3);
62 cmdtree
.Insert("RCPT", 4);
63 cmdtree
.Insert("DATA", 5);
64 cmdtree
.Insert("QUIT", 6);
65 cmdtree
.Insert("RSET", 7);
67 int Handle(Socket
*s
){
68 char buffer
[255], username
[255], recipent
[255];
70 int onrun
, cmd
, state
;
72 pcrecpp::RE
reCmd("\\w*:<(.*)>");
76 string mailfrom
, rcpt
;
79 s
->Write("220 FancyMail v0.1", 18);
83 memset(buffer
, 0, 255);
84 r
= s
->Read(buffer
, 255);
87 cmd
= cmdtree
.Lookup(buffer
);
88 }catch (SearchNotFound
){
94 s
->Write("250 ok localhost", 16);
99 s
->Write( "502 Not implemented", 19);
104 s
->Write( "502 Not implemented", 19);
108 ret
= reCmd
.PartialMatch(buffer
, &mailfrom
);
109 printf("[Debug] Sending Mail From: %s\n", mailfrom
.c_str());
110 s
->Write( "250 OK", 6);
116 s
->Write( "502 Not implemented", 19);
120 reCmd
.PartialMatch(buffer
, &rcpt
);
121 printf("[Debug] Recipent: %s\n", rcpt
.c_str());
122 s
->Write( "250 OK", 6);
128 s
->Write( "502 Not implemented", 19);
132 printf("Reciving Data!\n");
133 s
->Write( "354 OK", 6);
140 memset(buffer
, 0, 255);
142 l
= s
->Read( buffer
, 255);
143 printf("%s", buffer
);
145 if (strstr(buffer
, KEY_END_DATA
)){
147 printf("\nEnd of Data\n");
149 printf("Buffer[%i]: %s\n", l
, buffer
);
154 s
->Write( "250 OK", 6);
159 s
->Write( "250 OK", 6);
164 printf("Got Quit, Exiting\n");
165 s
->Write( "221 Exiting", 11);
170 printf("Not implemented [State: %i]: %s\n", state
, buffer
);
171 s
->Write( "502 Not implemented", 19);
176 printf("[COMMAND]: %s\n", buffer
);
179 printf("Closing Connection\n");
184 class SimpleLoad
: public LoadHandler
{
186 int Dispatch(Socket
*sock
, ProtocolHandler
*ph
){
188 return ph
->Handle(sock
);
193 int main(int argc
, char **argv
){
196 SMTPHandler
*handler
;
198 handler
= new SMTPHandler();
199 lh
= new SimpleLoad();
200 srv
= new BaseServer(handler
, SMTP_PORT
);
201 srv
->SetLoadhandler(lh
);