diff -r 000000000000 -r 92d00ff32c56 ext/bsdjail.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ext/bsdjail.c Fri Aug 15 15:43:38 2008 +0000 @@ -0,0 +1,233 @@ +/* + * dict.c - Ruby LinkParser - Dict Class + * $Id$ + * + * Authors: + * * Michael Granger + * + * 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 +#include + +#include +#include +#include +#include +#include + + +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 ); + +} +