2 * Copyright (c) 2008-2010 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 <dispatch/dispatch.h>
37 #include "si_module.h"
39 #define _PATH_SI_CONF "/etc/sysinfo.conf"
41 #define SEARCH_FLAG_CACHE_ENABLED 0x00000001
42 #define SEARCH_MODULE_FLAG_DISABLED 0x00000001
47 uint32_t *module_flags
;
54 search_list_t search_list
[CATEGORY_COUNT
];
56 } search_si_private_t
;
58 extern void si_cache_add_item(si_mod_t
*si
, si_mod_t
*src
, si_item_t
*item
);
59 extern void si_cache_add_list(si_mod_t
*si
, si_mod_t
*src
, si_list_t
*list
);
61 extern char **_fsi_tokenize(char *data
, const char *sep
, int trailing_empty
, int *ntokens
);
62 extern char *_fsi_get_line(FILE *fp
);
64 static void si_module_config_parse_line(search_si_private_t
*pp
, char *line
);
65 static void si_module_config_modules_for_category(search_si_private_t
*pp
, int cat
, int ntokens
, const char * const *tokens
);
68 search_get_module(search_si_private_t
*pp
, int cat
, int *n
)
72 if ((pp
== NULL
) || (n
== NULL
)) return NULL
;
77 /* Use custom search list if available */
78 if (pp
->search_list
[cat
].count
> 0 && x
< pp
->search_list
[cat
].count
)
80 return pp
->search_list
[cat
].module[x
];
83 /* Otherwise use the default search list */
84 while (x
< pp
->search_list
[CATEGORY_DEFAULT
].count
)
86 if (pp
->search_list
[CATEGORY_DEFAULT
].module_flags
[x
] & SEARCH_MODULE_FLAG_DISABLED
)
93 return pp
->search_list
[CATEGORY_DEFAULT
].module[x
];
100 __private_extern__
void
101 search_set_flags(si_mod_t
*si
, const char *name
, uint32_t flag
)
103 search_si_private_t
*pp
;
106 if (si
== NULL
) return;
107 if (si
->private == NULL
) return;
109 pp
= (search_si_private_t
*)si
->private;
111 for (i
= 0; i
< pp
->search_list
[CATEGORY_DEFAULT
].count
; i
++)
113 si_mod_t
*mod
= pp
->search_list
[CATEGORY_DEFAULT
].module[i
];
114 if ((mod
== NULL
) || (mod
->name
== NULL
)) continue;
116 if (string_equal(name
, mod
->name
))
118 pp
->search_list
[CATEGORY_DEFAULT
].module_flags
[i
] = flag
;
125 search_cat_cache(search_si_private_t
*pp
, int cat
)
127 if (pp
== NULL
) return NULL
;
128 if (cat
< 0 || cat
> CATEGORY_COUNT
) return NULL
;
130 if (pp
->search_list
[cat
].count
== 0)
132 cat
= CATEGORY_DEFAULT
;
135 if ((pp
->search_list
[cat
].flags
& SEARCH_FLAG_CACHE_ENABLED
) != 0)
144 search_close(si_mod_t
*si
)
147 search_si_private_t
*pp
;
149 if (si
== NULL
) return;
150 if (si
->private == NULL
) return;
152 pp
= (search_si_private_t
*)si
->private;
154 for (i
= 0; i
< CATEGORY_COUNT
; i
++)
156 if (pp
->search_list
[i
].module != NULL
)
158 free(pp
->search_list
[i
].module);
159 pp
->search_list
[i
].module = NULL
;
160 pp
->search_list
[i
].count
= 0;
161 pp
->search_list
[i
].flags
= 0;
169 search_item_byname(si_mod_t
*si
, const char *name
, int cat
, si_item_t
*(*call
)(si_mod_t
*, const char *))
172 search_si_private_t
*pp
;
176 if (si
== NULL
) return NULL
;
177 if (call
== NULL
) return NULL
;
179 pp
= (search_si_private_t
*)si
->private;
180 if (pp
== NULL
) return NULL
;
184 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
186 item
= call(src
, name
);
189 si_cache_add_item(search_cat_cache(pp
, cat
), src
, item
);
198 search_item_bynumber(si_mod_t
*si
, uint32_t number
, int cat
, si_item_t
*(*call
)(si_mod_t
*, uint32_t))
201 search_si_private_t
*pp
;
205 if (si
== NULL
) return NULL
;
206 if (call
== NULL
) return NULL
;
208 pp
= (search_si_private_t
*)si
->private;
209 if (pp
== NULL
) return NULL
;
213 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
215 item
= call(src
, number
);
218 si_cache_add_item(search_cat_cache(pp
, cat
), src
, item
);
227 search_list(si_mod_t
*si
, int cat
, si_list_t
*(*call
)(si_mod_t
*))
230 search_si_private_t
*pp
;
231 si_list_t
*list
, *all
;
232 si_mod_t
*cache
, *src
;
234 if (si
== NULL
) return NULL
;
235 if (call
== NULL
) return NULL
;
237 pp
= (search_si_private_t
*)si
->private;
238 if (pp
== NULL
) return NULL
;
240 cache
= search_cat_cache(pp
, cat
);
244 if (list
!= NULL
) return list
;
252 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
254 if (src
== pp
->cache
) continue;
263 all
= si_list_concat(all
, list
);
264 si_list_release(list
);
267 if ((all
!= NULL
) && (null_res
== 0)) si_cache_add_list(cache
, si
, all
);
272 search_user_byname(si_mod_t
*si
, const char *name
)
274 return search_item_byname(si
, name
, CATEGORY_USER
, si_user_byname
);
278 search_user_byuid(si_mod_t
*si
, uid_t uid
)
280 return search_item_bynumber(si
, (uint32_t)uid
, CATEGORY_USER
, si_user_byuid
);
284 search_user_all(si_mod_t
*si
)
286 return search_list(si
, CATEGORY_USER
, si_user_all
);
290 search_group_byname(si_mod_t
*si
, const char *name
)
292 return search_item_byname(si
, name
, CATEGORY_GROUP
, si_group_byname
);
296 search_group_bygid(si_mod_t
*si
, gid_t gid
)
298 return search_item_bynumber(si
, (uint32_t)gid
, CATEGORY_USER
, si_group_bygid
);
302 search_group_all(si_mod_t
*si
)
304 return search_list(si
, CATEGORY_GROUP
, si_group_all
);
308 search_groupist(si_mod_t
*si
, const char *name
)
310 return search_item_byname(si
, name
, CATEGORY_GROUPLIST
, si_grouplist
);
314 search_netgroup_byname(si_mod_t
*si
, const char *name
)
316 int i
, cat
, null_res
;
317 search_si_private_t
*pp
;
318 si_list_t
*list
, *all
;
319 si_mod_t
*cache
, *src
;
321 if (si
== NULL
) return NULL
;
323 pp
= (search_si_private_t
*)si
->private;
324 if (pp
== NULL
) return NULL
;
326 cat
= CATEGORY_NETGROUP
;
328 cache
= search_cat_cache(pp
, cat
);
331 list
= si_netgroup_byname(cache
, name
);
332 if (list
!= NULL
) return list
;
338 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
340 if (src
== pp
->cache
) continue;
342 list
= si_netgroup_byname(src
, name
);
349 all
= si_list_concat(all
, list
);
350 si_list_release(list
);
353 if ((all
!= NULL
) && (null_res
== 0)) si_cache_add_list(cache
, si
, all
);
358 search_in_netgroup(si_mod_t
*si
, const char *group
, const char *host
, const char *user
, const char *domain
)
361 search_si_private_t
*pp
;
364 if (si
== NULL
) return 0;
366 pp
= (search_si_private_t
*)si
->private;
367 if (pp
== NULL
) return 0;
369 cat
= CATEGORY_NETGROUP
;
373 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
375 innetgr
= si_in_netgroup(src
, group
, host
, user
, domain
);
376 if (innetgr
!= 0) return 1;
383 search_alias_byname(si_mod_t
*si
, const char *name
)
385 return search_item_byname(si
, name
, CATEGORY_ALIAS
, si_alias_byname
);
389 search_alias_all(si_mod_t
*si
)
391 return search_list(si
, CATEGORY_ALIAS
, si_alias_all
);
395 search_host_byname(si_mod_t
*si
, const char *name
, int af
, const char *interface
, uint32_t *err
)
398 search_si_private_t
*pp
;
402 if (err
!= NULL
) *err
= SI_STATUS_NO_ERROR
;
404 if ((si
== NULL
) || (name
== NULL
))
406 if (err
!= NULL
) *err
= SI_STATUS_H_ERRNO_NO_RECOVERY
;
410 pp
= (search_si_private_t
*)si
->private;
413 if (err
!= NULL
) *err
= SI_STATUS_H_ERRNO_NO_RECOVERY
;
417 cat
= CATEGORY_HOST_IPV4
;
418 if (af
== AF_INET6
) cat
= CATEGORY_HOST_IPV6
;
422 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
424 item
= si_host_byname(src
, name
, af
, interface
, err
);
427 si_cache_add_item(search_cat_cache(pp
, cat
), src
, item
);
432 if (err
!= NULL
) *err
= SI_STATUS_H_ERRNO_HOST_NOT_FOUND
;
437 search_host_byaddr(si_mod_t
*si
, const void *addr
, int af
, const char *interface
, uint32_t *err
)
440 search_si_private_t
*pp
;
444 if (err
!= NULL
) *err
= SI_STATUS_NO_ERROR
;
446 if ((si
== NULL
) || (addr
== NULL
))
448 if (err
!= NULL
) *err
= SI_STATUS_H_ERRNO_NO_RECOVERY
;
452 pp
= (search_si_private_t
*)si
->private;
455 if (err
!= NULL
) *err
= SI_STATUS_H_ERRNO_NO_RECOVERY
;
459 cat
= CATEGORY_HOST_IPV4
;
460 if (af
== AF_INET6
) cat
= CATEGORY_HOST_IPV6
;
464 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
466 item
= si_host_byaddr(src
, addr
, af
, interface
, err
);
469 si_cache_add_item(search_cat_cache(pp
, cat
), src
, item
);
474 if (err
!= NULL
) *err
= SI_STATUS_H_ERRNO_HOST_NOT_FOUND
;
479 search_host_all(si_mod_t
*si
)
481 return search_list(si
, CATEGORY_HOST
, si_host_all
);
485 search_network_byname(si_mod_t
*si
, const char *name
)
487 return search_item_byname(si
, name
, CATEGORY_NETWORK
, si_network_byname
);
491 search_network_byaddr(si_mod_t
*si
, uint32_t addr
)
493 return search_item_bynumber(si
, addr
, CATEGORY_NETWORK
, si_network_byaddr
);
497 search_network_all(si_mod_t
*si
)
499 return search_list(si
, CATEGORY_NETWORK
, si_network_all
);
503 search_service_byname(si_mod_t
*si
, const char *name
, const char *proto
)
507 search_si_private_t
*pp
;
510 if (si
== NULL
) return NULL
;
511 if (name
== NULL
) return NULL
;
513 pp
= (search_si_private_t
*)si
->private;
514 if (pp
== NULL
) return NULL
;
516 cat
= CATEGORY_SERVICE
;
519 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
521 item
= si_service_byname(src
, name
, proto
);
524 si_cache_add_item(search_cat_cache(pp
, cat
), src
, item
);
533 search_service_byport(si_mod_t
*si
, int port
, const char *proto
)
536 search_si_private_t
*pp
;
540 if (si
== NULL
) return NULL
;
542 pp
= (search_si_private_t
*)si
->private;
543 if (pp
== NULL
) return NULL
;
545 cat
= CATEGORY_SERVICE
;
548 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
550 item
= si_service_byport(src
, port
, proto
);
553 si_cache_add_item(search_cat_cache(pp
, cat
), src
, item
);
562 search_service_all(si_mod_t
*si
)
564 return search_list(si
, CATEGORY_SERVICE
, si_service_all
);
568 search_protocol_byname(si_mod_t
*si
, const char *name
)
570 return search_item_byname(si
, name
, CATEGORY_PROTOCOL
, si_protocol_byname
);
574 search_protocol_bynumber(si_mod_t
*si
, int number
)
576 return search_item_bynumber(si
, (uint32_t)number
, CATEGORY_PROTOCOL
, si_protocol_bynumber
);
580 search_protocol_all(si_mod_t
*si
)
582 return search_list(si
, CATEGORY_PROTOCOL
, si_protocol_all
);
586 search_rpc_byname(si_mod_t
*si
, const char *name
)
588 return search_item_byname(si
, name
, CATEGORY_RPC
, si_rpc_byname
);
592 search_rpc_bynumber(si_mod_t
*si
, int number
)
595 search_si_private_t
*pp
;
599 if (si
== NULL
) return NULL
;
601 pp
= (search_si_private_t
*)si
->private;
602 if (pp
== NULL
) return NULL
;
607 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
609 item
= si_rpc_bynumber(src
, number
);
612 si_cache_add_item(search_cat_cache(pp
, cat
), src
, item
);
621 search_rpc_all(si_mod_t
*si
)
623 return search_list(si
, CATEGORY_RPC
, si_rpc_all
);
627 search_fs_byspec(si_mod_t
*si
, const char *name
)
629 return search_item_byname(si
, name
, CATEGORY_FS
, si_fs_byspec
);
633 search_fs_byfile(si_mod_t
*si
, const char *name
)
635 return search_item_byname(si
, name
, CATEGORY_FS
, si_fs_byfile
);
639 search_fs_all(si_mod_t
*si
)
641 return search_list(si
, CATEGORY_FS
, si_fs_all
);
645 search_mac_byname(si_mod_t
*si
, const char *name
)
647 return search_item_byname(si
, name
, CATEGORY_MAC
, si_mac_byname
);
651 search_mac_bymac(si_mod_t
*si
, const char *mac
)
653 return search_item_byname(si
, mac
, CATEGORY_MAC
, si_mac_bymac
);
657 search_mac_all(si_mod_t
*si
)
659 return search_list(si
, CATEGORY_MAC
, si_mac_all
);
663 search_srv_byname(si_mod_t
*si
, const char* qname
, const char *interface
, uint32_t *err
)
666 si_list_t
*list
= NULL
;
668 search_si_private_t
*pp
;
670 if (si
== NULL
) return NULL
;
672 pp
= (search_si_private_t
*)si
->private;
673 if (pp
== NULL
) return NULL
;
678 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
680 if (src
== pp
->cache
) continue;
682 if (src
->vtable
->sim_srv_byname
!= NULL
)
684 list
= src
->vtable
->sim_srv_byname(src
, qname
, interface
, err
);
685 if (list
!= NULL
) return list
;
689 if ((i
> 0) && (err
!= NULL
)) *err
= SI_STATUS_EAI_NONAME
;
694 search_wants_addrinfo(si_mod_t
*si
)
698 search_si_private_t
*pp
;
700 if (si
== NULL
) return 0;
702 pp
= (search_si_private_t
*)si
->private;
703 if (pp
== NULL
) return 0;
705 cat
= CATEGORY_ADDRINFO
;
708 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
710 if (src
== pp
->cache
) continue;
711 if (src
->vtable
->sim_addrinfo
!= NULL
) return 1;
718 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
)
721 search_si_private_t
*pp
;
722 si_list_t
*list
= NULL
;
725 if (err
!= NULL
) *err
= SI_STATUS_EAI_FAIL
;
727 if (si
== NULL
) return NULL
;
729 pp
= (search_si_private_t
*)si
->private;
730 if (pp
== NULL
) return NULL
;
732 cat
= CATEGORY_ADDRINFO
;
735 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
737 if (src
== pp
->cache
) continue;
739 if (src
->vtable
->sim_addrinfo
!= NULL
)
741 list
= src
->vtable
->sim_addrinfo(src
, node
, serv
, family
, socktype
, protocol
, flags
, interface
, err
);
742 if (list
!= NULL
) return list
;
746 if ((i
> 0) && (err
!= NULL
)) *err
= SI_STATUS_EAI_NONAME
;
751 search_nameinfo(si_mod_t
*si
, const struct sockaddr
*sa
, int flags
, const char *interface
, uint32_t *err
)
754 search_si_private_t
*pp
;
758 if (err
!= NULL
) *err
= SI_STATUS_EAI_FAIL
;
760 if (si
== NULL
) return NULL
;
762 pp
= (search_si_private_t
*)si
->private;
763 if (pp
== NULL
) return NULL
;
765 cat
= CATEGORY_NAMEINFO
;
768 while (NULL
!= (src
= search_get_module(pp
, cat
, &i
)))
770 item
= si_nameinfo(src
, sa
, flags
, interface
, err
);
773 si_cache_add_item(search_cat_cache(pp
, cat
), src
, item
);
774 if (err
!= NULL
) *err
= SI_STATUS_NO_ERROR
;
779 if ((i
> 0) && (err
!= NULL
)) *err
= SI_STATUS_EAI_NONAME
;
784 search_is_valid(si_mod_t
*si
, si_item_t
*item
)
788 if (si
== NULL
) return 0;
789 if (item
== NULL
) return 0;
790 if (si
->name
== NULL
) return 0;
791 if (item
->src
== NULL
) return 0;
793 src
= (si_mod_t
*)item
->src
;
795 if (src
->name
== NULL
) return 0;
796 if (string_not_equal(si
->name
, src
->name
)) return 0;
801 si_module_static_search(void)
803 static const struct si_mod_vtable_s search_vtable
=
805 .sim_close
= &search_close
,
807 .sim_is_valid
= &search_is_valid
,
809 .sim_user_byname
= &search_user_byname
,
810 .sim_user_byuid
= &search_user_byuid
,
811 .sim_user_all
= &search_user_all
,
813 .sim_group_byname
= &search_group_byname
,
814 .sim_group_bygid
= &search_group_bygid
,
815 .sim_group_all
= &search_group_all
,
817 .sim_grouplist
= &search_groupist
,
819 .sim_netgroup_byname
= &search_netgroup_byname
,
820 .sim_in_netgroup
= &search_in_netgroup
,
822 .sim_alias_byname
= &search_alias_byname
,
823 .sim_alias_all
= &search_alias_all
,
825 .sim_host_byname
= &search_host_byname
,
826 .sim_host_byaddr
= &search_host_byaddr
,
827 .sim_host_all
= &search_host_all
,
829 .sim_network_byname
= &search_network_byname
,
830 .sim_network_byaddr
= &search_network_byaddr
,
831 .sim_network_all
= &search_network_all
,
833 .sim_service_byname
= &search_service_byname
,
834 .sim_service_byport
= &search_service_byport
,
835 .sim_service_all
= &search_service_all
,
837 .sim_protocol_byname
= &search_protocol_byname
,
838 .sim_protocol_bynumber
= &search_protocol_bynumber
,
839 .sim_protocol_all
= &search_protocol_all
,
841 .sim_rpc_byname
= &search_rpc_byname
,
842 .sim_rpc_bynumber
= &search_rpc_bynumber
,
843 .sim_rpc_all
= &search_rpc_all
,
845 .sim_fs_byspec
= &search_fs_byspec
,
846 .sim_fs_byfile
= &search_fs_byfile
,
847 .sim_fs_all
= &search_fs_all
,
849 .sim_mac_byname
= &search_mac_byname
,
850 .sim_mac_bymac
= &search_mac_bymac
,
851 .sim_mac_all
= &search_mac_all
,
853 .sim_addrinfo
= &search_addrinfo
,
854 .sim_wants_addrinfo
= &search_wants_addrinfo
,
855 .sim_nameinfo
= &search_nameinfo
,
857 .sim_srv_byname
= &search_srv_byname
,
864 .flags
= SI_MOD_FLAG_STATIC
,
867 .vtable
= &search_vtable
,
870 static dispatch_once_t once
;
872 dispatch_once(&once
, ^{
873 si
.name
= strdup("search");
874 search_si_private_t
*pp
= calloc(1, sizeof(search_si_private_t
));
878 * Default search order:
880 * 2) DirectoryService/OpenDirectory (where available)
885 const char * const modules
[] =
887 "default", // CATEGORY_DEFAULT
896 int count
= sizeof(modules
) / sizeof(char *);
897 si_module_config_modules_for_category(pp
, CATEGORY_DEFAULT
, count
, modules
);
898 pp
->cache
= pp
->search_list
[CATEGORY_DEFAULT
].module[0];
900 FILE *conf
= fopen(_PATH_SI_CONF
, "r");
906 char *line
= _fsi_get_line(conf
);
907 if (line
== NULL
) break;
909 si_module_config_parse_line(pp
, line
);
921 si_module_config_parse_line(search_si_private_t
*pp
, char *line
)
923 if (line
== NULL
|| line
[0] == '#') {
928 char **tokens
= _fsi_tokenize(line
, " : ", 0, &ntokens
);
930 int cat
= CATEGORY_INVALID
;
932 if (string_equal(tokens
[0], "default")) cat
= CATEGORY_DEFAULT
;
933 else if (string_equal(tokens
[0], "user")) cat
= CATEGORY_USER
;
934 else if (string_equal(tokens
[0], "group")) cat
= CATEGORY_GROUP
;
935 else if (string_equal(tokens
[0], "grouplist")) cat
= CATEGORY_GROUPLIST
;
936 else if (string_equal(tokens
[0], "netgroup")) cat
= CATEGORY_NETGROUP
;
937 else if (string_equal(tokens
[0], "alias")) cat
= CATEGORY_ALIAS
;
938 else if (string_equal(tokens
[0], "host")) cat
= CATEGORY_HOST_IPV4
;
939 else if (string_equal(tokens
[0], "network")) cat
= CATEGORY_NETWORK
;
940 else if (string_equal(tokens
[0], "service")) cat
= CATEGORY_SERVICE
;
941 else if (string_equal(tokens
[0], "protocol")) cat
= CATEGORY_PROTOCOL
;
942 else if (string_equal(tokens
[0], "rpc")) cat
= CATEGORY_RPC
;
943 else if (string_equal(tokens
[0], "fs")) cat
= CATEGORY_FS
;
944 else if (string_equal(tokens
[0], "mac")) cat
= CATEGORY_MAC
;
945 else if (string_equal(tokens
[0], "addrinfo")) cat
= CATEGORY_ADDRINFO
;
946 else if (string_equal(tokens
[0], "nameinfo")) cat
= CATEGORY_NAMEINFO
;
948 if (cat
!= CATEGORY_INVALID
)
950 si_module_config_modules_for_category(pp
, cat
, ntokens
, (const char * const *)tokens
);
957 si_module_config_modules_for_category(search_si_private_t
*pp
, int cat
, int ntokens
, const char * const *tokens
)
959 int count
= ntokens
- 1;
960 pp
->search_list
[cat
].count
= count
;
966 pp
->search_list
[cat
].module = (si_mod_t
**)calloc(pp
->search_list
[cat
].count
, sizeof(si_mod_t
*));
967 pp
->search_list
[cat
].module_flags
= (uint32_t *)calloc(pp
->search_list
[cat
].count
, sizeof(uint32_t));
968 if ((pp
->search_list
[cat
].module == NULL
) || (pp
->search_list
[cat
].module_flags
== NULL
))
970 free(pp
->search_list
[cat
].module);
971 free(pp
->search_list
[cat
].module_flags
);
976 for (i
= 1, j
= 0; i
< ntokens
; i
++)
978 si_mod_t
*mod
= si_module_with_name(tokens
[i
]);
981 pp
->search_list
[cat
].module[j
] = mod
;
984 if (string_equal(tokens
[i
], "cache"))
986 pp
->search_list
[cat
].flags
|= SEARCH_FLAG_CACHE_ENABLED
;