blob: cba8b5c61a0489ee8f18517289514373696de2c0 [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.
14 * 3. All advertising materials mentioning features or use of this
15 * software must display the following acknowledgement:
16 * This product includes software developed by Adam Dunkels.
17 * 4. The name of the author may not be used to endorse or promote
18 * products derived from this software without specific prior
19 * written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
22 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
27 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 *
33 * This file is part of the Contiki desktop environment
34 *
adamdunkels1f982712003-08-09 23:40:17 +000035 * $Id: configedit.c,v 1.4 2003/08/09 23:40:17 adamdunkels Exp $
adamdunkels5ca13272003-08-06 22:57:05 +000036 *
37 */
38
39#include "uip_main.h"
40#include "uip.h"
41#include "uip_arp.h"
42#include "resolv.h"
43#include "ctk.h"
44#include "ctk-draw.h"
45#include "dispatcher.h"
46
47#include "uip-signal.h"
48
49#include "program-handler.h"
50
51#include "c64-fs.h"
52
53#include "loader.h"
54
adamdunkels93d8ea72003-08-09 23:27:57 +000055#include <stdio.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
adamdunkels5ca13272003-08-06 22:57:05 +000062static struct ctk_label themelabel =
adamdunkels93d8ea72003-08-09 23:27:57 +000063 {CTK_LABEL(0, 1, LABELMAXWIDTH, 1, "CTK theme")};
adamdunkels5ca13272003-08-06 22:57:05 +000064static char theme[25];
65static struct ctk_textentry themetextentry =
adamdunkels93d8ea72003-08-09 23:27:57 +000066 {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 1, 16, 1, theme, 24)};
adamdunkels5ca13272003-08-06 22:57:05 +000067
68static struct ctk_label driverlabel =
adamdunkels93d8ea72003-08-09 23:27:57 +000069 {CTK_LABEL(0, 3, LABELMAXWIDTH, 1, "Net driver")};
adamdunkels5ca13272003-08-06 22:57:05 +000070static char driver[25];
71static struct ctk_textentry drivertextentry =
adamdunkels93d8ea72003-08-09 23:27:57 +000072 {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 3, 16, 1, driver, 24)};
73
74static struct ctk_label screensaverlabel =
75 {CTK_LABEL(0, 5, LABELMAXWIDTH, 1, "Screensaver")};
76static char screensaver[25];
77static struct ctk_textentry screensavertextentry =
78 {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 5, 16, 1, screensaver, 24)};
adamdunkels5ca13272003-08-06 22:57:05 +000079
80
81static struct ctk_label ipaddrlabel =
adamdunkels93d8ea72003-08-09 23:27:57 +000082 {CTK_LABEL(0, 7, LABELMAXWIDTH, 1, "IP address")};
adamdunkels5ca13272003-08-06 22:57:05 +000083static char ipaddr[25];
84static struct ctk_textentry ipaddrtextentry =
adamdunkels93d8ea72003-08-09 23:27:57 +000085 {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 7, 16, 1, ipaddr, 24)};
adamdunkels5ca13272003-08-06 22:57:05 +000086static struct ctk_label netmasklabel =
adamdunkels93d8ea72003-08-09 23:27:57 +000087 {CTK_LABEL(0, 9, LABELMAXWIDTH, 1, "Netmask")};
adamdunkels5ca13272003-08-06 22:57:05 +000088static char netmask[25];
89static struct ctk_textentry netmasktextentry =
adamdunkels93d8ea72003-08-09 23:27:57 +000090 {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 9, 16, 1, netmask, 24)};
adamdunkels5ca13272003-08-06 22:57:05 +000091static struct ctk_label gatewaylabel =
adamdunkels93d8ea72003-08-09 23:27:57 +000092 {CTK_LABEL(0, 11, LABELMAXWIDTH, 1, "Gateway")};
adamdunkels5ca13272003-08-06 22:57:05 +000093static char gateway[25];
94static struct ctk_textentry gatewaytextentry =
adamdunkels93d8ea72003-08-09 23:27:57 +000095 {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 11, 16, 1, gateway, 24)};
adamdunkels5ca13272003-08-06 22:57:05 +000096static struct ctk_label dnsserverlabel =
adamdunkels93d8ea72003-08-09 23:27:57 +000097 {CTK_LABEL(0, 13, LABELMAXWIDTH, 1, "DNS server")};
adamdunkels5ca13272003-08-06 22:57:05 +000098static char dnsserver[25];
99static struct ctk_textentry dnsservertextentry =
adamdunkels93d8ea72003-08-09 23:27:57 +0000100 {CTK_TEXTENTRY(LABELMAXWIDTH + 1, 13, 16, 1, dnsserver, 24)};
adamdunkels5ca13272003-08-06 22:57:05 +0000101
102static struct ctk_button savebutton =
adamdunkels93d8ea72003-08-09 23:27:57 +0000103 {CTK_BUTTON(0, 15, 12, "Save & close")};
adamdunkels5ca13272003-08-06 22:57:05 +0000104
105
106static struct ctk_button applybutton =
adamdunkels93d8ea72003-08-09 23:27:57 +0000107 {CTK_BUTTON(17, 15, 13, "Apply & close")};
adamdunkels5ca13272003-08-06 22:57:05 +0000108
109static DISPATCHER_SIGHANDLER(configedit_sighandler, s, data);
110static struct dispatcher_proc p =
111 {DISPATCHER_PROC("Config editor", NULL, configedit_sighandler, NULL)};
112static ek_id_t id;
113
114
115
116
117/*-----------------------------------------------------------------------------------*/
118struct ptentry {
119 char c;
120 char * (* pfunc)(char *str);
121};
122
123/*-----------------------------------------------------------------------------------*/
124static char *
125parse(char *str, struct ptentry *t)
126{
127 struct ptentry *p;
128
129 /* Loop over the parse table entries in t in order to find one that
130 matches the first character in str. */
131 for(p = t; p->c != 0; ++p) {
132 if(*str == p->c) {
133 /* Skip rest of the characters up to the first space. */
134 while(*str != ' ') {
135 ++str;
136 }
137
138 /* Skip all spaces.*/
139 while(*str == ' ') {
140 ++str;
141 }
142
143 /* Call parse table entry function and return. */
144 return p->pfunc(str);
145 }
146 }
147
148 /* Did not find matching entry in parse table. We just call the
149 default handler supplied by the caller and return. */
150 return p->pfunc(str);
151}
152/*-----------------------------------------------------------------------------------*/
153static char *
154skipnewline(char *str)
155{
156 /* Skip all characters until the newline. */
157 while(*str != '\n') {
158 ++str;
159 }
160
161 /* Return a pointer to the first character after the newline. */
162 return str + 1;
163}
164/*-----------------------------------------------------------------------------------*/
165static char *
166nullterminate(char *str)
167{
168 char *nt;
169
170 /* Nullterminate string. Start with finding newline character. */
171 for(nt = str; *nt != '\r' &&
172 *nt != '\n'; ++nt);
173
174 /* Replace newline with a null char. */
175 *nt = 0;
176
177 /* Return pointer to null char. */
178 return nt;
179}
180/*-----------------------------------------------------------------------------------*/
adamdunkels93d8ea72003-08-09 23:27:57 +0000181static char * __fastcall__
182copystr(char *dst, char *src, int len)
183{
184 char *nt = nullterminate(src);
185 strncpy(dst, src, len);
186 return nt + 1;
187}
188/*-----------------------------------------------------------------------------------*/
adamdunkels5ca13272003-08-06 22:57:05 +0000189static char *
190loaddriver(char *str)
191{
adamdunkels93d8ea72003-08-09 23:27:57 +0000192 return copystr(driver, str, sizeof(driver));
adamdunkels5ca13272003-08-06 22:57:05 +0000193}
194/*-----------------------------------------------------------------------------------*/
195static char *
196loadtheme(char *str)
197{
adamdunkels93d8ea72003-08-09 23:27:57 +0000198 return copystr(theme, str, sizeof(theme));
adamdunkels5ca13272003-08-06 22:57:05 +0000199}
200/*-----------------------------------------------------------------------------------*/
201static char *
adamdunkels1f982712003-08-09 23:40:17 +0000202loadscreensaver(char *str)
203{
204 return copystr(screensaver, str, sizeof(screensaver));
205}
206/*-----------------------------------------------------------------------------------*/
207static char *
adamdunkels5ca13272003-08-06 22:57:05 +0000208ipaddrconf(char *str)
209{
adamdunkels93d8ea72003-08-09 23:27:57 +0000210 return copystr(ipaddr, str, sizeof(ipaddr));
adamdunkels5ca13272003-08-06 22:57:05 +0000211}
212/*-----------------------------------------------------------------------------------*/
213static char *
214netmaskconf(char *str)
215{
adamdunkels93d8ea72003-08-09 23:27:57 +0000216 return copystr(netmask, str, sizeof(netmask));
adamdunkels5ca13272003-08-06 22:57:05 +0000217}
218/*-----------------------------------------------------------------------------------*/
219static char *
220drconf(char *str)
221{
adamdunkels93d8ea72003-08-09 23:27:57 +0000222 return copystr(gateway, str, sizeof(gateway));
adamdunkels5ca13272003-08-06 22:57:05 +0000223}
224/*-----------------------------------------------------------------------------------*/
225static char *
226dnsconf(char *str)
227{
adamdunkels93d8ea72003-08-09 23:27:57 +0000228 return copystr(dnsserver, str, sizeof(dnsserver));
adamdunkels5ca13272003-08-06 22:57:05 +0000229}
230/*-----------------------------------------------------------------------------------*/
231static struct ptentry initparsetab[] =
232 {{'l', loaddriver},
adamdunkels5ca13272003-08-06 22:57:05 +0000233 {'t', loadtheme},
adamdunkels1f982712003-08-09 23:40:17 +0000234 {'s', loadscreensaver},
adamdunkels5ca13272003-08-06 22:57:05 +0000235 {'i', ipaddrconf},
adamdunkels5ca13272003-08-06 22:57:05 +0000236 {'n', netmaskconf},
adamdunkels5ca13272003-08-06 22:57:05 +0000237 {'r', drconf},
adamdunkels5ca13272003-08-06 22:57:05 +0000238 {'d', dnsconf},
adamdunkels5ca13272003-08-06 22:57:05 +0000239 {'#', skipnewline},
240
241 /* Default action */
242 {0, skipnewline}};
243static void
244initscript(void)
245{
246 char line[40], *lineptr;
247 struct c64_fs_file f;
248
adamdunkelse89927e2003-08-06 23:14:20 +0000249 if(c64_fs_open("config.cfg", &f) == -1) {
adamdunkels5ca13272003-08-06 22:57:05 +0000250 return;
251 }
252 line[0] = ' ';
253 while(line[0] != '.' &&
254 line[0] != 0) {
255 lineptr = line;
256 do {
257 if(c64_fs_read(&f, lineptr, 1) != 1) {
258 c64_fs_close(&f);
259 return;
260 }
261 ++lineptr;
262 } while(*(lineptr - 1) != '\n' &&
263 *(lineptr - 1) != '\r');
264
265 *lineptr = 0;
266
267 if(line[0] != '.' &&
268 line[0] != 0) {
269 parse(line, initparsetab);
270 }
271
272 }
273 c64_fs_close(&f);
274 return;
275}
276/*-----------------------------------------------------------------------------------*/
277static void
278savescript(void)
279{
280 char line[40];
281 struct c64_fs_file f;
adamdunkels5ca13272003-08-06 22:57:05 +0000282
adamdunkelse89927e2003-08-06 23:14:20 +0000283 if(c64_fs_open("config.cfg", &f) == -1) {
adamdunkels5ca13272003-08-06 22:57:05 +0000284 return;
285 }
286 if(theme[0] != 0) {
287 sprintf(line, "t %s\n", theme);
adamdunkels93d8ea72003-08-09 23:27:57 +0000288 c64_fs_write(&f, line, strlen(line));
adamdunkels5ca13272003-08-06 22:57:05 +0000289 }
290 if(driver[0] != 0) {
291 sprintf(line, "l %s\n", driver);
adamdunkels93d8ea72003-08-09 23:27:57 +0000292 c64_fs_write(&f, line, strlen(line));
adamdunkels5ca13272003-08-06 22:57:05 +0000293 }
294 if(ipaddr[0] != 0) {
295 sprintf(line, "i %s\n", ipaddr);
adamdunkels93d8ea72003-08-09 23:27:57 +0000296 c64_fs_write(&f, line, strlen(line));
adamdunkels5ca13272003-08-06 22:57:05 +0000297 }
298 if(netmask[0] != 0) {
299 sprintf(line, "n %s\n", netmask);
adamdunkels93d8ea72003-08-09 23:27:57 +0000300 c64_fs_write(&f, line, strlen(line));
adamdunkels5ca13272003-08-06 22:57:05 +0000301 }
302 if(gateway[0] != 0) {
303 sprintf(line, "r %s\n", gateway);
adamdunkels93d8ea72003-08-09 23:27:57 +0000304 c64_fs_write(&f, line, strlen(line));
adamdunkels5ca13272003-08-06 22:57:05 +0000305 }
306 if(dnsserver[0] != 0) {
307 sprintf(line, "d %s\n", dnsserver);
adamdunkels93d8ea72003-08-09 23:27:57 +0000308 c64_fs_write(&f, line, strlen(line));
309 }
310
311 if(screensaver[0] != 0) {
312 sprintf(line, "s %s\n", screensaver);
313 c64_fs_write(&f, line, strlen(line));
adamdunkels5ca13272003-08-06 22:57:05 +0000314 }
315
316 sprintf(line, ".\n\0\n\n\n");
adamdunkels93d8ea72003-08-09 23:27:57 +0000317 c64_fs_write(&f, line, strlen(line));
adamdunkels5ca13272003-08-06 22:57:05 +0000318
319 c64_fs_close(&f);
320
321}
322/*-----------------------------------------------------------------------------------*/
323LOADER_INIT_FUNC(configedit_init)
324{
325 if(id == EK_ID_NONE) {
326 id = dispatcher_start(&p);
327
328 /* Create window. */
adamdunkels93d8ea72003-08-09 23:27:57 +0000329 ctk_window_new(&window, 32, 16, "Config editor");
adamdunkels5ca13272003-08-06 22:57:05 +0000330
331 CTK_WIDGET_ADD(&window, &themelabel);
332 CTK_WIDGET_ADD(&window, &themetextentry);
333
334 CTK_WIDGET_ADD(&window, &driverlabel);
335 CTK_WIDGET_ADD(&window, &drivertextentry);
336
adamdunkels93d8ea72003-08-09 23:27:57 +0000337 CTK_WIDGET_ADD(&window, &screensaverlabel);
338 CTK_WIDGET_ADD(&window, &screensavertextentry);
339
adamdunkels5ca13272003-08-06 22:57:05 +0000340 CTK_WIDGET_ADD(&window, &ipaddrlabel);
341 CTK_WIDGET_ADD(&window, &ipaddrtextentry);
342 CTK_WIDGET_ADD(&window, &netmasklabel);
343 CTK_WIDGET_ADD(&window, &netmasktextentry);
344 CTK_WIDGET_ADD(&window, &gatewaylabel);
345 CTK_WIDGET_ADD(&window, &gatewaytextentry);
346 CTK_WIDGET_ADD(&window, &dnsserverlabel);
347 CTK_WIDGET_ADD(&window, &dnsservertextentry);
348
349 CTK_WIDGET_ADD(&window, &savebutton);
350 CTK_WIDGET_ADD(&window, &applybutton);
351
352 CTK_WIDGET_FOCUS(&window, &themetextentry);
353
354 /* Fill the configuration strings with values from the current
355 configuration */
356 initscript();
357
358 dispatcher_listen(ctk_signal_button_activate);
359 dispatcher_listen(ctk_signal_window_close);
360 }
361 ctk_window_open(&window);
362}
363/*-----------------------------------------------------------------------------------*/
364
365/*-----------------------------------------------------------------------------------*/
366static void
367configedit_quit(void)
368{
369 dispatcher_exit(&p);
370 id = EK_ID_NONE;
371 LOADER_UNLOAD();
372}
373/*-----------------------------------------------------------------------------------*/
374static
375DISPATCHER_SIGHANDLER(configedit_sighandler, s, data)
376{
377 DISPATCHER_SIGHANDLER_ARGS(s, data);
378
379 if(s == ctk_signal_button_activate) {
380 if(data == (ek_data_t)&savebutton) {
381 savescript();
382 ctk_window_close(&window);
383 configedit_quit();
384 } else if(data == (ek_data_t)&applybutton) {
385 savescript();
386 ctk_window_close(&window);
387 configedit_quit();
388 dispatcher_emit(uip_signal_uninstall, NULL,
389 DISPATCHER_BROADCAST);
adamdunkelse89927e2003-08-06 23:14:20 +0000390 program_handler_load("config.prg");
adamdunkels5ca13272003-08-06 22:57:05 +0000391 }
392 } else if(s == ctk_signal_window_close ||
393 s == dispatcher_signal_quit) {
394 ctk_window_close(&window);
395 configedit_quit();
396 }
397}
398/*-----------------------------------------------------------------------------------*/