* Add a mkrf monkeypatch so BSD build flags are generated correctly.
* Fix typos!
/*
* bsdjail.c - Ruby jparallel
* $Id$
*
* 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 <ruby.h>
#include <intern.h>
#include <stdio.h>
#include <sys/param.h>
#include <sys/jail.h>
#include <sys/types.h>
#include <unistd.h>
VALUE rbjail_mBSD;
VALUE rbjail_cBSDJail;
/*
struct jail {
u_int32_t version;
char *path;
char *hostname;
u_int32_t ip_number;
};
*/
/*
* Allocation function
*/
static jail *
rbjail_jail_alloc()
{
jail *ptr = ALLOC( jail );
ptr->version = 0;
ptr->path = NULL;
ptr->hostname = NULL;
ptr->ip_number = 0;
debugMsg(( "Initialized a jail pointer <%p>", ptr ));
return ptr;
}
/*
* GC Free function
*/
static void
rbjail_jail_gc_free( ptr )
jail *ptr;
{
if ( ptr ) {
ptr->path = NULL;
ptr->hostname = NULL;
xfree( ptr );
}
else {
debugMsg(( "Not freeing an uninitialized rlink_SENTENCE" ));
}
}
/*
* Object validity checker. Returns the data pointer.
*/
static rlink_SENTENCE *
check_sentence( self )
VALUE self;
{
debugMsg(( "Checking a LinkParser::Sentence object (%d).", self ));
Check_Type( self, T_DATA );
if ( !IsSentence(self) ) {
rb_raise( rb_eTypeError, "wrong argument type %s (expected LinkParser::Sentence)",
rb_class2name(CLASS_OF( self )) );
}
return DATA_PTR( self );
}
/*
* Fetch the data pointer and check it for sanity.
*/
static rlink_SENTENCE *
get_sentence( self )
VALUE self;
{
rlink_SENTENCE *ptr = check_sentence( self );
debugMsg(( "Fetching a Sentence (%p).", ptr ));
if ( !ptr )
rb_raise( rb_eRuntimeError, "uninitialized Sentence" );
return ptr;
}
/*
* Publicly-usable sentence-fetcher
*/
rlink_SENTENCE *
rlink_get_sentence( self )
VALUE self;
{
return get_sentence( self );
}
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 kinfo_prison *sxp, *xp;
struct in_addr in;
size_t i, len;
if (sysctlbyname("jail.list", NULL, &len, NULL, 0) == -1)
rb_sys_fail("sysctlbyname(): jail.list");
xp = ALLOCA_N( kinfo_prison, 1 );
if (sysctlbyname("jail.list", xp, &len, NULL, 0) == -1) {
rb_sys_fail("sysctlbyname(): jail.list");
}
if (len < sizeof(*xp) || len % sizeof(*xp) ||
xp->pr_version != KINFO_PRISON_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++;
}
free(sxp);
exit(0);
}
void
Init_bsdjail( void )
{
rbjail_mBSD = rb_define_module( "BSD" );
rbjail_cBSDJail = rb_define_class_under( rbjail_mBSD, "Jail" );
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 );
}