prototype of irdumm - interactive ruby shell for dumm
This commit is contained in:
@@ -1,14 +1,18 @@
|
||||
lib_LTLIBRARIES = libdumm.la
|
||||
ipsec_PROGRAMS = dumm testing
|
||||
ipsec_PROGRAMS = dumm testing irdumm
|
||||
|
||||
libdumm_la_SOURCES = dumm.c dumm.h guest.c guest.h iface.c iface.h \
|
||||
bridge.c bridge.h mconsole.c mconsole.h cowfs.h cowfs.c
|
||||
dumm_SOURCES = main.c
|
||||
testing_SOURCES = testing.c
|
||||
irdumm_SOURCES = irdumm.c
|
||||
|
||||
libdumm_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la -lbridge -lfuse -lutil
|
||||
dumm_LDADD = -ldumm ${gtk_LIBS}
|
||||
libdumm_la_LIBADD = $(top_builddir)/src/libstrongswan/libstrongswan.la \
|
||||
-lbridge -lfuse -lutil
|
||||
dumm_LDADD = -ldumm ${gtk_LIBS}
|
||||
testing_LDADD = -ldumm
|
||||
irdumm_LDADD = -ldumm -lruby1.8
|
||||
|
||||
INCLUDES = -I$(top_srcdir)/src/libstrongswan ${gtk_CFLAGS}
|
||||
INCLUDES = -I$(top_srcdir)/src/libstrongswan ${gtk_CFLAGS} \
|
||||
-I/usr/lib/ruby/1.8/i486-linux/
|
||||
AM_CFLAGS = -D_FILE_OFFSET_BITS=64
|
||||
|
||||
+5
-6
@@ -49,8 +49,6 @@ struct private_dumm_t {
|
||||
linked_list_t *guests;
|
||||
/** list of managed bridges */
|
||||
linked_list_t *bridges;
|
||||
/** do not catch signals if we are destroying */
|
||||
bool destroying;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -219,8 +217,11 @@ static void destroy(private_dumm_t *this)
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
this->destroying = TRUE;
|
||||
this->guests->destroy_offset(this->guests, offsetof(guest_t, destroy));
|
||||
while (this->guests->remove_last(this->guests, (void**)&guest) == SUCCESS)
|
||||
{
|
||||
guest->destroy(guest);
|
||||
}
|
||||
this->guests->destroy(this->guests);
|
||||
free(this->guest_dir);
|
||||
free(this->template_dir);
|
||||
free(this->template);
|
||||
@@ -279,8 +280,6 @@ dumm_t *dumm_create(char *dir)
|
||||
this->public.load_template = (bool(*)(dumm_t*, char *name))load_template;
|
||||
this->public.destroy = (void(*)(dumm_t*))destroy;
|
||||
|
||||
this->destroying = FALSE;
|
||||
|
||||
if (dir && *dir == '/')
|
||||
{
|
||||
this->dir = strdup(dir);
|
||||
|
||||
+1
-1
@@ -114,7 +114,7 @@ static iface_t* create_iface(private_guest_t *this, char *name)
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
||||
iface = iface_create(this->name, name, this->mconsole);
|
||||
iface = iface_create(name, &this->public, this->mconsole);
|
||||
if (iface)
|
||||
{
|
||||
this->ifaces->insert_last(this->ifaces, iface);
|
||||
|
||||
+2
-2
@@ -19,11 +19,11 @@
|
||||
#include <library.h>
|
||||
#include <utils/enumerator.h>
|
||||
|
||||
#include "iface.h"
|
||||
|
||||
typedef enum guest_state_t guest_state_t;
|
||||
typedef struct guest_t guest_t;
|
||||
|
||||
#include "iface.h"
|
||||
|
||||
/**
|
||||
* @brief State of a guest (started, stopped, ...)
|
||||
*/
|
||||
|
||||
+27
-5
@@ -39,6 +39,8 @@ struct private_iface_t {
|
||||
char *hostif;
|
||||
/** bridge this interface is attached to */
|
||||
bridge_t *bridge;
|
||||
/** guest this interface is attached to */
|
||||
guest_t *guest;
|
||||
/** mconsole for guest */
|
||||
mconsole_t *mconsole;
|
||||
};
|
||||
@@ -103,6 +105,22 @@ static void set_bridge(private_iface_t *this, bridge_t *bridge)
|
||||
this->bridge = bridge;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of iface_t.get_bridge
|
||||
*/
|
||||
static bridge_t *get_bridge(private_iface_t *this)
|
||||
{
|
||||
return this->bridge;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of iface_t.get_guest
|
||||
*/
|
||||
static guest_t* get_guest(private_iface_t *this)
|
||||
{
|
||||
return this->guest;
|
||||
}
|
||||
|
||||
/**
|
||||
* destroy the tap device
|
||||
*/
|
||||
@@ -139,14 +157,15 @@ static bool destroy_tap(private_iface_t *this)
|
||||
/**
|
||||
* create the tap device
|
||||
*/
|
||||
static char* create_tap(private_iface_t *this, char *guest)
|
||||
static char* create_tap(private_iface_t *this)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int tap;
|
||||
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
|
||||
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s-%s", guest, this->guestif);
|
||||
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s-%s",
|
||||
this->guest->get_name(this->guest), this->guestif);
|
||||
|
||||
tap = open(TAP_DEVICE, O_RDWR);
|
||||
if (tap < 0)
|
||||
@@ -185,18 +204,21 @@ static void destroy(private_iface_t *this)
|
||||
/**
|
||||
* create the iface instance
|
||||
*/
|
||||
iface_t *iface_create(char *guest, char *guestif, mconsole_t *mconsole)
|
||||
iface_t *iface_create(char *name, guest_t *guest, mconsole_t *mconsole)
|
||||
{
|
||||
private_iface_t *this = malloc_thing(private_iface_t);
|
||||
|
||||
this->public.get_hostif = (char*(*)(iface_t*))get_hostif;
|
||||
this->public.get_guestif = (char*(*)(iface_t*))get_guestif;
|
||||
this->public.set_bridge = (void(*)(iface_t*, bridge_t*))set_bridge;
|
||||
this->public.get_bridge = (bridge_t*(*)(iface_t*))get_bridge;
|
||||
this->public.get_guest = (guest_t*(*)(iface_t*))get_guest;
|
||||
this->public.destroy = (void*)destroy;
|
||||
|
||||
this->mconsole = mconsole;
|
||||
this->guestif = strdup(guestif);
|
||||
this->hostif = create_tap(this, guest);
|
||||
this->guestif = strdup(name);
|
||||
this->guest = guest;
|
||||
this->hostif = create_tap(this);
|
||||
this->bridge = NULL;
|
||||
if (this->hostif == NULL)
|
||||
{
|
||||
|
||||
+17
-7
@@ -25,6 +25,7 @@ typedef struct iface_t iface_t;
|
||||
|
||||
#include "mconsole.h"
|
||||
#include "bridge.h"
|
||||
#include "guest.h"
|
||||
|
||||
/**
|
||||
* @brief Interface in a guest, connected to a tap device on the host.
|
||||
@@ -52,10 +53,19 @@ struct iface_t {
|
||||
*/
|
||||
void (*set_bridge)(iface_t *this, bridge_t *bridge);
|
||||
|
||||
/*
|
||||
bool (*add_addr) (iface_t *this, host_t *addr);
|
||||
enumerator_t* (*create_addr_enumerator) (iface_t *this);
|
||||
*/
|
||||
/**
|
||||
* @brief Get the bridge this iface is connected, or NULL.
|
||||
*
|
||||
* @return connected bridge, or NULL
|
||||
*/
|
||||
bridge_t* (*get_bridge)(iface_t *this);
|
||||
|
||||
/**
|
||||
* @brief Get the guest this iface belongs to.
|
||||
*
|
||||
* @return guest of this iface
|
||||
*/
|
||||
guest_t* (*get_guest)(iface_t *this);
|
||||
|
||||
/**
|
||||
* @brief Destroy an interface
|
||||
@@ -66,12 +76,12 @@ struct iface_t {
|
||||
/**
|
||||
* @brief Create a new interface for a guest
|
||||
*
|
||||
* @param guest name of the guest for this interface
|
||||
* @param guestif name of the interface in the guest
|
||||
* @param name name of the interface in the guest
|
||||
* @param guest guest this iface is connecting
|
||||
* @param mconsole mconsole of guest
|
||||
* @return interface descriptor, or NULL if failed
|
||||
*/
|
||||
iface_t *iface_create(char *guest, char *guestif, mconsole_t *mconsole);
|
||||
iface_t *iface_create(char *name, guest_t *guest, mconsole_t *mconsole);
|
||||
|
||||
#endif /* IFACE_H */
|
||||
|
||||
|
||||
@@ -0,0 +1,465 @@
|
||||
/*
|
||||
* 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 <http://www.fsf.org/copyleft/gpl.txt>.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <library.h>
|
||||
#include <dumm.h>
|
||||
|
||||
#undef PACKAGE_NAME
|
||||
#undef PACKAGE_TARNAME
|
||||
#undef PACKAGE_VERSION
|
||||
#undef PACKAGE_STRING
|
||||
#include <ruby.h>
|
||||
|
||||
dumm_t *dumm;
|
||||
|
||||
VALUE rbm_dumm;
|
||||
VALUE rbc_guest;
|
||||
VALUE rbc_bridge;
|
||||
VALUE rbc_iface;
|
||||
|
||||
/**
|
||||
* Guest invocation callback
|
||||
*/
|
||||
static pid_t invoke(void *null, guest_t *guest, char *args[], int argc)
|
||||
{
|
||||
pid_t pid;
|
||||
|
||||
args[argc] = "con0=xterm";
|
||||
|
||||
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:
|
||||
rb_raise(rb_eException, "starting guest failed");
|
||||
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)
|
||||
{
|
||||
return Qnil;
|
||||
}
|
||||
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 Qnil;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return Qnil;
|
||||
}
|
||||
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))
|
||||
{
|
||||
return Qtrue;
|
||||
}
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
static VALUE guest_stop(VALUE self)
|
||||
{
|
||||
guest_t *guest;
|
||||
|
||||
Data_Get_Struct(self, guest_t, guest);
|
||||
|
||||
if (guest->stop(guest, NULL))
|
||||
{
|
||||
return Qtrue;
|
||||
}
|
||||
return Qfalse;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return Data_Wrap_Struct(rbc_iface, NULL, NULL, iface);
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return Qnil;
|
||||
}
|
||||
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 Qnil;
|
||||
}
|
||||
|
||||
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, "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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
return Qnil;
|
||||
}
|
||||
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 Qnil;
|
||||
}
|
||||
|
||||
static VALUE bridge_new(VALUE class, VALUE name)
|
||||
|
||||
{
|
||||
bridge_t *bridge;
|
||||
|
||||
bridge = dumm->create_bridge(dumm, StringValuePtr(name));
|
||||
if (!bridge)
|
||||
{
|
||||
return Qnil;
|
||||
}
|
||||
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 Qnil;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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))
|
||||
{
|
||||
return self;
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
return self;
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
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, "delete", iface_delete, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* main routine, parses args and reads from console
|
||||
*/
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int state;
|
||||
struct sigaction action;
|
||||
|
||||
ruby_init();
|
||||
ruby_init_loadpath();
|
||||
|
||||
/* there are to 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();
|
||||
|
||||
sigemptyset(&action.sa_mask);
|
||||
action.sa_sigaction = sigchld_handler;
|
||||
action.sa_flags = SA_SIGINFO;
|
||||
sigaction(SIGCHLD, &action, NULL);
|
||||
|
||||
rb_require("irb");
|
||||
rb_eval_string_protect("include Dumm", &state);
|
||||
rb_eval_string_protect("IRB.start", &state);
|
||||
if (state)
|
||||
{
|
||||
rb_p(ruby_errinfo);
|
||||
}
|
||||
|
||||
dumm->destroy(dumm);
|
||||
|
||||
action.sa_handler = SIG_DFL;
|
||||
action.sa_flags = 0;
|
||||
sigaction(SIGCHLD, &action, NULL);
|
||||
|
||||
library_deinit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user