2 * Copyright (c) 2008-2009 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
33 #include <sys/param.h>
35 #include <arpa/inet.h>
36 #include "si_module.h"
38 #define _PATH_SI_CONF "/etc/sysinfo.conf"
40 #define SEARCH_FLAG_MAC 0x00000001
41 #define SEARCH_FLAG_APPLETV 0x00000002
42 #define SEARCH_FLAG_IPHONE 0x00000004
43 #define SEARCH_FLAG_CACHE_ENABLED 0x00010000
55 search_list_t search_list
[CATEGORY_COUNT
];
61 } search_si_private_t
;
63 __private_extern__
void si_cache_add_item(si_mod_t
*si
, si_mod_t
*src
, si_item_t
*item
);
64 __private_extern__
void si_cache_add_list(si_mod_t
*si
, si_mod_t
*src
, si_list_t
*list
);
66 __private_extern__
char **_fsi_tokenize(char *data
, const char *sep
, int trailing_empty
, int *ntokens
);
67 __private_extern__
char *_fsi_get_line(FILE *fp
);
70 extern int _ds_running();
72 static inline int _ds_running(void) { return 0; }
75 static __attribute__((noinline
)) si_mod_t
*
76 search_get_module(search_si_private_t
*pp
, int cat
, int *n
)
80 if ((pp
== NULL
) || (n
== NULL
)) return NULL
;
85 /* Use custom search list if available */
86 if (x
< pp
->search_list
[cat
].count
)
88 return pp
->search_list
[cat
].module[x
];
94 * 2) DS if available, otherwise flat files
95 * 3) mdns (for host lookups only)
99 case 0: return pp
->cache
;
100 case 1: if (_ds_running()) return pp
->ds
;
101 else return pp
->file
;
102 case 2: return pp
->mdns
;
103 default: return NULL
;
108 search_cat_cache(search_si_private_t
*pp
, int cat
)
110 if (pp
== NULL
) return NULL
;
111 if ((cat
< 0) || (cat
> CATEGORY_COUNT
)) return NULL
;
113 if (pp
->search_list
[cat
].count
> 0)
115 if (pp
->search_list
[cat
].flags
& SEARCH_FLAG_CACHE_ENABLED
) return pp
->cache
;
119 if ((pp
->flags
& SEARCH_FLAG_MAC
) || (pp
->flags
& SEARCH_FLAG_APPLETV
) || (pp
->flags
& SEARCH_FLAG_IPHONE
)) return pp
->cache
;
124 search_close(si_mod_t
*si
)
127 search_si_private_t
*pp
;
129 if (si
== NULL
) return;
130 if (si
->private == NULL
) return;
132 pp
= (search_si_private_t
*)si
->private;
134 si_module_release(pp
->cache
);
135 si_module_release(pp
->file
);
136 si_module_release(pp
->dns
);
137 si_module_release(pp
->mdns
);
138 si_module_release(pp
->ds
);
140 for (i
= 0; i
< CATEGORY_COUNT
; i
++)
142 if (pp
->search_list
[i
].module != NULL
)
144 free(pp
->search_list
[i
].module);
145 pp
->search_list
[i
].module = NULL
;
146 pp
->search_list
[i
].count
= 0;
147 pp
->search_list
[i
].flags
= 0;
155 search_item_byname(si_mod_t
*si
, const char *name
, int cat
, si_item_t
*(*call
)(si_mod_t
*, const char *))
158 search_si_private_t
*pp
;
162 if (si
== NULL
) return NULL
;
163 if (call
== NULL
) return NULL
;
165 pp
= (search_si_private_t
*)si
->private;
166 if (pp
== NULL
) return NULL
;
170 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
172 item
= call(src
, name
);
175 si_cache_add_item(search_cat_cache(pp
, cat
), src
, item
);
184 search_item_bynumber(si_mod_t
*si
, uint32_t number
, int cat
, si_item_t
*(*call
)(si_mod_t
*, uint32_t))
187 search_si_private_t
*pp
;
191 if (si
== NULL
) return NULL
;
192 if (call
== NULL
) return NULL
;
194 pp
= (search_si_private_t
*)si
->private;
195 if (pp
== NULL
) return NULL
;
199 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
201 item
= call(src
, number
);
204 si_cache_add_item(search_cat_cache(pp
, cat
), src
, item
);
213 search_list(si_mod_t
*si
, int cat
, si_list_t
*(*call
)(si_mod_t
*))
216 search_si_private_t
*pp
;
217 si_list_t
*list
, *all
;
218 si_mod_t
*cache
, *src
;
220 if (si
== NULL
) return NULL
;
221 if (call
== NULL
) return NULL
;
223 pp
= (search_si_private_t
*)si
->private;
224 if (pp
== NULL
) return NULL
;
226 cache
= search_cat_cache(pp
, cat
);
230 if (list
!= NULL
) return list
;
237 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
239 if (src
== pp
->cache
) continue;
242 if (list
== NULL
) continue;
244 all
= si_list_concat(all
, list
);
245 si_list_release(list
);
248 si_cache_add_list(cache
, si
, all
);
252 __private_extern__ si_item_t
*
253 search_user_byname(si_mod_t
*si
, const char *name
)
255 return search_item_byname(si
, name
, CATEGORY_USER
, si_user_byname
);
258 __private_extern__ si_item_t
*
259 search_user_byuid(si_mod_t
*si
, uid_t uid
)
261 return search_item_bynumber(si
, (uint32_t)uid
, CATEGORY_USER
, si_user_byuid
);
264 __private_extern__ si_list_t
*
265 search_user_all(si_mod_t
*si
)
267 return search_list(si
, CATEGORY_USER
, si_user_all
);
270 __private_extern__ si_item_t
*
271 search_group_byname(si_mod_t
*si
, const char *name
)
273 return search_item_byname(si
, name
, CATEGORY_GROUP
, si_group_byname
);
276 __private_extern__ si_item_t
*
277 search_group_bygid(si_mod_t
*si
, gid_t gid
)
279 return search_item_bynumber(si
, (uint32_t)gid
, CATEGORY_USER
, si_group_bygid
);
282 __private_extern__ si_list_t
*
283 search_group_all(si_mod_t
*si
)
285 return search_list(si
, CATEGORY_GROUP
, si_group_all
);
288 __private_extern__ si_item_t
*
289 search_groupist(si_mod_t
*si
, const char *name
)
291 return search_item_byname(si
, name
, CATEGORY_GROUPLIST
, si_grouplist
);
294 __private_extern__ si_list_t
*
295 search_netgroup_byname(si_mod_t
*si
, const char *name
)
298 search_si_private_t
*pp
;
299 si_list_t
*list
, *all
;
300 si_mod_t
*cache
, *src
;
302 if (si
== NULL
) return NULL
;
304 pp
= (search_si_private_t
*)si
->private;
305 if (pp
== NULL
) return NULL
;
307 cat
= CATEGORY_NETGROUP
;
309 cache
= search_cat_cache(pp
, cat
);
312 list
= si_netgroup_byname(cache
, name
);
313 if (list
!= NULL
) return list
;
319 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
321 if (src
== pp
->cache
) continue;
323 list
= si_netgroup_byname(src
, name
);
324 if (list
== NULL
) continue;
326 all
= si_list_concat(all
, list
);
327 si_list_release(list
);
330 si_cache_add_list(cache
, si
, all
);
334 __private_extern__
int
335 search_in_netgroup(si_mod_t
*si
, const char *group
, const char *host
, const char *user
, const char *domain
)
338 search_si_private_t
*pp
;
341 if (si
== NULL
) return 0;
343 pp
= (search_si_private_t
*)si
->private;
344 if (pp
== NULL
) return 0;
346 cat
= CATEGORY_NETGROUP
;
350 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
352 innetgr
= si_in_netgroup(src
, group
, host
, user
, domain
);
353 if (innetgr
!= 0) return 1;
359 __private_extern__ si_item_t
*
360 search_alias_byname(si_mod_t
*si
, const char *name
)
362 return search_item_byname(si
, name
, CATEGORY_ALIAS
, si_alias_byname
);
365 __private_extern__ si_list_t
*
366 search_alias_all(si_mod_t
*si
)
368 return search_list(si
, CATEGORY_ALIAS
, si_alias_all
);
371 __private_extern__ si_item_t
*
372 search_host_byname(si_mod_t
*si
, const char *name
, int af
, const char *interface
, uint32_t *err
)
375 search_si_private_t
*pp
;
379 if (err
!= NULL
) *err
= SI_STATUS_NO_ERROR
;
381 if ((si
== NULL
) || (name
== NULL
))
383 if (err
!= NULL
) *err
= SI_STATUS_H_ERRNO_NO_RECOVERY
;
387 pp
= (search_si_private_t
*)si
->private;
390 if (err
!= NULL
) *err
= SI_STATUS_H_ERRNO_NO_RECOVERY
;
394 cat
= CATEGORY_HOST_IPV4
;
395 if (af
== AF_INET6
) cat
= CATEGORY_HOST_IPV6
;
399 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
401 item
= si_host_byname(src
, name
, af
, interface
, err
);
404 si_cache_add_item(search_cat_cache(pp
, cat
), src
, item
);
409 if (err
!= NULL
) *err
= SI_STATUS_H_ERRNO_HOST_NOT_FOUND
;
413 __private_extern__ si_item_t
*
414 search_host_byaddr(si_mod_t
*si
, const void *addr
, int af
, const char *interface
, uint32_t *err
)
417 search_si_private_t
*pp
;
421 if (err
!= NULL
) *err
= SI_STATUS_NO_ERROR
;
423 if ((si
== NULL
) || (addr
== NULL
))
425 if (err
!= NULL
) *err
= SI_STATUS_H_ERRNO_NO_RECOVERY
;
429 pp
= (search_si_private_t
*)si
->private;
432 if (err
!= NULL
) *err
= SI_STATUS_H_ERRNO_NO_RECOVERY
;
436 cat
= CATEGORY_HOST_IPV4
;
437 if (af
== AF_INET6
) cat
= CATEGORY_HOST_IPV6
;
441 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
443 item
= si_host_byaddr(src
, addr
, af
, interface
, err
);
446 si_cache_add_item(search_cat_cache(pp
, cat
), src
, item
);
451 if (err
!= NULL
) *err
= SI_STATUS_H_ERRNO_HOST_NOT_FOUND
;
455 __private_extern__ si_list_t
*
456 search_host_all(si_mod_t
*si
)
458 return search_list(si
, CATEGORY_HOST
, si_host_all
);
461 __private_extern__ si_item_t
*
462 search_network_byname(si_mod_t
*si
, const char *name
)
464 return search_item_byname(si
, name
, CATEGORY_NETWORK
, si_network_byname
);
467 __private_extern__ si_item_t
*
468 search_network_byaddr(si_mod_t
*si
, uint32_t addr
)
470 return search_item_bynumber(si
, addr
, CATEGORY_NETWORK
, si_network_byaddr
);
473 __private_extern__ si_list_t
*
474 search_network_all(si_mod_t
*si
)
476 return search_list(si
, CATEGORY_NETWORK
, si_network_all
);
479 __private_extern__ si_item_t
*
480 search_service_byname(si_mod_t
*si
, const char *name
, const char *proto
)
484 search_si_private_t
*pp
;
487 if (si
== NULL
) return NULL
;
488 if (name
== NULL
) return NULL
;
490 pp
= (search_si_private_t
*)si
->private;
491 if (pp
== NULL
) return NULL
;
493 cat
= CATEGORY_SERVICE
;
496 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
498 item
= si_service_byname(src
, name
, proto
);
501 si_cache_add_item(search_cat_cache(pp
, cat
), src
, item
);
509 __private_extern__ si_item_t
*
510 search_service_byport(si_mod_t
*si
, int port
, const char *proto
)
513 search_si_private_t
*pp
;
517 if (si
== NULL
) return NULL
;
519 pp
= (search_si_private_t
*)si
->private;
520 if (pp
== NULL
) return NULL
;
522 cat
= CATEGORY_SERVICE
;
525 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
527 item
= si_service_byport(src
, port
, proto
);
530 si_cache_add_item(search_cat_cache(pp
, cat
), src
, item
);
538 __private_extern__ si_list_t
*
539 search_service_all(si_mod_t
*si
)
541 return search_list(si
, CATEGORY_SERVICE
, si_service_all
);
544 __private_extern__ si_item_t
*
545 search_protocol_byname(si_mod_t
*si
, const char *name
)
547 return search_item_byname(si
, name
, CATEGORY_PROTOCOL
, si_protocol_byname
);
550 __private_extern__ si_item_t
*
551 search_protocol_bynumber(si_mod_t
*si
, int number
)
553 return search_item_bynumber(si
, (uint32_t)number
, CATEGORY_PROTOCOL
, si_protocol_bynumber
);
556 __private_extern__ si_list_t
*
557 search_protocol_all(si_mod_t
*si
)
559 return search_list(si
, CATEGORY_PROTOCOL
, si_protocol_all
);
562 __private_extern__ si_item_t
*
563 search_rpc_byname(si_mod_t
*si
, const char *name
)
565 return search_item_byname(si
, name
, CATEGORY_RPC
, si_rpc_byname
);
568 __private_extern__ si_item_t
*
569 search_rpc_bynumber(si_mod_t
*si
, int number
)
572 search_si_private_t
*pp
;
576 if (si
== NULL
) return NULL
;
578 pp
= (search_si_private_t
*)si
->private;
579 if (pp
== NULL
) return NULL
;
584 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
586 item
= si_rpc_bynumber(src
, number
);
589 si_cache_add_item(search_cat_cache(pp
, cat
), src
, item
);
597 __private_extern__ si_list_t
*
598 search_rpc_all(si_mod_t
*si
)
600 return search_list(si
, CATEGORY_RPC
, si_rpc_all
);
603 __private_extern__ si_item_t
*
604 search_fs_byspec(si_mod_t
*si
, const char *name
)
606 return search_item_byname(si
, name
, CATEGORY_FS
, si_fs_byspec
);
609 __private_extern__ si_item_t
*
610 search_fs_byfile(si_mod_t
*si
, const char *name
)
612 return search_item_byname(si
, name
, CATEGORY_FS
, si_fs_byfile
);
615 __private_extern__ si_list_t
*
616 search_fs_all(si_mod_t
*si
)
618 return search_list(si
, CATEGORY_FS
, si_fs_all
);
621 __private_extern__ si_item_t
*
622 search_mac_byname(si_mod_t
*si
, const char *name
)
624 return search_item_byname(si
, name
, CATEGORY_MAC
, si_mac_byname
);
627 __private_extern__ si_item_t
*
628 search_mac_bymac(si_mod_t
*si
, const char *mac
)
630 return search_item_byname(si
, mac
, CATEGORY_MAC
, si_mac_bymac
);
633 __private_extern__ si_list_t
*
634 search_mac_all(si_mod_t
*si
)
636 return search_list(si
, CATEGORY_MAC
, si_mac_all
);
639 __private_extern__ si_list_t
*
640 search_srv_byname(si_mod_t
*si
, const char* qname
, const char *interface
, uint32_t *err
)
643 si_list_t
*list
= NULL
;
645 search_si_private_t
*pp
;
647 if (si
== NULL
) return NULL
;
649 pp
= (search_si_private_t
*)si
->private;
650 if (pp
== NULL
) return NULL
;
655 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
657 if (src
== pp
->cache
) continue;
659 if (src
->sim_srv_byname
!= NULL
)
661 list
= src
->sim_srv_byname(src
, qname
, interface
, err
);
662 if (list
!= NULL
) return list
;
666 if ((i
> 0) && (err
!= NULL
)) *err
= SI_STATUS_EAI_NONAME
;
670 __private_extern__
int
671 search_wants_addrinfo(si_mod_t
*si
)
675 search_si_private_t
*pp
;
677 if (si
== NULL
) return 0;
679 pp
= (search_si_private_t
*)si
->private;
680 if (pp
== NULL
) return 0;
682 cat
= CATEGORY_ADDRINFO
;
685 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
687 if (src
== pp
->cache
) continue;
688 if (src
->sim_addrinfo
!= NULL
) return 1;
694 __private_extern__ si_list_t
*
695 search_addrinfo(si_mod_t
*si
, const void *node
, const void *serv
, uint32_t family
, uint32_t socktype
, uint32_t protocol
, uint32_t flags
, const char *interface
, uint32_t *err
)
698 search_si_private_t
*pp
;
699 si_list_t
*list
= NULL
;
702 if (err
!= NULL
) *err
= SI_STATUS_EAI_FAIL
;
704 if (si
== NULL
) return NULL
;
706 pp
= (search_si_private_t
*)si
->private;
707 if (pp
== NULL
) return NULL
;
709 cat
= CATEGORY_ADDRINFO
;
712 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
714 if (src
== pp
->cache
) continue;
716 if (src
->sim_addrinfo
!= NULL
)
718 list
= src
->sim_addrinfo(src
, node
, serv
, family
, socktype
, protocol
, flags
, interface
, err
);
719 if (list
!= NULL
) return list
;
723 if ((i
> 0) && (err
!= NULL
)) *err
= SI_STATUS_EAI_NONAME
;
727 __private_extern__ si_item_t
*
728 search_nameinfo(si_mod_t
*si
, const struct sockaddr
*sa
, int flags
, const char *interface
, uint32_t *err
)
731 search_si_private_t
*pp
;
735 if (err
!= NULL
) *err
= SI_STATUS_EAI_FAIL
;
737 if (si
== NULL
) return NULL
;
739 pp
= (search_si_private_t
*)si
->private;
740 if (pp
== NULL
) return NULL
;
742 cat
= CATEGORY_NAMEINFO
;
745 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
747 item
= si_nameinfo(src
, sa
, flags
, interface
, err
);
750 si_cache_add_item(search_cat_cache(pp
, cat
), src
, item
);
751 if (err
!= NULL
) *err
= SI_STATUS_NO_ERROR
;
756 if ((i
> 0) && (err
!= NULL
)) *err
= SI_STATUS_EAI_NONAME
;
760 __private_extern__
int
761 search_is_valid(si_mod_t
*si
, si_item_t
*item
)
765 if (si
== NULL
) return 0;
766 if (item
== NULL
) return 0;
767 if (si
->name
== NULL
) return 0;
768 if (item
->src
== NULL
) return 0;
770 src
= (si_mod_t
*)item
->src
;
772 if (src
->name
== NULL
) return 0;
773 if (string_not_equal(si
->name
, src
->name
)) return 0;
782 search_si_private_t
*pp
;
784 out
= (si_mod_t
*)calloc(1, sizeof(si_mod_t
));
785 outname
= strdup("search");
786 pp
= (search_si_private_t
*)calloc(1, sizeof(search_si_private_t
));
788 if ((out
== NULL
) || (outname
== NULL
) || (pp
== NULL
))
790 if (out
!= NULL
) free(out
);
791 if (outname
!= NULL
) free(outname
);
792 if (pp
!= NULL
) free(pp
);
803 out
->sim_close
= search_close
;
805 out
->sim_is_valid
= search_is_valid
;
807 out
->sim_user_byname
= search_user_byname
;
808 out
->sim_user_byuid
= search_user_byuid
;
809 out
->sim_user_all
= search_user_all
;
811 out
->sim_group_byname
= search_group_byname
;
812 out
->sim_group_bygid
= search_group_bygid
;
813 out
->sim_group_all
= search_group_all
;
815 out
->sim_grouplist
= search_groupist
;
817 out
->sim_netgroup_byname
= search_netgroup_byname
;
818 out
->sim_in_netgroup
= search_in_netgroup
;
820 out
->sim_alias_byname
= search_alias_byname
;
821 out
->sim_alias_all
= search_alias_all
;
823 out
->sim_host_byname
= search_host_byname
;
824 out
->sim_host_byaddr
= search_host_byaddr
;
825 out
->sim_host_all
= search_host_all
;
827 out
->sim_network_byname
= search_network_byname
;
828 out
->sim_network_byaddr
= search_network_byaddr
;
829 out
->sim_network_all
= search_network_all
;
831 out
->sim_service_byname
= search_service_byname
;
832 out
->sim_service_byport
= search_service_byport
;
833 out
->sim_service_all
= search_service_all
;
835 out
->sim_protocol_byname
= search_protocol_byname
;
836 out
->sim_protocol_bynumber
= search_protocol_bynumber
;
837 out
->sim_protocol_all
= search_protocol_all
;
839 out
->sim_rpc_byname
= search_rpc_byname
;
840 out
->sim_rpc_bynumber
= search_rpc_bynumber
;
841 out
->sim_rpc_all
= search_rpc_all
;
843 out
->sim_fs_byspec
= search_fs_byspec
;
844 out
->sim_fs_byfile
= search_fs_byfile
;
845 out
->sim_fs_all
= search_fs_all
;
847 out
->sim_mac_byname
= search_mac_byname
;
848 out
->sim_mac_bymac
= search_mac_bymac
;
849 out
->sim_mac_all
= search_mac_all
;
851 out
->sim_addrinfo
= search_addrinfo
;
852 out
->sim_wants_addrinfo
= search_wants_addrinfo
;
853 out
->sim_nameinfo
= search_nameinfo
;
855 out
->sim_srv_byname
= search_srv_byname
;
861 init_optional_modules(search_si_private_t
*pp
)
863 if (pp
->mdns
== NULL
)
865 pp
->mdns
= si_module_with_name("mdns");
866 /* allow this to fail */
870 if (pp
->flags
& SEARCH_FLAG_MAC
)
874 pp
->ds
= si_module_with_name("ds");
875 /* allow this to fail */
880 if (pp
->flags
& (SEARCH_FLAG_APPLETV
| SEARCH_FLAG_IPHONE
))
884 pp
->dns
= si_module_with_name("dns");
885 /* allow this to fail */
890 __private_extern__ si_mod_t
*
891 si_module_static_search()
894 search_si_private_t
*pp
;
896 char *line
, **tokens
;
897 int cat
, i
, j
, ntokens
;
899 out
= search_alloc();
900 if (out
== NULL
) return NULL
;
902 pp
= (search_si_private_t
*)out
->private;
910 pp
->flags
= SEARCH_FLAG_CACHE_ENABLED
| SEARCH_FLAG_MAC
;
912 #ifdef CONFIG_APPLETV
913 pp
->flags
= SEARCH_FLAG_CACHE_ENABLED
| SEARCH_FLAG_APPLETV
;
917 pp
->flags
= SEARCH_FLAG_CACHE_ENABLED
| SEARCH_FLAG_IPHONE
;
920 pp
->cache
= si_module_with_name("cache");
921 if (pp
->cache
== NULL
)
927 pp
->file
= si_module_with_name("file");
928 if (pp
->file
== NULL
)
934 init_optional_modules(pp
);
936 conf
= fopen(_PATH_SI_CONF
, "r");
937 if (conf
== NULL
) return out
;
941 line
= _fsi_get_line(conf
);
942 if (line
== NULL
) break;
952 tokens
= _fsi_tokenize(line
, " : ", 0, &ntokens
);
963 if (string_equal(tokens
[0], "config"))
965 if (string_equal(tokens
[1], "mac")) pp
->flags
= SEARCH_FLAG_CACHE_ENABLED
| SEARCH_FLAG_MAC
;
966 else if (string_equal(tokens
[1], "appletv")) pp
->flags
= SEARCH_FLAG_CACHE_ENABLED
| SEARCH_FLAG_APPLETV
;
967 else if (string_equal(tokens
[1], "iphone")) pp
->flags
= SEARCH_FLAG_CACHE_ENABLED
| SEARCH_FLAG_IPHONE
;
969 init_optional_modules(pp
);
978 if (string_equal(tokens
[0], "user")) cat
= CATEGORY_USER
;
979 else if (string_equal(tokens
[0], "group")) cat
= CATEGORY_GROUP
;
980 else if (string_equal(tokens
[0], "grouplist")) cat
= CATEGORY_GROUPLIST
;
981 else if (string_equal(tokens
[0], "netgroup")) cat
= CATEGORY_NETGROUP
;
982 else if (string_equal(tokens
[0], "alias")) cat
= CATEGORY_ALIAS
;
983 else if (string_equal(tokens
[0], "host")) cat
= CATEGORY_HOST_IPV4
;
984 else if (string_equal(tokens
[0], "network")) cat
= CATEGORY_NETWORK
;
985 else if (string_equal(tokens
[0], "service")) cat
= CATEGORY_SERVICE
;
986 else if (string_equal(tokens
[0], "protocol")) cat
= CATEGORY_PROTOCOL
;
987 else if (string_equal(tokens
[0], "rpc")) cat
= CATEGORY_RPC
;
988 else if (string_equal(tokens
[0], "fs")) cat
= CATEGORY_FS
;
989 else if (string_equal(tokens
[0], "mac")) cat
= CATEGORY_MAC
;
990 else if (string_equal(tokens
[0], "addrinfo")) cat
= CATEGORY_ADDRINFO
;
991 else if (string_equal(tokens
[0], "nameinfo")) cat
= CATEGORY_NAMEINFO
;
1003 if (pp
->search_list
[cat
].module != NULL
)
1012 pp
->search_list
[cat
].count
= ntokens
- 1;
1013 pp
->search_list
[cat
].module = (si_mod_t
**)calloc(pp
->search_list
[cat
].count
, sizeof(si_mod_t
*));
1014 if (pp
->search_list
[cat
].module == NULL
)
1024 for (i
= 1, j
= 0; i
< ntokens
; i
++, j
++)
1026 if (string_equal(tokens
[i
], "cache"))
1028 pp
->search_list
[cat
].module[j
] = pp
->cache
;
1029 pp
->search_list
[cat
].flags
= SEARCH_FLAG_CACHE_ENABLED
;
1031 else if (string_equal(tokens
[i
], "file"))
1033 if (pp
->file
== NULL
) pp
->file
= si_module_with_name("file");
1034 pp
->search_list
[cat
].module[j
] = pp
->file
;
1036 else if (string_equal(tokens
[i
], "dns"))
1038 if (pp
->dns
== NULL
) pp
->dns
= si_module_with_name("dns");
1039 pp
->search_list
[cat
].module[j
] = pp
->dns
;
1041 else if (string_equal(tokens
[i
], "mdns"))
1043 if (pp
->mdns
== NULL
) pp
->mdns
= si_module_with_name("mdns");
1044 pp
->search_list
[cat
].module[j
] = pp
->mdns
;
1046 else if (string_equal(tokens
[i
], "ds"))
1048 if (pp
->ds
== NULL
) pp
->ds
= si_module_with_name("ds");
1049 pp
->search_list
[cat
].module[j
] = pp
->ds
;
1053 if (cat
== CATEGORY_HOST_IPV4
)
1055 cat
= CATEGORY_HOST_IPV6
;
1068 __private_extern__ si_mod_t
*
1069 search_custom(int n
, ...)
1073 search_si_private_t
*pp
;
1077 if (n
== 0) return si_module_static_search();
1079 out
= search_alloc();
1080 if (out
== NULL
) return NULL
;
1082 pp
= (search_si_private_t
*)out
->private;
1089 for (cat
= 0; cat
< CATEGORY_COUNT
; cat
++)
1091 pp
->search_list
[cat
].count
= n
;
1092 pp
->search_list
[cat
].module = (si_mod_t
**)calloc(pp
->search_list
[cat
].count
, sizeof(si_mod_t
*));
1093 if (pp
->search_list
[cat
].module == NULL
)
1103 for (i
= 0; i
< n
; i
++)
1105 name
= va_arg(ap
, char *);
1106 if (name
== NULL
) break;
1109 if (string_equal(name
, "cache"))
1111 if (pp
->cache
== NULL
)
1113 pp
->cache
= si_module_with_name("cache");
1115 if (pp
->cache
== NULL
)
1122 else if (string_equal(name
, "file"))
1124 if (pp
->file
== NULL
)
1126 pp
->file
= si_module_with_name("file");
1128 if (pp
->file
== NULL
)
1135 else if (string_equal(name
, "dns"))
1137 if (pp
->dns
== NULL
)
1139 pp
->dns
= si_module_with_name("dns");
1141 if (pp
->dns
== NULL
)
1148 else if (string_equal(name
, "mdns"))
1150 if (pp
->mdns
== NULL
)
1152 pp
->mdns
= si_module_with_name("mdns");
1154 if (pp
->mdns
== NULL
)
1161 else if (string_equal(name
, "ds"))
1165 pp
->ds
= si_module_with_name("ds");
1175 for (cat
= 0; cat
< CATEGORY_COUNT
; cat
++)
1177 if (string_equal(name
, "cache")) pp
->search_list
[cat
].flags
= SEARCH_FLAG_CACHE_ENABLED
;
1178 pp
->search_list
[cat
].module[i
] = m
;