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);