4 #include <EvBufferEvent.hpp>
15 void smtpfsm_advance(struct myfsm
* fsm
, int, void *);
22 struct bufferevent
* bev
;
24 const char * cur_line
;
26 smtp_ctx() : fsm(MYFSM_INIT()) { }
33 extern "C" void helo_enter(enum myevent ev
, enum mystate old_state
, void *ctx
)
35 smtp_ctx
* c
= (smtp_ctx
*)ctx
;
37 bufferevent
* bev
= c
->bev
;
38 evbuffer
* b
= ::evbuffer_new();
40 const char * line
= c
->cur_line
;
42 ::evbuffer_add_printf(b
, "250 Hello %s\r\n", line
+ 5);
43 ::bufferevent_write_buffer(bev
, b
);
48 extern "C" void react_250_ok(smtp_ctx
* c
)
50 bufferevent
* bev
= c
->bev
;
51 evbuffer
* b
= ::evbuffer_new();
53 ::evbuffer_add_printf(b
, "250 Ok\r\n");
54 ::bufferevent_write_buffer(bev
, b
);
59 extern "C" void mail_enter(enum myevent ev
, enum mystate old_state
, void *ctx
)
61 smtp_ctx
* c
= (smtp_ctx
*)ctx
;
66 extern "C" void rcpt_enter(enum myevent ev
, enum mystate old_state
, void *ctx
)
68 smtp_ctx
* c
= (smtp_ctx
*)ctx
;
73 extern "C" void data_enter(enum myevent ev
, enum mystate old_state
, void *ctx
)
75 smtp_ctx
* c
= (smtp_ctx
*)ctx
;
77 bufferevent
* bev
= c
->bev
;
78 evbuffer
* b
= ::evbuffer_new();
80 ::evbuffer_add_printf(b
, "354 End data with <CR><LF>.<CR><LF>\r\n");
81 ::bufferevent_write_buffer(bev
, b
);
86 extern "C" void quit_callback(enum myevent ev
, void *ctx
)
88 smtp_ctx
* c
= (smtp_ctx
*)ctx
;
90 bufferevent
* bev
= c
->bev
;
91 evbuffer
* b
= ::evbuffer_new();
93 ::evbuffer_add_printf(b
, "221 Bye\r\n");
94 ::bufferevent_write_buffer(bev
, b
);
99 extern "C" void quit_enter(enum myevent ev
, enum mystate old_state
, void *ctx
)
104 void readcb(struct bufferevent
*bev
, void * v
)
108 smtp_ctx
* c
= (smtp_ctx
*)v
;
110 while (line
= ::evbuffer_readline(bev
->input
))
114 if (MYFSM_CURRENT(c
->fsm
) != DATA
)
116 if (!strncmp(line
, "HELO ", 5) ||
117 !strncmp(line
, "EHLO ", 5))
120 //myfsm_advance(c->fsm, HELO, c, myerr, MYERR_LEN);
121 smtpfsm_advance(c
->fsm
, HELO
, c
);
124 if (!strncmp(line
, "MAIL", 4))
127 //myfsm_advance(c->fsm, MAIL, c, myerr, MYERR_LEN);
128 smtpfsm_advance(c
->fsm
, MAIL
, c
);
131 if (!strncmp(line
, "RCPT", 4))
134 //myfsm_advance(c->fsm, RCPT, c, myerr, MYERR_LEN);
135 smtpfsm_advance(c
->fsm
, RCPT
, c
);
138 if (!strncmp(line
, "DATA", 4))
141 //myfsm_advance(c->fsm, DATA, c, myerr, MYERR_LEN);
142 smtpfsm_advance(c
->fsm
, DATA
, c
);
145 if (!strncmp(line
, "QUIT", 4))
148 //myfsm_advance(c->fsm, QUIT, c, myerr, MYERR_LEN);
149 smtpfsm_advance(c
->fsm
, QUIT
, c
);
154 if (!strcmp(line
, "."))
156 //react_data_line(c);
157 //myfsm_advance(c->fsm, END_DATA, c, myerr, sizeof myerr - 1);
158 //myfsm_advance(c->fsm, END_DATA, c, myerr, sizeof(myerr) - 1);
159 smtpfsm_advance(c
->fsm
, END_DATA
, c
);
169 void writecb(struct bufferevent
*, void *)
174 void errorcb(struct bufferevent
*, short, void *)
179 void accept_handler(int s1
, short, void *)
181 smtp_ctx
* c
= new smtp_ctx
;
183 EvBufferEvent
* be
= new EvBufferEvent(readcb
, writecb
, errorcb
, c
);
188 c
->bev
= be
->_bufferevent
;
192 ::bufferevent_enable(be
->_bufferevent
, EV_READ
);
194 be
->write("220 www.example.com ESMTP postfix\r\n", 35);
202 int sock
= ::bind_socket(NULL
, 5525);
204 ::bufev_socket_listen(sock
, 10);
206 ioevent
accept_event(sock
, EV_READ
, &accept_handler
, NULL
);
207 ::event_add(&accept_event
, NULL
);