blob: 17a195403cf149a68aa9c8b7d2c04797967b3adc [file] [log] [blame]
adamdunkels6c190432004-09-09 20:51:18 +00001
2#include "contiki.h"
3#include "popc.h"
4#include "popc-strings.h"
5
6#define SEND_STRING(s, str) SOCKET_SEND(s, str, strlen(str))
7
8enum {
9 COMMAND_NONE,
10 COMMAND_RETR,
11 COMMAND_TOP,
12 COMMAND_QUIT
13};
14
15/*---------------------------------------------------------------------------*/
16static
17PT_THREAD(init_connection(struct popc_state *s))
18{
19 SOCKET_BEGIN(&s->s);
20
21 SOCKET_READTO(&s->s, '\n');
22 if(s->inputbuf[0] != '+') {
23 SOCKET_CLOSE_EXIT(&s->s);
24 }
25
26 SEND_STRING(&s->s, popc_strings_user);
27 SEND_STRING(&s->s, s->user);
28 SEND_STRING(&s->s, popc_strings_crnl);
29
30 SOCKET_READTO(&s->s, '\n');
31 if(s->inputbuf[0] != '+') {
32 SOCKET_CLOSE_EXIT(&s->s);
33 }
34
35 SEND_STRING(&s->s, popc_strings_pass);
36 SEND_STRING(&s->s, s->pass);
37 SEND_STRING(&s->s, popc_strings_crnl);
38
39 SOCKET_READTO(&s->s, '\n');
40 if(s->inputbuf[0] != '+') {
41 SOCKET_CLOSE_EXIT(&s->s);
42 }
43
44 popc_connected(s);
45
46 SOCKET_END(&s->s);
47}
48/*---------------------------------------------------------------------------*/
49static
50PT_THREAD(stat(struct popc_state *s))
51{
52 unsigned short num;
53 unsigned long size;
54 char *ptr;
55
56 SOCKET_BEGIN(&s->s);
57
58 SEND_STRING(&s->s, popc_strings_stat);
59
60 SOCKET_READTO(&s->s, '\n');
61 if(s->inputbuf[0] != '+') {
62 SOCKET_CLOSE_EXIT(&s->s);
63 }
64
65 num = 0;
66 for(ptr = &s->inputbuf[4]; *ptr >= '0' && *ptr <= '9'; ++ptr) {
67 num *= 10;
68 num += *ptr - '0';
69 }
70
71 size = 0;
72 for(ptr = ptr + 1; *ptr >= '0' && *ptr <= '9'; ++ptr) {
73 size *= 10;
74 size += *ptr - '0';
75 }
76
77 popc_messages(s, num, size);
78
79 SOCKET_END(&s->s);
80}
81/*---------------------------------------------------------------------------*/
82static
83PT_THREAD(retr(struct popc_state *s))
84{
85 SOCKET_BEGIN(&s->s);
86
87 SEND_STRING(&s->s, popc_strings_retr);
88 snprintf(s->outputbuf, sizeof(s->outputbuf), "%d", s->num);
89 SEND_STRING(&s->s, s->outputbuf);
90 SEND_STRING(&s->s, popc_strings_crnl);
91
92 SOCKET_READTO(&s->s, '\n');
93 if(s->inputbuf[0] != '+') {
94 SOCKET_CLOSE_EXIT(&s->s);
95 }
96
97 popc_msgbegin(s);
98 while(s->inputbuf[0] != '.') {
99 SOCKET_READTO(&s->s, '\n');
100 if(s->inputbuf[0] != '.') {
101 s->inputbuf[SOCKET_DATALEN(&s->s)] = 0;
102 popc_msgline(s, s->inputbuf, SOCKET_DATALEN(&s->s));
103 }
104 }
105 popc_msgend(s);
106
107 SOCKET_END(&s->s);
108
109}
110/*---------------------------------------------------------------------------*/
111static
112PT_THREAD(handle_connection(struct popc_state *s))
113{
114 PT_BEGIN(&s->pt);
115
116 SOCKET_INIT(&s->s, s->inputbuf, sizeof(s->inputbuf) - 1);
117
118 PT_WAIT_UNTIL(&s->pt, init_connection(s));
119 PT_WAIT_UNTIL(&s->pt, stat(s));
120
121 timer_set(&s->timer, CLOCK_SECOND * 30);
122
123 while(1) {
124 PT_WAIT_UNTIL(&s->pt, s->command != COMMAND_NONE ||
125 timer_expired(&s->timer));
126
127 if(timer_expired(&s->timer)) {
128 PT_WAIT_UNTIL(&s->pt, stat(s));
129 timer_set(&s->timer, CLOCK_SECOND * 30);
130 }
131
132 switch(s->command) {
133 case COMMAND_RETR:
134 PT_WAIT_UNTIL(&s->pt, retr(s));
135 break;
136 case COMMAND_QUIT:
137 tcp_markconn(uip_conn, NULL);
138 SOCKET_CLOSE(&s->s);
139 PT_EXIT(&s->pt);
140 break;
141 default:
142 break;
143 }
144 s->command = COMMAND_NONE;
145
146 }
147 PT_END(&s->pt);
148}
149/*---------------------------------------------------------------------------*/
150void
151popc_appcall(void *state)
152{
153 struct popc_state *s = (struct popc_state *)state;
154
155 if(uip_closed() || uip_aborted() || uip_timedout()) {
156 popc_closed(s);
157 } else if(uip_connected()) {
158 PT_INIT(&s->pt);
159 handle_connection(s);
160 } else if(s != NULL) {
161 handle_connection(s);
162 }
163
164}
165/*---------------------------------------------------------------------------*/
166void *
167popc_connect(struct popc_state *s, u16_t *addr,
168 char *user, char *pass)
169{
170 strncpy(s->user, user, sizeof(s->user));
171 strncpy(s->pass, pass, sizeof(s->pass));
172 s->conn = tcp_connect(addr, HTONS(110), s);
173 return s->conn;
174}
175/*---------------------------------------------------------------------------*/
176void
177popc_retr(struct popc_state *s, unsigned short num)
178{
179 s->command = COMMAND_RETR;
180 s->num = num;
181}
182/*---------------------------------------------------------------------------*/
183void
184popc_top(struct popc_state *s, unsigned short num, unsigned short lines)
185{
186 s->command = COMMAND_TOP;
187 s->num = num;
188 s->lines = lines;
189}
190/*---------------------------------------------------------------------------*/