2 * Copyright (C) 2007 Martin Willi
3 * Hochschule fuer Technik Rapperswil
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>.
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
22 #include <readline/readline.h>
23 #include <readline/history.h>
30 * global set of UMLs guests
35 * show usage information (program arguments)
40 printf(" --dir|-d <path> set working dir to <path>\n");
41 printf(" --help|-h show this help\n");
47 static char* get_line(char *format
, ...)
53 va_start(args
, format
);
54 vasprintf(&prompt
, format
, args
);
59 line
= readline(prompt
);
82 static guest_t
* get_guest(char *name
)
85 guest_t
*guest
= NULL
;
87 iterator
= dumm
->create_guest_iterator(dumm
);
88 while (iterator
->iterate(iterator
, (void**)&guest
))
90 if (streq(guest
->get_name(guest
), name
))
96 iterator
->destroy(iterator
);
101 * get a bridge by name
103 static bridge_t
* get_bridge(char *name
)
105 iterator_t
*iterator
;
106 bridge_t
*bridge
= NULL
;
108 iterator
= dumm
->create_bridge_iterator(dumm
);
109 while (iterator
->iterate(iterator
, (void**)&bridge
))
111 if (streq(bridge
->get_name(bridge
), name
))
117 iterator
->destroy(iterator
);
122 * get an interface by guest name
124 static iface_t
* get_iface(char *name
, char *ifname
)
126 iterator_t
*guests
, *ifaces
;
130 guests
= dumm
->create_guest_iterator(dumm
);
131 while (guests
->iterate(guests
, (void**)&guest
))
133 if (streq(guest
->get_name(guest
), name
))
136 ifaces
= guest
->create_iface_iterator(guest
);
137 while (ifaces
->iterate(ifaces
, (void**)&iface
))
139 if (streq(iface
->get_guestif(iface
), ifname
))
145 ifaces
->destroy(ifaces
);
152 guests
->destroy(guests
);
156 static void guest_addif_menu(guest_t
*guest
)
160 name
= get_line("interface name: ");
162 if (!guest
->create_iface(guest
, name
))
164 printf("creating interface failed\n");
169 static void guest_delif_menu(guest_t
*guest
)
173 iterator_t
*iterator
;
176 name
= get_line("interface name: ");
178 iterator
= guest
->create_iface_iterator(guest
);
179 while (iterator
->iterate(iterator
, (void**)&iface
))
181 if (streq(iface
->get_guestif(iface
), name
))
183 iterator
->remove(iterator
);
184 iface
->destroy(iface
);
189 iterator
->destroy(iterator
);
193 printf("interface '%s' not found\n");
198 static void guest_console(guest_t
*guest
)
202 for (con
= 1; con
<= 6; con
++)
204 char *pts
= guest
->get_console(guest
, con
);
207 printf("%d: %s\n", con
, pts
);
213 static void guest_menu(guest_t
*guest
)
217 char *line
= get_line("guest/%s# ", guest
->get_name(guest
));
219 if (streq(line
, "back"))
224 else if (streq(line
, "start"))
226 if (guest
->start(guest
))
228 printf("guest '%s' is running\n", guest
->get_name(guest
));
232 printf("failed to start guest '%s'\n", guest
->get_name(guest
));
235 else if (streq(line
, "stop"))
237 printf("stopping guest '%s'...\n", guest
->get_name(guest
));
239 printf("guest '%s' is down\n", guest
->get_name(guest
));
241 else if (streq(line
, "addif"))
243 guest_addif_menu(guest
);
245 else if (streq(line
, "delif"))
247 guest_delif_menu(guest
);
249 else if (streq(line
, "console"))
251 guest_console(guest
);
255 printf("back|start|stop|addif|delif|console\n");
261 static void guest_create_menu()
263 char *name
, *kernel
, *master
, *mem
;
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: ");
271 guest
= dumm
->create_guest(dumm
, name
, kernel
, master
, atoi(mem
));
274 printf("guest '%s' created\n", guest
->get_name(guest
));
279 printf("failed to create guest '%s'\n", name
);
287 static void guest_list_menu()
291 iterator_t
*iterator
;
293 char *line
= get_line("guest# ");
295 if (streq(line
, "back"))
300 else if (streq(line
, "list"))
302 iterator
= dumm
->create_guest_iterator(dumm
);
303 while (iterator
->iterate(iterator
, (void**)&guest
))
305 printf("%s\n", guest
->get_name(guest
));
307 iterator
->destroy(iterator
);
309 else if (streq(line
, "create"))
315 guest
= get_guest(line
);
322 printf("back|list|create|<guest>\n");
329 static void bridge_addif_menu(bridge_t
*bridge
)
334 name
= get_line("guest name: ");
335 ifname
= get_line("interface name: ");
337 iface
= get_iface(name
, ifname
);
340 printf("guest '%s' has no interface named '%s'\n", name
, ifname
);
342 else if (!bridge
->connect_iface(bridge
, iface
))
344 printf("failed to add interface '%s' to bridge '%s'\n", ifname
,
345 bridge
->get_name(bridge
));
351 static void bridge_delif_menu(bridge_t
*bridge
)
356 name
= get_line("guest name: ");
357 ifname
= get_line("interface name: ");
359 iface
= get_iface(name
, ifname
);
362 printf("guest '%s' has no interface named '%s'\n", name
, ifname
);
364 else if (!bridge
->disconnect_iface(bridge
, iface
))
366 printf("failed to remove interface '%s' from bridge '%s'\n", ifname
,
367 bridge
->get_name(bridge
));
373 static void bridge_menu(bridge_t
*bridge
)
377 char *line
= get_line("bridge/%s# ", bridge
->get_name(bridge
));
379 if (streq(line
, "back"))
384 else if (streq(line
, "list"))
386 iterator_t
*iterator
;
389 iterator
= bridge
->create_iface_iterator(bridge
);
390 while (iterator
->iterate(iterator
, (void**)&iface
))
392 printf("%s (%s)\n", iface
->get_guestif(iface
), iface
->get_hostif(iface
));
394 iterator
->destroy(iterator
);
396 else if (streq(line
, "addif"))
398 bridge_addif_menu(bridge
);
400 else if (streq(line
, "delif"))
402 bridge_delif_menu(bridge
);
406 printf("back|list|addif|delif\n");
412 static void bridge_create_menu()
417 name
= get_line("bridge name: ");
419 bridge
= dumm
->create_bridge(dumm
, name
);
422 printf("bridge '%s' created\n", bridge
->get_name(bridge
));
427 printf("failed to create bridge '%s'\n", name
);
432 static void bridge_list_menu()
436 iterator_t
*iterator
;
438 char *line
= get_line("bridge# ");
440 if (streq(line
, "back"))
445 else if (streq(line
, "list"))
447 iterator
= dumm
->create_bridge_iterator(dumm
);
448 while (iterator
->iterate(iterator
, (void**)&bridge
))
450 printf("%s\n", bridge
->get_name(bridge
));
452 iterator
->destroy(iterator
);
454 else if (streq(line
, "create"))
456 bridge_create_menu();
460 bridge
= get_bridge(line
);
467 printf("back|list|create|<bridge>\n");
474 static void template_menu()
478 name
= get_line("template name (or 'none'): ");
480 dumm
->load_template(dumm
, streq(name
, "none") ? NULL
: name
);
485 typedef bool (*uml_test_t
)(dumm_t
*dumm
);
487 static void test_menu()
495 name
= get_line("test name: ");
497 dir
= opendir("tests");
500 while ((ent
= readdir(dir
)))
505 len
= strlen(ent
->d_name
);
506 if (strlen(ent
->d_name
) < 4 || !streq(ent
->d_name
+ len
- 3, ".so"))
511 snprintf(buf
, sizeof(buf
), "%s/%s", "tests", ent
->d_name
);
512 handle
= dlopen(buf
, RTLD_LAZY
);
515 printf("failed to open test %s\n", ent
->d_name
);
518 test
= dlsym(handle
, "test");
519 if (test
&& dumm
->load_template(dumm
, ent
->d_name
))
521 printf("running test %s: ", ent
->d_name
);
533 printf("failed to open test %s\n", ent
->d_name
);
544 void signal_action(int sig
, siginfo_t
*info
, void *ucontext
)
552 * main routine, parses args and reads from console
554 int main(int argc
, char *argv
[])
556 struct sigaction action
;
561 struct option options
[] = {
567 switch (getopt_long(argc
, argv
, "d:h", options
, NULL
))
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)
591 printf("signal handler setup failed: %m.\n");
595 dumm
= dumm_create(dir
);
598 char *line
= get_line("# ");
600 if (streq(line
, "quit"))
605 else if (streq(line
, "guest"))
609 else if (streq(line
, "bridge"))
613 else if (streq(line
, "template"))
617 else if (streq(line
, "test"))
623 printf("quit|guest|bridge|template|test\n");
627 dumm
->load_template(dumm
, NULL
);