added UML modeler to autotools
[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
25 #include "dumm.h"
26
27 /**
28 * global set of UMLs guests
29 */
30 dumm_t *dumm;
31
32 /**
33 * show usage information (program arguments)
34 */
35 static void usage()
36 {
37 printf("Usage:\n");
38 printf(" --dir|-d <path> set working dir to <path>\n");
39 printf(" --help|-h show this help\n");
40 }
41
42 /**
43 * readline() wrapper
44 */
45 static char* get_line(char *format, ...)
46 {
47 char *line = NULL;
48 char *prompt = "";
49 va_list args;
50
51 va_start(args, format);
52 vasprintf(&prompt, format, args);
53 va_end(args);
54
55 while (TRUE)
56 {
57 line = readline(prompt);
58 if (line == NULL)
59 {
60 continue;
61 }
62 if (*line == '\0')
63 {
64 free(line);
65 continue;
66 }
67 add_history(line);
68 break;
69 }
70 free(prompt);
71 return line;
72 }
73
74 /**
75 * get a guest by name
76 */
77 static guest_t* get_guest(char *name)
78 {
79 iterator_t *iterator;
80 guest_t *guest = NULL;
81
82 iterator = dumm->create_guest_iterator(dumm);
83 while (iterator->iterate(iterator, (void**)&guest))
84 {
85 if (streq(guest->get_name(guest), name))
86 {
87 break;
88 }
89 guest = NULL;
90 }
91 iterator->destroy(iterator);
92 return guest;
93 }
94
95 /**
96 * get a bridge by name
97 */
98 static bridge_t* get_bridge(char *name)
99 {
100 iterator_t *iterator;
101 bridge_t *bridge = NULL;
102
103 iterator = dumm->create_bridge_iterator(dumm);
104 while (iterator->iterate(iterator, (void**)&bridge))
105 {
106 if (streq(bridge->get_name(bridge), name))
107 {
108 break;
109 }
110 bridge = NULL;
111 }
112 iterator->destroy(iterator);
113 return bridge;
114 }
115
116 /**
117 * get an interface by guest name
118 */
119 static iface_t* get_iface(char *name, char *ifname)
120 {
121 iterator_t *guests, *ifaces;
122 guest_t *guest;
123 iface_t *iface;
124
125 guests = dumm->create_guest_iterator(dumm);
126 while (guests->iterate(guests, (void**)&guest))
127 {
128 if (streq(guest->get_name(guest), name))
129 {
130 iface = NULL;
131 ifaces = guest->create_iface_iterator(guest);
132 while (ifaces->iterate(ifaces, (void**)&iface))
133 {
134 if (streq(iface->get_guestif(iface), ifname))
135 {
136 break;
137 }
138 iface = NULL;
139 }
140 ifaces->destroy(ifaces);
141 if (iface)
142 {
143 break;
144 }
145 }
146 }
147 guests->destroy(guests);
148 return iface;
149 }
150
151 static void guest_addif_menu(guest_t *guest)
152 {
153 char *name;
154
155 name = get_line("interface name: ");
156
157 if (!guest->create_iface(guest, name))
158 {
159 printf("creating interface failed\n");
160 }
161 }
162
163 static void guest_delif_menu(guest_t *guest)
164 {
165 char *name;
166 iface_t *iface;
167 iterator_t *iterator;
168 bool found = FALSE;
169
170 name = get_line("interface name: ");
171
172 iterator = guest->create_iface_iterator(guest);
173 while (iterator->iterate(iterator, (void**)&iface))
174 {
175 if (streq(iface->get_guestif(iface), name))
176 {
177 iterator->remove(iterator);
178 iface->destroy(iface);
179 found = TRUE;
180 break;
181 }
182 }
183 iterator->destroy(iterator);
184
185 if (!found)
186 {
187 printf("interface '%s' not found\n");
188 }
189 }
190
191 static void guest_menu(guest_t *guest)
192 {
193 while (TRUE)
194 {
195 char *line = get_line("guest/%s# ", guest->get_name(guest));
196
197 if (streq(line, "back"))
198 {
199 free(line);
200 break;
201 }
202 else if (streq(line, "start"))
203 {
204 if (guest->start(guest))
205 {
206 printf("guest '%s' is booting\n", guest->get_name(guest));
207 }
208 else
209 {
210 printf("failed to start guest '%s'\n", guest->get_name(guest));
211 }
212 }
213 else if (streq(line, "stop"))
214 {
215 printf("stopping guest '%s'...\n", guest->get_name(guest));
216 guest->stop(guest);
217 printf("guest '%s' is down\n", guest->get_name(guest));
218 }
219 else if (streq(line, "addif"))
220 {
221 guest_addif_menu(guest);
222 }
223 else if (streq(line, "delif"))
224 {
225 guest_delif_menu(guest);
226 }
227 else
228 {
229 printf("back|start|stop|addif|delif\n");
230 }
231 free(line);
232 }
233 }
234
235 static void guest_create_menu()
236 {
237 char *name, *kernel, *master, *mem;
238 guest_t *guest;
239
240 name = get_line("guest name: ");
241 kernel = get_line("kernel image: ");
242 master = get_line("master filesystem: ");
243 mem = get_line("amount of memory in MB: ");
244
245 guest = dumm->create_guest(dumm, name, kernel, master, atoi(mem));
246 if (guest)
247 {
248 printf("guest '%s' created\n", guest->get_name(guest));
249 guest_menu(guest);
250 }
251 else
252 {
253 printf("failed to create guest '%s'\n", name);
254 }
255 }
256
257 static void guest_list_menu()
258 {
259 while (TRUE)
260 {
261 iterator_t *iterator;
262 guest_t *guest;
263 char *line = get_line("guest# ");
264
265 if (streq(line, "back"))
266 {
267 free(line);
268 break;
269 }
270 else if (streq(line, "list"))
271 {
272 iterator = dumm->create_guest_iterator(dumm);
273 while (iterator->iterate(iterator, (void**)&guest))
274 {
275 printf("%s\n", guest->get_name(guest));
276 }
277 iterator->destroy(iterator);
278 }
279 else if (streq(line, "create"))
280 {
281 guest_create_menu();
282 }
283 else
284 {
285 guest = get_guest(line);
286 if (guest)
287 {
288 guest_menu(guest);
289 }
290 else
291 {
292 printf("back|list|create|<guest>\n");
293 }
294 }
295 free(line);
296 }
297 }
298
299 static void bridge_addif_menu(bridge_t *bridge)
300 {
301 char *name, *ifname;
302 iface_t *iface;
303
304 name = get_line("guest name: ");
305 ifname = get_line("interface name: ");
306
307 iface = get_iface(name, ifname);
308 if (!iface)
309 {
310 printf("guest '%s' has no interface named '%s'\n", name, ifname);
311 }
312 else if (!bridge->connect_iface(bridge, iface))
313 {
314 printf("failed to add interface '%s' to bridge '%s'\n", ifname,
315 bridge->get_name(bridge));
316 }
317 }
318
319 static void bridge_delif_menu(bridge_t *bridge)
320 {
321 char *name, *ifname;
322 iface_t *iface;
323
324 name = get_line("guest name: ");
325 ifname = get_line("interface name: ");
326
327 iface = get_iface(name, ifname);
328 if (!iface)
329 {
330 printf("guest '%s' has no interface named '%s'\n", name, ifname);
331 }
332 else if (!bridge->disconnect_iface(bridge, iface))
333 {
334 printf("failed to remove interface '%s' from bridge '%s'\n", ifname,
335 bridge->get_name(bridge));
336 }
337 }
338
339 static void bridge_menu(bridge_t *bridge)
340 {
341 while (TRUE)
342 {
343 char *line = get_line("bridge/%s# ", bridge->get_name(bridge));
344
345 if (streq(line, "back"))
346 {
347 free(line);
348 break;
349 }
350 else if (streq(line, "list"))
351 {
352 iterator_t *iterator;
353 iface_t *iface;
354
355 iterator = bridge->create_iface_iterator(bridge);
356 while (iterator->iterate(iterator, (void**)&iface))
357 {
358 printf("%s (%s)\n", iface->get_guestif(iface), iface->get_hostif(iface));
359 }
360 iterator->destroy(iterator);
361 }
362 else if (streq(line, "addif"))
363 {
364 bridge_addif_menu(bridge);
365 }
366 else if (streq(line, "delif"))
367 {
368 bridge_delif_menu(bridge);
369 }
370 else
371 {
372 printf("back|list|addif|delif\n");
373 }
374 free(line);
375 }
376 }
377
378 static void bridge_create_menu()
379 {
380 char *name;
381 bridge_t *bridge;
382
383 name = get_line("bridge name: ");
384
385 bridge = dumm->create_bridge(dumm, name);
386 if (bridge)
387 {
388 printf("bridge '%s' created\n", bridge->get_name(bridge));
389 bridge_menu(bridge);
390 }
391 else
392 {
393 printf("failed to create bridge '%s'\n", name);
394 }
395 }
396
397 static void bridge_list_menu()
398 {
399 while (TRUE)
400 {
401 iterator_t *iterator;
402 bridge_t *bridge;
403 char *line = get_line("bridge# ");
404
405 if (streq(line, "back"))
406 {
407 free(line);
408 break;
409 }
410 else if (streq(line, "list"))
411 {
412 iterator = dumm->create_bridge_iterator(dumm);
413 while (iterator->iterate(iterator, (void**)&bridge))
414 {
415 printf("%s\n", bridge->get_name(bridge));
416 }
417 iterator->destroy(iterator);
418 }
419 else if (streq(line, "create"))
420 {
421 bridge_create_menu();
422 }
423 else
424 {
425 bridge = get_bridge(line);
426 if (bridge)
427 {
428 bridge_menu(bridge);
429 }
430 else
431 {
432 printf("back|list|create|<bridge>\n");
433 }
434 }
435 free(line);
436 }
437 }
438
439 /**
440 * Signal handler
441 */
442 void signal_action(int sig, siginfo_t *info, void *ucontext)
443 {
444 dumm->destroy(dumm);
445 clear_history();
446 exit(0);
447 }
448
449 /**
450 * main routine, parses args and reads from console
451 */
452 int main(int argc, char *argv[])
453 {
454 struct sigaction action;
455 char *dir = ".";
456
457 while (TRUE)
458 {
459 struct option options[] = {
460 {"dir", 1, 0, 0},
461 {"help", 0, 0, 0},
462 {0, 0, 0, 0}
463 };
464
465 switch (getopt_long(argc, argv, "d:h", options, NULL))
466 {
467 case -1:
468 break;
469 case 'd':
470 dir = optarg;
471 continue;
472 case 'h':
473 usage();
474 return 0;
475 default:
476 usage();
477 return 1;
478 }
479 break;
480 }
481
482 memset(&action, 0, sizeof(action));
483 action.sa_sigaction = signal_action;
484 action.sa_flags = SA_SIGINFO;
485 if (sigaction(SIGINT, &action, NULL) != 0 ||
486 sigaction(SIGQUIT, &action, NULL) != 0 ||
487 sigaction(SIGTERM, &action, NULL) != 0)
488 {
489 printf("signal handler setup failed: %m.\n");
490 return 1;
491 }
492
493 dumm = dumm_create(dir);
494 while (TRUE)
495 {
496 char *line = get_line("# ");
497
498 if (streq(line, "quit"))
499 {
500 free(line);
501 break;
502 }
503 else if (streq(line, "guest"))
504 {
505 guest_list_menu();
506 }
507 else if (streq(line, "bridge"))
508 {
509 bridge_list_menu();
510 }
511 else
512 {
513 printf("quit|guest|bridge\n");
514 }
515 free(line);
516 }
517 dumm->destroy(dumm);
518 clear_history();
519 return 0;
520 }
521