blob: 1796e4062f1798c71e24074e95a25363173a2bee [file] [log] [blame]
adamdunkels5ca13272003-08-06 22:57:05 +00001/*
2 * Copyright (c) 2002, 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
11 * copyright notice, this list of conditions and the following
12 * disclaimer in the documentation and/or other materials provided
13 * with the distribution.
adamdunkels5abe18e2004-08-09 21:00:28 +000014 * 3. The name of the author may not be used to endorse or promote
adamdunkels5ca13272003-08-06 22:57:05 +000015 * products derived from this software without specific prior
16 * written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
24 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 * This file is part of the Contiki desktop environment
31 *
adamdunkels0ec151b2004-09-12 13:36:02 +000032 * $Id: configedit.c,v 1.13 2004/09/12 13:36:03 adamdunkels Exp $
adamdunkels5ca13272003-08-06 22:57:05 +000033 *
34 */
35
adamdunkels0a08fda2004-07-04 18:33:07 +000036#include "contiki.h"
adamdunkelsc012c562004-09-12 07:27:33 +000037
38#include "ctk-draw-service.h"
39#include "packet-service.h"
40
adamdunkels5ca13272003-08-06 22:57:05 +000041#include "uip.h"
42#include "uip_arp.h"
43#include "resolv.h"
44#include "ctk.h"
45#include "ctk-draw.h"
adamdunkels5ca13272003-08-06 22:57:05 +000046
adamdunkels5ca13272003-08-06 22:57:05 +000047#include "program-handler.h"
48
adamdunkels5abe18e2004-08-09 21:00:28 +000049#include "cfs.h"
adamdunkels5ca13272003-08-06 22:57:05 +000050
51#include "loader.h"
52
adamdunkels93d8ea72003-08-09 23:27:57 +000053#include <stdio.h>
54
adamdunkels0a08fda2004-07-04 18:33:07 +000055#include <string.h>
56
adamdunkels5ca13272003-08-06 22:57:05 +000057/* TCP/IP configuration window. */
58static struct ctk_window window;
59
adamdunkels93d8ea72003-08-09 23:27:57 +000060#define LABELMAXWIDTH 12
61
adamdunkels0ec151b2004-09-12 13:36:02 +000062static struct ctk_label cfslabel =
63 {CTK_LABEL(0, 1, LABELMAXWIDTH, 1, "Disk driver")};
64static char cfs[25];
65static struct ctk_textentry cfstextentry =
66 {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 1, 16, 1, cfs, 24)};
67
adamdunkels5ca13272003-08-06 22:57:05 +000068static struct ctk_label themelabel =
adamdunkels0ec151b2004-09-12 13:36:02 +000069 {CTK_LABEL(0, 3, LABELMAXWIDTH, 1, "CTK theme")};
adamdunkels5ca13272003-08-06 22:57:05 +000070static char theme[25];
71static struct ctk_textentry themetextentry =
adamdunkels0ec151b2004-09-12 13:36:02 +000072 {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 3, 16, 1, theme, 24)};
adamdunkels5ca13272003-08-06 22:57:05 +000073
74static struct ctk_label driverlabel =
adamdunkels0ec151b2004-09-12 13:36:02 +000075 {CTK_LABEL(0, 5, LABELMAXWIDTH, 1, "Net driver")};
adamdunkels5ca13272003-08-06 22:57:05 +000076static char driver[25];
77static struct ctk_textentry drivertextentry =
adamdunkels0ec151b2004-09-12 13:36:02 +000078 {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 5, 16, 1, driver, 24)};
adamdunkels93d8ea72003-08-09 23:27:57 +000079
80static struct ctk_label screensaverlabel =
adamdunkels0ec151b2004-09-12 13:36:02 +000081 {CTK_LABEL(0, 7, LABELMAXWIDTH, 1, "Screensaver")};
adamdunkels93d8ea72003-08-09 23:27:57 +000082static char screensaver[25];
83static struct ctk_textentry screensavertextentry =
adamdunkels0ec151b2004-09-12 13:36:02 +000084 {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 7, 16, 1, screensaver, 24)};
adamdunkels5ca13272003-08-06 22:57:05 +000085
86
87static struct ctk_label ipaddrlabel =
adamdunkels0ec151b2004-09-12 13:36:02 +000088 {CTK_LABEL(0, 9, LABELMAXWIDTH, 1, "IP address")};
adamdunkels5ca13272003-08-06 22:57:05 +000089static char ipaddr[25];
90static struct ctk_textentry ipaddrtextentry =
adamdunkels0ec151b2004-09-12 13:36:02 +000091 {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 9, 16, 1, ipaddr, 24)};
adamdunkels5ca13272003-08-06 22:57:05 +000092static struct ctk_label netmasklabel =
adamdunkels0ec151b2004-09-12 13:36:02 +000093 {CTK_LABEL(0, 11, LABELMAXWIDTH, 1, "Netmask")};
adamdunkels5ca13272003-08-06 22:57:05 +000094static char netmask[25];
95static struct ctk_textentry netmasktextentry =
adamdunkels0ec151b2004-09-12 13:36:02 +000096 {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 11, 16, 1, netmask, 24)};
adamdunkels5ca13272003-08-06 22:57:05 +000097static struct ctk_label gatewaylabel =
adamdunkels0ec151b2004-09-12 13:36:02 +000098 {CTK_LABEL(0, 13, LABELMAXWIDTH, 1, "Gateway")};
adamdunkels5ca13272003-08-06 22:57:05 +000099static char gateway[25];
100static struct ctk_textentry gatewaytextentry =
adamdunkels0ec151b2004-09-12 13:36:02 +0000101 {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 13, 16, 1, gateway, 24)};
adamdunkels5ca13272003-08-06 22:57:05 +0000102static struct ctk_label dnsserverlabel =
adamdunkels0ec151b2004-09-12 13:36:02 +0000103 {CTK_LABEL(0, 15, LABELMAXWIDTH, 1, "DNS server")};
adamdunkels5ca13272003-08-06 22:57:05 +0000104static char dnsserver[25];
105static struct ctk_textentry dnsservertextentry =
adamdunkels0ec151b2004-09-12 13:36:02 +0000106 {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 15, 16, 1, dnsserver, 24)};
adamdunkels5ca13272003-08-06 22:57:05 +0000107
108static struct ctk_button savebutton =
adamdunkels0ec151b2004-09-12 13:36:02 +0000109 {CTK_BUTTON(0, 17, 12, "Save & close")};
adamdunkelsf9c86242003-08-29 20:31:12 +0000110static struct ctk_button cancelbutton =
adamdunkels0ec151b2004-09-12 13:36:02 +0000111 {CTK_BUTTON(24, 17, 6, "Cancel")};
adamdunkels5ca13272003-08-06 22:57:05 +0000112
adamdunkels0a08fda2004-07-04 18:33:07 +0000113/*static DISPATCHER_SIGHANDLER(configedit_sighandler, s, data);
adamdunkels5ca13272003-08-06 22:57:05 +0000114static struct dispatcher_proc p =
115 {DISPATCHER_PROC("Config editor", NULL, configedit_sighandler, NULL)};
adamdunkels0a08fda2004-07-04 18:33:07 +0000116 static ek_id_t id;*/
adamdunkels5ca13272003-08-06 22:57:05 +0000117
adamdunkels0a08fda2004-07-04 18:33:07 +0000118EK_EVENTHANDLER(eventhandler, ev, data);
119EK_PROCESS(p, "Config editor", EK_PRIO_NORMAL,
120 eventhandler, NULL, NULL);
121static ek_id_t id = EK_ID_NONE;
adamdunkels5ca13272003-08-06 22:57:05 +0000122
123
124/*-----------------------------------------------------------------------------------*/
125struct ptentry {
126 char c;
127 char * (* pfunc)(char *str);
128};
129
130/*-----------------------------------------------------------------------------------*/
131static char *
132parse(char *str, struct ptentry *t)
133{
134 struct ptentry *p;
135
136 /* Loop over the parse table entries in t in order to find one that
137 matches the first character in str. */
138 for(p = t; p->c != 0; ++p) {
139 if(*str == p->c) {
140 /* Skip rest of the characters up to the first space. */
141 while(*str != ' ') {
142 ++str;
143 }
144
145 /* Skip all spaces.*/
146 while(*str == ' ') {
147 ++str;
148 }
149
150 /* Call parse table entry function and return. */
151 return p->pfunc(str);
152 }
153 }
154
155 /* Did not find matching entry in parse table. We just call the
156 default handler supplied by the caller and return. */
157 return p->pfunc(str);
158}
159/*-----------------------------------------------------------------------------------*/
160static char *
161skipnewline(char *str)
162{
163 /* Skip all characters until the newline. */
164 while(*str != '\n') {
165 ++str;
166 }
167
168 /* Return a pointer to the first character after the newline. */
169 return str + 1;
170}
171/*-----------------------------------------------------------------------------------*/
172static char *
173nullterminate(char *str)
174{
175 char *nt;
176
177 /* Nullterminate string. Start with finding newline character. */
178 for(nt = str; *nt != '\r' &&
179 *nt != '\n'; ++nt);
180
181 /* Replace newline with a null char. */
182 *nt = 0;
183
adamdunkelsa8a50ab2003-08-20 19:51:47 +0000184 /* Remove trailing spaces. */
185 while(nt > str && *(nt - 1) == ' ') {
186 *(nt - 1) = 0;
187 --nt;
188 }
189
adamdunkels5ca13272003-08-06 22:57:05 +0000190 /* Return pointer to null char. */
191 return nt;
192}
193/*-----------------------------------------------------------------------------------*/
adamdunkels93d8ea72003-08-09 23:27:57 +0000194static char * __fastcall__
195copystr(char *dst, char *src, int len)
196{
197 char *nt = nullterminate(src);
198 strncpy(dst, src, len);
199 return nt + 1;
200}
201/*-----------------------------------------------------------------------------------*/
adamdunkels5ca13272003-08-06 22:57:05 +0000202static char *
203loaddriver(char *str)
204{
adamdunkels93d8ea72003-08-09 23:27:57 +0000205 return copystr(driver, str, sizeof(driver));
adamdunkels5ca13272003-08-06 22:57:05 +0000206}
207/*-----------------------------------------------------------------------------------*/
208static char *
209loadtheme(char *str)
210{
adamdunkels93d8ea72003-08-09 23:27:57 +0000211 return copystr(theme, str, sizeof(theme));
adamdunkels5ca13272003-08-06 22:57:05 +0000212}
213/*-----------------------------------------------------------------------------------*/
214static char *
adamdunkels0ec151b2004-09-12 13:36:02 +0000215loadcfs(char *str)
216{
217 return copystr(cfs, str, sizeof(cfs));
218}
219/*-----------------------------------------------------------------------------------*/
220static char *
adamdunkels1f982712003-08-09 23:40:17 +0000221loadscreensaver(char *str)
222{
223 return copystr(screensaver, str, sizeof(screensaver));
224}
225/*-----------------------------------------------------------------------------------*/
226static char *
adamdunkels5ca13272003-08-06 22:57:05 +0000227ipaddrconf(char *str)
228{
adamdunkels93d8ea72003-08-09 23:27:57 +0000229 return copystr(ipaddr, str, sizeof(ipaddr));
adamdunkels5ca13272003-08-06 22:57:05 +0000230}
231/*-----------------------------------------------------------------------------------*/
232static char *
233netmaskconf(char *str)
234{
adamdunkels93d8ea72003-08-09 23:27:57 +0000235 return copystr(netmask, str, sizeof(netmask));
adamdunkels5ca13272003-08-06 22:57:05 +0000236}
237/*-----------------------------------------------------------------------------------*/
238static char *
239drconf(char *str)
240{
adamdunkels93d8ea72003-08-09 23:27:57 +0000241 return copystr(gateway, str, sizeof(gateway));
adamdunkels5ca13272003-08-06 22:57:05 +0000242}
243/*-----------------------------------------------------------------------------------*/
244static char *
245dnsconf(char *str)
246{
adamdunkels93d8ea72003-08-09 23:27:57 +0000247 return copystr(dnsserver, str, sizeof(dnsserver));
adamdunkels5ca13272003-08-06 22:57:05 +0000248}
249/*-----------------------------------------------------------------------------------*/
250static struct ptentry initparsetab[] =
adamdunkelsa8a50ab2003-08-20 19:51:47 +0000251 {{'n', loaddriver},
adamdunkels5ca13272003-08-06 22:57:05 +0000252 {'t', loadtheme},
adamdunkels0ec151b2004-09-12 13:36:02 +0000253 {'c', loadcfs},
adamdunkels1f982712003-08-09 23:40:17 +0000254 {'s', loadscreensaver},
adamdunkels5ca13272003-08-06 22:57:05 +0000255 {'i', ipaddrconf},
adamdunkelsa8a50ab2003-08-20 19:51:47 +0000256 {'m', netmaskconf},
adamdunkels5ca13272003-08-06 22:57:05 +0000257 {'r', drconf},
adamdunkels5ca13272003-08-06 22:57:05 +0000258 {'d', dnsconf},
adamdunkels5ca13272003-08-06 22:57:05 +0000259 {'#', skipnewline},
260
261 /* Default action */
262 {0, skipnewline}};
263static void
264initscript(void)
265{
266 char line[40], *lineptr;
adamdunkels5abe18e2004-08-09 21:00:28 +0000267 /* struct c64_fs_file f;*/
268 int f;
adamdunkels5ca13272003-08-06 22:57:05 +0000269
adamdunkels5abe18e2004-08-09 21:00:28 +0000270 if((f = cfs_open("config.cfg", 0)) == -1) {
adamdunkels5ca13272003-08-06 22:57:05 +0000271 return;
272 }
273 line[0] = ' ';
274 while(line[0] != '.' &&
275 line[0] != 0) {
276 lineptr = line;
277 do {
adamdunkels5abe18e2004-08-09 21:00:28 +0000278 if(cfs_read(f, lineptr, 1) != 1) {
279 cfs_close(f);
adamdunkels5ca13272003-08-06 22:57:05 +0000280 return;
281 }
282 ++lineptr;
283 } while(*(lineptr - 1) != '\n' &&
284 *(lineptr - 1) != '\r');
285
286 *lineptr = 0;
287
288 if(line[0] != '.' &&
289 line[0] != 0) {
290 parse(line, initparsetab);
291 }
292
293 }
adamdunkels5abe18e2004-08-09 21:00:28 +0000294 cfs_close(f);
adamdunkels5ca13272003-08-06 22:57:05 +0000295 return;
296}
297/*-----------------------------------------------------------------------------------*/
adamdunkels81780132003-08-15 18:44:26 +0000298static int
299makeline(char *line, char c, char *str)
300{
301 int len;
302
303 len = strlen(str);
304
305 line[0] = c;
306 line[1] = ' ';
307 strcpy(&line[2], str);
308 line[2 + len] = '\n';
309 line[3 + len] = 0;
310 return len + 3;
311}
312/*-----------------------------------------------------------------------------------*/
adamdunkels5ca13272003-08-06 22:57:05 +0000313static void
314savescript(void)
315{
316 char line[40];
adamdunkels5abe18e2004-08-09 21:00:28 +0000317 /* struct c64_fs_file f;*/
318 int f;
adamdunkels5ca13272003-08-06 22:57:05 +0000319
adamdunkels5abe18e2004-08-09 21:00:28 +0000320 if((f = cfs_open("config.cfg", CFS_WRITE)) == -1) {
adamdunkels5ca13272003-08-06 22:57:05 +0000321 return;
322 }
323 if(theme[0] != 0) {
adamdunkels5abe18e2004-08-09 21:00:28 +0000324 cfs_write(f, line, makeline(line, 't', theme));
adamdunkels5ca13272003-08-06 22:57:05 +0000325 }
326 if(driver[0] != 0) {
adamdunkels5abe18e2004-08-09 21:00:28 +0000327 cfs_write(f, line, makeline(line, 'n', driver));
adamdunkels5ca13272003-08-06 22:57:05 +0000328 }
329 if(ipaddr[0] != 0) {
adamdunkels5abe18e2004-08-09 21:00:28 +0000330 cfs_write(f, line, makeline(line, 'i', ipaddr));
adamdunkels5ca13272003-08-06 22:57:05 +0000331 }
332 if(netmask[0] != 0) {
adamdunkels5abe18e2004-08-09 21:00:28 +0000333 cfs_write(f, line, makeline(line, 'm', netmask));
adamdunkels5ca13272003-08-06 22:57:05 +0000334 }
335 if(gateway[0] != 0) {
adamdunkels5abe18e2004-08-09 21:00:28 +0000336 cfs_write(f, line, makeline(line, 'r', gateway));
adamdunkels5ca13272003-08-06 22:57:05 +0000337 }
338 if(dnsserver[0] != 0) {
adamdunkels5abe18e2004-08-09 21:00:28 +0000339 cfs_write(f, line, makeline(line, 'd', dnsserver));
adamdunkels93d8ea72003-08-09 23:27:57 +0000340 }
341
342 if(screensaver[0] != 0) {
adamdunkels5abe18e2004-08-09 21:00:28 +0000343 cfs_write(f, line, makeline(line, 's', screensaver));
adamdunkels5ca13272003-08-06 22:57:05 +0000344 }
345
adamdunkels81780132003-08-15 18:44:26 +0000346 strcpy(line, ".\n\0\n\n\n");
adamdunkels5abe18e2004-08-09 21:00:28 +0000347 cfs_write(f, line, strlen(line));
adamdunkels5ca13272003-08-06 22:57:05 +0000348
adamdunkels5abe18e2004-08-09 21:00:28 +0000349 cfs_close(f);
adamdunkels5ca13272003-08-06 22:57:05 +0000350
351}
352/*-----------------------------------------------------------------------------------*/
adamdunkels7cde6092003-08-24 22:35:22 +0000353LOADER_INIT_FUNC(configedit_init, arg)
adamdunkels5ca13272003-08-06 22:57:05 +0000354{
adamdunkels7cde6092003-08-24 22:35:22 +0000355 arg_free(arg);
356
adamdunkels5ca13272003-08-06 22:57:05 +0000357 if(id == EK_ID_NONE) {
adamdunkels0a08fda2004-07-04 18:33:07 +0000358 id = ek_start(&p);
359 }
360}
361/*-----------------------------------------------------------------------------------*/
362
363/*-----------------------------------------------------------------------------------*/
364static void
365configedit_quit(void)
366{
367 ek_exit();
368 id = EK_ID_NONE;
369 LOADER_UNLOAD();
370}
371/*-----------------------------------------------------------------------------------*/
adamdunkelsc012c562004-09-12 07:27:33 +0000372static void
373quit_services(void)
374{
adamdunkels0ec151b2004-09-12 13:36:02 +0000375 cfs_init_init(NULL);
adamdunkelsc012c562004-09-12 07:27:33 +0000376 ctk_draw_quit();
377}
378/*-----------------------------------------------------------------------------------*/
adamdunkels0a08fda2004-07-04 18:33:07 +0000379EK_EVENTHANDLER(eventhandler, ev, data)
380{
381 EK_EVENTHANDLER_ARGS(ev, data);
382
383 if(ev == EK_EVENT_INIT) {
adamdunkels5ca13272003-08-06 22:57:05 +0000384 /* Create window. */
adamdunkels0ec151b2004-09-12 13:36:02 +0000385 ctk_window_new(&window, 32, 18, "Config editor");
386
387 CTK_WIDGET_ADD(&window, &cfslabel);
388 CTK_WIDGET_ADD(&window, &cfstextentry);
adamdunkels5ca13272003-08-06 22:57:05 +0000389
390 CTK_WIDGET_ADD(&window, &themelabel);
391 CTK_WIDGET_ADD(&window, &themetextentry);
adamdunkels0ec151b2004-09-12 13:36:02 +0000392
adamdunkels5ca13272003-08-06 22:57:05 +0000393 CTK_WIDGET_ADD(&window, &driverlabel);
394 CTK_WIDGET_ADD(&window, &drivertextentry);
395
adamdunkels93d8ea72003-08-09 23:27:57 +0000396 CTK_WIDGET_ADD(&window, &screensaverlabel);
397 CTK_WIDGET_ADD(&window, &screensavertextentry);
398
adamdunkels5ca13272003-08-06 22:57:05 +0000399 CTK_WIDGET_ADD(&window, &ipaddrlabel);
400 CTK_WIDGET_ADD(&window, &ipaddrtextentry);
401 CTK_WIDGET_ADD(&window, &netmasklabel);
402 CTK_WIDGET_ADD(&window, &netmasktextentry);
403 CTK_WIDGET_ADD(&window, &gatewaylabel);
404 CTK_WIDGET_ADD(&window, &gatewaytextentry);
405 CTK_WIDGET_ADD(&window, &dnsserverlabel);
406 CTK_WIDGET_ADD(&window, &dnsservertextentry);
407
408 CTK_WIDGET_ADD(&window, &savebutton);
adamdunkelsf9c86242003-08-29 20:31:12 +0000409 CTK_WIDGET_ADD(&window, &cancelbutton);
adamdunkels5ca13272003-08-06 22:57:05 +0000410
411 CTK_WIDGET_FOCUS(&window, &themetextentry);
412
413 /* Fill the configuration strings with values from the current
414 configuration */
415 initscript();
416
adamdunkels0a08fda2004-07-04 18:33:07 +0000417 ctk_window_open(&window);
adamdunkels5ca13272003-08-06 22:57:05 +0000418
adamdunkels0a08fda2004-07-04 18:33:07 +0000419 } else if(ev == ctk_signal_button_activate) {
adamdunkels5ca13272003-08-06 22:57:05 +0000420 if(data == (ek_data_t)&savebutton) {
adamdunkelsc012c562004-09-12 07:27:33 +0000421 quit_services();
adamdunkels5ca13272003-08-06 22:57:05 +0000422 savescript();
423 ctk_window_close(&window);
adamdunkelsa8a50ab2003-08-20 19:51:47 +0000424 configedit_quit();
adamdunkels7cde6092003-08-24 22:35:22 +0000425 program_handler_load("config.prg", NULL);
adamdunkelsa8a50ab2003-08-20 19:51:47 +0000426 } else if(data == (ek_data_t)&cancelbutton) {
adamdunkels5ca13272003-08-06 22:57:05 +0000427 ctk_window_close(&window);
428 configedit_quit();
adamdunkels5ca13272003-08-06 22:57:05 +0000429 }
adamdunkels0a08fda2004-07-04 18:33:07 +0000430 } else if(ev == ctk_signal_window_close ||
431 ev == EK_EVENT_REQUEST_EXIT) {
adamdunkels5ca13272003-08-06 22:57:05 +0000432 ctk_window_close(&window);
433 configedit_quit();
434 }
435}
436/*-----------------------------------------------------------------------------------*/