* It compiles!
* Removed additional leftover link parser stuff.
* Removed unused memory allocate/free stuff until I discuss with my
cohort. It may be back... it may be left over from linkparser too. ;)
* list() works, but cores. Not sure why yet. Really, list() should be
renamed to something sensible, and return instantiated BSD::Jail
objects to attach() to or get additional info on.
* Ruby C bindings are way, way fun. Reminds me how little C I can
remember with one project a year :)
/*
*
* bsdjail.c - Ruby jparallel
* $Id$
*
* vim: set nosta noet ts=4 sw=4:
*
* Authors:
* * Michael Granger <ged@FaerieMUD.org>
* * Mahlon E. Smith <mahlon@martini.nu>
*
* Copyright (c) 2006 The FaerieMUD Consortium.
*
* This work is licensed under the Creative Commons Attribution License. To
* view a copy of this license, visit
* http://creativecommons.org/licenses/by/1.0 or send a letter to Creative
* Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
*
*/
#include "bsdjail.h"
VALUE rbjail_mBSD;
VALUE rbjail_cBSDJail;
/*
struct jail {
u_int32_t version;
char *path;
char *hostname;
u_int32_t ip_number;
};
*/
static void
rbjail_do_jail_attach( int jid )
{
if ( jail_attach(jid) == -1 )
rb_sys_fail( "jail_attach" );
}
/* Mostly ripped off from Ruby's process.c */
static VALUE
rbjail_attach_block( int jid )
{
int pid;
rb_secure(2);
fflush(stdout);
fflush(stderr);
switch ( pid = fork() ) {
case 0:
rb_thread_atfork();
if ( rb_block_given_p() ) {
int status;
rbjail_do_jail_attach( jid );
rb_protect( rb_yield, Qundef, &status );
ruby_stop( status );
}
return Qnil;
case -1:
rb_sys_fail( "fork(2)" );
return Qnil;
default:
return INT2FIX( pid );
}
}
static VALUE
rbjail_attach( int argc, VALUE *argv, VALUE self )
{
VALUE jidnum, rval;
int jid;
rb_scan_args( argc, argv, "1", &jidnum );
jid = NUM2INT( jidnum );
if ( rb_block_given_p() ) {
rval = rbjail_attach_block( jid );
}
else {
rbjail_do_jail_attach( jid );
rval = Qtrue;
}
return rval;
}
static VALUE
rbjail_list( VALUE self )
{
struct xprison *xp;
struct in_addr in;
size_t i, len;
/* Get the size of the xprison and allocate memory to it. */
if ( sysctlbyname("security.jail.list", NULL, &len, NULL, 0) == -1 )
rb_sys_fail("sysctlbyname(): security.jail.list");
xp = ALLOCA_N( struct xprison, 1 );
/* Get and sanity check the current prison list */
if ( sysctlbyname("security.jail.list", xp, &len, NULL, 0) == -1 ) {
rb_sys_fail("sysctlbyname(): security.jail.list");
}
if ( len < sizeof(*xp) || len % sizeof(*xp) ||
xp->pr_version != XPRISON_VERSION )
rb_fatal("Kernel and userland out of sync");
len /= sizeof(*xp);
printf(" JID IP Address Hostname Path\n");
for ( i = 0; i < len; i++ ) {
in.s_addr = ntohl( xp->pr_ip );
printf("%6d %-15.15s %-29.29s %.74s\n",
xp->pr_id, inet_ntoa(in), xp->pr_host, xp->pr_path);
xp++;
}
return self;
}
void
Init_bsdjail( void )
{
rbjail_mBSD = rb_define_module( "BSD" );
rbjail_cBSDJail = rb_define_class_under( rbjail_mBSD, "Jail", rb_cObject );
rb_define_singleton_method( rbjail_cBSDJail, "list", rbjail_list, 0 );
/*
rb_define_alloc_function( rbjail_cBSDJail, );
rb_define_method( rbjail_cBSDJail, "attach", rbjail_attach, -1 );
*/
}