Load the bitmap file only after connections has been
[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 - 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->bitmap) {
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     /* Destroy old bitmap if loadmaped */
370     silc_free(map->bitmap);
371     map->bitmap = NULL;
372
373     /* Execute directly if there are no connections */
374     if (map->conns_num == 0) {
375       /* Load the bitmap image */
376       if (!silc_map_load_ppm(map, filename))
377         retval = SILC_CONFIG_ESILENT;
378     } else {
379       map->loadmap.filename = strdup(filename);
380       map->loadmap.writemap = TRUE;
381     }
382
383     /* Cleanup */
384     silc_free(filename);
385     filename = NULL;
386
387     return retval;
388   }
389
390   if (!strcmp(name, "filename"))
391     filename = strdup((char *)val);
392   else
393     retval = SILC_CONFIG_ESILENT;
394
395   return retval;
396 }
397
398 /* Command: writemap, writemap the map into bitmap file. */
399
400 SILC_CONFIG_CALLBACK(silc_map_cmd_writemap)
401 {
402   SilcMap map = context;
403   int retval = SILC_CONFIG_OK;
404
405   if (type == SILC_CONFIG_ARG_BLOCK) {
406     if (!filename)
407       return SILC_CONFIG_EMISSFIELDS;
408
409     SILC_LOG_DEBUG(("writemap: file: %s", filename));
410
411     /* Execute directly if there are no connections */
412     if (map->conns_num == 0) {
413       /* Writemap the map */
414       if (!silc_map_write_ppm(map, filename))
415         retval = SILC_CONFIG_ESILENT;
416     } else {
417       map->writemap.filename = strdup(filename);
418       map->writemap.writemap = TRUE;
419     }
420
421     /* Cleanup */
422     silc_free(filename);
423     filename = NULL;
424
425     return retval;
426   }
427
428   if (!strcmp(name, "filename"))
429     filename = strdup((char *)val);
430   else
431     retval = SILC_CONFIG_ESILENT;
432
433   return retval;
434 }
435
436 /* Command: writemaphtml, writes HTML map of the image map. */
437
438 SILC_CONFIG_CALLBACK(silc_map_cmd_writemaphtml)
439 {
440   SilcMap map = context;
441   int retval = SILC_CONFIG_OK;
442
443   if (type == SILC_CONFIG_ARG_BLOCK) {
444     int i;
445     if (!filename)
446       return SILC_CONFIG_EMISSFIELDS;
447
448     SILC_LOG_DEBUG(("writemaphtml: file: %s", filename));
449
450     /* Will generate HTML map page */
451     i = map->writemaphtml_count;
452     map->writemaphtml = silc_realloc(map->writemaphtml,
453                                      sizeof(*map->writemaphtml) * (i + 1));
454     map->writemaphtml[i].filename = filename;
455     map->writemaphtml[i].text = text;
456     if (lon)
457       map->writemaphtml[i].x = silc_map_lon2x(map, lon);
458     if (lat)
459       map->writemaphtml[i].y = silc_map_lat2y(map, lat);
460     map->writemaphtml[i].writemaphtml = TRUE;
461     map->writemaphtml_count++;
462
463     /* Clean up */
464     silc_free(lat);
465     silc_free(lon);
466     filename = NULL;
467     text = NULL;
468     lat = lon = NULL;
469
470     return retval;
471   }
472
473   if (!strcmp(name, "filename"))
474     filename = strdup((char *)val);
475   else if (!strcmp(name, "image"))
476     text = strdup((char *)val);
477   else if (!strcmp(name, "cut_lat"))
478     lat = strdup((char *)val);
479   else if (!strcmp(name, "cut_lon"))
480     lon = strdup((char *)val);
481   else
482     retval = SILC_CONFIG_ESILENT;
483
484   return retval;
485 }
486
487 /* Command: writehtml, writes the gathered data into HTML pages. */
488
489 SILC_CONFIG_CALLBACK(silc_map_cmd_writehtml)
490 {
491   SilcMap map = context;
492   int retval = SILC_CONFIG_OK;
493
494   if (type == SILC_CONFIG_ARG_BLOCK) {
495     if (!filename)
496       return SILC_CONFIG_EMISSFIELDS;
497
498     SILC_LOG_DEBUG(("writehtml: file: %s", filename));
499
500     /* Will generate HTML pages */
501     map->writehtml.filename = filename;
502     map->writehtml.text = text;         /* class */
503     map->writehtml.writehtml = TRUE;
504     filename = text = NULL;
505
506     return retval;
507   }
508   if (!strcmp(name, "filename"))
509     filename = strdup((char *)val);
510   else if (!strcmp(name, "class"))
511     text = strdup((char *)val);
512   else
513     retval = SILC_CONFIG_ESILENT;
514
515   return retval;
516 }
517
518 /* Command: writerel, writes the uptime reliability graph. */
519
520 SILC_CONFIG_CALLBACK(silc_map_cmd_writerel)
521 {
522   SilcMap map = context;
523   int retval = SILC_CONFIG_OK;
524
525   if (type == SILC_CONFIG_ARG_BLOCK) {
526     if (!filename)
527       return SILC_CONFIG_EMISSFIELDS;
528
529     SILC_LOG_DEBUG(("writerel: file: %s", filename));
530
531     /* Will generate uptime reliability graph */
532     map->writerel.filename = filename;
533     map->writerel.text = text;          /* class */
534     map->writerel.writerel = TRUE;
535     filename = text = NULL;
536
537     return retval;
538   }
539   if (!strcmp(name, "filename"))
540     filename = strdup((char *)val);
541   else if (!strcmp(name, "class"))
542     text = strdup((char *)val);
543   else
544     retval = SILC_CONFIG_ESILENT;
545
546   return retval;
547 }
548
549 /* Command: cut, cut's a specified area from the map. */
550
551 SILC_CONFIG_CALLBACK(silc_map_cmd_cut)
552 {
553   SilcMap map = context;
554   int retval = SILC_CONFIG_OK;
555   bool ret;
556
557   if (type == SILC_CONFIG_ARG_BLOCK) {
558     SilcMap map2;
559     int i;
560
561     if (!filename || !lat || !lon || !width || !height)
562       return SILC_CONFIG_EMISSFIELDS;
563
564     SILC_LOG_DEBUG(("cut: lat: %s lon: %s w: %ld h: %ld file: %s",
565                     lat, lon, width, height, filename));
566
567     /* Execute directly if not inside connection block */
568     if (!curr_conn) {
569       if (!map->conns_num) {
570         /* Before any connection blocks */
571
572         /* Cut the chunk from the map. */
573         ret = silc_map_cut(map, silc_map_lon2x(map, lon),
574                            silc_map_lat2y(map, lat),
575                            width, height, &map2);
576         if (ret) {
577           /* Writemap the chunk. */
578           ret = silc_map_write_ppm(map2, filename);
579           silc_map_free(map2);
580         }
581         if (!ret)
582           retval = SILC_CONFIG_ESILENT;
583       } else {
584         /* After all connection blocks */
585         i = map->cut_count;
586         map->cut = silc_realloc(map->cut, sizeof(*map->cut) * (i + 1));
587         map->cut[i].filename = strdup(filename);
588         map->cut[i].x = silc_map_lon2x(map, lon);
589         map->cut[i].y = silc_map_lat2y(map, lat);
590         map->cut[i].width = width;
591         map->cut[i].height = height;
592         map->cut[i].cut = TRUE;
593         map->cut_count++;
594       }
595     } else {
596       SilcMapCommand cmd = silc_calloc(1, sizeof(*cmd));
597       if (!cmd)
598         return SILC_CONFIG_ESILENT;
599
600       silc_dlist_add(curr_conn->commands, cmd);
601       cmd->filename = strdup(filename);
602       cmd->x = silc_map_lon2x(map, lon);
603       cmd->y = silc_map_lat2y(map, lat);
604       cmd->width = width;
605       cmd->height = height;
606       cmd->cut = TRUE;
607     }
608
609     /* Cleanup */
610     silc_free(filename);
611     silc_free(lat);
612     silc_free(lon);
613     filename = NULL;
614     lat = NULL;
615     lon = NULL;
616     width = 0;
617     height = 0;
618
619     return retval;
620   }
621
622   if (!strcmp(name, "lat"))
623     lat = strdup((char *)val);
624   else if (!strcmp(name, "lon"))
625     lon = strdup((char *)val);
626   else if (!strcmp(name, "width"))
627     width = (SilcUInt32)*(int *)val;
628   else if (!strcmp(name, "height"))
629     height = (SilcUInt32)*(int *)val;
630   else if (!strcmp(name, "filename"))
631     filename = strdup((char *)val);
632   else
633     retval = SILC_CONFIG_ESILENT;
634
635   return retval;
636 }
637
638 /* Command: rectangle, draws a rectangle on the map. */
639
640 SILC_CONFIG_CALLBACK(silc_map_cmd_rectangle)
641 {
642   SilcMap map = context;
643   int retval = SILC_CONFIG_OK;
644   bool ret;
645
646   if (type == SILC_CONFIG_ARG_BLOCK) {
647     if (!lat || !lon)
648       return SILC_CONFIG_EMISSFIELDS;
649
650     SILC_LOG_DEBUG(("rectangle: lat: %s lon: %s color: %d %d %d",
651                     lat, lon, r, g, b));
652
653     if (lr == -1) {
654       lr = r;
655       lg = g;
656       lb = b;
657     }
658
659     /* Execute directly if not for connection */
660     if (!curr_conn && map->bitmap) {
661       /* Draw the rectangle */
662       ret = silc_map_draw_rectangle(map, silc_map_lon2x(map, lon),
663                                     silc_map_lat2y(map, lat),
664                                     r, g, b, text, lposx, lposy, lr, lg, lb);
665       if (!ret)
666         retval = SILC_CONFIG_ESILENT;
667     } else {
668       SilcMapCommand cmd = silc_calloc(1, sizeof(*cmd));
669       if (!cmd)
670         return SILC_CONFIG_ESILENT;
671
672       silc_dlist_add(curr_conn->commands, cmd);
673       cmd->r = r;
674       cmd->g = g;
675       cmd->b = b;
676       cmd->lr = lr;
677       cmd->lg = lg;
678       cmd->lb = lb;
679       cmd->x = silc_map_lon2x(map, lon);
680       cmd->y = silc_map_lat2y(map, lat);
681       cmd->text = text ? strdup(text) : NULL;
682       cmd->lposx = lposx;
683       cmd->lposy = lposy;
684       cmd->draw_rectangle = TRUE;
685       cmd->color_set = color_set;
686       cmd->lcolor_set = lcolor_set;
687     }
688
689     /* Cleanup */
690     silc_free(text);
691     silc_free(lat);
692     silc_free(lon);
693     text = NULL;
694     lat = NULL;
695     lon = NULL;
696     lposx = 0;
697     lposy = 0;
698     lr = lg = lb = -1;
699     color_set = lcolor_set = FALSE;
700
701     return retval;
702   }
703
704   if (!strcmp(name, "lat"))
705     lat = strdup((char *)val);
706   else if (!strcmp(name, "lon"))
707     lon = strdup((char *)val);
708   else if (!strcmp(name, "color")) {
709     if (!silc_map_parse_color((const char *)val, &r, &g, &b))
710       retval = SILC_CONFIG_ESILENT;
711     color_set = TRUE;
712   } else if (!strcmp(name, "label"))
713     text = strdup((char *)val);
714   else if (!strcmp(name, "lposx"))
715     lposx = (SilcInt32)*(int *)val;
716   else if (!strcmp(name, "lposy"))
717     lposy = (SilcInt32)*(int *)val;
718   else if (!strcmp(name, "lcolor")) {
719     if (!silc_map_parse_color((const char *)val, &lr, &lg, &lb))
720       retval = SILC_CONFIG_ESILENT;
721     lcolor_set = TRUE;
722  } else
723     retval = SILC_CONFIG_ESILENT;
724
725   return retval;
726 }
727
728 /* Command: circle, draws a circle on the map. */
729
730 SILC_CONFIG_CALLBACK(silc_map_cmd_circle)
731 {
732   SilcMap map = context;
733   int retval = SILC_CONFIG_OK;
734   bool ret;
735
736   if (type == SILC_CONFIG_ARG_BLOCK) {
737     if (!lat || !lon)
738       return SILC_CONFIG_EMISSFIELDS;
739
740     SILC_LOG_DEBUG(("circle: lat: %s lon: %s color: %d %d %d",
741                     lat, lon, r, g, b));
742
743     if (lr == -1) {
744       lr = r;
745       lg = g;
746       lb = b;
747     }
748
749     /* Execute directly if not for connection */
750     if (!curr_conn && map->bitmap) {
751       /* Draw the circle */
752       ret = silc_map_draw_circle(map, silc_map_lon2x(map, lon),
753                                  silc_map_lat2y(map, lat),
754                                  r, g, b, text, lposx, lposy, lr, lg, lb);
755       if (!ret)
756         retval = SILC_CONFIG_ESILENT;
757     } else {
758       SilcMapCommand cmd = silc_calloc(1, sizeof(*cmd));
759       if (!cmd)
760         return SILC_CONFIG_ESILENT;
761
762       silc_dlist_add(curr_conn->commands, cmd);
763       cmd->r = r;
764       cmd->g = g;
765       cmd->b = b;
766       cmd->lr = lr;
767       cmd->lg = lg;
768       cmd->lb = lb;
769       cmd->x = silc_map_lon2x(map, lon);
770       cmd->y = silc_map_lat2y(map, lat);
771       cmd->text = text ? strdup(text) : NULL;
772       cmd->lposx = lposx;
773       cmd->lposy = lposy;
774       cmd->draw_circle = TRUE;
775       cmd->color_set = color_set;
776       cmd->lcolor_set = lcolor_set;
777     }
778
779     /* Cleanup */
780     silc_free(text);
781     silc_free(lat);
782     silc_free(lon);
783     text = NULL;
784     lat = NULL;
785     lon = NULL;
786     lposx = 0;
787     lposy = 0;
788     lr = lg = lb = -1;
789     color_set = lcolor_set = FALSE;
790
791     return retval;
792   }
793
794   if (!strcmp(name, "lat"))
795     lat = strdup((char *)val);
796   else if (!strcmp(name, "lon"))
797     lon = strdup((char *)val);
798   else if (!strcmp(name, "color")) {
799     if (!silc_map_parse_color((const char *)val, &r, &g, &b))
800       retval = SILC_CONFIG_ESILENT;
801     color_set = TRUE;
802   } else if (!strcmp(name, "label"))
803     text = strdup((char *)val);
804   else if (!strcmp(name, "lposx"))
805     lposx = (SilcInt32)*(int *)val;
806   else if (!strcmp(name, "lposy"))
807     lposy = (SilcInt32)*(int *)val;
808   else if (!strcmp(name, "lcolor")) {
809     if (!silc_map_parse_color((const char *)val, &lr, &lg, &lb))
810       retval = SILC_CONFIG_ESILENT;
811     lcolor_set = TRUE;
812   } else
813     retval = SILC_CONFIG_ESILENT;
814
815   return retval;
816 }
817
818 /* Command: line, draws a line between two points in the map. */
819
820 SILC_CONFIG_CALLBACK(silc_map_cmd_line)
821 {
822   SilcMap map = context;
823   int retval = SILC_CONFIG_OK;
824   bool ret;
825
826   if (type == SILC_CONFIG_ARG_BLOCK) {
827     if (!lat || !lon || !lat2 || !lon2)
828       return SILC_CONFIG_EMISSFIELDS;
829
830     SILC_LOG_DEBUG(("line: alat: %s alon: %s blat: %s blon: %s "
831                     "width: %ld color: %d %d %d",
832                     lat, lon, lat2, lon2, width, r, g, b));
833
834     if (!width)
835       width = 1;
836
837     /* Execute directly if not for connection */
838     if (!curr_conn && map->bitmap) {
839       /* Draw the line */
840       ret = silc_map_draw_line(map, width,
841                                silc_map_lon2x(map, lon),
842                                silc_map_lat2y(map, lat),
843                                silc_map_lon2x(map, lon2),
844                                silc_map_lat2y(map, lat2),
845                                r, g, b);
846       if (!ret)
847         retval = SILC_CONFIG_ESILENT;
848     } else {
849       SilcMapCommand cmd = silc_calloc(1, sizeof(*cmd));
850       if (!cmd)
851         return SILC_CONFIG_ESILENT;
852
853       silc_dlist_add(curr_conn->commands, cmd);
854       cmd->r = r;
855       cmd->g = g;
856       cmd->b = b;
857       cmd->x = silc_map_lon2x(map, lon);
858       cmd->y = silc_map_lat2y(map, lat);
859       cmd->x2 = silc_map_lon2x(map, lon2);
860       cmd->y2 = silc_map_lat2y(map, lat2);
861       cmd->width = width;
862       cmd->draw_line = TRUE;
863       cmd->color_set = color_set;
864     }
865
866     /* Cleanup */
867     silc_free(lat);
868     silc_free(lon);
869     silc_free(lat2);
870     silc_free(lon2);
871     lat = NULL;
872     lon = NULL;
873     lat2 = NULL;
874     lon2 = NULL;
875     width = 0;
876     color_set = FALSE;
877
878     return retval;
879   }
880
881   if (!strcmp(name, "a_lat"))
882     lat = strdup((char *)val);
883   else if (!strcmp(name, "a_lon"))
884     lon = strdup((char *)val);
885   else if (!strcmp(name, "b_lat"))
886     lat2 = strdup((char *)val);
887   else if (!strcmp(name, "b_lon"))
888     lon2 = strdup((char *)val);
889   else if (!strcmp(name, "width"))
890     width = (SilcUInt32)*(int *)val;
891   else if (!strcmp(name, "color")) {
892     if (!silc_map_parse_color((const char *)val, &r, &g, &b))
893       retval = SILC_CONFIG_ESILENT;
894     color_set = TRUE;
895   } else
896     retval = SILC_CONFIG_ESILENT;
897
898   return retval;
899 }
900
901 /* Command: text, prints a text on the map. */
902
903 SILC_CONFIG_CALLBACK(silc_map_cmd_text)
904 {
905   SilcMap map = context;
906   int retval = SILC_CONFIG_OK;
907   bool ret;
908
909   if (type == SILC_CONFIG_ARG_BLOCK) {
910     if (!lat || !lon || !text)
911       return SILC_CONFIG_EMISSFIELDS;
912
913     SILC_LOG_DEBUG(("text: lat: %s lon: %s color: %d %d %d text: %s",
914                     lat, lon, r, g, b, text));
915
916     /* Execute directly if not for connection */
917     if (!curr_conn && map->bitmap) {
918       /* Print the text */
919       ret = silc_map_draw_text(map, text,
920                                silc_map_lon2x(map, lon),
921                                silc_map_lat2y(map, lat),
922                                r, g, b);
923       if (!ret)
924         retval = SILC_CONFIG_ESILENT;
925     } else {
926       SilcMapCommand cmd = silc_calloc(1, sizeof(*cmd));
927       if (!cmd)
928         return SILC_CONFIG_ESILENT;
929
930       silc_dlist_add(curr_conn->commands, cmd);
931       cmd->r = r;
932       cmd->g = g;
933       cmd->b = b;
934       cmd->x = silc_map_lon2x(map, lon);
935       cmd->y = silc_map_lat2y(map, lat);
936       cmd->text = text ? strdup(text) : NULL;
937       cmd->draw_text = TRUE;
938       cmd->color_set = color_set;
939     }
940
941     /* Cleanup */
942     silc_free(text);
943     silc_free(lat);
944     silc_free(lon);
945     text = NULL;
946     lat = NULL;
947     lon = NULL;
948     color_set = FALSE;
949
950     return retval;
951   }
952
953   if (!strcmp(name, "lat"))
954     lat = strdup((char *)val);
955   else if (!strcmp(name, "lon"))
956     lon = strdup((char *)val);
957   else if (!strcmp(name, "color")) {
958     if (!silc_map_parse_color((const char *)val, &r, &g, &b))
959       retval = SILC_CONFIG_ESILENT;
960     color_set = TRUE;
961   } else if (!strcmp(name, "text"))
962     text = strdup((char *)val);
963   else
964     retval = SILC_CONFIG_ESILENT;
965
966   return retval;
967 }
968
969 /* Parses the commands from the file `filename'. */
970
971 bool silc_map_commands_parse(SilcMap map, const char *filename)
972 {
973   SilcConfigEntity ent;
974   SilcConfigFile *file;
975   bool retval = TRUE;
976   int ret;
977
978   SILC_LOG_DEBUG(("Parsing commands"));
979
980   /* Open commands file */
981   file = silc_config_open(filename);
982   if (!file) {
983     fprintf(stderr, "Cannot open commands file '%s'\n", filename);
984     return FALSE;
985   }
986
987   /* Parse the commands */
988   ent = silc_config_init(file);
989   silc_config_register_table(ent, silc_map_table_main, map);
990   ret = silc_config_main(ent);
991
992   SILC_LOG_DEBUG(("Parsing status: %s", silc_config_strerror(ret)));
993
994   if (ret && ret != SILC_CONFIG_ESILENT) {
995     fprintf(stderr, "Error parsing commands: %s, line %d\n",
996             silc_config_strerror(ret), silc_config_get_line(file));
997     retval = FALSE;
998   }
999
1000   /* Cleanup */
1001   silc_config_close(file);
1002   return retval;
1003 }