ext/bsdjail.c
branchmahlon-misc
changeset 11 e908d309e7ec
parent 9 4c51ebe6e9b6
equal deleted inserted replaced
10:b1426511fb64 11:e908d309e7ec
     1 /*
     1 /*
       
     2  *
     2  *  bsdjail.c - Ruby jparallel
     3  *  bsdjail.c - Ruby jparallel
     3  *  $Id$
     4  *  $Id$
       
     5  *
       
     6  *  vim: set nosta noet ts=4 sw=4:
     4  *  
     7  *  
     5  *  Authors:
     8  *  Authors:
     6  *    * Michael Granger <ged@FaerieMUD.org>
     9  *    * Michael Granger <ged@FaerieMUD.org>
     7  *    * Mahlon E. Smith <mahlon@martini.nu>
    10  *    * Mahlon E. Smith <mahlon@martini.nu>
     8  *  
    11  *  
    13  *  http://creativecommons.org/licenses/by/1.0 or send a letter to Creative
    16  *  http://creativecommons.org/licenses/by/1.0 or send a letter to Creative
    14  *  Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
    17  *  Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
    15  *  
    18  *  
    16  */
    19  */
    17 
    20 
    18 #include <ruby.h>
    21 #include "bsdjail.h"
    19 #include <intern.h>
       
    20 
       
    21 #include <stdio.h>
       
    22 #include <sys/param.h>
       
    23 #include <sys/jail.h>
       
    24 #include <sys/types.h>
       
    25 #include <unistd.h>
       
    26 
       
    27 
    22 
    28 VALUE rbjail_mBSD;
    23 VALUE rbjail_mBSD;
    29 VALUE rbjail_cBSDJail;
    24 VALUE rbjail_cBSDJail;
    30 
    25 
    31 
    26 
    36 	char            *hostname;
    31 	char            *hostname;
    37 	u_int32_t       ip_number;
    32 	u_int32_t       ip_number;
    38 };
    33 };
    39 */
    34 */
    40 
    35 
    41 /*
       
    42  * Allocation function
       
    43  */
       
    44 static jail *
       
    45 rbjail_jail_alloc()
       
    46 {
       
    47 	jail *ptr = ALLOC( jail );
       
    48 	
       
    49 	ptr->version	= 0;
       
    50 	ptr->path		= NULL;
       
    51 	ptr->hostname	= NULL;
       
    52 	ptr->ip_number	= 0;
       
    53 	
       
    54 	debugMsg(( "Initialized a jail pointer <%p>", ptr ));
       
    55 	return ptr;
       
    56 }
       
    57 
       
    58 
       
    59 /*
       
    60  * GC Free function
       
    61  */
       
    62 static void
       
    63 rbjail_jail_gc_free( ptr )
       
    64 	jail *ptr;
       
    65 {
       
    66 	if ( ptr ) {
       
    67 		ptr->path		= NULL;
       
    68 		ptr->hostname	= NULL;
       
    69 		xfree( ptr );
       
    70 	}
       
    71 	
       
    72 	else {
       
    73 		debugMsg(( "Not freeing an uninitialized rlink_SENTENCE" ));
       
    74 	}
       
    75 }
       
    76 
       
    77 
       
    78 /*
       
    79  * Object validity checker. Returns the data pointer.
       
    80  */
       
    81 static rlink_SENTENCE *
       
    82 check_sentence( self )
       
    83 	 VALUE	self;
       
    84 {
       
    85 	debugMsg(( "Checking a LinkParser::Sentence object (%d).", self ));
       
    86 	Check_Type( self, T_DATA );
       
    87 
       
    88     if ( !IsSentence(self) ) {
       
    89 		rb_raise( rb_eTypeError, "wrong argument type %s (expected LinkParser::Sentence)",
       
    90 				  rb_class2name(CLASS_OF( self )) );
       
    91     }
       
    92 	
       
    93 	return DATA_PTR( self );
       
    94 }
       
    95 
       
    96 
       
    97 /*
       
    98  * Fetch the data pointer and check it for sanity.
       
    99  */
       
   100 static rlink_SENTENCE *
       
   101 get_sentence( self )
       
   102 	 VALUE self;
       
   103 {
       
   104 	rlink_SENTENCE *ptr = check_sentence( self );
       
   105 
       
   106 	debugMsg(( "Fetching a Sentence (%p).", ptr ));
       
   107 	if ( !ptr )
       
   108 		rb_raise( rb_eRuntimeError, "uninitialized Sentence" );
       
   109 
       
   110 	return ptr;
       
   111 }
       
   112 
       
   113 
       
   114 /*
       
   115  * Publicly-usable sentence-fetcher
       
   116  */
       
   117 rlink_SENTENCE *
       
   118 rlink_get_sentence( self )
       
   119 	VALUE self;
       
   120 {
       
   121 	return get_sentence( self );
       
   122 }
       
   123 
       
   124 
       
   125 
       
   126 
       
   127 
       
   128 
    36 
   129 static void
    37 static void
   130 rbjail_do_jail_attach( int jid )
    38 rbjail_do_jail_attach( int jid )
   131 {
    39 {
   132 	if ( jail_attach(jid) == -1 )
    40 	if ( jail_attach(jid) == -1 )
   135 
    43 
   136 /* Mostly ripped off from Ruby's process.c */
    44 /* Mostly ripped off from Ruby's process.c */
   137 static VALUE
    45 static VALUE
   138 rbjail_attach_block( int jid )
    46 rbjail_attach_block( int jid )
   139 {
    47 {
   140     int pid;
    48 	int pid;
   141 
    49 
   142     rb_secure(2);
    50 	rb_secure(2);
   143 
    51 
   144     fflush(stdout);
    52 	fflush(stdout);
   145     fflush(stderr);
    53 	fflush(stderr);
   146 
    54 
   147 	switch ( pid = fork() ) {
    55 	switch ( pid = fork() ) {
   148 		case 0:
    56 		case 0:
   149 			rb_thread_atfork();
    57 			rb_thread_atfork();
   150 			if ( rb_block_given_p() ) {
    58 			if ( rb_block_given_p() ) {
   168 static VALUE
    76 static VALUE
   169 rbjail_attach( int argc, VALUE *argv, VALUE self )
    77 rbjail_attach( int argc, VALUE *argv, VALUE self )
   170 {
    78 {
   171 	VALUE jidnum, rval;
    79 	VALUE jidnum, rval;
   172 	int jid;
    80 	int jid;
   173 	
    81 
   174 	rb_scan_args( argc, argv, "1", &jidnum );
    82 	rb_scan_args( argc, argv, "1", &jidnum );
   175 	jid = NUM2INT( jidnum );
    83 	jid = NUM2INT( jidnum );
   176 
    84 
   177 	if ( rb_block_given_p() ) {
    85 	if ( rb_block_given_p() ) {
   178 		rval = rbjail_attach_block( jid );
    86 		rval = rbjail_attach_block( jid );
   179 	}
    87 	}
   180 	
    88 
   181 	else {
    89 	else {
   182 		rbjail_do_jail_attach( jid );
    90 		rbjail_do_jail_attach( jid );
   183 		rval = Qtrue;
    91 		rval = Qtrue;
   184 	}
    92 	}
   185 	
    93 
   186 	return rval;
    94 	return rval;
   187 }
    95 }
   188 
    96 
   189 static VALUE
    97 static VALUE
   190 	rbjail_list( VALUE self )
    98 rbjail_list( VALUE self )
   191 {
    99 {
   192 	struct kinfo_prison *sxp, *xp;
   100 	struct xprison *xp;
   193 	struct in_addr in;
   101 	struct in_addr in;
   194 	size_t i, len;
   102 	size_t i, len;
   195 
   103 
   196 	if (sysctlbyname("jail.list", NULL, &len, NULL, 0) == -1)
   104 	/* Get the size of the xprison and allocate memory to it. */
   197 		rb_sys_fail("sysctlbyname(): jail.list");
   105 	if ( sysctlbyname("security.jail.list", NULL, &len, NULL, 0) == -1 )
       
   106 		rb_sys_fail("sysctlbyname(): security.jail.list");
       
   107 	xp = ALLOCA_N( struct xprison, 1 );
   198 
   108 
   199 	xp = ALLOCA_N( kinfo_prison, 1 );
   109 	/* Get and sanity check the current prison list */
   200 
   110 	if ( sysctlbyname("security.jail.list", xp, &len, NULL, 0) == -1 ) {
   201 	if (sysctlbyname("jail.list", xp, &len, NULL, 0) == -1) {
   111 		rb_sys_fail("sysctlbyname(): security.jail.list");
   202 		rb_sys_fail("sysctlbyname(): jail.list");
       
   203 	}
   112 	}
   204 
   113 	if ( len < sizeof(*xp) || len % sizeof(*xp) ||
   205 	if (len < sizeof(*xp) || len % sizeof(*xp) ||
   114 			xp->pr_version != XPRISON_VERSION )
   206 		xp->pr_version != KINFO_PRISON_VERSION)
       
   207 		rb_fatal("Kernel and userland out of sync");
   115 		rb_fatal("Kernel and userland out of sync");
   208 
   116 
   209 	len /= sizeof(*xp);
   117 	len /= sizeof(*xp);
   210 	printf("   JID  IP Address      Hostname                      Path\n");
   118 	printf("   JID  IP Address      Hostname                      Path\n");
   211 	for (i = 0; i < len; i++) {
   119 	for ( i = 0; i < len; i++ ) {
   212 		in.s_addr = ntohl(xp->pr_ip);
   120 		in.s_addr = ntohl( xp->pr_ip );
   213 		printf("%6d  %-15.15s %-29.29s %.74s\n",
   121 		printf("%6d  %-15.15s %-29.29s %.74s\n",
   214 			xp->pr_id, inet_ntoa(in), xp->pr_host, xp->pr_path);
   122 				xp->pr_id, inet_ntoa(in), xp->pr_host, xp->pr_path);
   215 		xp++;
   123 		xp++;
   216 	}
   124 	}
   217 	free(sxp);
   125 	return self;
   218 	exit(0);
       
   219 
       
   220 }
   126 }
   221 
   127 
   222 void
   128 void
   223 Init_bsdjail( void )
   129 Init_bsdjail( void )
   224 {
   130 {
   225 	rbjail_mBSD = rb_define_module( "BSD" );
   131 	rbjail_mBSD = rb_define_module( "BSD" );
   226 	rbjail_cBSDJail = rb_define_class_under( rbjail_mBSD, "Jail" );
   132 	rbjail_cBSDJail = rb_define_class_under( rbjail_mBSD, "Jail", rb_cObject );
   227 
   133 
   228 	rb_define_singleton_method( rbjail_cBSDJail, "list", rbjail_list, 0 );
   134 	rb_define_singleton_method( rbjail_cBSDJail, "list", rbjail_list, 0 );
   229 	rb_define_alloc_function( rbjail_cBSDJail, )
   135 
   230 	
   136 	/*
       
   137 	rb_define_alloc_function( rbjail_cBSDJail, );
       
   138 
   231 	rb_define_method( rbjail_cBSDJail, "attach", rbjail_attach, -1 );
   139 	rb_define_method( rbjail_cBSDJail, "attach", rbjail_attach, -1 );
   232 	
   140 	*/
   233 }
   141 }
   234 
   142