Graphviz presentation of SMTP test FSM
[hlafsm.git] / test / smtp.cpp
blobaf6b2ea7aee63b8e6cd0070190ce93e15f18f12c
2 #include <ioevent>
4 #include <EvBufferEvent.hpp>
6 #include <evhttp.h>
8 #include <iostream>
10 extern "C" {
11 #include "smtpfsm.h"
14 extern "C" {
15 void smtpfsm_advance(struct myfsm * fsm, int, void *);
18 struct smtp_ctx {
19 struct myfsm * fsm;
21 EvBufferEvent * be;
22 struct bufferevent * bev;
24 const char * cur_line;
26 smtp_ctx() : fsm(MYFSM_INIT()) { }
28 ~smtp_ctx() {
29 MYFSM_FREE(fsm);
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);
45 ::evbuffer_free(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);
56 ::evbuffer_free(b);
59 extern "C" void mail_enter(enum myevent ev, enum mystate old_state, void *ctx)
61 smtp_ctx * c = (smtp_ctx *)ctx;
63 react_250_ok(c);
66 extern "C" void rcpt_enter(enum myevent ev, enum mystate old_state, void *ctx)
68 smtp_ctx * c = (smtp_ctx *)ctx;
70 react_250_ok(c);
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);
83 ::evbuffer_free(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);
96 ::evbuffer_free(b);
99 extern "C" void quit_enter(enum myevent ev, enum mystate old_state, void *ctx)
104 void readcb(struct bufferevent *bev, void * v)
106 char * line;
108 smtp_ctx * c = (smtp_ctx *)v;
110 while (line = ::evbuffer_readline(bev->input))
112 c->cur_line = line;
114 if (MYFSM_CURRENT(c->fsm) != DATA)
116 if (!strncmp(line, "HELO ", 5) ||
117 !strncmp(line, "EHLO ", 5))
119 //react_helo(c);
120 //myfsm_advance(c->fsm, HELO, c, myerr, MYERR_LEN);
121 smtpfsm_advance(c->fsm, HELO, c);
123 else
124 if (!strncmp(line, "MAIL", 4))
126 //react_250_ok(c);
127 //myfsm_advance(c->fsm, MAIL, c, myerr, MYERR_LEN);
128 smtpfsm_advance(c->fsm, MAIL, c);
130 else
131 if (!strncmp(line, "RCPT", 4))
133 //react_250_ok(c);
134 //myfsm_advance(c->fsm, RCPT, c, myerr, MYERR_LEN);
135 smtpfsm_advance(c->fsm, RCPT, c);
137 else
138 if (!strncmp(line, "DATA", 4))
140 //react_data(c);
141 //myfsm_advance(c->fsm, DATA, c, myerr, MYERR_LEN);
142 smtpfsm_advance(c->fsm, DATA, c);
144 else
145 if (!strncmp(line, "QUIT", 4))
147 //react_bye(c);
148 //myfsm_advance(c->fsm, QUIT, c, myerr, MYERR_LEN);
149 smtpfsm_advance(c->fsm, QUIT, c);
152 else
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);
163 free(line);
164 c->cur_line = NULL;
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);
185 be->accept(s1);
187 c->be = be;
188 c->bev = be->_bufferevent;
190 c->cur_line = NULL;
192 ::bufferevent_enable(be->_bufferevent, EV_READ);
194 be->write("220 www.example.com ESMTP postfix\r\n", 35);
198 main()
200 ::event_init();
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);
209 ::event_dispatch();