author | Mahlon E. Smith <mahlon@martini.nu> |
Tue, 14 Oct 2008 16:11:19 +0000 | |
branch | mahlon-misc |
changeset 9 | 4c51ebe6e9b6 |
parent 0 | 92d00ff32c56 |
child 11 | e908d309e7ec |
permissions | -rw-r--r-- |
0 | 1 |
/* |
9
4c51ebe6e9b6
* Add a mkrf monkeypatch so BSD build flags are generated correctly.
Mahlon E. Smith <mahlon@martini.nu>
parents:
0
diff
changeset
|
2 |
* bsdjail.c - Ruby jparallel |
0 | 3 |
* $Id$ |
4 |
* |
|
5 |
* Authors: |
|
6 |
* * Michael Granger <ged@FaerieMUD.org> |
|
9
4c51ebe6e9b6
* Add a mkrf monkeypatch so BSD build flags are generated correctly.
Mahlon E. Smith <mahlon@martini.nu>
parents:
0
diff
changeset
|
7 |
* * Mahlon E. Smith <mahlon@martini.nu> |
0 | 8 |
* |
9 |
* Copyright (c) 2006 The FaerieMUD Consortium. |
|
10 |
* |
|
11 |
* This work is licensed under the Creative Commons Attribution License. To |
|
12 |
* view a copy of this license, visit |
|
13 |
* http://creativecommons.org/licenses/by/1.0 or send a letter to Creative |
|
14 |
* Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA. |
|
15 |
* |
|
16 |
*/ |
|
17 |
||
18 |
#include <ruby.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 |
||
28 |
VALUE rbjail_mBSD; |
|
29 |
VALUE rbjail_cBSDJail; |
|
30 |
||
31 |
||
32 |
/* |
|
33 |
struct jail { |
|
34 |
u_int32_t version; |
|
35 |
char *path; |
|
36 |
char *hostname; |
|
37 |
u_int32_t ip_number; |
|
38 |
}; |
|
39 |
*/ |
|
40 |
||
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 |
||
129 |
static void |
|
130 |
rbjail_do_jail_attach( int jid ) |
|
131 |
{ |
|
132 |
if ( jail_attach(jid) == -1 ) |
|
133 |
rb_sys_fail( "jail_attach" ); |
|
134 |
} |
|
135 |
||
136 |
/* Mostly ripped off from Ruby's process.c */ |
|
137 |
static VALUE |
|
138 |
rbjail_attach_block( int jid ) |
|
139 |
{ |
|
140 |
int pid; |
|
141 |
||
142 |
rb_secure(2); |
|
143 |
||
144 |
fflush(stdout); |
|
145 |
fflush(stderr); |
|
146 |
||
147 |
switch ( pid = fork() ) { |
|
148 |
case 0: |
|
149 |
rb_thread_atfork(); |
|
150 |
if ( rb_block_given_p() ) { |
|
151 |
int status; |
|
152 |
||
153 |
rbjail_do_jail_attach( jid ); |
|
154 |
rb_protect( rb_yield, Qundef, &status ); |
|
155 |
ruby_stop( status ); |
|
156 |
} |
|
157 |
return Qnil; |
|
158 |
||
159 |
case -1: |
|
160 |
rb_sys_fail( "fork(2)" ); |
|
161 |
return Qnil; |
|
162 |
||
163 |
default: |
|
164 |
return INT2FIX( pid ); |
|
165 |
} |
|
166 |
} |
|
167 |
||
168 |
static VALUE |
|
169 |
rbjail_attach( int argc, VALUE *argv, VALUE self ) |
|
170 |
{ |
|
171 |
VALUE jidnum, rval; |
|
172 |
int jid; |
|
173 |
||
174 |
rb_scan_args( argc, argv, "1", &jidnum ); |
|
175 |
jid = NUM2INT( jidnum ); |
|
176 |
||
177 |
if ( rb_block_given_p() ) { |
|
178 |
rval = rbjail_attach_block( jid ); |
|
179 |
} |
|
180 |
||
181 |
else { |
|
182 |
rbjail_do_jail_attach( jid ); |
|
183 |
rval = Qtrue; |
|
184 |
} |
|
185 |
||
186 |
return rval; |
|
187 |
} |
|
188 |
||
189 |
static VALUE |
|
190 |
rbjail_list( VALUE self ) |
|
191 |
{ |
|
192 |
struct kinfo_prison *sxp, *xp; |
|
193 |
struct in_addr in; |
|
194 |
size_t i, len; |
|
195 |
||
196 |
if (sysctlbyname("jail.list", NULL, &len, NULL, 0) == -1) |
|
197 |
rb_sys_fail("sysctlbyname(): jail.list"); |
|
198 |
||
199 |
xp = ALLOCA_N( kinfo_prison, 1 ); |
|
200 |
||
201 |
if (sysctlbyname("jail.list", xp, &len, NULL, 0) == -1) { |
|
202 |
rb_sys_fail("sysctlbyname(): jail.list"); |
|
203 |
} |
|
204 |
||
205 |
if (len < sizeof(*xp) || len % sizeof(*xp) || |
|
206 |
xp->pr_version != KINFO_PRISON_VERSION) |
|
207 |
rb_fatal("Kernel and userland out of sync"); |
|
208 |
||
209 |
len /= sizeof(*xp); |
|
210 |
printf(" JID IP Address Hostname Path\n"); |
|
211 |
for (i = 0; i < len; i++) { |
|
212 |
in.s_addr = ntohl(xp->pr_ip); |
|
213 |
printf("%6d %-15.15s %-29.29s %.74s\n", |
|
214 |
xp->pr_id, inet_ntoa(in), xp->pr_host, xp->pr_path); |
|
215 |
xp++; |
|
216 |
} |
|
217 |
free(sxp); |
|
218 |
exit(0); |
|
219 |
||
220 |
} |
|
221 |
||
222 |
void |
|
223 |
Init_bsdjail( void ) |
|
224 |
{ |
|
225 |
rbjail_mBSD = rb_define_module( "BSD" ); |
|
226 |
rbjail_cBSDJail = rb_define_class_under( rbjail_mBSD, "Jail" ); |
|
227 |
||
228 |
rb_define_singleton_method( rbjail_cBSDJail, "list", rbjail_list, 0 ); |
|
229 |
rb_define_alloc_function( rbjail_cBSDJail, ) |
|
230 |
||
231 |
rb_define_method( rbjail_cBSDJail, "attach", rbjail_attach, -1 ); |
|
232 |
||
233 |
} |
|
234 |