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 char *demomsg
= "From: Test John <testjohn@localhost>\n"
25 "To: test@localhost\n"
26 "Content-Type: text/plain\n"
27 "Date: Wed, 06 Jun 2007 15:21:21 -0700\n"
28 "Message-Id: <1181168481.15047.2.camel@localhost>\n"
30 "X-Mailer: Evolution 2.10.1 \n"
31 "Content-Transfer-Encoding: 7bit\n"
35 const int POP3_PORT
= 12001; //25;
36 const char CRLF
[2] = {0x0D, 0x0A};
38 const int CMD_USER
= 1;
39 const int CMD_PASS
= 2;
40 const int CMD_STAT
= 3;
41 const int CMD_LIST
= 4;
42 const int CMD_RETR
= 5;
43 const int CMD_DELE
= 6;
44 const int CMD_NOOP
= 7;
45 const int CMD_QUIT
= 8;
46 const int CMD_RSET
= 9;
47 const int CMD_TOP
= 10;
48 const int CMD_CAPA
= 10;
50 const char KEY_END_DATA
[6] = {0x0D, 0x0A, '.', 0x0D, 0x0A, 0x00};
54 #define STATE_TRANSACTION 3
55 #define STATE_UPDATE 4
58 if ((v
>= 65) && (v
<= 90))
64 if ((v
>= 97) && (v
<= 122))
76 class POP3Handler
: public ProtocolHandler
{
77 SearchTree
<int, 27, &knhash
> cmdtree
;
80 cmdtree
.Insert("USER", 1);
81 cmdtree
.Insert("PASS", 2);
82 cmdtree
.Insert("STAT", 3);
83 cmdtree
.Insert("LIST", 4);
84 cmdtree
.Insert("RETR", 5);
85 cmdtree
.Insert("DELE", 6);
86 cmdtree
.Insert("NOOP", 7);
87 cmdtree
.Insert("QUIT", 8);
88 cmdtree
.Insert("RSET", 9);
89 cmdtree
.Insert("TOP", 10);
90 cmdtree
.Insert("CAPA", 11);
91 printf("SearchTree Memory Usage: %i bytes\n", cmdtree
.getTreeSize());
93 int Handle(Socket
*s
){
98 int onrun
, cmd
, state
;
102 pcrecpp::RE
reg("[\\w\\a]*\\s([\\w\\a]*)");
104 ipc
= IPC::CreateIPC("socket://127.0.0.1:14000");
106 s
->Write("+OK FancyMail v0.1", 18);
114 memset(buffer
, 0, 255);
115 r
= s
->Read(buffer
, 255);
118 cmd
= cmdtree
.Lookup(buffer
);
119 }catch (SearchNotFound
){
123 if (cmd
== CMD_QUIT
){
124 printf("Got QUIT\n");
127 state
= STATE_UPDATE
;
132 if (cmd
== CMD_USER
){
133 reg
.PartialMatch(buffer
, &user
);
134 printf("Got USERNAME: %s\n", user
.c_str());
140 printf("INVALID [AUTH]: %s\n", buffer
);
141 s
->Write( "-ERR", 4);
146 if (cmd
== CMD_PASS
){
147 reg
.PartialMatch(buffer
, &pass
);
149 printf("Got Password: %s\n", pass
.c_str());
153 if (ipc
->RequestIPC())
157 msg
= new IPCMessage("auth");
158 msg
->PushParam((char*)user
.c_str());
159 msg
->PushParam((char*)pass
.c_str());
160 ipc
->PushMessage(msg
);
162 while(ipc
->PeekMessage() == 0){
164 msg
= ipc
->PopMessage();
168 if (!strcmp(msg
->GetMessageName(), "authok")){
171 state
= STATE_TRANSACTION
;
173 s
->Write( "-ERR", 4);
179 printf("INVALID [AUTH2]: %s\n", buffer
);
180 s
->Write( "-ERR", 4);
185 case STATE_TRANSACTION
:
188 printf("Got STAT Command\n");
189 s
->Write( "+OK 3 400", 9);
193 printf("Got LIST Command: %s\n", buffer
);
197 s
->Write( "1 150", 5);
200 s
->Write( "2 150", 5);
203 s
->Write( "3 100", 5);
209 printf("Got RETR Command: %s\n", buffer
);
210 s
->Write( "+OK 150 octets", 14);
213 s
->Write( demomsg
, strlen(demomsg
));
220 printf("Got DELE Command: %s\n", buffer
);
225 printf("Got NOOP Command\n");
230 printf("Got RSET Command\n");
234 printf("Got TOP Command: %s\n", buffer
);
235 for (i
= strlen(buffer
); i
> 0; i
--){
236 if (buffer
[i
] == ' ')
240 i
= atoi((char*)(buffer
+ i
));
248 for (r
= 0; r
< i
; r
++){
249 sscanf((char*)(demomsg
+j
), "%s", buffer
);
250 j
= j
+ strlen(buffer
);
251 s
->Write( buffer
, strlen(buffer
));
258 printf("INVALID [TRANS]: %s\n", buffer
);
259 s
->Write( "-ERR", 4);
268 printf("Closing Connection\n");
273 class SimpleLoad
: public LoadHandler
{
275 int Dispatch(Socket
*sock
, ProtocolHandler
*ph
){
277 return ph
->Handle(sock
);
282 int main(int argc
, char **argv
){
287 pop3
= new POP3Handler();
288 srv
= new BaseServer(pop3
, 12001);
289 lh
= new SimpleLoad();
290 srv
->SetLoadhandler(lh
);