]>
Commit | Line | Data |
---|---|---|
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 | ||
35 | void | |
36 | ni_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 | ||
52 | int | |
53 | ni_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 | ||
74 | void | |
75 | ni_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 | ||
85 | ni_idlist | |
86 | ni_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 | ||
101 | void | |
102 | ni_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 | ||
118 | void | |
119 | ni_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 | ||
133 | void | |
134 | ni_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 | ||
150 | void | |
151 | ni_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 | ||
167 | ni_proplist | |
168 | ni_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 | ||
184 | ni_index | |
185 | ni_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 | ||
213 | ni_property | |
214 | ni_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 | ||
225 | void | |
226 | ni_prop_free( | |
227 | ni_property *prop | |
228 | ) | |
229 | { | |
230 | ni_name_free(&prop->nip_name); | |
231 | ni_namelist_free(&prop->nip_val); | |
232 | } | |
233 | ||
234 | int | |
235 | ni_name_match( | |
236 | ni_name_const nm1, | |
237 | ni_name_const nm2 | |
238 | ) | |
239 | { | |
240 | return (strcmp(nm1, nm2) == 0); | |
241 | } | |
242 | ||
243 | ni_name | |
244 | ni_name_dup( | |
245 | ni_name_const nm | |
246 | ) | |
247 | { | |
248 | return (strcpy(malloc(strlen(nm) + 1), nm)); | |
249 | } | |
250 | ||
251 | ||
252 | void | |
253 | ni_name_free( | |
254 | ni_name *nm | |
255 | ) | |
256 | { | |
257 | if (*nm != NULL) { | |
258 | free(*nm); | |
259 | *nm = NULL; | |
260 | } | |
261 | } | |
262 | ||
263 | ni_namelist | |
264 | ni_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 | ||
279 | void | |
280 | ni_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 | ||
296 | void | |
297 | ni_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 | ||
313 | void | |
314 | ni_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 | ||
328 | ni_index | |
329 | ni_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 | ||
344 | void | |
345 | ni_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 | ||
363 | void | |
364 | ni_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 | ||
380 | void | |
381 | ni_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 | */ | |
405 | ni_status | |
406 | ni_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 | */ | |
433 | ni_status | |
434 | ni_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 | ||
476 | ni_status | |
477 | ni_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 | } |