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