--- /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 <ged@FaerieMUD.org>
+ *
+ * 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 );
+
+}
+