Libinfo-173.1.tar.gz
[apple/libinfo.git] / lookup.subproj / lu_bootparam.c
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.1 (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 /*
25 * Bootparams lookup - netinfo only
26 * Copyright (C) 1989 by NeXT, Inc.
27 */
28 #include <stdlib.h>
29 #include <mach/mach.h>
30 #include <stdio.h>
31 #include <string.h>
32 #include <rpc/types.h>
33 #include <rpc/xdr.h>
34 #include <bootparams.h>
35
36 #include "lookup.h"
37 #include "_lu_types.h"
38 #include "lu_utils.h"
39
40 static void
41 free_bootparams_data(struct bootparamsent *b)
42 {
43 char **param;
44
45 if (b == NULL) return;
46
47 if (b->bp_name != NULL) free(b->bp_name);
48
49 param = b->bp_bootparams;
50 if (param != NULL)
51 {
52 while (*param != NULL) free(*param++);
53 free(b->bp_bootparams);
54 }
55 }
56
57 static void
58 free_bootparams(struct bootparamsent *b)
59 {
60 if (b == NULL) return;
61 free_bootparams_data(b);
62 free(b);
63 }
64
65 static void
66 free_lu_thread_info_bootparams(void *x)
67 {
68 struct lu_thread_info *tdata;
69
70 if (x == NULL) return;
71
72 tdata = (struct lu_thread_info *)x;
73
74 if (tdata->lu_entry != NULL)
75 {
76 free_bootparams((struct bootparamsent *)tdata->lu_entry);
77 tdata->lu_entry = NULL;
78 }
79
80 _lu_data_free_vm_xdr(tdata);
81
82 free(tdata);
83 }
84
85 static struct bootparamsent *
86 extract_bootparams(XDR *xdr)
87 {
88 int i, j, nkeys, nvals, status;
89 char *key, **vals;
90 struct bootparamsent *b;
91
92 if (xdr == NULL) return NULL;
93
94 if (!xdr_int(xdr, &nkeys)) return NULL;
95
96 b = (struct bootparamsent *)calloc(1, sizeof(struct bootparamsent));
97
98 for (i = 0; i < nkeys; i++)
99 {
100 key = NULL;
101 vals = NULL;
102 nvals = 0;
103
104 status = _lu_xdr_attribute(xdr, &key, &vals, &nvals);
105 if (status < 0)
106 {
107 free_bootparams(b);
108 return NULL;
109 }
110
111 if (nvals == 0)
112 {
113 free(key);
114 continue;
115 }
116
117 j = 0;
118
119 if ((b->bp_name == NULL) && (!strcmp("name", key)))
120 {
121 b->bp_name = vals[0];
122 j = 1;
123 }
124 else if ((b->bp_bootparams == NULL) && (!strcmp("bootparams", key)))
125 {
126 b->bp_bootparams = vals;
127 j = nvals;
128 vals = NULL;
129 }
130
131 free(key);
132 if (vals != NULL)
133 {
134 for (; j < nvals; j++) free(vals[j]);
135 free(vals);
136 }
137 }
138
139 if (b->bp_name == NULL) b->bp_name = strdup("");
140 if (b->bp_bootparams == NULL) b->bp_bootparams = (char **)calloc(1, sizeof(char *));
141
142 return b;
143 }
144
145 static void
146 recycle_bootparams(struct lu_thread_info *tdata, struct bootparamsent *in)
147 {
148 struct bootparamsent *b;
149
150 if (tdata == NULL) return;
151 b = (struct bootparamsent *)tdata->lu_entry;
152
153 if (in == NULL)
154 {
155 free_bootparams(b);
156 tdata->lu_entry = NULL;
157 }
158
159 if (tdata->lu_entry == NULL)
160 {
161 tdata->lu_entry = in;
162 return;
163 }
164
165 free_bootparams_data(b);
166
167 b->bp_name = in->bp_name;
168 b->bp_bootparams = in->bp_bootparams;
169
170 free(in);
171 }
172
173 static struct bootparamsent *
174 lu_bootparams_getbyname(const char *name)
175 {
176 struct bootparamsent *b;
177 unsigned datalen;
178 char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT];
179 char *lookup_buf;
180 XDR outxdr;
181 XDR inxdr;
182 int size;
183 static int proc = -1;
184 int count;
185
186 if (proc < 0)
187 {
188 if (_lookup_link(_lu_port, "bootparams_getbyname", &proc)
189 != KERN_SUCCESS)
190 {
191 return (NULL);
192 }
193 }
194
195 xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE);
196 if (!xdr__lu_string(&outxdr, (_lu_string *)&name))
197 {
198 xdr_destroy(&outxdr);
199 return (NULL);
200 }
201
202 size = xdr_getpos(&outxdr);
203 xdr_destroy(&outxdr);
204
205 datalen = 0;
206 lookup_buf = NULL;
207
208 if (_lookup_all(_lu_port, proc, (unit *)namebuf, size, &lookup_buf,
209 &datalen) != KERN_SUCCESS)
210 {
211 return (NULL);
212 }
213
214 datalen *= BYTES_PER_XDR_UNIT;
215 if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
216
217 xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
218
219 count = 0;
220 if (!xdr_int(&inxdr, &count))
221 {
222 xdr_destroy(&inxdr);
223 vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
224 return NULL;
225 }
226
227 if (count == 0)
228 {
229 xdr_destroy(&inxdr);
230 vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
231 return NULL;
232 }
233
234 b = extract_bootparams(&inxdr);
235 xdr_destroy(&inxdr);
236 vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
237
238 return b;
239 }
240
241 static void
242 lu_bootparams_endent(void)
243 {
244 struct lu_thread_info *tdata;
245
246 tdata = _lu_data_create_key(_lu_data_key_bootparams, free_lu_thread_info_bootparams);
247 _lu_data_free_vm_xdr(tdata);
248 }
249
250 static void
251 lu_bootparams_setent(void)
252 {
253 lu_bootparams_endent();
254 }
255
256 static struct bootparamsent *
257 lu_bootparams_getent(void)
258 {
259 struct bootparamsent *b;
260 static int proc = -1;
261 struct lu_thread_info *tdata;
262
263 tdata = _lu_data_create_key(_lu_data_key_bootparams, free_lu_thread_info_bootparams);
264 if (tdata == NULL)
265 {
266 tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
267 _lu_data_set_key(_lu_data_key_bootparams, tdata);
268 }
269
270 if (tdata->lu_vm == NULL)
271 {
272 if (proc < 0)
273 {
274 if (_lookup_link(_lu_port, "bootparams_getent", &proc) != KERN_SUCCESS)
275 {
276 lu_bootparams_endent();
277 return NULL;
278 }
279 }
280
281 if (_lookup_all(_lu_port, proc, NULL, 0, &(tdata->lu_vm), &(tdata->lu_vm_length)) != KERN_SUCCESS)
282 {
283 lu_bootparams_endent();
284 return NULL;
285 }
286
287 /* mig stubs measure size in words (4 bytes) */
288 tdata->lu_vm_length *= 4;
289
290 if (tdata->lu_xdr != NULL)
291 {
292 xdr_destroy(tdata->lu_xdr);
293 free(tdata->lu_xdr);
294 }
295 tdata->lu_xdr = (XDR *)calloc(1, sizeof(XDR));
296
297 xdrmem_create(tdata->lu_xdr, tdata->lu_vm, tdata->lu_vm_length, XDR_DECODE);
298 if (!xdr_int(tdata->lu_xdr, &tdata->lu_vm_cursor))
299 {
300 lu_bootparams_endent();
301 return NULL;
302 }
303 }
304
305 if (tdata->lu_vm_cursor == 0)
306 {
307 lu_bootparams_endent();
308 return NULL;
309 }
310
311 b = extract_bootparams(tdata->lu_xdr);
312 if (b == NULL)
313 {
314 lu_bootparams_endent();
315 return NULL;
316 }
317
318 tdata->lu_vm_cursor--;
319
320 return b;
321 }
322
323 struct bootparamsent *
324 bootparams_getbyname(const char *name)
325 {
326 struct bootparamsent *res;
327 struct lu_thread_info *tdata;
328
329 tdata = _lu_data_create_key(_lu_data_key_bootparams, free_lu_thread_info_bootparams);
330 if (tdata == NULL)
331 {
332 tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
333 _lu_data_set_key(_lu_data_key_bootparams, tdata);
334 }
335
336 if (_lu_running())
337 {
338 res = lu_bootparams_getbyname(name);
339 recycle_bootparams(tdata, res);
340 return (struct bootparamsent *)tdata->lu_entry;
341 }
342
343 return NULL;
344 }
345
346 struct bootparamsent *
347 bootparams_getent(void)
348 {
349 struct bootparamsent *res;
350 struct lu_thread_info *tdata;
351
352 tdata = _lu_data_create_key(_lu_data_key_bootparams, free_lu_thread_info_bootparams);
353 if (tdata == NULL)
354 {
355 tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
356 _lu_data_set_key(_lu_data_key_bootparams, tdata);
357 }
358
359 if (_lu_running())
360 {
361 res = lu_bootparams_getent();
362 recycle_bootparams(tdata, res);
363 return (struct bootparamsent *)tdata->lu_entry;
364 }
365
366 return NULL;
367 }
368
369 void
370 bootparams_setent(void)
371 {
372 if (_lu_running()) lu_bootparams_setent();
373 }
374
375 void
376 bootparams_endent(void)
377 {
378 if (_lu_running()) lu_bootparams_endent();
379 }