completed pkcs7 parsing methods
[strongswan.git] / src / dumm / main.c
1 /*
2 * Copyright (C) 2007 Martin Willi
3 * Hochschule fuer Technik Rapperswil
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 */
15
16 #define _GNU_SOURCE
17
18 #include <stdio.h>
19 #include <unistd.h>
20 #include <getopt.h>
21 #include <library.h>
22 #include <readline/readline.h>
23 #include <readline/history.h>
24 #include <dlfcn.h>
25 #include <dirent.h>
26
27 #include "dumm.h"
28
29 /**
30 * global set of UMLs guests
31 */
32 dumm_t *dumm;
33
34 /**
35 * show usage information (program arguments)
36 */
37 static void usage()
38 {
39 printf("Usage:\n");
40 printf(" --dir|-d <path> set working dir to <path>\n");
41 printf(" --help|-h show this help\n");
42 }
43
44 /**
45 * readline() wrapper
46 */
47 static char* get_line(char *format, ...)
48 {
49 char *line = NULL;
50 char *prompt = "";
51 va_list args;
52
53 va_start(args, format);
54 vasprintf(&prompt, format, args);
55 va_end(args);
56
57 while (TRUE)
58 {
59 line = readline(prompt);
60 if (line == NULL)
61 {
62 printf("quit\n");
63 dumm->destroy(dumm);
64 clear_history();
65 exit(0);
66 }
67 if (*line == '\0')
68 {
69 free(line);
70 continue;
71 }
72 add_history(line);
73 break;
74 }
75 free(prompt);
76 return line;
77 }
78
79 /**
80 * get a guest by name
81 */
82 static guest_t* get_guest(char *name)
83 {
84 iterator_t *iterator;
85 guest_t *guest = NULL;
86
87 iterator = dumm->create_guest_iterator(dumm);
88 while (iterator->iterate(iterator, (void**)&guest))
89 {
90 if (streq(guest->get_name(guest), name))
91 {
92 break;
93 }
94 guest = NULL;
95 }
96 iterator->destroy(iterator);
97 return guest;
98 }
99
100 /**
101 * get a bridge by name
102 */
103 static bridge_t* get_bridge(char *name)
104 {
105 iterator_t *iterator;
106 bridge_t *bridge = NULL;
107
108 iterator = dumm->create_bridge_iterator(dumm);
109 while (iterator->iterate(iterator, (void**)&bridge))
110 {
111 if (streq(bridge->get_name(bridge), name))
112 {
113 break;
114 }
115 bridge = NULL;
116 }
117 iterator->destroy(iterator);
118 return bridge;
119 }
120
121 /**
122 * get an interface by guest name
123 */
124 static iface_t* get_iface(char *name, char *ifname)
125 {
126 iterator_t *guests, *ifaces;
127 guest_t *guest;
128 iface_t *iface;
129
130 guests = dumm->create_guest_iterator(dumm);
131 while (guests->iterate(guests, (void**)&guest))
132 {
133 if (streq(guest->get_name(guest), name))
134 {
135 iface = NULL;
136 ifaces = guest->create_iface_iterator(guest);
137 while (ifaces->iterate(ifaces, (void**)&iface))
138 {
139 if (streq(iface->get_guestif(iface), ifname))
140 {
141 break;
142 }
143 iface = NULL;
144 }
145 ifaces->destroy(ifaces);
146 if (iface)
147 {
148 break;
149 }
150 }
151 }
152 guests->destroy(guests);
153 return iface;
154 }
155
156 static void guest_addif_menu(guest_t *guest)
157 {
158 char *name;
159
160 name = get_line("interface name: ");
161
162 if (!guest->create_iface(guest, name))
163 {
164 printf("creating interface failed\n");
165 }
166 free(name);
167 }
168
169 static void guest_delif_menu(guest_t *guest)
170 {
171 char *name;
172 iface_t *iface;
173 iterator_t *iterator;
174 bool found = FALSE;
175
176 name = get_line("interface name: ");
177
178 iterator = guest->create_iface_iterator(guest);
179 while (iterator->iterate(iterator, (void**)&iface))
180 {
181 if (streq(iface->get_guestif(iface), name))
182 {
183 iterator->remove(iterator);
184 iface->destroy(iface);
185 found = TRUE;
186 break;
187 }
188 }
189 iterator->destroy(iterator);
190
191 if (!found)
192 {
193 printf("interface '%s' not found\n");
194 }
195 free(name);
196 }
197
198 static void guest_console(guest_t *guest)
199 {
200 int con;
201
202 for (con = 1; con <= 6; con++)
203 {
204 char *pts = guest->get_console(guest, con);
205 if (pts)
206 {
207 printf("%d: %s\n", con, pts);
208 free(pts);
209 }
210 }
211 }
212
213 static void guest_menu(guest_t *guest)
214 {
215 while (TRUE)
216 {
217 char *line = get_line("guest/%s# ", guest->get_name(guest));
218
219 if (streq(line, "back"))
220 {
221 free(line);
222 break;
223 }
224 else if (streq(line, "start"))
225 {
226 if (guest->start(guest))
227 {
228 printf("guest '%s' is running\n", guest->get_name(guest));
229 }
230 else
231 {
232 printf("failed to start guest '%s'\n", guest->get_name(guest));
233 }
234 }
235 else if (streq(line, "stop"))
236 {
237 printf("stopping guest '%s'...\n", guest->get_name(guest));
238 guest->stop(guest);
239 printf("guest '%s' is down\n", guest->get_name(guest));
240 }
241 else if (streq(line, "addif"))
242 {
243 guest_addif_menu(guest);
244 }
245 else if (streq(line, "delif"))
246 {
247 guest_delif_menu(guest);
248 }
249 else if (streq(line, "console"))
250 {
251 guest_console(guest);
252 }
253 else
254 {
255 printf("back|start|stop|addif|delif|console\n");
256 }
257 free(line);
258 }
259 }
260
261 static void guest_create_menu()
262 {
263 char *name, *kernel, *master, *mem;
264 guest_t *guest;
265
266 name = get_line("guest name: ");
267 kernel = get_line("kernel image: ");
268 master = get_line("master filesystem: ");
269 mem = get_line("amount of memory in MB: ");
270
271 guest = dumm->create_guest(dumm, name, kernel, master, atoi(mem));
272 if (guest)
273 {
274 printf("guest '%s' created\n", guest->get_name(guest));
275 guest_menu(guest);
276 }
277 else
278 {
279 printf("failed to create guest '%s'\n", name);
280 }
281 free(name);
282 free(kernel);
283 free(master);
284 free(mem);
285 }
286
287 static void guest_list_menu()
288 {
289 while (TRUE)
290 {
291 iterator_t *iterator;
292 guest_t *guest;
293 char *line = get_line("guest# ");
294
295 if (streq(line, "back"))
296 {
297 free(line);
298 break;
299 }
300 else if (streq(line, "list"))
301 {
302 iterator = dumm->create_guest_iterator(dumm);
303 while (iterator->iterate(iterator, (void**)&guest))
304 {
305 printf("%s\n", guest->get_name(guest));
306 }
307 iterator->destroy(iterator);
308 }
309 else if (streq(line, "create"))
310 {
311 guest_create_menu();
312 }
313 else
314 {
315 guest = get_guest(line);
316 if (guest)
317 {
318 guest_menu(guest);
319 }
320 else
321 {
322 printf("back|list|create|<guest>\n");
323 }
324 }
325 free(line);
326 }
327 }
328
329 static void bridge_addif_menu(bridge_t *bridge)
330 {
331 char *name, *ifname;
332 iface_t *iface;
333
334 name = get_line("guest name: ");
335 ifname = get_line("interface name: ");
336
337 iface = get_iface(name, ifname);
338 if (!iface)
339 {
340 printf("guest '%s' has no interface named '%s'\n", name, ifname);
341 }
342 else if (!bridge->connect_iface(bridge, iface))
343 {
344 printf("failed to add interface '%s' to bridge '%s'\n", ifname,
345 bridge->get_name(bridge));
346 }
347 free(name);
348 free(ifname);
349 }
350
351 static void bridge_delif_menu(bridge_t *bridge)
352 {
353 char *name, *ifname;
354 iface_t *iface;
355
356 name = get_line("guest name: ");
357 ifname = get_line("interface name: ");
358
359 iface = get_iface(name, ifname);
360 if (!iface)
361 {
362 printf("guest '%s' has no interface named '%s'\n", name, ifname);
363 }
364 else if (!bridge->disconnect_iface(bridge, iface))
365 {
366 printf("failed to remove interface '%s' from bridge '%s'\n", ifname,
367 bridge->get_name(bridge));
368 }
369 free(name);
370 free(ifname);
371 }
372
373 static void bridge_menu(bridge_t *bridge)
374 {
375 while (TRUE)
376 {
377 char *line = get_line("bridge/%s# ", bridge->get_name(bridge));
378
379 if (streq(line, "back"))
380 {
381 free(line);
382 break;
383 }
384 else if (streq(line, "list"))
385 {
386 iterator_t *iterator;
387 iface_t *iface;
388
389 iterator = bridge->create_iface_iterator(bridge);
390 while (iterator->iterate(iterator, (void**)&iface))
391 {
392 printf("%s (%s)\n", iface->get_guestif(iface), iface->get_hostif(iface));
393 }
394 iterator->destroy(iterator);
395 }
396 else if (streq(line, "addif"))
397 {
398 bridge_addif_menu(bridge);
399 }
400 else if (streq(line, "delif"))
401 {
402 bridge_delif_menu(bridge);
403 }
404 else
405 {
406 printf("back|list|addif|delif\n");
407 }
408 free(line);
409 }
410 }
411
412 static void bridge_create_menu()
413 {
414 char *name;
415 bridge_t *bridge;
416
417 name = get_line("bridge name: ");
418
419 bridge = dumm->create_bridge(dumm, name);
420 if (bridge)
421 {
422 printf("bridge '%s' created\n", bridge->get_name(bridge));
423 bridge_menu(bridge);
424 }
425 else
426 {
427 printf("failed to create bridge '%s'\n", name);
428 }
429 free(name);
430 }
431
432 static void bridge_list_menu()
433 {
434 while (TRUE)
435 {
436 iterator_t *iterator;
437 bridge_t *bridge;
438 char *line = get_line("bridge# ");
439
440 if (streq(line, "back"))
441 {
442 free(line);
443 break;
444 }
445 else if (streq(line, "list"))
446 {
447 iterator = dumm->create_bridge_iterator(dumm);
448 while (iterator->iterate(iterator, (void**)&bridge))
449 {
450 printf("%s\n", bridge->get_name(bridge));
451 }
452 iterator->destroy(iterator);
453 }
454 else if (streq(line, "create"))
455 {
456 bridge_create_menu();
457 }
458 else
459 {
460 bridge = get_bridge(line);
461 if (bridge)
462 {
463 bridge_menu(bridge);
464 }
465 else
466 {
467 printf("back|list|create|<bridge>\n");
468 }
469 }
470 free(line);
471 }
472 }
473
474 static void template_menu()
475 {
476 char *name;
477
478 name = get_line("template name (or 'none'): ");
479
480 dumm->load_template(dumm, streq(name, "none") ? NULL : name);
481
482 free(name);
483 }
484
485 typedef bool (*uml_test_t)(dumm_t *dumm);
486
487 static void test_menu()
488 {
489 char *name;
490 void *handle;
491 struct dirent *ent;
492 DIR *dir;
493 uml_test_t test;
494
495 name = get_line("test name: ");
496
497 dir = opendir("tests");
498 if (dir)
499 {
500 while ((ent = readdir(dir)))
501 {
502 char buf[PATH_MAX];
503 size_t len;
504
505 len = strlen(ent->d_name);
506 if (strlen(ent->d_name) < 4 || !streq(ent->d_name + len - 3, ".so"))
507 {
508 continue;
509 }
510
511 snprintf(buf, sizeof(buf), "%s/%s", "tests", ent->d_name);
512 handle = dlopen(buf, RTLD_LAZY);
513 if (!handle)
514 {
515 printf("failed to open test %s\n", ent->d_name);
516 continue;
517 }
518 test = dlsym(handle, "test");
519 if (test && dumm->load_template(dumm, ent->d_name))
520 {
521 printf("running test %s: ", ent->d_name);
522 if (test(dumm))
523 {
524 printf("success\n");
525 }
526 else
527 {
528 printf("failed\n");
529 }
530 }
531 else
532 {
533 printf("failed to open test %s\n", ent->d_name);
534 }
535 dlclose(handle);
536 }
537 }
538 free(name);
539 }
540
541 /**
542 * Signal handler
543 */
544 void signal_action(int sig, siginfo_t *info, void *ucontext)
545 {
546 dumm->destroy(dumm);
547 clear_history();
548 exit(0);
549 }
550
551 /**
552 * main routine, parses args and reads from console
553 */
554 int main(int argc, char *argv[])
555 {
556 struct sigaction action;
557 char *dir = ".";
558
559 while (TRUE)
560 {
561 struct option options[] = {
562 {"dir", 1, 0, 0},
563 {"help", 0, 0, 0},
564 {0, 0, 0, 0}
565 };
566
567 switch (getopt_long(argc, argv, "d:h", options, NULL))
568 {
569 case -1:
570 break;
571 case 'd':
572 dir = optarg;
573 continue;
574 case 'h':
575 usage();
576 return 0;
577 default:
578 usage();
579 return 1;
580 }
581 break;
582 }
583
584 memset(&action, 0, sizeof(action));
585 action.sa_sigaction = signal_action;
586 action.sa_flags = SA_SIGINFO;
587 if (sigaction(SIGINT, &action, NULL) != 0 ||
588 sigaction(SIGQUIT, &action, NULL) != 0 ||
589 sigaction(SIGTERM, &action, NULL) != 0)
590 {
591 printf("signal handler setup failed: %m.\n");
592 return 1;
593 }
594
595 dumm = dumm_create(dir);
596 while (TRUE)
597 {
598 char *line = get_line("# ");
599
600 if (streq(line, "quit"))
601 {
602 free(line);
603 break;
604 }
605 else if (streq(line, "guest"))
606 {
607 guest_list_menu();
608 }
609 else if (streq(line, "bridge"))
610 {
611 bridge_list_menu();
612 }
613 else if (streq(line, "template"))
614 {
615 template_menu();
616 }
617 else if (streq(line, "test"))
618 {
619 test_menu();
620 }
621 else
622 {
623 printf("quit|guest|bridge|template|test\n");
624 }
625 free(line);
626 }
627 dumm->load_template(dumm, NULL);
628 dumm->destroy(dumm);
629 clear_history();
630 return 0;
631 }
632