blob: d1ac150980006f63fd08c0aa94aedbb4776e95fe [file] [log] [blame]
adamdunkelsa2f3c422004-09-12 20:24:53 +00001/*
2 * Copyright (c) 2004, Adam Dunkels.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the Institute nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * This file is part of the Contiki operating system.
30 *
31 * Author: Adam Dunkels <adam@sics.se>
32 *
adamdunkelsd0791bb2005-02-22 22:23:07 +000033 * $Id: popc.c,v 1.3 2005/02/22 22:23:08 adamdunkels Exp $
adamdunkelsa2f3c422004-09-12 20:24:53 +000034 */
adamdunkels6c190432004-09-09 20:51:18 +000035
36#include "contiki.h"
37#include "popc.h"
38#include "popc-strings.h"
39
adamdunkelsd0791bb2005-02-22 22:23:07 +000040#define SEND_STRING(s, str) PSOCK_SEND(s, str, strlen(str))
adamdunkels6c190432004-09-09 20:51:18 +000041
42enum {
43 COMMAND_NONE,
44 COMMAND_RETR,
45 COMMAND_TOP,
46 COMMAND_QUIT
47};
48
49/*---------------------------------------------------------------------------*/
50static
51PT_THREAD(init_connection(struct popc_state *s))
52{
adamdunkelsd0791bb2005-02-22 22:23:07 +000053 PSOCK_BEGIN(&s->s);
adamdunkels6c190432004-09-09 20:51:18 +000054
adamdunkelsd0791bb2005-02-22 22:23:07 +000055 PSOCK_READTO(&s->s, '\n');
adamdunkels6c190432004-09-09 20:51:18 +000056 if(s->inputbuf[0] != '+') {
adamdunkelsd0791bb2005-02-22 22:23:07 +000057 PSOCK_CLOSE_EXIT(&s->s);
adamdunkels6c190432004-09-09 20:51:18 +000058 }
59
60 SEND_STRING(&s->s, popc_strings_user);
61 SEND_STRING(&s->s, s->user);
62 SEND_STRING(&s->s, popc_strings_crnl);
63
adamdunkelsd0791bb2005-02-22 22:23:07 +000064 PSOCK_READTO(&s->s, '\n');
adamdunkels6c190432004-09-09 20:51:18 +000065 if(s->inputbuf[0] != '+') {
adamdunkelsd0791bb2005-02-22 22:23:07 +000066 PSOCK_CLOSE_EXIT(&s->s);
adamdunkels6c190432004-09-09 20:51:18 +000067 }
68
69 SEND_STRING(&s->s, popc_strings_pass);
70 SEND_STRING(&s->s, s->pass);
71 SEND_STRING(&s->s, popc_strings_crnl);
72
adamdunkelsd0791bb2005-02-22 22:23:07 +000073 PSOCK_READTO(&s->s, '\n');
adamdunkels6c190432004-09-09 20:51:18 +000074 if(s->inputbuf[0] != '+') {
adamdunkelsd0791bb2005-02-22 22:23:07 +000075 PSOCK_CLOSE_EXIT(&s->s);
adamdunkels6c190432004-09-09 20:51:18 +000076 }
77
78 popc_connected(s);
79
adamdunkelsd0791bb2005-02-22 22:23:07 +000080 PSOCK_END(&s->s);
adamdunkels6c190432004-09-09 20:51:18 +000081}
82/*---------------------------------------------------------------------------*/
83static
84PT_THREAD(stat(struct popc_state *s))
85{
86 unsigned short num;
87 unsigned long size;
88 char *ptr;
89
adamdunkelsd0791bb2005-02-22 22:23:07 +000090 PSOCK_BEGIN(&s->s);
adamdunkels6c190432004-09-09 20:51:18 +000091
92 SEND_STRING(&s->s, popc_strings_stat);
93
adamdunkelsd0791bb2005-02-22 22:23:07 +000094 PSOCK_READTO(&s->s, '\n');
adamdunkels6c190432004-09-09 20:51:18 +000095 if(s->inputbuf[0] != '+') {
adamdunkelsd0791bb2005-02-22 22:23:07 +000096 PSOCK_CLOSE_EXIT(&s->s);
adamdunkels6c190432004-09-09 20:51:18 +000097 }
98
99 num = 0;
100 for(ptr = &s->inputbuf[4]; *ptr >= '0' && *ptr <= '9'; ++ptr) {
101 num *= 10;
102 num += *ptr - '0';
103 }
104
105 size = 0;
106 for(ptr = ptr + 1; *ptr >= '0' && *ptr <= '9'; ++ptr) {
107 size *= 10;
108 size += *ptr - '0';
109 }
110
111 popc_messages(s, num, size);
112
adamdunkelsd0791bb2005-02-22 22:23:07 +0000113 PSOCK_END(&s->s);
adamdunkels6c190432004-09-09 20:51:18 +0000114}
115/*---------------------------------------------------------------------------*/
116static
117PT_THREAD(retr(struct popc_state *s))
118{
adamdunkelsd0791bb2005-02-22 22:23:07 +0000119 PSOCK_BEGIN(&s->s);
adamdunkels6c190432004-09-09 20:51:18 +0000120
121 SEND_STRING(&s->s, popc_strings_retr);
122 snprintf(s->outputbuf, sizeof(s->outputbuf), "%d", s->num);
123 SEND_STRING(&s->s, s->outputbuf);
124 SEND_STRING(&s->s, popc_strings_crnl);
125
adamdunkelsd0791bb2005-02-22 22:23:07 +0000126 PSOCK_READTO(&s->s, '\n');
adamdunkels6c190432004-09-09 20:51:18 +0000127 if(s->inputbuf[0] != '+') {
adamdunkelsd0791bb2005-02-22 22:23:07 +0000128 PSOCK_CLOSE_EXIT(&s->s);
adamdunkels6c190432004-09-09 20:51:18 +0000129 }
130
131 popc_msgbegin(s);
132 while(s->inputbuf[0] != '.') {
adamdunkelsd0791bb2005-02-22 22:23:07 +0000133 PSOCK_READTO(&s->s, '\n');
adamdunkels6c190432004-09-09 20:51:18 +0000134 if(s->inputbuf[0] != '.') {
adamdunkelsd0791bb2005-02-22 22:23:07 +0000135 s->inputbuf[PSOCK_DATALEN(&s->s)] = 0;
136 popc_msgline(s, s->inputbuf, PSOCK_DATALEN(&s->s));
adamdunkels6c190432004-09-09 20:51:18 +0000137 }
138 }
139 popc_msgend(s);
140
adamdunkelsd0791bb2005-02-22 22:23:07 +0000141 PSOCK_END(&s->s);
adamdunkels6c190432004-09-09 20:51:18 +0000142
143}
144/*---------------------------------------------------------------------------*/
145static
146PT_THREAD(handle_connection(struct popc_state *s))
147{
148 PT_BEGIN(&s->pt);
149
adamdunkelsd0791bb2005-02-22 22:23:07 +0000150 PSOCK_INIT(&s->s, s->inputbuf, sizeof(s->inputbuf) - 1);
adamdunkels6c190432004-09-09 20:51:18 +0000151
152 PT_WAIT_UNTIL(&s->pt, init_connection(s));
153 PT_WAIT_UNTIL(&s->pt, stat(s));
154
155 timer_set(&s->timer, CLOCK_SECOND * 30);
156
157 while(1) {
158 PT_WAIT_UNTIL(&s->pt, s->command != COMMAND_NONE ||
159 timer_expired(&s->timer));
160
161 if(timer_expired(&s->timer)) {
162 PT_WAIT_UNTIL(&s->pt, stat(s));
163 timer_set(&s->timer, CLOCK_SECOND * 30);
164 }
165
166 switch(s->command) {
167 case COMMAND_RETR:
168 PT_WAIT_UNTIL(&s->pt, retr(s));
169 break;
170 case COMMAND_QUIT:
171 tcp_markconn(uip_conn, NULL);
adamdunkelsd0791bb2005-02-22 22:23:07 +0000172 PSOCK_CLOSE(&s->s);
adamdunkels6c190432004-09-09 20:51:18 +0000173 PT_EXIT(&s->pt);
174 break;
175 default:
176 break;
177 }
178 s->command = COMMAND_NONE;
179
180 }
181 PT_END(&s->pt);
182}
183/*---------------------------------------------------------------------------*/
184void
185popc_appcall(void *state)
186{
187 struct popc_state *s = (struct popc_state *)state;
188
189 if(uip_closed() || uip_aborted() || uip_timedout()) {
190 popc_closed(s);
191 } else if(uip_connected()) {
192 PT_INIT(&s->pt);
193 handle_connection(s);
194 } else if(s != NULL) {
195 handle_connection(s);
196 }
197
198}
199/*---------------------------------------------------------------------------*/
200void *
201popc_connect(struct popc_state *s, u16_t *addr,
202 char *user, char *pass)
203{
204 strncpy(s->user, user, sizeof(s->user));
205 strncpy(s->pass, pass, sizeof(s->pass));
206 s->conn = tcp_connect(addr, HTONS(110), s);
207 return s->conn;
208}
209/*---------------------------------------------------------------------------*/
210void
211popc_retr(struct popc_state *s, unsigned short num)
212{
213 s->command = COMMAND_RETR;
214 s->num = num;
215}
216/*---------------------------------------------------------------------------*/
217void
218popc_top(struct popc_state *s, unsigned short num, unsigned short lines)
219{
220 s->command = COMMAND_TOP;
221 s->num = num;
222 s->lines = lines;
223}
224/*---------------------------------------------------------------------------*/