blob: 98ce6598bf9c7702848ff913b090b9134d2082ac [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: ircc.c,v 1.9 2005/02/22 22:23:08 adamdunkels Exp $
adamdunkelsa2f3c422004-09-12 20:24:53 +000034 */
adamdunkels2bd076e2004-09-03 08:11:09 +000035
36#include "contiki.h"
adamdunkels5a2df1c2004-09-01 19:11:42 +000037#include "ircc.h"
38
adamdunkels25e95082004-09-12 07:12:44 +000039#include "irc-conf.h"
40
adamdunkels2bd076e2004-09-03 08:11:09 +000041#include "ircc-strings.h"
42
adamdunkelsf7a92b22004-09-12 17:53:29 +000043#include "petsciiconv.h"
44
adamdunkels5a2df1c2004-09-01 19:11:42 +000045#include <string.h>
46
47#define PORT 6667
48
adamdunkelsd0791bb2005-02-22 22:23:07 +000049#define SEND_STRING(s, str) PSOCK_SEND(s, str, strlen(str))
adamdunkels5a2df1c2004-09-01 19:11:42 +000050
adamdunkels2bd076e2004-09-03 08:11:09 +000051#define ISO_space 0x20
52#define ISO_bang 0x21
53#define ISO_at 0x40
54#define ISO_cr 0x0d
55#define ISO_nl 0x0a
56#define ISO_colon 0x3a
57#define ISO_O 0x4f
58
adamdunkels5a2df1c2004-09-01 19:11:42 +000059enum {
60 COMMAND_NONE,
61 COMMAND_JOIN,
62 COMMAND_PART,
63 COMMAND_MSG,
adamdunkels8d8b7452004-09-09 21:05:56 +000064 COMMAND_ACTIONMSG,
adamdunkels5a2df1c2004-09-01 19:11:42 +000065 COMMAND_LIST,
adamdunkels2bd076e2004-09-03 08:11:09 +000066 COMMAND_QUIT
adamdunkels5a2df1c2004-09-01 19:11:42 +000067};
68
69/*---------------------------------------------------------------------------*/
70void
71ircc_init(void)
72{
73
74}
75/*---------------------------------------------------------------------------*/
76static char *
adamdunkels2bd076e2004-09-03 08:11:09 +000077copystr(char *dest, const char *src, int n)
adamdunkels5a2df1c2004-09-01 19:11:42 +000078{
79 int len;
80
81 len = strlen(src);
82 strncpy(dest, src, n);
83
84 if(len > n) {
85 return dest + n;
86 } else {
87 return dest + len;
88 }
89}
90/*---------------------------------------------------------------------------*/
91static
92PT_THREAD(setup_connection(struct ircc_state *s))
93{
94 char *ptr;
95
96
adamdunkelsd0791bb2005-02-22 22:23:07 +000097 PSOCK_BEGIN(&s->s);
adamdunkels5a2df1c2004-09-01 19:11:42 +000098
99 ptr = s->outputbuf;
adamdunkels25e95082004-09-12 07:12:44 +0000100 ptr = copystr(ptr, ircc_strings_nick, sizeof(s->outputbuf));
adamdunkels5a2df1c2004-09-01 19:11:42 +0000101 ptr = copystr(ptr, s->nick, sizeof(s->outputbuf) - (ptr - s->outputbuf));
adamdunkels25e95082004-09-12 07:12:44 +0000102 ptr = copystr(ptr, ircc_strings_crnl_user, sizeof(s->outputbuf) - (ptr - s->outputbuf));
adamdunkels5a2df1c2004-09-01 19:11:42 +0000103 ptr = copystr(ptr, s->nick, sizeof(s->outputbuf) - (ptr - s->outputbuf));
adamdunkels25e95082004-09-12 07:12:44 +0000104 ptr = copystr(ptr, ircc_strings_contiki, sizeof(s->outputbuf) - (ptr - s->outputbuf));
adamdunkels5a2df1c2004-09-01 19:11:42 +0000105 ptr = copystr(ptr, s->server, sizeof(s->outputbuf) - (ptr - s->outputbuf));
adamdunkels25e95082004-09-12 07:12:44 +0000106 ptr = copystr(ptr, ircc_strings_colon_contiki, sizeof(s->outputbuf) - (ptr - s->outputbuf));
adamdunkels5a2df1c2004-09-01 19:11:42 +0000107
108 SEND_STRING(&s->s, s->outputbuf);
109
adamdunkelsd0791bb2005-02-22 22:23:07 +0000110 PSOCK_END(&s->s);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000111}
112/*---------------------------------------------------------------------------*/
113static
114PT_THREAD(join_channel(struct ircc_state *s))
115{
adamdunkelsd0791bb2005-02-22 22:23:07 +0000116 PSOCK_BEGIN(&s->s);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000117
adamdunkels25e95082004-09-12 07:12:44 +0000118 SEND_STRING(&s->s, ircc_strings_join);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000119 SEND_STRING(&s->s, s->channel);
adamdunkels25e95082004-09-12 07:12:44 +0000120 SEND_STRING(&s->s, ircc_strings_crnl);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000121
122 ircc_sent(s);
123
adamdunkelsd0791bb2005-02-22 22:23:07 +0000124 PSOCK_END(&s->s);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000125}
126/*---------------------------------------------------------------------------*/
127static
128PT_THREAD(part_channel(struct ircc_state *s))
129{
adamdunkelsd0791bb2005-02-22 22:23:07 +0000130 PSOCK_BEGIN(&s->s);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000131
adamdunkels25e95082004-09-12 07:12:44 +0000132 SEND_STRING(&s->s, ircc_strings_part);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000133 SEND_STRING(&s->s, s->channel);
adamdunkels25e95082004-09-12 07:12:44 +0000134 SEND_STRING(&s->s, ircc_strings_crnl);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000135
136 ircc_sent(s);
137
adamdunkelsd0791bb2005-02-22 22:23:07 +0000138 PSOCK_END(&s->s);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000139}
140/*---------------------------------------------------------------------------*/
141static
142PT_THREAD(list_channel(struct ircc_state *s))
143{
adamdunkelsd0791bb2005-02-22 22:23:07 +0000144 PSOCK_BEGIN(&s->s);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000145
adamdunkels25e95082004-09-12 07:12:44 +0000146 SEND_STRING(&s->s, ircc_strings_list);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000147 SEND_STRING(&s->s, s->channel);
adamdunkels25e95082004-09-12 07:12:44 +0000148 SEND_STRING(&s->s, ircc_strings_crnl);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000149
150 ircc_sent(s);
151
adamdunkelsd0791bb2005-02-22 22:23:07 +0000152 PSOCK_END(&s->s);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000153}
154/*---------------------------------------------------------------------------*/
155static
156PT_THREAD(send_message(struct ircc_state *s))
157{
158 char *ptr;
159
adamdunkelsd0791bb2005-02-22 22:23:07 +0000160 PSOCK_BEGIN(&s->s);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000161
162 ptr = s->outputbuf;
adamdunkels25e95082004-09-12 07:12:44 +0000163 ptr = copystr(ptr, ircc_strings_privmsg, sizeof(s->outputbuf));
adamdunkels5a2df1c2004-09-01 19:11:42 +0000164 ptr = copystr(ptr, s->channel, sizeof(s->outputbuf) - (ptr - s->outputbuf));
adamdunkels25e95082004-09-12 07:12:44 +0000165 ptr = copystr(ptr, ircc_strings_colon, sizeof(s->outputbuf) - (ptr - s->outputbuf));
adamdunkels5a2df1c2004-09-01 19:11:42 +0000166 ptr = copystr(ptr, s->msg, sizeof(s->outputbuf) - (ptr - s->outputbuf));
adamdunkels25e95082004-09-12 07:12:44 +0000167 ptr = copystr(ptr, ircc_strings_crnl, sizeof(s->outputbuf) - (ptr - s->outputbuf));
adamdunkels5a2df1c2004-09-01 19:11:42 +0000168
169 SEND_STRING(&s->s, s->outputbuf);
170
171 ircc_sent(s);
172
adamdunkelsd0791bb2005-02-22 22:23:07 +0000173 PSOCK_END(&s->s);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000174}
175/*---------------------------------------------------------------------------*/
adamdunkels8d8b7452004-09-09 21:05:56 +0000176static
177PT_THREAD(send_actionmessage(struct ircc_state *s))
178{
179 char *ptr;
180
adamdunkelsd0791bb2005-02-22 22:23:07 +0000181 PSOCK_BEGIN(&s->s);
adamdunkels8d8b7452004-09-09 21:05:56 +0000182
183 ptr = s->outputbuf;
adamdunkels25e95082004-09-12 07:12:44 +0000184 ptr = copystr(ptr, ircc_strings_privmsg, sizeof(s->outputbuf));
adamdunkels8d8b7452004-09-09 21:05:56 +0000185 ptr = copystr(ptr, s->channel, sizeof(s->outputbuf) - (ptr - s->outputbuf));
adamdunkels25e95082004-09-12 07:12:44 +0000186 ptr = copystr(ptr, ircc_strings_colon, sizeof(s->outputbuf) - (ptr - s->outputbuf));
187 ptr = copystr(ptr, ircc_strings_action, sizeof(s->outputbuf) - (ptr - s->outputbuf));
adamdunkels8d8b7452004-09-09 21:05:56 +0000188 ptr = copystr(ptr, s->msg, sizeof(s->outputbuf) - (ptr - s->outputbuf));
adamdunkels25e95082004-09-12 07:12:44 +0000189 ptr = copystr(ptr, ircc_strings_ctcpcrnl, sizeof(s->outputbuf) - (ptr - s->outputbuf));
adamdunkels8d8b7452004-09-09 21:05:56 +0000190
191
192 SEND_STRING(&s->s, s->outputbuf);
193
194 ircc_sent(s);
195
adamdunkelsd0791bb2005-02-22 22:23:07 +0000196 PSOCK_END(&s->s);
adamdunkels8d8b7452004-09-09 21:05:56 +0000197}
198/*---------------------------------------------------------------------------*/
adamdunkels5a2df1c2004-09-01 19:11:42 +0000199struct parse_result {
adamdunkels2bd076e2004-09-03 08:11:09 +0000200 char *msg;
201
adamdunkels5a2df1c2004-09-01 19:11:42 +0000202 char *user;
203 char *host;
204 char *name;
205 char *command;
206 char *middle;
207 char *trailing;
208};
adamdunkels2bd076e2004-09-03 08:11:09 +0000209static struct parse_result r;
210static void
211parse_whitespace(void)
adamdunkels5a2df1c2004-09-01 19:11:42 +0000212{
adamdunkels2bd076e2004-09-03 08:11:09 +0000213 while(*r.msg == ISO_space) ++r.msg;
adamdunkels5a2df1c2004-09-01 19:11:42 +0000214}
adamdunkels2bd076e2004-09-03 08:11:09 +0000215static void
216parse_word(void)
adamdunkels5a2df1c2004-09-01 19:11:42 +0000217{
adamdunkels2bd076e2004-09-03 08:11:09 +0000218 char *ptr;
219 ptr = strchr(r.msg, ISO_space);
220 if(ptr != NULL) {
221 r.msg = ptr;
222 }
adamdunkels5a2df1c2004-09-01 19:11:42 +0000223}
adamdunkels2bd076e2004-09-03 08:11:09 +0000224static void
225parse_user(void)
adamdunkels5a2df1c2004-09-01 19:11:42 +0000226{
adamdunkels2bd076e2004-09-03 08:11:09 +0000227 parse_whitespace();
228 r.user = r.msg;
229 parse_word();
230 *r.msg = 0;
231 ++r.msg;
adamdunkels5a2df1c2004-09-01 19:11:42 +0000232}
adamdunkels2bd076e2004-09-03 08:11:09 +0000233static void
234parse_host(void)
adamdunkels5a2df1c2004-09-01 19:11:42 +0000235{
adamdunkels2bd076e2004-09-03 08:11:09 +0000236 parse_whitespace();
237 r.host = r.msg;
238 parse_word();
239 *r.msg = 0;
240 ++r.msg;
adamdunkels5a2df1c2004-09-01 19:11:42 +0000241}
242
adamdunkels2bd076e2004-09-03 08:11:09 +0000243static void
244parse_name(void)
adamdunkels5a2df1c2004-09-01 19:11:42 +0000245{
adamdunkels2bd076e2004-09-03 08:11:09 +0000246 parse_whitespace();
247 r.name = r.msg;
248 parse_word();
249 *r.msg = 0;
250 ++r.msg;
adamdunkels5a2df1c2004-09-01 19:11:42 +0000251}
252
adamdunkels2bd076e2004-09-03 08:11:09 +0000253static void
254parse_prefix(void)
adamdunkels5a2df1c2004-09-01 19:11:42 +0000255{
adamdunkels2bd076e2004-09-03 08:11:09 +0000256 parse_name();
257 if(*r.msg == ISO_bang) {
258 ++r.msg;
259 parse_user();
adamdunkels5a2df1c2004-09-01 19:11:42 +0000260 }
adamdunkels2bd076e2004-09-03 08:11:09 +0000261 if(*r.msg == ISO_at) {
262 ++r.msg;
263 parse_host();
adamdunkels5a2df1c2004-09-01 19:11:42 +0000264 }
265}
266
267static void
adamdunkels2bd076e2004-09-03 08:11:09 +0000268parse_command(void)
adamdunkels5a2df1c2004-09-01 19:11:42 +0000269{
adamdunkels2bd076e2004-09-03 08:11:09 +0000270 parse_whitespace();
271 r.command = r.msg;
272 parse_word();
273 *r.msg = 0;
274 ++r.msg;
275}
276
adamdunkels8b1784b2004-09-05 07:13:05 +0000277/*static void
adamdunkels2bd076e2004-09-03 08:11:09 +0000278parse_trailing(void)
279{
280 r.trailing = r.msg;
281 while(*r.msg != 0 && *r.msg != ISO_cr && *r.msg != ISO_nl) ++r.msg;
282 *r.msg = 0;
283 ++r.msg;
adamdunkels8b1784b2004-09-05 07:13:05 +0000284}*/
adamdunkels2bd076e2004-09-03 08:11:09 +0000285
286static void
287parse_params(void)
288{
289 char *ptr;
290
291 parse_whitespace();
292 ptr = strchr(r.msg, ISO_colon);
293 if(ptr != NULL) {
294 r.trailing = ptr + 1;
295 ptr = strchr(ptr, ISO_cr);
296 if(ptr != NULL) {
297 *ptr = 0;
298 }
299 }
300}
301
302static void
303parse(char *msg, struct parse_result *dummy)
304{
305 r.msg = msg;
306 if(*r.msg == ISO_cr || *r.msg == ISO_nl) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000307 return;
308 }
adamdunkels2bd076e2004-09-03 08:11:09 +0000309 if(*r.msg == ISO_colon) {
310 ++r.msg;
311 parse_prefix();
adamdunkels5a2df1c2004-09-01 19:11:42 +0000312 }
313
adamdunkels2bd076e2004-09-03 08:11:09 +0000314 parse_command();
315 parse_params();
316
adamdunkels25e95082004-09-12 07:12:44 +0000317 /* printf("user %s host %s name %s command %s middle %s trailing %s\n",
318 r.user, r.host, r.name, r.command, r.middle, r.trailing);*/
adamdunkels5a2df1c2004-09-01 19:11:42 +0000319}
adamdunkels2bd076e2004-09-03 08:11:09 +0000320
adamdunkels5a2df1c2004-09-01 19:11:42 +0000321/*---------------------------------------------------------------------------*/
322static
323PT_THREAD(handle_input(struct ircc_state *s))
324{
adamdunkels5a2df1c2004-09-01 19:11:42 +0000325 char *ptr;
adamdunkels2bd076e2004-09-03 08:11:09 +0000326 /* struct parse_result r;*/
adamdunkels5a2df1c2004-09-01 19:11:42 +0000327
adamdunkelsd0791bb2005-02-22 22:23:07 +0000328 PSOCK_BEGIN(&s->s);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000329
adamdunkelsd0791bb2005-02-22 22:23:07 +0000330 PSOCK_READTO(&s->s, ISO_nl);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000331
adamdunkelsd0791bb2005-02-22 22:23:07 +0000332 if(PSOCK_DATALEN(&s->s) > 0) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000333
adamdunkelsd0791bb2005-02-22 22:23:07 +0000334 s->inputbuf[PSOCK_DATALEN(&s->s)] = 0;
adamdunkels5a2df1c2004-09-01 19:11:42 +0000335
adamdunkels25e95082004-09-12 07:12:44 +0000336 if(strncmp(s->inputbuf, ircc_strings_ping, 5) == 0) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000337 strncpy(s->outputbuf, s->inputbuf, sizeof(s->outputbuf));
338
339 /* Turn "PING" into "PONG" */
adamdunkels2bd076e2004-09-03 08:11:09 +0000340 s->outputbuf[1] = ISO_O;
adamdunkels5a2df1c2004-09-01 19:11:42 +0000341 SEND_STRING(&s->s, s->outputbuf);
342 } else {
343
344 memset(&r, 0, sizeof(r));
345
346 parse(s->inputbuf, &r);
347
348 if(r.name != NULL) {
adamdunkels2bd076e2004-09-03 08:11:09 +0000349 ptr = strchr(r.name, ISO_bang);
350 if(ptr != NULL) {
351 *ptr = 0;
adamdunkels5a2df1c2004-09-01 19:11:42 +0000352 }
353 }
354
adamdunkels25e95082004-09-12 07:12:44 +0000355 if(r.command != NULL && strncmp(r.command, ircc_strings_join, 4) == 0) {
356 ircc_text_output(s, "Joined channel", r.name);
357 } else if(r.command != NULL && strncmp(r.command, ircc_strings_part, 4) == 0) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000358 ircc_text_output(s, "Left channel", r.name);
adamdunkels25e95082004-09-12 07:12:44 +0000359 } else if(r.trailing != NULL) {
360 if(strncmp(r.trailing, ircc_strings_action,
361 strlen(ircc_strings_action)) == 0) {
362 ptr = strchr(&r.trailing[1], 1);
363 if(ptr != NULL) {
364 *ptr = 0;
365 }
adamdunkelsf7a92b22004-09-12 17:53:29 +0000366 ptr = &r.trailing[strlen(ircc_strings_action)];
367 petsciiconv_topetscii(r.name, strlen(r.name));
368 petsciiconv_topetscii(ptr, strlen(ptr));
369 ircc_text_output(s, r.name, ptr);
adamdunkels25e95082004-09-12 07:12:44 +0000370 } else if(strncmp(r.trailing, ircc_strings_version_query,
371 strlen(ircc_strings_version_query)) == 0) {
372 if(r.name != NULL) {
373 strncpy(s->outputbuf, r.name, sizeof(s->outputbuf));
374 SEND_STRING(&s->s, ircc_strings_notice);
375 /* user is temporarily stored in outputbuf. */
376 SEND_STRING(&s->s, s->outputbuf);
377 SEND_STRING(&s->s, ircc_strings_colon);
378 SEND_STRING(&s->s, ircc_strings_version);
379 SEND_STRING(&s->s, ircc_strings_version_string);
380 SEND_STRING(&s->s, IRC_CONF_SYSTEM_STRING);
381 SEND_STRING(&s->s, ircc_strings_ctcpcrnl);
382 }
383 } else {
adamdunkelsf7a92b22004-09-12 17:53:29 +0000384 petsciiconv_topetscii(r.name, strlen(r.name));
385 petsciiconv_topetscii(r.trailing, strlen(r.trailing));
adamdunkels25e95082004-09-12 07:12:44 +0000386 ircc_text_output(s, r.name, r.trailing);
387 }
adamdunkels5a2df1c2004-09-01 19:11:42 +0000388 }
389 }
390 }
391
adamdunkelsd0791bb2005-02-22 22:23:07 +0000392 PSOCK_END(&s->s);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000393}
394/*---------------------------------------------------------------------------*/
395static
396PT_THREAD(data_or_command(struct ircc_state *s))
397{
adamdunkelsd0791bb2005-02-22 22:23:07 +0000398 PSOCK_BEGIN(&s->s);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000399
adamdunkelsd0791bb2005-02-22 22:23:07 +0000400 PSOCK_WAIT_UNTIL(&s->s, PSOCK_NEWDATA(&s->s) ||
401 (s->command != COMMAND_NONE));
adamdunkels5a2df1c2004-09-01 19:11:42 +0000402
adamdunkelsd0791bb2005-02-22 22:23:07 +0000403 PSOCK_END(&s->s);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000404}
405/*---------------------------------------------------------------------------*/
406static
407PT_THREAD(handle_connection(struct ircc_state *s))
408{
409 PT_BEGIN(&s->pt);
410
adamdunkelsd0791bb2005-02-22 22:23:07 +0000411 PSOCK_INIT(&s->s, s->inputbuf, sizeof(s->inputbuf) - 1);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000412
413 PT_WAIT_THREAD(&s->pt, setup_connection(s));
414
415 while(1) {
416
417 PT_WAIT_UNTIL(&s->pt, data_or_command(s));
418
adamdunkelsd0791bb2005-02-22 22:23:07 +0000419 if(PSOCK_NEWDATA(&s->s)) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000420 PT_WAIT_THREAD(&s->pt, handle_input(s));
421 }
422
423 switch(s->command) {
424 case COMMAND_JOIN:
425 s->command = COMMAND_NONE;
426 PT_WAIT_THREAD(&s->pt, join_channel(s));
427 break;
428 case COMMAND_PART:
429 s->command = COMMAND_NONE;
430 PT_WAIT_THREAD(&s->pt, part_channel(s));
431 break;
432 case COMMAND_MSG:
433 s->command = COMMAND_NONE;
434 PT_WAIT_THREAD(&s->pt, send_message(s));
435 break;
adamdunkels8d8b7452004-09-09 21:05:56 +0000436 case COMMAND_ACTIONMSG:
437 s->command = COMMAND_NONE;
438 PT_WAIT_THREAD(&s->pt, send_actionmessage(s));
439 break;
adamdunkels5a2df1c2004-09-01 19:11:42 +0000440 case COMMAND_LIST:
441 s->command = COMMAND_NONE;
442 PT_WAIT_THREAD(&s->pt, list_channel(s));
443 break;
adamdunkels2bd076e2004-09-03 08:11:09 +0000444 case COMMAND_QUIT:
adamdunkels5a2df1c2004-09-01 19:11:42 +0000445 s->command = COMMAND_NONE;
adamdunkels2bd076e2004-09-03 08:11:09 +0000446 tcp_markconn(uip_conn, NULL);
adamdunkelsd0791bb2005-02-22 22:23:07 +0000447 PSOCK_CLOSE(&s->s);
adamdunkels2bd076e2004-09-03 08:11:09 +0000448 ek_post(EK_PROC_ID(EK_CURRENT()), EK_EVENT_REQUEST_EXIT, NULL);
adamdunkels5a2df1c2004-09-01 19:11:42 +0000449 PT_EXIT(&s->pt);
450 break;
451 default:
452 break;
453 }
454 }
455
456 PT_END(&s->pt);
457}
458/*---------------------------------------------------------------------------*/
459void
460ircc_appcall(void *s)
461{
462 if(uip_closed() || uip_aborted() || uip_timedout()) {
463 ircc_closed(s);
464 } else if(uip_connected()) {
465 ircc_connected(s);
466 PT_INIT(&((struct ircc_state *)s)->pt);
467 memset(((struct ircc_state *)s)->channel, 0,
468 sizeof(((struct ircc_state *)s)->channel));
469 ((struct ircc_state *)s)->command = COMMAND_NONE;
470 handle_connection(s);
adamdunkels2bd076e2004-09-03 08:11:09 +0000471 } else if(s != NULL) {
adamdunkels5a2df1c2004-09-01 19:11:42 +0000472 handle_connection(s);
473 }
474}
475/*---------------------------------------------------------------------------*/
476struct ircc_state *
477ircc_connect(struct ircc_state *s, char *servername, u16_t *ipaddr,
478 char *nick)
479{
480 s->conn = tcp_connect(ipaddr, HTONS(PORT), s);
481 if(s->conn == NULL) {
482 return NULL;
483 }
484 s->server = servername;
485 s->nick = nick;
486 return s;
487}
488/*---------------------------------------------------------------------------*/
489void
490ircc_list(struct ircc_state *s)
491{
492 s->command = COMMAND_LIST;
493}
494/*---------------------------------------------------------------------------*/
495void
496ircc_join(struct ircc_state *s, char *channel)
497{
498 strncpy(s->channel, channel, sizeof(s->channel));
499 s->command = COMMAND_JOIN;
500}
501/*---------------------------------------------------------------------------*/
502void
503ircc_part(struct ircc_state *s)
504{
505 s->command = COMMAND_PART;
506}
507/*---------------------------------------------------------------------------*/
508void
adamdunkels2bd076e2004-09-03 08:11:09 +0000509ircc_quit(struct ircc_state *s)
510{
511 s->command = COMMAND_QUIT;
512}
513/*---------------------------------------------------------------------------*/
514void
adamdunkels5a2df1c2004-09-01 19:11:42 +0000515ircc_msg(struct ircc_state *s, char *msg)
516{
517 s->msg = msg;
518 s->command = COMMAND_MSG;
519}
520/*---------------------------------------------------------------------------*/
adamdunkels8d8b7452004-09-09 21:05:56 +0000521void
522ircc_actionmsg(struct ircc_state *s, char *msg)
523{
524 s->msg = msg;
525 s->command = COMMAND_ACTIONMSG;
526}
527/*---------------------------------------------------------------------------*/