]> git.saurik.com Git - apple/libinfo.git/blame - netinfo.subproj/ni_util.c
Libinfo-129.1.tar.gz
[apple/libinfo.git] / netinfo.subproj / ni_util.c
CommitLineData
03fb6eb0
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.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 * Utility routines for netinfo data structures
26 * Copyright (C) 1989 by NeXT, Inc.
27 */
28#include <netinfo/ni.h>
29#include <stdlib.h>
30#include <stdio.h>
31#include <strings.h>
32#include <regex.h>
33#include "mm.h"
34
35void
36ni_idlist_insert(
37 ni_idlist *cl,
38 ni_index id,
39 ni_index where
40 )
41{
42 ni_index i;
43
44 MM_GROW_ARRAY(cl->niil_val, cl->niil_len);
45 for (i = cl->niil_len; i > where; i--) {
46 cl->niil_val[i] = cl->niil_val[i - 1];
47 }
48 cl->niil_val[i] = id;
49 cl->niil_len++;
50}
51
52int
53ni_idlist_delete(
54 ni_idlist *idlist,
55 ni_index id
56 )
57{
58 ni_index j;
59 ni_index i;
60
61 for (i = 0; i < idlist->niil_len; i++) {
62 if (idlist->niil_val[i] == id) {
63 for (j = i + 1; j < idlist->niil_len; j++) {
64 idlist->niil_val[j - 1] = idlist->niil_val[j];
65 }
66 MM_SHRINK_ARRAY(idlist->niil_val, idlist->niil_len--);
67 return(1);
68 }
69 }
70 return (0);
71}
72
73
74void
75ni_idlist_free(
76 ni_idlist *idlist
77 )
78{
79 if (idlist->niil_val != NULL) {
80 MM_FREE_ARRAY(idlist->niil_val, idlist->niil_len);
81 }
82 NI_INIT(idlist);
83}
84
85ni_idlist
86ni_idlist_dup(
87 const ni_idlist idlist
88 )
89{
90 ni_idlist newlist;
91 ni_index i;
92
93 newlist.niil_len = idlist.niil_len;
94 MM_ALLOC_ARRAY(newlist.niil_val, idlist.niil_len);
95 for (i = 0; i < idlist.niil_len; i++) {
96 newlist.niil_val[i] = idlist.niil_val[i];
97 }
98 return (newlist);
99}
100
101void
102ni_proplist_insert(
103 ni_proplist *pl,
104 const ni_property prop,
105 ni_index where
106 )
107{
108 ni_index i;
109
110 MM_GROW_ARRAY(pl->nipl_val, pl->nipl_len);
111 for (i = pl->nipl_len; i > where; i--) {
112 pl->nipl_val[i] = pl->nipl_val[i - 1];
113 }
114 pl->nipl_val[i] = ni_prop_dup(prop);
115 pl->nipl_len++;
116}
117
118void
119ni_proplist_delete(
120 ni_proplist *pl,
121 ni_index which
122 )
123{
124 int i;
125
126 ni_prop_free(&pl->nipl_val[which]);
127 for (i = which + 1; i < pl->nipl_len; i++) {
128 pl->nipl_val[i - 1] = pl->nipl_val[i];
129 }
130 MM_SHRINK_ARRAY(pl->nipl_val, pl->nipl_len--);
131}
132
133void
134ni_proplist_free(
135 ni_proplist *pl
136 )
137{
138 ni_index i;
139
140 if (pl->nipl_val == NULL) {
141 return;
142 }
143 for (i = 0; i < pl->nipl_len; i++) {
144 ni_prop_free(&pl->nipl_val[i]);
145 }
146 MM_FREE_ARRAY(pl->nipl_val, pl->nipl_len);
147 NI_INIT(pl);
148}
149
150void
151ni_proplist_list_free(
152 ni_proplist_list *pll
153 )
154{
155 ni_index i;
156
157 if (pll->nipll_val == NULL) {
158 return;
159 }
160 for (i = 0; i < pll->nipll_len; i++) {
161 ni_proplist_free(&pll->nipll_val[i]);
162 }
163 MM_FREE_ARRAY(pll->nipll_val, pll->nipll_len);
164 NI_INIT(pll);
165}
166
167ni_proplist
168ni_proplist_dup(
169 const ni_proplist pl
170 )
171{
172 ni_proplist newlist;
173 ni_index i;
174
175 newlist.nipl_len = pl.nipl_len;
176 MM_ALLOC_ARRAY(newlist.nipl_val, pl.nipl_len);
177 for (i = 0; i < pl.nipl_len; i++) {
178 newlist.nipl_val[i].nip_name = ni_name_dup(pl.nipl_val[i].nip_name);
179 newlist.nipl_val[i].nip_val = ni_namelist_dup(pl.nipl_val[i].nip_val);
180 }
181 return (newlist);
182}
183
184ni_index
185ni_proplist_match(
186 const ni_proplist pl,
187 ni_name_const pname,
188 ni_name_const pval
189 )
190{
191 ni_index i;
192 ni_index j;
193 ni_namelist nl;
194
195 for (i = 0; i < pl.nipl_len; i++) {
196 if (ni_name_match(pname, pl.nipl_val[i].nip_name)) {
197 if (pval == NULL) {
198 return (i);
199 }
200 nl = pl.nipl_val[i].nip_val;
201 for (j = 0; j < nl.ninl_len; j++) {
202 if (ni_name_match(pval, nl.ninl_val[j])) {
203 return (i);
204 }
205 }
206 break;
207 }
208 }
209 return (NI_INDEX_NULL);
210}
211
212
213ni_property
214ni_prop_dup(
215 const ni_property prop
216 )
217{
218 ni_property newprop;
219
220 newprop.nip_name = ni_name_dup(prop.nip_name);
221 newprop.nip_val = ni_namelist_dup(prop.nip_val);
222 return (newprop);
223}
224
225void
226ni_prop_free(
227 ni_property *prop
228 )
229{
230 ni_name_free(&prop->nip_name);
231 ni_namelist_free(&prop->nip_val);
232}
233
234int
235ni_name_match(
236 ni_name_const nm1,
237 ni_name_const nm2
238 )
239{
240 return (strcmp(nm1, nm2) == 0);
241}
242
243ni_name
244ni_name_dup(
245 ni_name_const nm
246 )
247{
248 return (strcpy(malloc(strlen(nm) + 1), nm));
249}
250
251
252void
253ni_name_free(
254 ni_name *nm
255 )
256{
257 if (*nm != NULL) {
258 free(*nm);
259 *nm = NULL;
260 }
261}
262
263ni_namelist
264ni_namelist_dup(
265 const ni_namelist nl
266 )
267{
268 ni_namelist newlist;
269 ni_index i;
270
271 newlist.ninl_len = nl.ninl_len;
272 MM_ALLOC_ARRAY(newlist.ninl_val, newlist.ninl_len);
273 for (i = 0; i < nl.ninl_len; i++) {
274 newlist.ninl_val[i] = ni_name_dup(nl.ninl_val[i]);
275 }
276 return (newlist);
277}
278
279void
280ni_namelist_free(
281 ni_namelist *nl
282 )
283{
284 ni_index i;
285
286 if (nl->ninl_val == NULL) {
287 return;
288 }
289 for (i = 0; i < nl->ninl_len; i++) {
290 ni_name_free(&nl->ninl_val[i]);
291 }
292 MM_FREE_ARRAY(nl->ninl_val, nl->ninl_len);
293 NI_INIT(nl);
294}
295
296void
297ni_namelist_insert(
298 ni_namelist *nl,
299 ni_name_const nm,
300 ni_index where
301 )
302{
303 ni_index i;
304
305 MM_GROW_ARRAY(nl->ninl_val, nl->ninl_len);
306 for (i = nl->ninl_len; i > where; i--) {
307 nl->ninl_val[i] = nl->ninl_val[i - 1];
308 }
309 nl->ninl_val[i] = ni_name_dup(nm);
310 nl->ninl_len++;
311}
312
313void
314ni_namelist_delete(
315 ni_namelist *nl,
316 ni_index which
317 )
318{
319 int i;
320
321 ni_name_free(&nl->ninl_val[which]);
322 for (i = which + 1; i < nl-> ninl_len; i++) {
323 nl->ninl_val[i - 1] = nl->ninl_val[i];
324 }
325 MM_SHRINK_ARRAY(nl->ninl_val, nl->ninl_len--);
326}
327
328ni_index
329ni_namelist_match(
330 const ni_namelist nl,
331 ni_name_const nm
332 )
333{
334 ni_index i;
335
336 for (i = 0; i < nl.ninl_len; i++) {
337 if (ni_name_match(nl.ninl_val[i], nm)) {
338 return (i);
339 }
340 }
341 return (NI_INDEX_NULL);
342}
343
344void
345ni_entrylist_insert(
346 ni_entrylist *el,
347 const ni_entry en
348 )
349{
350 ni_entry entry;
351
352 MM_GROW_ARRAY(el->niel_val, el->niel_len);
353 entry.id = en.id;
354 if (en.names != NULL) {
355 MM_ALLOC(entry.names);
356 *entry.names = ni_namelist_dup(*en.names);
357 } else {
358 entry.names = NULL;
359 }
360 el->niel_val[el->niel_len++] = entry;
361}
362
363void
364ni_entrylist_delete(
365 ni_entrylist *el,
366 ni_index which
367 )
368{
369 int i;
370
371 if (el->niel_val[which].names != NULL) {
372 ni_namelist_free(el->niel_val[which].names);
373 }
374 for (i = which + 1; i < el-> niel_len; i++) {
375 el->niel_val[i - 1] = el->niel_val[i];
376 }
377 MM_SHRINK_ARRAY(el->niel_val, el->niel_len--);
378}
379
380void
381ni_entrylist_free(
382 ni_entrylist *el
383 )
384{
385 ni_index i;
386
387 if (el->niel_val == NULL) {
388 return;
389 }
390 for (i = 0; i < el->niel_len; i++) {
391 if (el->niel_val[i].names != NULL) {
392 ni_namelist_free(el->niel_val[i].names);
393 MM_FREE(el->niel_val[i].names);
394 }
395 }
396 MM_FREE_ARRAY(el->niel_val, el->niel_len);
397 NI_INIT(el);
398}
399
400
401
402/*
403 * We can do this without an addition to the protocol
404 */
405ni_status
406ni_lookupprop(
407 void *ni,
408 ni_id *id,
409 ni_name_const pname,
410 ni_namelist *nl
411 )
412{
413 ni_status status;
414 ni_namelist list;
415 ni_index which;
416
417 NI_INIT(&list);
418 status = ni_listprops(ni, id, &list);
419 if (status != NI_OK) {
420 return (status);
421 }
422 which = ni_namelist_match(list, pname);
423 ni_namelist_free(&list);
424 if (which == NI_INDEX_NULL) {
425 return (NI_NOPROP);
426 }
427 return (ni_readprop(ni, id, which, nl));
428}
429
430/*
431 * Search from local domain to root domain to locate a path.
432 */
433ni_status
434ni_find(void **dom, ni_id *nid, ni_name dirname, unsigned int timeout)
435{
436 void *d, *p;
437 ni_id n;
438 ni_status status;
3b7c7bd7 439 struct sockaddr_in addr;
03fb6eb0
A
440
441 *dom = NULL;
442 nid->nii_object = NI_INDEX_NULL;
443 nid->nii_instance = NI_INDEX_NULL;
444
3b7c7bd7
A
445 memset(&addr, 0, sizeof(struct sockaddr_in));
446 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
03fb6eb0 447
3b7c7bd7
A
448 d = ni_connect(&addr, "local");
449 if (d == NULL) return NI_FAILED;
03fb6eb0
A
450
451 while (d != NULL)
452 {
3b7c7bd7
A
453 if (timeout > 0)
454 {
455 ni_setreadtimeout(d, timeout);
456 ni_setabort(d, 1);
457 }
458
03fb6eb0
A
459 status = ni_pathsearch(d, &n, dirname);
460 if (status == NI_OK)
461 {
462 *dom = d;
463 *nid = n;
464 return NI_OK;
465 }
466
467 status = ni_open(d, "..", &p);
468 ni_free(d);
469 d = NULL;
470 if (status == NI_OK) d = p;
471 }
472
473 return NI_NODIR;
474}
475
476ni_status
477ni_search(void *handle, ni_id *dir, ni_name name, ni_name expr, int flags, ni_entrylist *entries)
478{
479 regex_t *cexp;
480 int i, j, found;
481 ni_entrylist el;
482 ni_namelist *nl;
483 ni_status status;
484
3b7c7bd7 485 /* compile the regular expression */
03fb6eb0
A
486 cexp = (regex_t *)malloc(sizeof(regex_t));
487 memset(cexp, 0, sizeof(regex_t));
488 i = regcomp(cexp, expr, flags);
c6f155da
A
489 if (i != 0)
490 {
491 free(cexp);
492 return NI_FAILED;
493 }
03fb6eb0 494
3b7c7bd7
A
495 /* get subdirectory list */
496 NI_INIT(&el);
497 status = ni_list(handle, dir, name, &el);
498 if (status != NI_OK)
499 {
500 regfree(cexp);
501 free(cexp);
502 return status;
503 }
504
03fb6eb0
A
505 for (i = 0; i < el.ni_entrylist_len; i++)
506 {
507 if (el.ni_entrylist_val[i].names == NULL) continue;
508
509 nl = el.ni_entrylist_val[i].names;
510
a0865d63 511 found = 0;
03fb6eb0
A
512 for (j = 0; j < nl->ni_namelist_len; j++)
513 {
03fb6eb0 514 if (regexec(cexp, nl->ni_namelist_val[j], 0, NULL, 0) != 0) continue;
03fb6eb0
A
515 found = 1;
516 break;
517 }
518
519 if (found == 0) continue;
520
521 if (entries->ni_entrylist_len == 0)
522 {
523 entries->ni_entrylist_val = malloc(sizeof(ni_entry));
524 }
525 else
526 {
527 entries->ni_entrylist_val = (ni_entry *)realloc(entries->ni_entrylist_val, (entries->ni_entrylist_len + 1) * sizeof(ni_entry));
528 }
529
530 entries->ni_entrylist_val[entries->ni_entrylist_len].id = el.ni_entrylist_val[i].id;
531 entries->ni_entrylist_val[entries->ni_entrylist_len].names = el.ni_entrylist_val[i].names;
532 el.ni_entrylist_val[i].names = NULL;
533 entries->ni_entrylist_len++;
534 }
535
536 ni_entrylist_free(&el);
c6f155da 537 regfree(cexp);
03fb6eb0
A
538 free(cexp);
539
540 return NI_OK;
541}