The SILC Project

source navigation ]
identifier search ]
freetext search ]
file search ]

silc/silcmap/silcmap_command.c

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