Missing NULL's in config tables.
[silc.git] / apps / silcmap / silcmap_command.c
1 /*
2
3   silcmap_command.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2003 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19
20 #include "silcincludes.h"
21 #include "silcclient.h"
22 #include "silcmap.h"
23
24 /******* Command Script Parsing **********************************************/
25
26 SILC_CONFIG_CALLBACK(silc_map_cmd_server);
27 SILC_CONFIG_CALLBACK(silc_map_cmd_loadmap);
28 SILC_CONFIG_CALLBACK(silc_map_cmd_writemap);
29 SILC_CONFIG_CALLBACK(silc_map_cmd_writemaphtml);
30 SILC_CONFIG_CALLBACK(silc_map_cmd_writehtml);
31 SILC_CONFIG_CALLBACK(silc_map_cmd_cut);
32 SILC_CONFIG_CALLBACK(silc_map_cmd_rectangle);
33 SILC_CONFIG_CALLBACK(silc_map_cmd_circle);
34 SILC_CONFIG_CALLBACK(silc_map_cmd_line);
35 SILC_CONFIG_CALLBACK(silc_map_cmd_text);
36
37 static const SilcConfigTable silc_map_table_loadmap[] =
38 {
39   { "filename", SILC_CONFIG_ARG_STR, silc_map_cmd_loadmap, NULL },
40   { NULL },
41 };
42
43 static const SilcConfigTable silc_map_table_writemap[] =
44 {
45   { "filename", SILC_CONFIG_ARG_STR, silc_map_cmd_writemap, NULL },
46   { NULL },
47 };
48
49 static const SilcConfigTable silc_map_table_writemaphtml[] =
50 {
51   { "filename", SILC_CONFIG_ARG_STR, silc_map_cmd_writemaphtml, NULL },
52   { "image", SILC_CONFIG_ARG_STR, silc_map_cmd_writemaphtml, NULL },
53   { "cut_lat", SILC_CONFIG_ARG_STRE, silc_map_cmd_writemaphtml, NULL },
54   { "cut_lon", SILC_CONFIG_ARG_STRE, silc_map_cmd_writemaphtml, NULL },
55   { NULL },
56 };
57
58 static const SilcConfigTable silc_map_table_writehtml[] =
59 {
60   { "filename", SILC_CONFIG_ARG_STR, silc_map_cmd_writehtml, NULL },
61   { "class", SILC_CONFIG_ARG_STRE, silc_map_cmd_writehtml, NULL },
62   { NULL },
63 };
64
65 static const SilcConfigTable silc_map_table_cut[] =
66 {
67   { "lat", SILC_CONFIG_ARG_STR, silc_map_cmd_cut, NULL },
68   { "lon", SILC_CONFIG_ARG_STR, silc_map_cmd_cut, NULL },
69   { "width", SILC_CONFIG_ARG_INT, silc_map_cmd_cut, NULL },
70   { "height", SILC_CONFIG_ARG_INT, silc_map_cmd_cut, NULL },
71   { "filename", SILC_CONFIG_ARG_STR, silc_map_cmd_cut, NULL },
72   { NULL },
73 };
74
75 static const SilcConfigTable silc_map_table_rectangle[] =
76 {
77   { "lat", SILC_CONFIG_ARG_STR, silc_map_cmd_rectangle, NULL },
78   { "lon", SILC_CONFIG_ARG_STR, silc_map_cmd_rectangle, NULL },
79   { "color", SILC_CONFIG_ARG_STR, silc_map_cmd_rectangle, NULL },
80   { "label", SILC_CONFIG_ARG_STR, silc_map_cmd_rectangle, NULL },
81   { "lposx", SILC_CONFIG_ARG_INT, silc_map_cmd_rectangle, NULL },
82   { "lposy", SILC_CONFIG_ARG_INT, silc_map_cmd_rectangle, NULL },
83   { "lcolor", SILC_CONFIG_ARG_STR, silc_map_cmd_rectangle, NULL },
84   { NULL },
85 };
86
87 static const SilcConfigTable silc_map_table_circle[] =
88 {
89   { "lat", SILC_CONFIG_ARG_STR, silc_map_cmd_circle, NULL },
90   { "lon", SILC_CONFIG_ARG_STR, silc_map_cmd_circle, NULL },
91   { "color", SILC_CONFIG_ARG_STR, silc_map_cmd_circle, NULL },
92   { "label", SILC_CONFIG_ARG_STR, silc_map_cmd_circle, NULL },
93   { "lposx", SILC_CONFIG_ARG_INT, silc_map_cmd_circle, NULL },
94   { "lposy", SILC_CONFIG_ARG_INT, silc_map_cmd_circle, NULL },
95   { "lcolor", SILC_CONFIG_ARG_STR, silc_map_cmd_circle, NULL },
96   { NULL },
97 };
98
99 static const SilcConfigTable silc_map_table_line[] =
100 {
101   { "a_lat", SILC_CONFIG_ARG_STR, silc_map_cmd_line, NULL },
102   { "a_lon", SILC_CONFIG_ARG_STR, silc_map_cmd_line, NULL },
103   { "b_lat", SILC_CONFIG_ARG_STR, silc_map_cmd_line, NULL },
104   { "b_lon", SILC_CONFIG_ARG_STR, silc_map_cmd_line, NULL },
105   { "width", SILC_CONFIG_ARG_STR, silc_map_cmd_line, NULL },
106   { "color", SILC_CONFIG_ARG_STR, silc_map_cmd_line, NULL },
107   { NULL },
108 };
109
110 static const SilcConfigTable silc_map_table_text[] =
111 {
112   { "lat", SILC_CONFIG_ARG_STR, silc_map_cmd_text, NULL },
113   { "lon", SILC_CONFIG_ARG_STR, silc_map_cmd_text, NULL },
114   { "color", SILC_CONFIG_ARG_STR, silc_map_cmd_text, NULL },
115   { "text", SILC_CONFIG_ARG_STR, silc_map_cmd_text, NULL },
116   { NULL },
117 };
118
119 static const SilcConfigTable silc_map_table_server[] =
120 {
121   /* Details */
122   { "hostname", SILC_CONFIG_ARG_STR, silc_map_cmd_server, NULL },
123   { "ip", SILC_CONFIG_ARG_STR, silc_map_cmd_server, NULL },
124   { "port", SILC_CONFIG_ARG_INT, silc_map_cmd_server, NULL },
125   { "public_key", SILC_CONFIG_ARG_STR, silc_map_cmd_server, NULL },
126   { "country", SILC_CONFIG_ARG_STR, silc_map_cmd_server, NULL },
127   { "city", SILC_CONFIG_ARG_STR, silc_map_cmd_server, NULL },
128   { "admin", SILC_CONFIG_ARG_STR, silc_map_cmd_server, NULL },
129   { "description", SILC_CONFIG_ARG_STRE, silc_map_cmd_server, NULL },
130   { "html_url", SILC_CONFIG_ARG_STRE, silc_map_cmd_server, NULL },
131
132   /* Connect params */
133   { "connect", SILC_CONFIG_ARG_TOGGLE, silc_map_cmd_server, NULL },
134   { "connect_timeout", SILC_CONFIG_ARG_INT, silc_map_cmd_server, NULL },
135
136   /* Statistics */
137   { "starttime", SILC_CONFIG_ARG_TOGGLE, silc_map_cmd_server, NULL },
138   { "uptime", SILC_CONFIG_ARG_TOGGLE, silc_map_cmd_server, NULL },
139   { "clients", SILC_CONFIG_ARG_TOGGLE, silc_map_cmd_server, NULL },
140   { "channels", SILC_CONFIG_ARG_TOGGLE, silc_map_cmd_server, NULL },
141   { "server_ops", SILC_CONFIG_ARG_TOGGLE, silc_map_cmd_server, NULL },
142   { "router_ops", SILC_CONFIG_ARG_TOGGLE, silc_map_cmd_server, NULL },
143   { "cell_clients", SILC_CONFIG_ARG_TOGGLE, silc_map_cmd_server, NULL },
144   { "cell_channels", SILC_CONFIG_ARG_TOGGLE, silc_map_cmd_server, NULL },
145   { "cell_servers", SILC_CONFIG_ARG_TOGGLE, silc_map_cmd_server, NULL },
146   { "all_clients", SILC_CONFIG_ARG_TOGGLE, silc_map_cmd_server, NULL },
147   { "all_channels", SILC_CONFIG_ARG_TOGGLE, silc_map_cmd_server, NULL },
148   { "all_servers", SILC_CONFIG_ARG_TOGGLE, silc_map_cmd_server, NULL },
149   { "all_routers", SILC_CONFIG_ARG_TOGGLE, silc_map_cmd_server, NULL },
150   { "all_server_ops", SILC_CONFIG_ARG_TOGGLE, silc_map_cmd_server, NULL },
151   { "all_router_ops", SILC_CONFIG_ARG_TOGGLE, silc_map_cmd_server, NULL },
152   { "motd", SILC_CONFIG_ARG_TOGGLE, silc_map_cmd_server, NULL },
153
154   /* Colors */
155   { "up_color", SILC_CONFIG_ARG_STR, silc_map_cmd_server, NULL },
156   { "down_color", SILC_CONFIG_ARG_STR, silc_map_cmd_server, NULL },
157   { "up_text_color", SILC_CONFIG_ARG_STR, silc_map_cmd_server, NULL },
158   { "down_text_color", SILC_CONFIG_ARG_STR, silc_map_cmd_server, NULL },
159
160   /* Map commands */
161   { "cut", SILC_CONFIG_ARG_BLOCK,
162     silc_map_cmd_cut, silc_map_table_cut },
163   { "rectangle", SILC_CONFIG_ARG_BLOCK,
164     silc_map_cmd_rectangle, silc_map_table_rectangle },
165   { "circle", SILC_CONFIG_ARG_BLOCK,
166     silc_map_cmd_circle, silc_map_table_circle },
167   { "line", SILC_CONFIG_ARG_BLOCK,
168     silc_map_cmd_line, silc_map_table_line },
169   { "text", SILC_CONFIG_ARG_BLOCK,
170     silc_map_cmd_text, silc_map_table_text },
171   { NULL },
172 };
173
174 static const SilcConfigTable silc_map_table_main[] =
175 {
176   { "server", SILC_CONFIG_ARG_BLOCK,
177     silc_map_cmd_server, silc_map_table_server },
178   { "loadmap", SILC_CONFIG_ARG_BLOCK,
179     silc_map_cmd_loadmap, silc_map_table_loadmap },
180   { "writemap", SILC_CONFIG_ARG_BLOCK,
181     silc_map_cmd_writemap, silc_map_table_writemap },
182   { "writemaphtml", SILC_CONFIG_ARG_BLOCK,
183     silc_map_cmd_writemaphtml, silc_map_table_writemaphtml },
184   { "writehtml", SILC_CONFIG_ARG_BLOCK,
185     silc_map_cmd_writehtml, silc_map_table_writehtml },
186   { "cut", SILC_CONFIG_ARG_BLOCK,
187     silc_map_cmd_cut, silc_map_table_cut },
188   { "rectangle", SILC_CONFIG_ARG_BLOCK,
189     silc_map_cmd_rectangle, silc_map_table_rectangle },
190   { "circle", SILC_CONFIG_ARG_BLOCK,
191     silc_map_cmd_circle, silc_map_table_circle },
192   { "line", SILC_CONFIG_ARG_BLOCK,
193     silc_map_cmd_line, silc_map_table_line },
194   { "text", SILC_CONFIG_ARG_BLOCK,
195     silc_map_cmd_text, silc_map_table_text },
196   { NULL },
197 };
198
199 /* Command datas.  Used when command is outside server { } section. */
200 static char *filename = NULL;
201 static char *lat = NULL;
202 static char *lon = NULL;
203 static char *lat2 = NULL;
204 static char *lon2 = NULL;
205 static SilcUInt32 width = 0;
206 static SilcUInt32 height = 0;
207 static SilcInt16 r = 0;
208 static SilcInt16 g = 0;
209 static SilcInt16 b = 0;
210 static SilcInt16 lr = -1;
211 static SilcInt16 lg = -1;
212 static SilcInt16 lb = -1;
213 static char *text = NULL;
214 static SilcInt32 lposx = 0;
215 static SilcInt32 lposy = 0;
216 static bool color_set = FALSE;
217 static bool lcolor_set = FALSE;
218
219 /* Current server section. */
220 SilcMapConnection curr_conn = NULL;
221
222 /* Command: server, performs the connection to the remote server and
223    gathers statistical information. */
224
225 SILC_CONFIG_CALLBACK(silc_map_cmd_server)
226 {
227   SilcMap map = context;
228   int retval = SILC_CONFIG_OK;
229
230   if (!map->bitmap) {
231     fprintf(stderr, "You must call loadmap command before server command\n");
232     return SILC_CONFIG_ESILENT;
233   }
234
235   if (type == SILC_CONFIG_ARG_BLOCK) {
236     SILC_LOG_DEBUG(("Server config parsed"));
237
238     if (!curr_conn->ips) {
239       fprintf(stderr, "IP must be configured\n");
240       return SILC_CONFIG_EMISSFIELDS;
241     }
242     if (!curr_conn->hostnames) {
243       fprintf(stderr, "Hostname must be configured\n");
244       return SILC_CONFIG_EMISSFIELDS;
245     }
246     if (!curr_conn->port) {
247       fprintf(stderr, "Port must be configured\n");
248       return SILC_CONFIG_EMISSFIELDS;
249     }
250
251     /* The server data is now gathered.  We continue by creating the
252        connection to the server and executing the requested commands. */
253     silc_map_connect(map, curr_conn);
254     map->conns_num++;
255
256     /* Cleanup */
257     curr_conn = NULL;
258
259     return retval;
260   }
261
262   /* Mark the current parsed server */
263   if (!curr_conn) {
264     curr_conn = silc_calloc(1, sizeof(*curr_conn));
265     if (!curr_conn)
266       return SILC_CONFIG_ESILENT;
267
268     curr_conn->hostnames = silc_dlist_init();
269     curr_conn->ips = silc_dlist_init();
270     curr_conn->commands = silc_dlist_init();
271     curr_conn->map = map;
272     if (!map->conns)
273       map->conns = silc_dlist_init();
274     silc_dlist_add(map->conns, curr_conn);
275   }
276
277   if (!strcmp(name, "hostname")) {
278     silc_dlist_add(curr_conn->hostnames, strdup((char *)val));
279   } else if (!strcmp(name, "ip")) {
280     silc_dlist_add(curr_conn->ips, strdup((char *)val));
281   } else if (!strcmp(name, "port")) {
282     curr_conn->port = (SilcUInt32)*(int *)val;
283   } else if (!strcmp(name, "public_key")) {
284     curr_conn->public_key = strdup((char *)val);
285   } else if (!strcmp(name, "country")) {
286     curr_conn->country = strdup((char *)val);
287   } else if (!strcmp(name, "city")) {
288     curr_conn->city = strdup((char *)val);
289   } else if (!strcmp(name, "admin")) {
290     curr_conn->admin = strdup((char *)val);
291   } else if (!strcmp(name, "description")) {
292     curr_conn->description = strdup((char *)val);
293   } else if (!strcmp(name, "html_url")) {
294     curr_conn->html_url = strdup((char *)val);
295   } else if (!strcmp(name, "connect")) {
296     curr_conn->connect = (bool)*(int *)val;
297   } else if (!strcmp(name, "connect_timeout")) {
298     curr_conn->connect_timeout = (SilcUInt32)*(int *)val;
299   } else if (!strcmp(name, "starttime")) {
300     curr_conn->starttime = (bool)*(int *)val;
301   } else if (!strcmp(name, "uptime")) {
302     curr_conn->uptime = (bool)*(int *)val;
303   } else if (!strcmp(name, "clients")) {
304     curr_conn->clients = (bool)*(int *)val;
305   } else if (!strcmp(name, "channels")) {
306     curr_conn->channels = (bool)*(int *)val;
307   } else if (!strcmp(name, "server_ops")) {
308     curr_conn->server_ops = (bool)*(int *)val;
309   } else if (!strcmp(name, "router_ops")) {
310     curr_conn->router_ops = (bool)*(int *)val;
311   } else if (!strcmp(name, "cell_clients")) {
312     curr_conn->cell_clients = (bool)*(int *)val;
313   } else if (!strcmp(name, "cell_channels")) {
314     curr_conn->cell_channels = (bool)*(int *)val;
315   } else if (!strcmp(name, "cell_servers")) {
316     curr_conn->cell_servers = (bool)*(int *)val;
317   } else if (!strcmp(name, "all_clients")) {
318     curr_conn->all_clients = (bool)*(int *)val;
319   } else if (!strcmp(name, "all_channels")) {
320     curr_conn->all_channels = (bool)*(int *)val;
321   } else if (!strcmp(name, "all_servers")) {
322     curr_conn->all_servers = (bool)*(int *)val;
323   } else if (!strcmp(name, "all_routers")) {
324     curr_conn->all_routers = (bool)*(int *)val;
325   } else if (!strcmp(name, "all_server_ops")) {
326     curr_conn->all_server_ops = (bool)*(int *)val;
327   } else if (!strcmp(name, "all_router_ops")) {
328     curr_conn->all_router_ops = (bool)*(int *)val;
329   } else if (!strcmp(name, "motd")) {
330     curr_conn->motd = (bool)*(int *)val;
331   } else if (!strcmp(name, "up_color")) {
332     curr_conn->up_color = strdup((char *)val);
333   } else if (!strcmp(name, "down_color")) {
334     curr_conn->down_color = strdup((char *)val);
335   } else if (!strcmp(name, "up_text_color")) {
336     curr_conn->up_text_color = strdup((char *)val);
337   } else if (!strcmp(name, "down_text_color")) {
338     curr_conn->down_text_color = strdup((char *)val);
339   } else {
340     retval = SILC_CONFIG_ESILENT;
341   }
342
343   return retval;
344 }
345
346 /* Command: loadmap, loadmaps the bitmap map image. */
347
348 SILC_CONFIG_CALLBACK(silc_map_cmd_loadmap)
349 {
350   SilcMap map = context;
351   int retval = SILC_CONFIG_OK;
352
353   if (type == SILC_CONFIG_ARG_BLOCK) {
354     if (!filename)
355       return SILC_CONFIG_EMISSFIELDS;
356
357     SILC_LOG_DEBUG(("loadmap: file: %s", filename));
358
359     /* Destroy old bitmap if loadmaped */
360     silc_free(map->bitmap);
361
362     /* Loadmap the bitmap image */
363     if (!silc_map_load_ppm(map, filename))
364       retval = SILC_CONFIG_ESILENT;
365
366     /* Cleanup */
367     silc_free(filename);
368     filename = NULL;
369
370     return retval;
371   }
372
373   if (!strcmp(name, "filename"))
374     filename = strdup((char *)val);
375   else
376     retval = SILC_CONFIG_ESILENT;
377
378   return retval;
379 }
380
381 /* Command: writemap, writemap the map into bitmap file. */
382
383 SILC_CONFIG_CALLBACK(silc_map_cmd_writemap)
384 {
385   SilcMap map = context;
386   int retval = SILC_CONFIG_OK;
387
388   if (type == SILC_CONFIG_ARG_BLOCK) {
389     if (!filename)
390       return SILC_CONFIG_EMISSFIELDS;
391
392     SILC_LOG_DEBUG(("writemap: file: %s", filename));
393
394     /* Execute directly if there are no connections */
395     if (map->conns_num == 0) {
396       /* Writemap the map */
397       if (!silc_map_write_ppm(map, filename))
398         retval = SILC_CONFIG_ESILENT;
399     } else {
400       map->writemap.filename = strdup(filename);
401       map->writemap.writemap = TRUE;
402     }
403
404     /* Cleanup */
405     silc_free(filename);
406     filename = NULL;
407
408     return retval;
409   }
410
411   if (!strcmp(name, "filename"))
412     filename = strdup((char *)val);
413   else
414     retval = SILC_CONFIG_ESILENT;
415
416   return retval;
417 }
418
419 /* Command: writemaphtml, writes HTML map of the image map. */
420
421 SILC_CONFIG_CALLBACK(silc_map_cmd_writemaphtml)
422 {
423   SilcMap map = context;
424   int retval = SILC_CONFIG_OK;
425
426   if (type == SILC_CONFIG_ARG_BLOCK) {
427     int i;
428     if (!filename)
429       return SILC_CONFIG_EMISSFIELDS;
430
431     SILC_LOG_DEBUG(("writemaphtml: file: %s", filename));
432
433     /* Will generate HTML map page */
434     i = map->writemaphtml_count;
435     map->writemaphtml = silc_realloc(map->writemaphtml,
436                                      sizeof(*map->writemaphtml) * (i + 1));
437     map->writemaphtml[i].filename = filename;
438     map->writemaphtml[i].text = text;
439     if (lon)
440       map->writemaphtml[i].x = silc_map_lon2x(map, lon);
441     if (lat)
442       map->writemaphtml[i].y = silc_map_lat2y(map, lat);
443     map->writemaphtml[i].writemaphtml = TRUE;
444     map->writemaphtml_count++;
445
446     /* Clean up */
447     silc_free(lat);
448     silc_free(lon);
449     filename = NULL;
450     text = NULL;
451     lat = lon = NULL;
452
453     return retval;
454   }
455
456   if (!strcmp(name, "filename"))
457     filename = strdup((char *)val);
458   else if (!strcmp(name, "image"))
459     text = strdup((char *)val);
460   else if (!strcmp(name, "cut_lat"))
461     lat = strdup((char *)val);
462   else if (!strcmp(name, "cut_lon"))
463     lon = strdup((char *)val);
464   else
465     retval = SILC_CONFIG_ESILENT;
466
467   return retval;
468 }
469
470 /* Command: writehtml, writes the gathered data into HTML pages. */
471
472 SILC_CONFIG_CALLBACK(silc_map_cmd_writehtml)
473 {
474   SilcMap map = context;
475   int retval = SILC_CONFIG_OK;
476
477   if (type == SILC_CONFIG_ARG_BLOCK) {
478     if (!filename)
479       return SILC_CONFIG_EMISSFIELDS;
480
481     SILC_LOG_DEBUG(("writehtml: file: %s", filename));
482
483     /* Will generate HTML pages */
484     map->writehtml.filename = filename;
485     map->writehtml.text = text;         /* class */
486     map->writehtml.writehtml = TRUE;
487     filename = text = NULL;
488
489     return retval;
490   }
491   if (!strcmp(name, "filename"))
492     filename = strdup((char *)val);
493   else if (!strcmp(name, "class"))
494     text = strdup((char *)val);
495   else
496     retval = SILC_CONFIG_ESILENT;
497
498   return retval;
499 }
500
501 /* Command: cut, cut's a specified area from the map. */
502
503 SILC_CONFIG_CALLBACK(silc_map_cmd_cut)
504 {
505   SilcMap map = context;
506   int retval = SILC_CONFIG_OK;
507   bool ret;
508
509   if (type == SILC_CONFIG_ARG_BLOCK) {
510     SilcMap map2;
511     int i;
512
513     if (!filename || !lat || !lon || !width || !height)
514       return SILC_CONFIG_EMISSFIELDS;
515
516     SILC_LOG_DEBUG(("cut: lat: %s lon: %s w: %ld h: %ld file: %s",
517                     lat, lon, width, height, filename));
518
519     /* Execute directly if not inside connection block */
520     if (!curr_conn) {
521       if (!map->conns_num) {
522         /* Before any connection blocks */
523
524         /* Cut the chunk from the map. */
525         ret = silc_map_cut(map, silc_map_lon2x(map, lon),
526                            silc_map_lat2y(map, lat),
527                            width, height, &map2);
528         if (ret) {
529           /* Writemap the chunk. */
530           ret = silc_map_write_ppm(map2, filename);
531           silc_map_free(map2);
532         }
533         if (!ret)
534           retval = SILC_CONFIG_ESILENT;
535       } else {
536         /* After all connection blocks */
537         i = map->cut_count;
538         map->cut = silc_realloc(map->cut, sizeof(*map->cut) * (i + 1));
539         map->cut[i].filename = strdup(filename);
540         map->cut[i].x = silc_map_lon2x(map, lon);
541         map->cut[i].y = silc_map_lat2y(map, lat);
542         map->cut[i].width = width;
543         map->cut[i].height = height;
544         map->cut[i].cut = TRUE;
545         map->cut_count++;
546       }
547     } else {
548       SilcMapCommand cmd = silc_calloc(1, sizeof(*cmd));
549       if (!cmd)
550         return SILC_CONFIG_ESILENT;
551
552       silc_dlist_add(curr_conn->commands, cmd);
553       cmd->filename = strdup(filename);
554       cmd->x = silc_map_lon2x(map, lon);
555       cmd->y = silc_map_lat2y(map, lat);
556       cmd->width = width;
557       cmd->height = height;
558       cmd->cut = TRUE;
559     }
560
561     /* Cleanup */
562     silc_free(filename);
563     silc_free(lat);
564     silc_free(lon);
565     filename = NULL;
566     lat = NULL;
567     lon = NULL;
568     width = 0;
569     height = 0;
570
571     return retval;
572   }
573
574   if (!strcmp(name, "lat"))
575     lat = strdup((char *)val);
576   else if (!strcmp(name, "lon"))
577     lon = strdup((char *)val);
578   else if (!strcmp(name, "width"))
579     width = (SilcUInt32)*(int *)val;
580   else if (!strcmp(name, "height"))
581     height = (SilcUInt32)*(int *)val;
582   else if (!strcmp(name, "filename"))
583     filename = strdup((char *)val);
584   else
585     retval = SILC_CONFIG_ESILENT;
586
587   return retval;
588 }
589
590 /* Command: rectangle, draws a rectangle on the map. */
591
592 SILC_CONFIG_CALLBACK(silc_map_cmd_rectangle)
593 {
594   SilcMap map = context;
595   int retval = SILC_CONFIG_OK;
596   bool ret;
597
598   if (type == SILC_CONFIG_ARG_BLOCK) {
599     if (!lat || !lon)
600       return SILC_CONFIG_EMISSFIELDS;
601
602     SILC_LOG_DEBUG(("rectangle: lat: %s lon: %s color: %d %d %d",
603                     lat, lon, r, g, b));
604
605     if (lr == -1) {
606       lr = r;
607       lg = g;
608       lb = b;
609     }
610
611     /* Execute directly if not for connection */
612     if (!curr_conn) {
613       /* Draw the rectangle */
614       ret = silc_map_draw_rectangle(map, silc_map_lon2x(map, lon),
615                                     silc_map_lat2y(map, lat),
616                                     r, g, b, text, lposx, lposy, lr, lg, lb);
617       if (!ret)
618         retval = SILC_CONFIG_ESILENT;
619     } else {
620       SilcMapCommand cmd = silc_calloc(1, sizeof(*cmd));
621       if (!cmd)
622         return SILC_CONFIG_ESILENT;
623
624       silc_dlist_add(curr_conn->commands, cmd);
625       cmd->r = r;
626       cmd->g = g;
627       cmd->b = b;
628       cmd->lr = lr;
629       cmd->lg = lg;
630       cmd->lb = lb;
631       cmd->x = silc_map_lon2x(map, lon);
632       cmd->y = silc_map_lat2y(map, lat);
633       cmd->text = text ? strdup(text) : NULL;
634       cmd->lposx = lposx;
635       cmd->lposy = lposy;
636       cmd->draw_rectangle = TRUE;
637       cmd->color_set = color_set;
638       cmd->lcolor_set = lcolor_set;
639     }
640
641     /* Cleanup */
642     silc_free(text);
643     silc_free(lat);
644     silc_free(lon);
645     text = NULL;
646     lat = NULL;
647     lon = NULL;
648     lposx = 0;
649     lposy = 0;
650     lr = lg = lb = -1;
651     color_set = lcolor_set = FALSE;
652
653     return retval;
654   }
655
656   if (!strcmp(name, "lat"))
657     lat = strdup((char *)val);
658   else if (!strcmp(name, "lon"))
659     lon = strdup((char *)val);
660   else if (!strcmp(name, "color")) {
661     if (!silc_map_parse_color((const char *)val, &r, &g, &b))
662       retval = SILC_CONFIG_ESILENT;
663     color_set = TRUE;
664   } else if (!strcmp(name, "label"))
665     text = strdup((char *)val);
666   else if (!strcmp(name, "lposx"))
667     lposx = (SilcInt32)*(int *)val;
668   else if (!strcmp(name, "lposy"))
669     lposy = (SilcInt32)*(int *)val;
670   else if (!strcmp(name, "lcolor")) {
671     if (!silc_map_parse_color((const char *)val, &lr, &lg, &lb))
672       retval = SILC_CONFIG_ESILENT;
673     lcolor_set = TRUE;
674  } else
675     retval = SILC_CONFIG_ESILENT;
676
677   return retval;
678 }
679
680 /* Command: circle, draws a circle on the map. */
681
682 SILC_CONFIG_CALLBACK(silc_map_cmd_circle)
683 {
684   SilcMap map = context;
685   int retval = SILC_CONFIG_OK;
686   bool ret;
687
688   if (type == SILC_CONFIG_ARG_BLOCK) {
689     if (!lat || !lon)
690       return SILC_CONFIG_EMISSFIELDS;
691
692     SILC_LOG_DEBUG(("circle: lat: %s lon: %s color: %d %d %d",
693                     lat, lon, r, g, b));
694
695     if (lr == -1) {
696       lr = r;
697       lg = g;
698       lb = b;
699     }
700
701     /* Execute directly if not for connection */
702     if (!curr_conn) {
703       /* Draw the circle */
704       ret = silc_map_draw_circle(map, silc_map_lon2x(map, lon),
705                                  silc_map_lat2y(map, lat),
706                                  r, g, b, text, lposx, lposy, lr, lg, lb);
707       if (!ret)
708         retval = SILC_CONFIG_ESILENT;
709     } else {
710       SilcMapCommand cmd = silc_calloc(1, sizeof(*cmd));
711       if (!cmd)
712         return SILC_CONFIG_ESILENT;
713
714       silc_dlist_add(curr_conn->commands, cmd);
715       cmd->r = r;
716       cmd->g = g;
717       cmd->b = b;
718       cmd->lr = lr;
719       cmd->lg = lg;
720       cmd->lb = lb;
721       cmd->x = silc_map_lon2x(map, lon);
722       cmd->y = silc_map_lat2y(map, lat);
723       cmd->text = text ? strdup(text) : NULL;
724       cmd->lposx = lposx;
725       cmd->lposy = lposy;
726       cmd->draw_circle = TRUE;
727       cmd->color_set = color_set;
728       cmd->lcolor_set = lcolor_set;
729     }
730
731     /* Cleanup */
732     silc_free(text);
733     silc_free(lat);
734     silc_free(lon);
735     text = NULL;
736     lat = NULL;
737     lon = NULL;
738     lposx = 0;
739     lposy = 0;
740     lr = lg = lb = -1;
741     color_set = lcolor_set = FALSE;
742
743     return retval;
744   }
745
746   if (!strcmp(name, "lat"))
747     lat = strdup((char *)val);
748   else if (!strcmp(name, "lon"))
749     lon = strdup((char *)val);
750   else if (!strcmp(name, "color")) {
751     if (!silc_map_parse_color((const char *)val, &r, &g, &b))
752       retval = SILC_CONFIG_ESILENT;
753     color_set = TRUE;
754   } else if (!strcmp(name, "label"))
755     text = strdup((char *)val);
756   else if (!strcmp(name, "lposx"))
757     lposx = (SilcInt32)*(int *)val;
758   else if (!strcmp(name, "lposy"))
759     lposy = (SilcInt32)*(int *)val;
760   else if (!strcmp(name, "lcolor")) {
761     if (!silc_map_parse_color((const char *)val, &lr, &lg, &lb))
762       retval = SILC_CONFIG_ESILENT;
763     lcolor_set = TRUE;
764   } else
765     retval = SILC_CONFIG_ESILENT;
766
767   return retval;
768 }
769
770 /* Command: line, draws a line between two points in the map. */
771
772 SILC_CONFIG_CALLBACK(silc_map_cmd_line)
773 {
774   SilcMap map = context;
775   int retval = SILC_CONFIG_OK;
776   bool ret;
777
778   if (type == SILC_CONFIG_ARG_BLOCK) {
779     if (!lat || !lon || !lat2 || !lon2)
780       return SILC_CONFIG_EMISSFIELDS;
781
782     SILC_LOG_DEBUG(("line: alat: %s alon: %s blat: %s blon: %s "
783                     "width: %ld color: %d %d %d",
784                     lat, lon, lat2, lon2, width, r, g, b));
785
786     if (!width)
787       width = 1;
788
789     /* Execute directly if not for connection */
790     if (!curr_conn) {
791       /* Draw the line */
792       ret = silc_map_draw_line(map, width,
793                                silc_map_lon2x(map, lon),
794                                silc_map_lat2y(map, lat),
795                                silc_map_lon2x(map, lon2),
796                                silc_map_lat2y(map, lat2),
797                                r, g, b);
798       if (!ret)
799         retval = SILC_CONFIG_ESILENT;
800     } else {
801       SilcMapCommand cmd = silc_calloc(1, sizeof(*cmd));
802       if (!cmd)
803         return SILC_CONFIG_ESILENT;
804
805       silc_dlist_add(curr_conn->commands, cmd);
806       cmd->r = r;
807       cmd->g = g;
808       cmd->b = b;
809       cmd->x = silc_map_lon2x(map, lon);
810       cmd->y = silc_map_lat2y(map, lat);
811       cmd->x2 = silc_map_lon2x(map, lon2);
812       cmd->y2 = silc_map_lat2y(map, lat2);
813       cmd->width = width;
814       cmd->draw_line = TRUE;
815       cmd->color_set = color_set;
816     }
817
818     /* Cleanup */
819     silc_free(lat);
820     silc_free(lon);
821     silc_free(lat2);
822     silc_free(lon2);
823     lat = NULL;
824     lon = NULL;
825     lat2 = NULL;
826     lon2 = NULL;
827     width = 0;
828     color_set = FALSE;
829
830     return retval;
831   }
832
833   if (!strcmp(name, "a_lat"))
834     lat = strdup((char *)val);
835   else if (!strcmp(name, "a_lon"))
836     lon = strdup((char *)val);
837   else if (!strcmp(name, "b_lat"))
838     lat2 = strdup((char *)val);
839   else if (!strcmp(name, "b_lon"))
840     lon2 = strdup((char *)val);
841   else if (!strcmp(name, "width"))
842     width = (SilcUInt32)*(int *)val;
843   else if (!strcmp(name, "color")) {
844     if (!silc_map_parse_color((const char *)val, &r, &g, &b))
845       retval = SILC_CONFIG_ESILENT;
846     color_set = TRUE;
847   } else
848     retval = SILC_CONFIG_ESILENT;
849
850   return retval;
851 }
852
853 /* Command: text, prints a text on the map. */
854
855 SILC_CONFIG_CALLBACK(silc_map_cmd_text)
856 {
857   SilcMap map = context;
858   int retval = SILC_CONFIG_OK;
859   bool ret;
860
861   if (type == SILC_CONFIG_ARG_BLOCK) {
862     if (!lat || !lon || !text)
863       return SILC_CONFIG_EMISSFIELDS;
864
865     SILC_LOG_DEBUG(("text: lat: %s lon: %s color: %d %d %d text: %s",
866                     lat, lon, r, g, b, text));
867
868     /* Execute directly if not for connection */
869     if (!curr_conn) {
870       /* Print the text */
871       ret = silc_map_draw_text(map, text,
872                                silc_map_lon2x(map, lon),
873                                silc_map_lat2y(map, lat),
874                                r, g, b);
875       if (!ret)
876         retval = SILC_CONFIG_ESILENT;
877     } else {
878       SilcMapCommand cmd = silc_calloc(1, sizeof(*cmd));
879       if (!cmd)
880         return SILC_CONFIG_ESILENT;
881
882       silc_dlist_add(curr_conn->commands, cmd);
883       cmd->r = r;
884       cmd->g = g;
885       cmd->b = b;
886       cmd->x = silc_map_lon2x(map, lon);
887       cmd->y = silc_map_lat2y(map, lat);
888       cmd->text = text ? strdup(text) : NULL;
889       cmd->draw_text = TRUE;
890       cmd->color_set = color_set;
891     }
892
893     /* Cleanup */
894     silc_free(text);
895     silc_free(lat);
896     silc_free(lon);
897     text = NULL;
898     lat = NULL;
899     lon = NULL;
900     color_set = FALSE;
901
902     return retval;
903   }
904
905   if (!strcmp(name, "lat"))
906     lat = strdup((char *)val);
907   else if (!strcmp(name, "lon"))
908     lon = strdup((char *)val);
909   else if (!strcmp(name, "color")) {
910     if (!silc_map_parse_color((const char *)val, &r, &g, &b))
911       retval = SILC_CONFIG_ESILENT;
912     color_set = TRUE;
913   } else if (!strcmp(name, "text"))
914     text = strdup((char *)val);
915   else
916     retval = SILC_CONFIG_ESILENT;
917
918   return retval;
919 }
920
921 /* Parses the commands from the file `filename'. */
922
923 bool silc_map_commands_parse(SilcMap map, const char *filename)
924 {
925   SilcConfigEntity ent;
926   SilcConfigFile *file;
927   bool retval = TRUE;
928   int ret;
929
930   SILC_LOG_DEBUG(("Parsing commands"));
931
932   /* Open commands file */
933   file = silc_config_open(filename);
934   if (!file) {
935     fprintf(stderr, "Cannot open commands file '%s'\n", filename);
936     return FALSE;
937   }
938
939   /* Parse the commands */
940   ent = silc_config_init(file);
941   silc_config_register_table(ent, silc_map_table_main, map);
942   ret = silc_config_main(ent);
943
944   SILC_LOG_DEBUG(("Parsing status: %s", silc_config_strerror(ret)));
945
946   if (ret && ret != SILC_CONFIG_ESILENT) {
947     fprintf(stderr, "Error parsing commands: %s, line %ld\n",
948             silc_config_strerror(ret), silc_config_get_line(file));
949     retval = FALSE;
950   }
951
952   /* Cleanup */
953   silc_config_close(file);
954   return retval;
955 }