]>
Commit | Line | Data |
---|---|---|
1815bff5 A |
1 | /* |
2 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights | |
7 | * Reserved. This file contains Original Code and/or Modifications of | |
8 | * Original Code as defined in and that are subject to the Apple Public | |
9 | * Source License Version 1.0 (the 'License'). You may not use this file | |
10 | * except in compliance with the License. Please obtain a copy of the | |
11 | * License at http://www.apple.com/publicsource and read it before using | |
12 | * this file. | |
13 | * | |
14 | * The Original Code and all software distributed under the License are | |
15 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
16 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
17 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
18 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the | |
19 | * License for the specific language governing rights and limitations | |
20 | * under the License." | |
21 | * | |
22 | * @APPLE_LICENSE_HEADER_END@ | |
23 | */ | |
24 | #import "bootstrap.h" | |
25 | ||
26 | #import <mach.h> | |
27 | #import <stdarg.h> | |
28 | #import <stdio.h> | |
29 | #import <sys/boolean.h> | |
30 | ||
31 | #define NELEM(x) (sizeof(x)/sizeof(x[0])) | |
32 | #define LAST_ELEMENT(x) ((x)[NELEM(x)-1]) | |
33 | ||
34 | print(const char *format, ...) | |
35 | { | |
36 | va_list ap; | |
37 | ||
38 | va_start(ap, format); | |
39 | vfprintf(stderr, format, ap); | |
40 | fprintf(stderr, "\n"); | |
41 | va_end(ap); | |
42 | } | |
43 | ||
44 | error(const char *format, ...) | |
45 | { | |
46 | va_list ap; | |
47 | ||
48 | va_start(ap, format); | |
49 | fprintf(stderr, "ERROR: "); | |
50 | vfprintf(stderr, format, ap); | |
51 | fprintf(stderr, "\n"); | |
52 | va_end(ap); | |
53 | } | |
54 | ||
55 | ||
56 | main() | |
57 | { | |
58 | kern_return_t result; | |
59 | port_t bootstrap_port, port, myport; | |
60 | port_type_t ptype; | |
61 | port_t *mach_ports; | |
62 | port_t *ports; | |
63 | unsigned port_cnt; | |
64 | unsigned mach_ports_cnt; | |
65 | name_t name_array[4]; | |
66 | boolean_t all_known; | |
67 | port_t unpriv_port; | |
68 | port_t subset_port; | |
69 | port_t sub_reg_port; | |
70 | boolean_t active; | |
71 | name_array_t service_names; | |
72 | unsigned service_cnt, server_cnt, service_active_cnt; | |
73 | name_array_t server_names; | |
74 | boolean_t *service_actives; | |
75 | int i; | |
76 | ||
77 | print("test server running"); | |
78 | result = task_get_bootstrap_port(task_self(), &bootstrap_port); | |
79 | if (result != KERN_SUCCESS) { | |
80 | error("Couldn't get bootstrap port: %d", result); | |
81 | exit(1); | |
82 | } else | |
83 | print("Bootstrap port is %d", bootstrap_port); | |
84 | if (bootstrap_port == PORT_NULL) { | |
85 | error("Invalid bootstrap port"); | |
86 | exit(1); | |
87 | } | |
88 | ||
89 | /* | |
90 | * Try a checkin | |
91 | */ | |
92 | print("Checkin test 1"); | |
93 | result = bootstrap_check_in(bootstrap_port, "FreeService1", &port); | |
94 | if (result != BOOTSTRAP_SUCCESS) | |
95 | error("Checkin failed: %d", result); | |
96 | else { | |
97 | result = port_type(task_self(), port, &ptype); | |
98 | if (result != KERN_SUCCESS) | |
99 | error("port type failed: %d", result); | |
100 | else | |
101 | print("Checkin returned port type 0x%x", ptype); | |
102 | /* | |
103 | * Try a status request | |
104 | */ | |
105 | result = bootstrap_status(bootstrap_port, "FreeService1", &active); | |
106 | if (result != BOOTSTRAP_SUCCESS) | |
107 | error("Status failed: %d", result); | |
108 | else if (active != TRUE) | |
109 | error("Service shown inactive"); | |
110 | } | |
111 | ||
112 | /* | |
113 | * Try a lookup | |
114 | */ | |
115 | print("lookup test"); | |
116 | result = bootstrap_look_up(bootstrap_port, "FreeService2", &port); | |
117 | if (result != BOOTSTRAP_SUCCESS) | |
118 | error("lookup failed: %d", result); | |
119 | else { | |
120 | result = port_type(task_self(), port, &ptype); | |
121 | if (result != KERN_SUCCESS) | |
122 | error("port type failed: %d", result); | |
123 | else | |
124 | print("Lookup returned port type 0x%x", ptype); | |
125 | /* | |
126 | * Try a status request | |
127 | */ | |
128 | result = bootstrap_status(bootstrap_port, "FreeService2", &active); | |
129 | if (result != BOOTSTRAP_SUCCESS) | |
130 | error("Status failed: %d", result); | |
131 | else if (active != FALSE) | |
132 | error("Service shown active"); | |
133 | } | |
134 | ||
135 | /* | |
136 | * Test that mach ports are initialized | |
137 | */ | |
138 | print("mach ports test"); | |
139 | result = mach_ports_lookup(task_self(), &mach_ports, &mach_ports_cnt); | |
140 | if (result != KERN_SUCCESS) | |
141 | error("mach_ports_lookup failed: %d", result); | |
142 | else { | |
143 | result = bootstrap_look_up(bootstrap_port, "NetMsgService", &port); | |
144 | if (result != BOOTSTRAP_SUCCESS) | |
145 | error("Lookup of NetMsgService failed: %d", result); | |
146 | else if (port != mach_ports[0]) | |
147 | error("mach ports not setup correctly for NetMsgService"); | |
148 | ||
149 | result = bootstrap_look_up(bootstrap_port, "EnvironService", &port); | |
150 | if (result != BOOTSTRAP_SUCCESS) | |
151 | error("Lookup of EnvironService failed: %d", result); | |
152 | else if (port != mach_ports[1]) | |
153 | error("mach ports not setup correctly for EnvironService"); | |
154 | ||
155 | result = bootstrap_look_up(bootstrap_port, "Service", &port); | |
156 | if (result != BOOTSTRAP_SUCCESS) | |
157 | error("Lookup of Service failed: %d", result); | |
158 | else if (port != mach_ports[2]) | |
159 | error("mach ports not setup correctly for Service"); | |
160 | ||
161 | result = bootstrap_look_up(bootstrap_port, "WindowService", &port); | |
162 | if (result != BOOTSTRAP_SUCCESS) | |
163 | error("Lookup of WindowService failed: %d", result); | |
164 | else if (port != mach_ports[3]) | |
165 | error("mach ports not setup correctly for WindowService"); | |
166 | } | |
167 | ||
168 | /* | |
169 | * Try doing a checkin with the old service interface | |
170 | */ | |
171 | result = service_checkin(mach_ports[2], mach_ports[1], &myport); | |
172 | if (result != KERN_SUCCESS) | |
173 | error("service checkin failed: %d", result); | |
174 | else { | |
175 | result = port_type(task_self(), myport, &ptype); | |
176 | if (result != KERN_SUCCESS) | |
177 | error("port type failed: %d", result); | |
178 | else | |
179 | print("Checkin returned port type 0x%x", ptype); | |
180 | } | |
181 | ||
182 | /* | |
183 | * Try a register | |
184 | */ | |
185 | print("register test"); | |
186 | print("...Dynamic creation"); | |
187 | result = port_allocate(task_self(), &myport); | |
188 | if (result != KERN_SUCCESS) | |
189 | error("couldn't allocate port: %d", result); | |
190 | else { | |
191 | result = bootstrap_register(bootstrap_port, "NewService", myport); | |
192 | if (result != BOOTSTRAP_SUCCESS) | |
193 | error("Couldn't register port: %d", result); | |
194 | else { | |
195 | ||
196 | /* | |
197 | * Try a lookup on just registered port | |
198 | */ | |
199 | result = bootstrap_look_up(bootstrap_port, "NewService", &port); | |
200 | if (result != BOOTSTRAP_SUCCESS) | |
201 | error("lookup failed: %d", result); | |
202 | else { | |
203 | result = port_type(task_self(), port, &ptype); | |
204 | if (result != KERN_SUCCESS) | |
205 | error("port type failed: %d", result); | |
206 | else { | |
207 | print("Lookup returned port type 0x%x", ptype); | |
208 | if (port != myport) | |
209 | error("lookup didn't match register"); | |
210 | } | |
211 | } | |
212 | ||
213 | /* | |
214 | * Try re-registering service name | |
215 | */ | |
216 | result = bootstrap_register(bootstrap_port, "NewService", myport); | |
217 | if (result != BOOTSTRAP_SERVICE_ACTIVE) | |
218 | error("Unexpected register response: %d", result); | |
219 | ||
220 | /* | |
221 | * Delete the port. This should cause the service to go away | |
222 | * in the server. | |
223 | */ | |
224 | port_deallocate(task_self(), myport); | |
225 | ||
226 | result = bootstrap_look_up(bootstrap_port, "NewService", &port); | |
227 | if (result != BOOTSTRAP_UNKNOWN_SERVICE) | |
228 | error("service active after port deleted"); | |
229 | } | |
230 | } | |
231 | ||
232 | print("...Declared service"); | |
233 | result = port_allocate(task_self(), &myport); | |
234 | if (result != KERN_SUCCESS) | |
235 | error("couldn't allocate port: %d", result); | |
236 | else { | |
237 | result = bootstrap_register(bootstrap_port, "FreeService2", myport); | |
238 | if (result != BOOTSTRAP_SUCCESS) | |
239 | error("Couldn't register port: %d", result); | |
240 | else { | |
241 | ||
242 | /* | |
243 | * Try a lookup on just registered port | |
244 | */ | |
245 | result = bootstrap_look_up(bootstrap_port, "FreeService2", &port); | |
246 | if (result != BOOTSTRAP_SUCCESS) | |
247 | error("lookup failed: %d", result); | |
248 | else { | |
249 | result = port_type(task_self(), port, &ptype); | |
250 | if (result != KERN_SUCCESS) | |
251 | error("port type failed: %d", result); | |
252 | else { | |
253 | print("Lookup returned port type 0x%x", ptype); | |
254 | if (port != myport) | |
255 | error("lookup didn't match register"); | |
256 | } | |
257 | } | |
258 | ||
259 | /* | |
260 | * Delete the port. This should cause service to revert. | |
261 | */ | |
262 | port_deallocate(task_self(), myport); | |
263 | ||
264 | result = bootstrap_status(bootstrap_port, "FreeService2", &active); | |
265 | if (result != BOOTSTRAP_SUCCESS) | |
266 | error("Status failed: %d", result); | |
267 | else if (active != FALSE) | |
268 | error("Service shown active"); | |
269 | } | |
270 | } | |
271 | ||
272 | /* | |
273 | * Try a checkin on a port bound to Terminal server | |
274 | */ | |
275 | print("Bound checkin test -- Terminal"); | |
276 | result = bootstrap_check_in(bootstrap_port, "TerminalService", &port); | |
277 | if (result != BOOTSTRAP_SUCCESS) | |
278 | error("Checkin of TerminalService failed: %d", result); | |
279 | else { | |
280 | result = port_type(task_self(), port, &ptype); | |
281 | if (result != KERN_SUCCESS) | |
282 | error("port type failed: %d", result); | |
283 | print("Checkin returned port type 0x%x", ptype); | |
284 | } | |
285 | ||
286 | /* | |
287 | * Try a checkin on a port bound to Sleep server | |
288 | */ | |
289 | print("Bound checkin test -- Sleep"); | |
290 | result = bootstrap_check_in(bootstrap_port, "SleepService", &port); | |
291 | if (result != BOOTSTRAP_SUCCESS) | |
292 | print("Checkin of SleepService failed (as expected): %d", | |
293 | result); | |
294 | else { | |
295 | result = port_type(task_self(), port, &ptype); | |
296 | if (result != KERN_SUCCESS) | |
297 | error("port type failed: %d", result); | |
298 | error("Checkin returned port type 0x%x(didn't fail!)", ptype); | |
299 | } | |
300 | ||
301 | /* | |
302 | * Try a lookup_array | |
303 | */ | |
304 | print("Lookup array test"); | |
305 | ||
306 | strncpy(&name_array[0], "NetMsgService", sizeof(name_array[0])); | |
307 | LAST_ELEMENT(name_array[0]) = '\0'; | |
308 | strncpy(&name_array[1], "EnvironService", sizeof(name_array[1])); | |
309 | LAST_ELEMENT(name_array[1]) = '\0'; | |
310 | strncpy(&name_array[2], "Service", sizeof(name_array[2])); | |
311 | LAST_ELEMENT(name_array[2]) = '\0'; | |
312 | strncpy(&name_array[3], "WindowService", sizeof(name_array[3])); | |
313 | LAST_ELEMENT(name_array[3]) = '\0'; | |
314 | ||
315 | result = bootstrap_look_up_array(bootstrap_port, name_array, 4, &ports, | |
316 | &port_cnt, &all_known); | |
317 | if (result != BOOTSTRAP_SUCCESS) | |
318 | error("Lookup array failed: %d", result); | |
319 | else { | |
320 | print("Port count = %d, all known = %d", port_cnt, all_known); | |
321 | for (i = 0; i < 4; i++) | |
322 | if (ports[i] != mach_ports[i]) | |
323 | error("port mismatch on port %d", i); | |
324 | } | |
325 | ||
326 | /* | |
327 | * Get an unprivileged port | |
328 | */ | |
329 | print("Unprivileged port test"); | |
330 | result = port_allocate(task_self(), &myport); | |
331 | result = bootstrap_get_unpriv_port(bootstrap_port, &unpriv_port); | |
332 | if (result != BOOTSTRAP_SUCCESS) | |
333 | error("Couldn't get unpriv port: %d", result); | |
334 | else { | |
335 | /* | |
336 | * Try doing an unpriv operation | |
337 | */ | |
338 | result = bootstrap_look_up(unpriv_port, "FreeService2", &port); | |
339 | if (result != BOOTSTRAP_SUCCESS) | |
340 | error("lookup failed: %d", result); | |
341 | /* | |
342 | * Try doing a privileged operation | |
343 | */ | |
344 | result = bootstrap_register(unpriv_port, "ANewService", myport); | |
345 | if (result != BOOTSTRAP_NOT_PRIVILEGED) | |
346 | error("Unexpected register port response: %d", result); | |
347 | ||
348 | /* | |
349 | * Try creating a subset port. | |
350 | */ | |
351 | result = bootstrap_subset(unpriv_port, task_self(), | |
352 | &subset_port); | |
353 | if (result != BOOTSTRAP_SUCCESS) | |
354 | error("Couldn't get subset port from unpriv %d", | |
355 | result); | |
356 | } | |
357 | ||
358 | /* | |
359 | * Get a subset port. | |
360 | */ | |
361 | print("Subset port test"); | |
362 | result = bootstrap_subset(bootstrap_port, task_self(), &subset_port); | |
363 | if (result != BOOTSTRAP_SUCCESS) | |
364 | error("Couldn't get subset port: %d", result); | |
365 | else { | |
366 | ||
367 | /* | |
368 | * Register a port. | |
369 | */ | |
370 | result = port_allocate(task_self(), &sub_reg_port); | |
371 | if (result != KERN_SUCCESS) | |
372 | error("port_allocate of sub_reg_port failed %d", | |
373 | result); | |
374 | result = bootstrap_register(subset_port, "SubsetReg", | |
375 | sub_reg_port); | |
376 | if (result != BOOTSTRAP_SUCCESS) | |
377 | error("register of SubsetReg failed on subset port %d", | |
378 | result); | |
379 | /* | |
380 | * Check that port registered only in subset. | |
381 | */ | |
382 | result = bootstrap_status(bootstrap_port, "SubsetReg", | |
383 | &active); | |
384 | if (result != BOOTSTRAP_UNKNOWN_SERVICE) | |
385 | error("status of SubsetReg ok on bootstrap! %d", | |
386 | result); | |
387 | result = bootstrap_status(subset_port, "SubsetReg", | |
388 | &active); | |
389 | if (result != BOOTSTRAP_SUCCESS) | |
390 | error("status of SubsetReg failed on subset port %d", | |
391 | result); | |
392 | if (!active) | |
393 | error("SubsetReg isn't active"); | |
394 | ||
395 | ||
396 | /* | |
397 | * Try an info request. | |
398 | */ | |
399 | print("Subset info request"); | |
400 | result = bootstrap_info(subset_port, &service_names, | |
401 | &service_cnt, | |
402 | &server_names, &server_cnt, &service_actives, | |
403 | &service_active_cnt); | |
404 | if (result != BOOTSTRAP_SUCCESS) | |
405 | error("info failed: %d", result); | |
406 | else { | |
407 | for (i = 0; i < service_cnt; i++) | |
408 | print("Name: %s Server: %s Active: %s", | |
409 | service_names[i], | |
410 | server_names[i][0] == '\0' | |
411 | ? "Unknown" | |
412 | : server_names[i], | |
413 | service_actives[i] ? "Yes" : "No"); | |
414 | } | |
415 | } | |
416 | ||
417 | /* | |
418 | * Try an info request | |
419 | */ | |
420 | print("Info test"); | |
421 | result = bootstrap_info(bootstrap_port, &service_names, &service_cnt, | |
422 | &server_names, &server_cnt, &service_actives, &service_active_cnt); | |
423 | if (result != BOOTSTRAP_SUCCESS) | |
424 | error("info failed: %d", result); | |
425 | else { | |
426 | for (i = 0; i < service_cnt; i++) | |
427 | print("Name: %s Server: %s Active: %s", service_names[i], | |
428 | server_names[i][0] == '\0' ? "Unknown" : server_names[i], | |
429 | service_actives[i] ? "Yes" : "No"); | |
430 | } | |
431 | ||
432 | exit(0); | |
433 | } | |
434 | ||
435 | ||
436 |