|
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 |