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