diff --git a/src/dumm/Makefile.am b/src/dumm/Makefile.am index 99369e2ef..d82d5f5fc 100644 --- a/src/dumm/Makefile.am +++ b/src/dumm/Makefile.am @@ -1,3 +1,5 @@ +EXTRA_DIST = ext/dumm.c ext/extconf.rb ext/README + lib_LTLIBRARIES = libdumm.la ipsec_PROGRAMS = dumm irdumm diff --git a/src/dumm/ext/README b/src/dumm/ext/README new file mode 100644 index 000000000..270d9d59d --- /dev/null +++ b/src/dumm/ext/README @@ -0,0 +1,8 @@ +DUMM Ruby Extension +=================== + +Build and Install + + $ ruby extconf.rb + $ make + # make install diff --git a/src/dumm/ext/dumm.c b/src/dumm/ext/dumm.c new file mode 100644 index 000000000..6a34df967 --- /dev/null +++ b/src/dumm/ext/dumm.c @@ -0,0 +1,582 @@ +/* + * Copyright (C) 2008 Tobias Brunner + * Copyright (C) 2008 Martin Willi + * Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See . + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * $Id$ + */ + +#include +#include +#include +#include + +#include +#include +#include + +#undef PACKAGE_NAME +#undef PACKAGE_TARNAME +#undef PACKAGE_VERSION +#undef PACKAGE_STRING +#include + +static dumm_t *dumm; + +static VALUE rbm_dumm; +static VALUE rbc_guest; +static VALUE rbc_bridge; +static VALUE rbc_iface; +static VALUE rbc_template; + +/** + * Guest invocation callback + */ +static pid_t invoke(void *null, guest_t *guest, char *args[], int argc) +{ + pid_t pid; + + args[argc++] = "con0=xterm"; + args[argc++] = "xterm=gnome-terminal,-t,-x"; + + pid = fork(); + switch (pid) + { + case 0: /* child */ + /* create a new process group in order to prevent signals (e.g. + * SIGINT) sent to the parent from terminating the child */ + setpgid(0, 0); + dup2(open("/dev/null", 0), 1); + dup2(open("/dev/null", 0), 2); + execvp(args[0], args); + /* FALL */ + case -1: + return 0; + default: + return pid; + } +} + +/** + * SIGCHLD signal handler + */ +static void sigchld_handler(int signal, siginfo_t *info, void* ptr) +{ + enumerator_t *enumerator; + guest_t *guest; + + enumerator = dumm->create_guest_enumerator(dumm); + while (enumerator->enumerate(enumerator, &guest)) + { + if (guest->get_pid(guest) == info->si_pid) + { + guest->sigchild(guest); + break; + } + } + enumerator->destroy(enumerator); +} + +/** + * Guest bindings + */ +static VALUE guest_get(VALUE class, VALUE key) +{ + enumerator_t *enumerator; + guest_t *guest, *found = NULL; + + enumerator = dumm->create_guest_enumerator(dumm); + while (enumerator->enumerate(enumerator, &guest)) + { + if (streq(guest->get_name(guest), StringValuePtr(key))) + { + found = guest; + break; + } + } + enumerator->destroy(enumerator); + if (!found) + { + rb_raise(rb_eRuntimeError, "guest not found"); + } + return Data_Wrap_Struct(class, NULL, NULL, found); +} + +static VALUE guest_each(int argc, VALUE *argv, VALUE class) +{ + enumerator_t *enumerator; + guest_t *guest; + + if (!rb_block_given_p()) + { + rb_raise(rb_eArgError, "must be called with a block"); + } + enumerator = dumm->create_guest_enumerator(dumm); + while (enumerator->enumerate(enumerator, &guest)) + { + rb_yield(Data_Wrap_Struct(class, NULL, NULL, guest)); + } + enumerator->destroy(enumerator); + return class; +} + +static VALUE guest_new(VALUE class, VALUE name, VALUE kernel, + VALUE master, VALUE mem) +{ + guest_t *guest; + + guest = dumm->create_guest(dumm, StringValuePtr(name), StringValuePtr(kernel), + StringValuePtr(master), FIX2INT(mem)); + if (!guest) + { + rb_raise(rb_eRuntimeError, "creating guest failed"); + } + return Data_Wrap_Struct(class, NULL, NULL, guest); +} + +static VALUE guest_to_s(VALUE self) +{ + guest_t *guest; + + Data_Get_Struct(self, guest_t, guest); + return rb_str_new2(guest->get_name(guest)); +} + +static VALUE guest_start(VALUE self) +{ + guest_t *guest; + + Data_Get_Struct(self, guest_t, guest); + + if (!guest->start(guest, invoke, NULL, NULL)) + { + rb_raise(rb_eRuntimeError, "starting guest failed"); + } + return self; +} + +static VALUE guest_stop(VALUE self) +{ + guest_t *guest; + + Data_Get_Struct(self, guest_t, guest); + guest->stop(guest, NULL); + return self; +} + +static void exec_cb(void *data, char *buf) +{ + rb_yield(rb_str_new2(buf)); +} + +static VALUE guest_exec(VALUE self, VALUE cmd) +{ + guest_t *guest; + bool block; + int ret; + + block = rb_block_given_p(); + Data_Get_Struct(self, guest_t, guest); + if ((ret = guest->exec_str(guest, block ? (void*)exec_cb : NULL, TRUE, NULL, + "%s", StringValuePtr(cmd))) != 0) + { + rb_raise(rb_eRuntimeError, "executing command failed (%d)", ret); + } + return self; +} + +static VALUE guest_add_iface(VALUE self, VALUE name) +{ + guest_t *guest; + iface_t *iface; + + Data_Get_Struct(self, guest_t, guest); + iface = guest->create_iface(guest, StringValuePtr(name)); + if (!iface) + { + rb_raise(rb_eRuntimeError, "adding interface failed"); + } + return Data_Wrap_Struct(rbc_iface, NULL, NULL, iface); +} + +static VALUE guest_get_iface(VALUE self, VALUE key) +{ + enumerator_t *enumerator; + iface_t *iface, *found = NULL; + guest_t *guest; + + Data_Get_Struct(self, guest_t, guest); + enumerator = guest->create_iface_enumerator(guest); + while (enumerator->enumerate(enumerator, &iface)) + { + if (streq(iface->get_guestif(iface), StringValuePtr(key))) + { + found = iface; + break; + } + } + enumerator->destroy(enumerator); + if (!found) + { + rb_raise(rb_eRuntimeError, "interface not found"); + } + return Data_Wrap_Struct(rbc_iface, NULL, NULL, iface); +} + +static VALUE guest_each_iface(int argc, VALUE *argv, VALUE self) +{ + enumerator_t *enumerator; + guest_t *guest; + iface_t *iface; + + if (!rb_block_given_p()) + { + rb_raise(rb_eArgError, "must be called with a block"); + } + Data_Get_Struct(self, guest_t, guest); + enumerator = guest->create_iface_enumerator(guest); + while (enumerator->enumerate(enumerator, &iface)) + { + rb_yield(Data_Wrap_Struct(rbc_iface, NULL, NULL, iface)); + } + enumerator->destroy(enumerator); + return self; +} + +static VALUE guest_delete(VALUE self) +{ + guest_t *guest; + + Data_Get_Struct(self, guest_t, guest); + dumm->delete_guest(dumm, guest); + return Qnil; +} + +static void guest_init() +{ + rbc_guest = rb_define_class_under(rbm_dumm , "Guest", rb_cObject); + rb_define_singleton_method(rbc_guest, "[]", guest_get, 1); + rb_define_singleton_method(rbc_guest, "each", guest_each, -1); + rb_define_singleton_method(rbc_guest, "new", guest_new, 4); + rb_define_method(rbc_guest, "to_s", guest_to_s, 0); + rb_define_method(rbc_guest, "start", guest_start, 0); + rb_define_method(rbc_guest, "stop", guest_stop, 0); + rb_define_method(rbc_guest, "exec", guest_exec, 1); + rb_define_method(rbc_guest, "add", guest_add_iface, 1); + rb_define_method(rbc_guest, "[]", guest_get_iface, 1); + rb_define_method(rbc_guest, "each", guest_each_iface, -1); + rb_define_method(rbc_guest, "delete", guest_delete, 0); + rb_include_module(rb_class_of(rbc_guest), rb_mEnumerable); + rb_include_module(rbc_guest, rb_mEnumerable); +} + +/** + * Bridge binding + */ +static VALUE bridge_get(VALUE class, VALUE key) +{ + enumerator_t *enumerator; + bridge_t *bridge, *found = NULL; + + enumerator = dumm->create_bridge_enumerator(dumm); + while (enumerator->enumerate(enumerator, &bridge)) + { + if (streq(bridge->get_name(bridge), StringValuePtr(key))) + { + found = bridge; + break; + } + } + enumerator->destroy(enumerator); + if (!found) + { + rb_raise(rb_eRuntimeError, "bridge not found"); + } + return Data_Wrap_Struct(class, NULL, NULL, found); +} + +static VALUE bridge_each(int argc, VALUE *argv, VALUE class) +{ + enumerator_t *enumerator; + bridge_t *bridge; + + if (!rb_block_given_p()) + { + rb_raise(rb_eArgError, "must be called with a block"); + } + enumerator = dumm->create_bridge_enumerator(dumm); + while (enumerator->enumerate(enumerator, &bridge)) + { + rb_yield(Data_Wrap_Struct(class, NULL, NULL, bridge)); + } + enumerator->destroy(enumerator); + return class; +} + +static VALUE bridge_new(VALUE class, VALUE name) + +{ + bridge_t *bridge; + + bridge = dumm->create_bridge(dumm, StringValuePtr(name)); + if (!bridge) + { + rb_raise(rb_eRuntimeError, "creating bridge failed"); + } + return Data_Wrap_Struct(class, NULL, NULL, bridge); +} + +static VALUE bridge_to_s(VALUE self) +{ + bridge_t *bridge; + + Data_Get_Struct(self, bridge_t, bridge); + return rb_str_new2(bridge->get_name(bridge)); +} + +static VALUE bridge_each_iface(int argc, VALUE *argv, VALUE self) +{ + enumerator_t *enumerator; + bridge_t *bridge; + iface_t *iface; + + if (!rb_block_given_p()) + { + rb_raise(rb_eArgError, "must be called with a block"); + } + Data_Get_Struct(self, bridge_t, bridge); + enumerator = bridge->create_iface_enumerator(bridge); + while (enumerator->enumerate(enumerator, &iface)) + { + rb_yield(Data_Wrap_Struct(rbc_iface, NULL, NULL, iface)); + } + enumerator->destroy(enumerator); + return self; +} + +static VALUE bridge_delete(VALUE self) +{ + bridge_t *bridge; + + Data_Get_Struct(self, bridge_t, bridge); + dumm->delete_bridge(dumm, bridge); + return Qnil; +} + +static void bridge_init() +{ + rbc_bridge = rb_define_class_under(rbm_dumm , "Bridge", rb_cObject); + rb_define_singleton_method(rbc_bridge, "[]", bridge_get, 1); + rb_define_singleton_method(rbc_bridge, "each", bridge_each, -1); + rb_define_singleton_method(rbc_bridge, "new", bridge_new, 1); + rb_define_method(rbc_bridge, "to_s", bridge_to_s, 0); + rb_define_method(rbc_bridge, "each", bridge_each_iface, -1); + rb_define_method(rbc_bridge, "delete", bridge_delete, 0); + rb_include_module(rb_class_of(rbc_bridge), rb_mEnumerable); + rb_include_module(rbc_bridge, rb_mEnumerable); +} + +/** + * Iface wrapper + */ +static VALUE iface_to_s(VALUE self) +{ + iface_t *iface; + + Data_Get_Struct(self, iface_t, iface); + return rb_str_new2(iface->get_hostif(iface)); +} + +static VALUE iface_connect(VALUE self, VALUE vbridge) +{ + iface_t *iface; + bridge_t *bridge; + + Data_Get_Struct(self, iface_t, iface); + Data_Get_Struct(vbridge, bridge_t, bridge); + if (!bridge->connect_iface(bridge, iface)) + { + rb_raise(rb_eRuntimeError, "connecting iface failed"); + } + return self; +} + +static VALUE iface_disconnect(VALUE self) +{ + iface_t *iface; + bridge_t *bridge; + + Data_Get_Struct(self, iface_t, iface); + bridge = iface->get_bridge(iface); + if (!bridge || !bridge->disconnect_iface(bridge, iface)) + { + rb_raise(rb_eRuntimeError, "disconnecting iface failed"); + } + return self; +} + +static VALUE iface_add_addr(VALUE self, VALUE name) +{ + iface_t *iface; + host_t *addr; + + addr = host_create_from_string(StringValuePtr(name), 0); + if (!addr) + { + rb_raise(rb_eArgError, "invalid IP address"); + } + Data_Get_Struct(self, iface_t, iface); + if (!iface->add_address(iface, addr)) + { + rb_raise(rb_eRuntimeError, "adding address failed"); + } + addr->destroy(addr); + return self; +} + +static VALUE iface_each_addr(int argc, VALUE *argv, VALUE self) +{ + enumerator_t *enumerator; + iface_t *iface; + host_t *addr; + char buf[64]; + + if (!rb_block_given_p()) + { + rb_raise(rb_eArgError, "must be called with a block"); + } + Data_Get_Struct(self, iface_t, iface); + enumerator = iface->create_address_enumerator(iface); + while (enumerator->enumerate(enumerator, &addr)) + { + snprintf(buf, sizeof(buf), "%H", addr); + rb_yield(rb_str_new2(buf)); + } + enumerator->destroy(enumerator); + return self; +} + +static VALUE iface_del_addr(VALUE self, VALUE vaddr) +{ + iface_t *iface; + host_t *addr; + + addr = host_create_from_string(StringValuePtr(vaddr), 0); + if (!addr) + { + rb_raise(rb_eArgError, "invalid IP address"); + } + Data_Get_Struct(self, iface_t, iface); + if (!iface->delete_address(iface, addr)) + { + addr->destroy(addr); + rb_raise(rb_eRuntimeError, "address not found"); + } + addr->destroy(addr); + return self; +} + +static VALUE iface_delete(VALUE self) +{ + guest_t *guest; + iface_t *iface; + + Data_Get_Struct(self, iface_t, iface); + guest = iface->get_guest(iface); + guest->destroy_iface(guest, iface); + return Qnil; +} + +static void iface_init() +{ + rbc_iface = rb_define_class_under(rbm_dumm , "Iface", rb_cObject); + rb_define_method(rbc_iface, "to_s", iface_to_s, 0); + rb_define_method(rbc_iface, "connect", iface_connect, 1); + rb_define_method(rbc_iface, "disconnect", iface_disconnect, 0); + rb_define_method(rbc_iface, "add", iface_add_addr, 1); + rb_define_method(rbc_iface, "del", iface_del_addr, 1); + rb_define_method(rbc_iface, "each", iface_each_addr, -1); + rb_define_method(rbc_iface, "delete", iface_delete, 0); + rb_include_module(rbc_iface, rb_mEnumerable); +} + +static VALUE template_load(VALUE class, VALUE name) +{ + if (!dumm->load_template(dumm, StringValuePtr(name))) + { + rb_raise(rb_eRuntimeError, "loading template failed"); + } + return class; +} + +static VALUE template_unload(VALUE class) +{ + if (!dumm->load_template(dumm, NULL)) + { + rb_raise(rb_eRuntimeError, "unloading template failed"); + } + return class; +} + +static void template_init() +{ + rbc_template = rb_define_class_under(rbm_dumm , "Template", rb_cObject); + rb_define_singleton_method(rbc_template, "load", template_load, 1); + rb_define_singleton_method(rbc_template, "unload", template_unload, 0); +} + +/** + * extension finalization + */ +void Final_dumm() +{ + struct sigaction action; + + dumm->destroy(dumm); + + sigemptyset(&action.sa_mask); + action.sa_handler = SIG_DFL; + action.sa_flags = 0; + sigaction(SIGCHLD, &action, NULL); + + library_deinit(); +} + +/** + * extension initialization + */ +void Init_dumm() +{ + struct sigaction action; + + /* there are too many to report, rubyruby... */ + setenv("LEAK_DETECTIVE_DISABLE", "1", 1); + + library_init(NULL); + + dumm = dumm_create(NULL); + + rbm_dumm = rb_define_module("Dumm"); + + guest_init(); + bridge_init(); + iface_init(); + template_init(); + + sigemptyset(&action.sa_mask); + action.sa_sigaction = sigchld_handler; + action.sa_flags = SA_SIGINFO; + sigaction(SIGCHLD, &action, NULL); + + rb_set_end_proc(Final_dumm, 0); +} diff --git a/src/dumm/ext/extconf.rb b/src/dumm/ext/extconf.rb new file mode 100644 index 000000000..136be5c2c --- /dev/null +++ b/src/dumm/ext/extconf.rb @@ -0,0 +1,21 @@ +# +# DUMM for Ruby +# + +require "mkmf" + +dir_config("dumm") + +unless find_header('library.h', '../../libstrongswan') and + find_header('dumm.h', '..') + puts "... failed: one or more header files not found!" + exit +end + +unless find_library('dumm', 'dumm_create') + puts "... failed: 'libdumm' not found!" + exit +end + +create_makefile("dumm") + diff --git a/src/dumm/guest.c b/src/dumm/guest.c index 79dc45ff6..dbb4c6f7d 100644 --- a/src/dumm/guest.c +++ b/src/dumm/guest.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2008 Tobias Brunner * Copyright (C) 2007 Martin Willi * Hochschule fuer Technik Rapperswil * diff --git a/src/dumm/guest.h b/src/dumm/guest.h index 3b1b06435..b430095f1 100644 --- a/src/dumm/guest.h +++ b/src/dumm/guest.h @@ -1,4 +1,5 @@ /* + * Copyright (C) 2008 Tobias Brunner * Copyright (C) 2007 Martin Willi * Hochschule fuer Technik Rapperswil * diff --git a/src/dumm/iface.c b/src/dumm/iface.c index 350ab825c..78c6c7c92 100644 --- a/src/dumm/iface.c +++ b/src/dumm/iface.c @@ -1,4 +1,5 @@ /* + * Copyright (C) 2008 Tobias Brunner * Copyright (C) 2007 Martin Willi * Hochschule fuer Technik Rapperswil * Copyright (C) 2002 Jeff Dike diff --git a/src/dumm/irdumm.c b/src/dumm/irdumm.c index d9437400a..bca8ce1db 100644 --- a/src/dumm/irdumm.c +++ b/src/dumm/irdumm.c @@ -13,579 +13,28 @@ * for more details. */ -#include -#include -#include -#include - -#include -#include -#include - #undef PACKAGE_NAME #undef PACKAGE_TARNAME #undef PACKAGE_VERSION #undef PACKAGE_STRING #include -dumm_t *dumm; - -VALUE rbm_dumm; -VALUE rbc_guest; -VALUE rbc_bridge; -VALUE rbc_iface; -VALUE rbc_template; - -/** - * Guest invocation callback - */ -static pid_t invoke(void *null, guest_t *guest, char *args[], int argc) -{ - pid_t pid; - - args[argc++] = "con0=xterm"; - args[argc++] = "xterm=gnome-terminal,-t,-x"; - - pid = fork(); - switch (pid) - { - case 0: /* child */ - dup2(open("/dev/null", 0), 1); - dup2(open("/dev/null", 0), 2); - execvp(args[0], args); - /* FALL */ - case -1: - return 0; - default: - return pid; - } -} - -/** - * SIGCHLD signal handler - */ -static void sigchld_handler(int signal, siginfo_t *info, void* ptr) -{ - enumerator_t *enumerator; - guest_t *guest; - - enumerator = dumm->create_guest_enumerator(dumm); - while (enumerator->enumerate(enumerator, &guest)) - { - if (guest->get_pid(guest) == info->si_pid) - { - guest->sigchild(guest); - break; - } - } - enumerator->destroy(enumerator); -} - -/** - * SIGINT/SEGV/TERM signal handler - */ -static void sigint_handler(int signal, siginfo_t *info, void* ptr) -{ - struct sigaction action; - - dumm->destroy(dumm); - - action.sa_handler = SIG_DFL; - action.sa_flags = 0; - sigaction(SIGCHLD, &action, NULL); - - library_deinit(); - exit(0); -} - -/** - * Guest bindings - */ -static VALUE guest_get(VALUE class, VALUE key) -{ - enumerator_t *enumerator; - guest_t *guest, *found = NULL; - - enumerator = dumm->create_guest_enumerator(dumm); - while (enumerator->enumerate(enumerator, &guest)) - { - if (streq(guest->get_name(guest), StringValuePtr(key))) - { - found = guest; - break; - } - } - enumerator->destroy(enumerator); - if (!found) - { - rb_raise(rb_eRuntimeError, "guest not found"); - } - return Data_Wrap_Struct(class, NULL, NULL, found); -} - -static VALUE guest_each(int argc, VALUE *argv, VALUE class) -{ - enumerator_t *enumerator; - guest_t *guest; - - if (!rb_block_given_p()) - { - rb_raise(rb_eArgError, "must be called with a block"); - } - enumerator = dumm->create_guest_enumerator(dumm); - while (enumerator->enumerate(enumerator, &guest)) - { - rb_yield(Data_Wrap_Struct(class, NULL, NULL, guest)); - } - enumerator->destroy(enumerator); - return class; -} - -static VALUE guest_new(VALUE class, VALUE name, VALUE kernel, - VALUE master, VALUE mem) -{ - guest_t *guest; - - guest = dumm->create_guest(dumm, StringValuePtr(name), StringValuePtr(kernel), - StringValuePtr(master), FIX2INT(mem)); - if (!guest) - { - rb_raise(rb_eRuntimeError, "creating guest failed"); - } - return Data_Wrap_Struct(class, NULL, NULL, guest); -} - -static VALUE guest_to_s(VALUE self) -{ - guest_t *guest; - - Data_Get_Struct(self, guest_t, guest); - return rb_str_new2(guest->get_name(guest)); -} - -static VALUE guest_start(VALUE self) -{ - guest_t *guest; - - Data_Get_Struct(self, guest_t, guest); - - if (!guest->start(guest, invoke, NULL, NULL)) - { - rb_raise(rb_eRuntimeError, "starting guest failed"); - } - return self; -} - -static VALUE guest_stop(VALUE self) -{ - guest_t *guest; - - Data_Get_Struct(self, guest_t, guest); - guest->stop(guest, NULL); - return self; -} - -static void exec_cb(void *data, char *buf) -{ - rb_yield(rb_str_new2(buf)); -} - -static VALUE guest_exec(VALUE self, VALUE cmd) -{ - guest_t *guest; - bool block; - int ret; - - block = rb_block_given_p(); - Data_Get_Struct(self, guest_t, guest); - if ((ret = guest->exec_str(guest, block ? (void*)exec_cb : NULL, TRUE, NULL, - "%s", StringValuePtr(cmd))) != 0) - { - rb_raise(rb_eRuntimeError, "executing command failed (%d)", ret); - } - return self; -} - -static VALUE guest_add_iface(VALUE self, VALUE name) -{ - guest_t *guest; - iface_t *iface; - - Data_Get_Struct(self, guest_t, guest); - iface = guest->create_iface(guest, StringValuePtr(name)); - if (!iface) - { - rb_raise(rb_eRuntimeError, "adding interface failed"); - } - return Data_Wrap_Struct(rbc_iface, NULL, NULL, iface); -} - -static VALUE guest_get_iface(VALUE self, VALUE key) -{ - enumerator_t *enumerator; - iface_t *iface, *found = NULL; - guest_t *guest; - - Data_Get_Struct(self, guest_t, guest); - enumerator = guest->create_iface_enumerator(guest); - while (enumerator->enumerate(enumerator, &iface)) - { - if (streq(iface->get_guestif(iface), StringValuePtr(key))) - { - found = iface; - break; - } - } - enumerator->destroy(enumerator); - if (!found) - { - rb_raise(rb_eRuntimeError, "interface not found"); - } - return Data_Wrap_Struct(rbc_iface, NULL, NULL, iface); -} - -static VALUE guest_each_iface(int argc, VALUE *argv, VALUE self) -{ - enumerator_t *enumerator; - guest_t *guest; - iface_t *iface; - - if (!rb_block_given_p()) - { - rb_raise(rb_eArgError, "must be called with a block"); - } - Data_Get_Struct(self, guest_t, guest); - enumerator = guest->create_iface_enumerator(guest); - while (enumerator->enumerate(enumerator, &iface)) - { - rb_yield(Data_Wrap_Struct(rbc_iface, NULL, NULL, iface)); - } - enumerator->destroy(enumerator); - return self; -} - -static VALUE guest_delete(VALUE self) -{ - guest_t *guest; - - Data_Get_Struct(self, guest_t, guest); - dumm->delete_guest(dumm, guest); - return Qnil; -} - -static void guest_init() -{ - rbc_guest = rb_define_class_under(rbm_dumm , "Guest", rb_cObject); - rb_define_singleton_method(rbc_guest, "[]", guest_get, 1); - rb_define_singleton_method(rbc_guest, "each", guest_each, -1); - rb_define_singleton_method(rbc_guest, "new", guest_new, 4); - rb_define_method(rbc_guest, "to_s", guest_to_s, 0); - rb_define_method(rbc_guest, "start", guest_start, 0); - rb_define_method(rbc_guest, "stop", guest_stop, 0); - rb_define_method(rbc_guest, "exec", guest_exec, 1); - rb_define_method(rbc_guest, "add", guest_add_iface, 1); - rb_define_method(rbc_guest, "[]", guest_get_iface, 1); - rb_define_method(rbc_guest, "each", guest_each_iface, -1); - rb_define_method(rbc_guest, "delete", guest_delete, 0); - rb_include_module(rb_class_of(rbc_guest), rb_mEnumerable); - rb_include_module(rbc_guest, rb_mEnumerable); -} - -/** - * Bridge binding - */ -static VALUE bridge_get(VALUE class, VALUE key) -{ - enumerator_t *enumerator; - bridge_t *bridge, *found = NULL; - - enumerator = dumm->create_bridge_enumerator(dumm); - while (enumerator->enumerate(enumerator, &bridge)) - { - if (streq(bridge->get_name(bridge), StringValuePtr(key))) - { - found = bridge; - break; - } - } - enumerator->destroy(enumerator); - if (!found) - { - rb_raise(rb_eRuntimeError, "bridge not found"); - } - return Data_Wrap_Struct(class, NULL, NULL, found); -} - -static VALUE bridge_each(int argc, VALUE *argv, VALUE class) -{ - enumerator_t *enumerator; - bridge_t *bridge; - - if (!rb_block_given_p()) - { - rb_raise(rb_eArgError, "must be called with a block"); - } - enumerator = dumm->create_bridge_enumerator(dumm); - while (enumerator->enumerate(enumerator, &bridge)) - { - rb_yield(Data_Wrap_Struct(class, NULL, NULL, bridge)); - } - enumerator->destroy(enumerator); - return class; -} - -static VALUE bridge_new(VALUE class, VALUE name) - -{ - bridge_t *bridge; - - bridge = dumm->create_bridge(dumm, StringValuePtr(name)); - if (!bridge) - { - rb_raise(rb_eRuntimeError, "creating bridge failed"); - } - return Data_Wrap_Struct(class, NULL, NULL, bridge); -} - -static VALUE bridge_to_s(VALUE self) -{ - bridge_t *bridge; - - Data_Get_Struct(self, bridge_t, bridge); - return rb_str_new2(bridge->get_name(bridge)); -} - -static VALUE bridge_each_iface(int argc, VALUE *argv, VALUE self) -{ - enumerator_t *enumerator; - bridge_t *bridge; - iface_t *iface; - - if (!rb_block_given_p()) - { - rb_raise(rb_eArgError, "must be called with a block"); - } - Data_Get_Struct(self, bridge_t, bridge); - enumerator = bridge->create_iface_enumerator(bridge); - while (enumerator->enumerate(enumerator, &iface)) - { - rb_yield(Data_Wrap_Struct(rbc_iface, NULL, NULL, iface)); - } - enumerator->destroy(enumerator); - return self; -} - -static VALUE bridge_delete(VALUE self) -{ - bridge_t *bridge; - - Data_Get_Struct(self, bridge_t, bridge); - dumm->delete_bridge(dumm, bridge); - return Qnil; -} - -static void bridge_init() -{ - rbc_bridge = rb_define_class_under(rbm_dumm , "Bridge", rb_cObject); - rb_define_singleton_method(rbc_bridge, "[]", bridge_get, 1); - rb_define_singleton_method(rbc_bridge, "each", bridge_each, -1); - rb_define_singleton_method(rbc_bridge, "new", bridge_new, 1); - rb_define_method(rbc_bridge, "to_s", bridge_to_s, 0); - rb_define_method(rbc_bridge, "each", bridge_each_iface, -1); - rb_define_method(rbc_bridge, "delete", bridge_delete, 0); - rb_include_module(rb_class_of(rbc_bridge), rb_mEnumerable); - rb_include_module(rbc_bridge, rb_mEnumerable); -} - -/** - * Iface wrapper - */ -static VALUE iface_to_s(VALUE self) -{ - iface_t *iface; - - Data_Get_Struct(self, iface_t, iface); - return rb_str_new2(iface->get_hostif(iface)); -} - -static VALUE iface_connect(VALUE self, VALUE vbridge) -{ - iface_t *iface; - bridge_t *bridge; - - Data_Get_Struct(self, iface_t, iface); - Data_Get_Struct(vbridge, bridge_t, bridge); - if (!bridge->connect_iface(bridge, iface)) - { - rb_raise(rb_eRuntimeError, "connecting iface failed"); - } - return self; -} - -static VALUE iface_disconnect(VALUE self) -{ - iface_t *iface; - bridge_t *bridge; - - Data_Get_Struct(self, iface_t, iface); - bridge = iface->get_bridge(iface); - if (!bridge || !bridge->disconnect_iface(bridge, iface)) - { - rb_raise(rb_eRuntimeError, "disconnecting iface failed"); - } - return self; -} - -static VALUE iface_add_addr(VALUE self, VALUE name) -{ - iface_t *iface; - host_t *addr; - - addr = host_create_from_string(StringValuePtr(name), 0); - if (!addr) - { - rb_raise(rb_eArgError, "invalid IP address"); - } - Data_Get_Struct(self, iface_t, iface); - if (!iface->add_address(iface, addr)) - { - rb_raise(rb_eRuntimeError, "adding address failed"); - } - addr->destroy(addr); - return self; -} - -static VALUE iface_each_addr(int argc, VALUE *argv, VALUE self) -{ - enumerator_t *enumerator; - iface_t *iface; - host_t *addr; - char buf[64]; - - if (!rb_block_given_p()) - { - rb_raise(rb_eArgError, "must be called with a block"); - } - Data_Get_Struct(self, iface_t, iface); - enumerator = iface->create_address_enumerator(iface); - while (enumerator->enumerate(enumerator, &addr)) - { - snprintf(buf, sizeof(buf), "%H", addr); - rb_yield(rb_str_new2(buf)); - } - enumerator->destroy(enumerator); - return self; -} - -static VALUE iface_del_addr(VALUE self, VALUE vaddr) -{ - iface_t *iface; - host_t *addr; - - addr = host_create_from_string(StringValuePtr(vaddr), 0); - if (!addr) - { - rb_raise(rb_eArgError, "invalid IP address"); - } - Data_Get_Struct(self, iface_t, iface); - if (!iface->delete_address(iface, addr)) - { - addr->destroy(addr); - rb_raise(rb_eRuntimeError, "address not found"); - } - addr->destroy(addr); - return self; -} - -static VALUE iface_delete(VALUE self) -{ - guest_t *guest; - iface_t *iface; - - Data_Get_Struct(self, iface_t, iface); - guest = iface->get_guest(iface); - guest->destroy_iface(guest, iface); - return Qnil; -} - -static void iface_init() -{ - rbc_iface = rb_define_class_under(rbm_dumm , "Iface", rb_cObject); - rb_define_method(rbc_iface, "to_s", iface_to_s, 0); - rb_define_method(rbc_iface, "connect", iface_connect, 1); - rb_define_method(rbc_iface, "disconnect", iface_disconnect, 0); - rb_define_method(rbc_iface, "add", iface_add_addr, 1); - rb_define_method(rbc_iface, "del", iface_del_addr, 1); - rb_define_method(rbc_iface, "each", iface_each_addr, -1); - rb_define_method(rbc_iface, "delete", iface_delete, 0); - rb_include_module(rbc_iface, rb_mEnumerable); -} - -static VALUE template_load(VALUE class, VALUE name) -{ - if (!dumm->load_template(dumm, StringValuePtr(name))) - { - rb_raise(rb_eRuntimeError, "loading template failed"); - } - return class; -} - -static VALUE template_unload(VALUE class) -{ - if (!dumm->load_template(dumm, NULL)) - { - rb_raise(rb_eRuntimeError, "unloading template failed"); - } - return class; -} - -static void template_init() -{ - rbc_template = rb_define_class_under(rbm_dumm , "Template", rb_cObject); - rb_define_singleton_method(rbc_template, "load", template_load, 1); - rb_define_singleton_method(rbc_template, "unload", template_unload, 0); -} - /** * main routine, parses args and reads from console */ int main(int argc, char *argv[]) { int state, i; - struct sigaction action; char buf[512]; ruby_init(); ruby_init_loadpath(); - /* there are too many to report, rubyruby... */ - setenv("LEAK_DETECTIVE_DISABLE", "1", 1); - - library_init(NULL); - - dumm = dumm_create(NULL); - - rbm_dumm = rb_define_module("Dumm"); - - guest_init(); - bridge_init(); - iface_init(); - template_init(); - - sigemptyset(&action.sa_mask); - action.sa_flags = SA_SIGINFO; - action.sa_sigaction = sigchld_handler; - sigaction(SIGCHLD, &action, NULL); - action.sa_sigaction = sigint_handler; - sigaction(SIGINT, &action, NULL); - sigaction(SIGTERM, &action, NULL); - sigaction(SIGSEGV, &action, NULL); - sigaction(SIGHUP, &action, NULL); - - rb_eval_string_protect("include Dumm", &state); + rb_eval_string_protect("require 'dumm' and include Dumm", &state); if (state) { rb_p(ruby_errinfo); + printf("Please install the ruby extension first!\n"); } for (i = 1; i < argc; i++) { @@ -605,13 +54,6 @@ int main(int argc, char *argv[]) rb_p(ruby_errinfo); } - dumm->destroy(dumm); - - action.sa_handler = SIG_DFL; - action.sa_flags = 0; - sigaction(SIGCHLD, &action, NULL); - - library_deinit(); ruby_finalize(); return 0; } diff --git a/src/dumm/mconsole.c b/src/dumm/mconsole.c index 71062bedf..53f3e5644 100644 --- a/src/dumm/mconsole.c +++ b/src/dumm/mconsole.c @@ -248,7 +248,7 @@ static void destroy(private_mconsole_t *this) } /** - * setup the mconsole notify connection and wait for its readyness + * setup the mconsole notify connection and wait for its readiness */ static bool wait_for_notify(private_mconsole_t *this, char *nsock) {