2 * Copyright (c) 2008-2018 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@
24 #include "libinfo_common.h"
33 #include <printerdb.h>
34 #include <sys/param.h>
35 #include <sys/syscall.h>
37 #include <arpa/inet.h>
38 #include <netinet/if_ether.h>
39 #include "si_module.h"
41 #include <thread_data.h>
42 #include <sys/kauth.h>
43 #include "netdb_async.h"
44 #include <dispatch/dispatch.h>
45 #include <mach-o/dyld_priv.h>
49 #define IPPROTO_UNSPEC 0
50 #define IPV6_ADDR_LEN 16
51 #define IPV4_ADDR_LEN 4
53 #define SYSTEM_UID_LIMIT 500
56 extern int __initgroups(u_int gidsetsize
, gid_t
*gidset
, int gmuid
);
58 /* SPI from long ago */
61 extern struct addrinfo
*si_list_to_addrinfo(si_list_t
*list
);
62 extern int getnameinfo_link(const struct sockaddr
*sa
, socklen_t salen
, char *host
, size_t hostlen
, char *serv
, size_t servlen
, int flags
);
63 __private_extern__
void search_set_flags(si_mod_t
*si
, const char *name
, uint32_t flag
);
66 * Impedence matching for async calls.
68 * This layer holds on to the caller's callback and context in this
69 * structure, which gets passed to the si_module async routines along
70 * with a callbac in this layer. When this layer gets a callback,
71 * it can save the item or list in thread-specific memory and then
72 * invoke the caller's callback with the appropriate data type.
86 static si_mod_t
*search
= NULL
;
88 if (search
== NULL
) search
= si_module_with_name("file");
97 static si_mod_t
*search
= NULL
;
99 if (search
== NULL
) search
= si_module_with_name("search");
106 si_search_module_set_flags(const char *name
, uint32_t flag
)
108 search_set_flags(si_search(), name
, flag
);
112 si_libinfo_general_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
120 struct grouplist_s
*l
;
129 if (ctx
== NULL
) return;
131 sictx
= (si_context_t
*)ctx
;
133 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
136 si_item_release(item
);
140 if (sictx
->key_offset
>= 0)
142 LI_set_thread_item(sictx
->cat
+ sictx
->key_offset
, item
);
146 if (item
!= NULL
) res
.x
= (char*)((uintptr_t)item
+ sizeof(si_item_t
));
152 ((si_user_async_callback
)(sictx
->orig_callback
))(res
.u
, sictx
->orig_context
);
157 ((si_group_async_callback
)(sictx
->orig_callback
))(res
.g
, sictx
->orig_context
);
160 case CATEGORY_GROUPLIST
:
162 ((si_grouplist_async_callback
)(sictx
->orig_callback
))(res
.l
, sictx
->orig_context
);
165 case CATEGORY_HOST_IPV4
:
166 case CATEGORY_HOST_IPV6
:
168 ((si_host_async_callback
)(sictx
->orig_callback
))(res
.h
, sictx
->orig_context
);
171 case CATEGORY_NETWORK
:
173 ((si_network_async_callback
)(sictx
->orig_callback
))(res
.n
, sictx
->orig_context
);
176 case CATEGORY_SERVICE
:
178 ((si_service_async_callback
)(sictx
->orig_callback
))(res
.s
, sictx
->orig_context
);
181 case CATEGORY_PROTOCOL
:
183 ((si_protocol_async_callback
)(sictx
->orig_callback
))(res
.p
, sictx
->orig_context
);
188 ((si_rpc_async_callback
)(sictx
->orig_callback
))(res
.r
, sictx
->orig_context
);
193 ((si_fs_async_callback
)(sictx
->orig_callback
))(res
.f
, sictx
->orig_context
);
205 getpwnam(const char *name
)
210 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
212 item
= si_user_byname(si_search(), name
);
213 LI_set_thread_item(CATEGORY_USER
+ 100, item
);
215 if (item
== NULL
) return NULL
;
216 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
220 getpwnam_async_call(const char *name
, si_user_async_callback callback
, void *context
)
225 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
228 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
229 if (sictx
== NULL
) return MACH_PORT_NULL
;
231 sictx
->orig_callback
= callback
;
232 sictx
->orig_context
= context
;
233 sictx
->cat
= CATEGORY_USER
;
234 sictx
->key_offset
= 100;
236 return si_async_call(si_search(), SI_CALL_USER_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
240 getpwnam_async_handle_reply(mach_msg_header_t
*msg
)
243 fprintf(stderr
, "<< %s\n", __func__
);
246 si_async_handle_reply(msg
);
253 si_item_t
*item
= NULL
;
256 fprintf(stderr
, "-> %s %d\n", __func__
, uid
);
259 // Search the file module first for all system uids
260 // (ie, uid value < 500) since they should all be
261 // in the /etc/*passwd file.
262 if (uid
< SYSTEM_UID_LIMIT
)
263 item
= si_user_byuid(si_search_file(), uid
);
266 item
= si_user_byuid(si_search(), uid
);
267 LI_set_thread_item(CATEGORY_USER
+ 200, item
);
269 if (item
== NULL
) return NULL
;
270 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
274 getpwuid_async_call(uid_t uid
, si_user_async_callback callback
, void *context
)
279 fprintf(stderr
, ">> %s %d\n", __func__
, uid
);
282 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
283 if (sictx
== NULL
) return MACH_PORT_NULL
;
285 sictx
->orig_callback
= callback
;
286 sictx
->orig_context
= context
;
287 sictx
->cat
= CATEGORY_USER
;
288 sictx
->key_offset
= 200;
290 // Search the file module first for all system uids
291 // (ie, uid value < 500) since they should all be
292 // in the /etc/*passwd file.
293 if (uid
< SYSTEM_UID_LIMIT
)
295 si_item_t
*item
= si_user_byuid(si_search_file(), uid
);
298 si_item_release(item
);
299 return si_async_call(si_search_file(), SI_CALL_USER_BYUID
, NULL
, NULL
, NULL
, (uint32_t)uid
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
303 return si_async_call(si_search(), SI_CALL_USER_BYUID
, NULL
, NULL
, NULL
, (uint32_t)uid
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
307 getpwuid_async_handle_reply(mach_msg_header_t
*msg
)
310 fprintf(stderr
, "<< %s\n", __func__
);
313 si_async_handle_reply(msg
);
318 getpwuuid(uuid_t uuid
)
323 uuid_string_t uuidstr
;
324 uuid_unparse_upper(uuid
, uuidstr
);
325 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
328 item
= si_user_byuuid(si_search(), uuid
);
329 LI_set_thread_item(CATEGORY_USER
+ 300, item
);
331 if (item
== NULL
) return NULL
;
332 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
340 fprintf(stderr
, "-- %s\n", __func__
);
343 LI_set_thread_list(CATEGORY_USER
, NULL
);
354 fprintf(stderr
, "-> %s\n", __func__
);
357 list
= LI_get_thread_list(CATEGORY_USER
);
360 list
= si_user_all(si_search());
361 LI_set_thread_list(CATEGORY_USER
, list
);
364 item
= si_list_next(list
);
365 if (item
== NULL
) return NULL
;
367 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
375 fprintf(stderr
, "-- %s\n", __func__
);
378 LI_set_thread_list(CATEGORY_USER
, NULL
);
383 setpassent(int ignored
)
388 fprintf(stderr
, "-> %s\n", __func__
);
391 list
= LI_get_thread_list(CATEGORY_USER
);
394 if (list
== NULL
) return 0;
402 getgrnam(const char *name
)
407 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
410 item
= si_group_byname(si_search(), name
);
411 LI_set_thread_item(CATEGORY_GROUP
+ 100, item
);
413 if (item
== NULL
) return NULL
;
414 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
418 getgrnam_async_call(const char *name
, si_group_async_callback callback
, void *context
)
423 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
426 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
427 if (sictx
== NULL
) return MACH_PORT_NULL
;
429 sictx
->orig_callback
= callback
;
430 sictx
->orig_context
= context
;
431 sictx
->cat
= CATEGORY_GROUP
;
432 sictx
->key_offset
= 100;
434 return si_async_call(si_search(), SI_CALL_GROUP_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
438 getgrnam_async_handle_reply(mach_msg_header_t
*msg
)
441 fprintf(stderr
, "<< %s\n", __func__
);
444 si_async_handle_reply(msg
);
454 fprintf(stderr
, "-> %s %d\n", __func__
, gid
);
457 item
= si_group_bygid(si_search(), gid
);
458 LI_set_thread_item(CATEGORY_GROUP
+ 200, item
);
460 if (item
== NULL
) return NULL
;
461 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
465 getgrgid_async_call(gid_t gid
, si_group_async_callback callback
, void *context
)
470 fprintf(stderr
, ">> %s %d\n", __func__
, gid
);
473 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
474 if (sictx
== NULL
) return MACH_PORT_NULL
;
476 sictx
->orig_callback
= callback
;
477 sictx
->orig_context
= context
;
478 sictx
->cat
= CATEGORY_GROUP
;
479 sictx
->key_offset
= 200;
481 return si_async_call(si_search(), SI_CALL_GROUP_BYGID
, NULL
, NULL
, NULL
, (uint32_t)gid
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
485 getgruid_async_handle_reply(mach_msg_header_t
*msg
)
488 fprintf(stderr
, "<< %s\n", __func__
);
491 si_async_handle_reply(msg
);
496 getgruuid(uuid_t uuid
)
501 uuid_string_t uuidstr
;
502 uuid_unparse_upper(uuid
, uuidstr
);
503 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
506 item
= si_group_byuuid(si_search(), uuid
);
507 LI_set_thread_item(CATEGORY_GROUP
+ 300, item
);
509 if (item
== NULL
) return NULL
;
510 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
518 fprintf(stderr
, "-- %s\n", __func__
);
521 LI_set_thread_list(CATEGORY_GROUP
, NULL
);
532 fprintf(stderr
, "-> %s\n", __func__
);
535 list
= LI_get_thread_list(CATEGORY_GROUP
);
538 list
= si_group_all(si_search());
539 LI_set_thread_list(CATEGORY_GROUP
, list
);
542 item
= si_list_next(list
);
543 if (item
== NULL
) return NULL
;
545 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
553 fprintf(stderr
, "-- %s\n", __func__
);
556 LI_set_thread_list(CATEGORY_GROUP
, NULL
);
561 setgroupent(int ignored
)
566 fprintf(stderr
, "-> %s\n", __func__
);
569 list
= LI_get_thread_list(CATEGORY_GROUP
);
572 if (list
== NULL
) return 0;
579 innetgr(const char *group
, const char *host
, const char *user
, const char *domain
)
583 fprintf(stderr
, "-> %s %s %s %s %s\n", __func__
, group
, host
, user
, domain
);
586 res
= si_in_netgroup(si_search(), group
, host
, user
, domain
);
589 fprintf(stderr
, "<- %s %d\n", __func__
, res
);
595 /* N.B. there is no async innetgr */
598 * setnetgrent is really more like a getXXXbyname routine than a
599 * setXXXent routine, since we are looking up a netgroup by name.
603 setnetgrent(const char *name
)
608 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
611 list
= si_netgroup_byname(si_search(), name
);
612 LI_set_thread_list(CATEGORY_NETGROUP
, list
);
615 /* N.B. there is no async getnetgrent */
619 getnetgrent(char **host
, char **user
, char **domain
)
623 struct netgrent_s
*ng
;
626 fprintf(stderr
, "-> %s\n", __func__
);
629 list
= LI_get_thread_list(CATEGORY_NETGROUP
);
630 item
= si_list_next(list
);
631 if (item
== NULL
) return 0;
633 ng
= (struct netgrent_s
*)((uintptr_t)item
+ sizeof(si_item_t
));
637 *domain
= ng
->ng_domain
;
647 fprintf(stderr
, "-- %s\n", __func__
);
650 LI_set_thread_list(CATEGORY_NETGROUP
, NULL
);
655 _check_groups(const char *function
, int32_t ngroups
)
657 static dispatch_once_t once
;
659 if (ngroups
> 0 && ngroups
< NGROUPS_MAX
) {
663 /* only log once per process */
664 dispatch_once(&once
, ^(void) {
665 const char *proc_name
= getprogname();
666 if (strcmp(proc_name
, "id") != 0 && strcmp(proc_name
, "smbd") != 0 && strcmp(proc_name
, "rpcsvchost") != 0) {
667 #pragma clang diagnostic push
668 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
669 aslmsg msg
= asl_new(ASL_TYPE_MSG
);
672 snprintf(buffer
, sizeof(buffer
), "%d", (ngroups
== 0 ? INT_MAX
: ngroups
));
673 asl_set(msg
, "com.apple.message.value", buffer
);
675 asl_set(msg
, "com.apple.message.domain", "com.apple.system.libinfo");
676 asl_set(msg
, "com.apple.message.result", "noop");
677 asl_set(msg
, "com.apple.message.signature", function
);
679 asl_log(NULL
, msg
, ASL_LEVEL_NOTICE
, "%s called triggering group enumeration", function
);
683 #pragma clang diagnostic pop
691 getgrouplist_internal(const char *name
, int basegid
, gid_t
*groups
, uint32_t *ngroups
)
693 int i
, j
, x
, g
, add
, max
;
698 * On input, ngroups specifies the size of the groups array.
699 * On output, it is set to the number of groups that are being returned.
700 * Returns -1 if the size is too small to fit all the groups that were found.
704 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
707 if (name
== NULL
) return 0;
708 if (groups
== NULL
) return 0;
709 if (ngroups
== NULL
) return 0;
713 if (max
<= 0) return 0;
718 item
= si_grouplist(si_search(), name
, max
+1);
719 LI_set_thread_item(CATEGORY_GROUPLIST
, item
);
720 if (item
== NULL
) return 0;
722 gl
= (si_grouplist_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
726 for (i
= 0; i
< gl
->gl_count
; i
++)
730 for (j
= 0; j
< x
; j
++) {
731 if (groups
[j
] == g
) {
736 if (add
== 0) continue;
738 if (x
>= max
) return -1;
749 getgrouplist(const char *name
, int basegid
, int *groups
, int *ngroups
)
752 _check_groups("getgrouplist", *ngroups
);
755 return getgrouplist_internal(name
, basegid
, (gid_t
*)groups
, (uint32_t *)ngroups
);
759 merge_gid(gid_t
*list
, gid_t g
, int32_t *count
)
765 for (i
= 0; i
< cnt
; i
++) {
766 if (list
[i
] == g
) return;
774 _getgrouplist_2_internal(const char *name
, gid_t basegid
, gid_t
**groups
)
781 item
= si_grouplist(si_search(), name
, INT_MAX
);
782 LI_set_thread_item(CATEGORY_GROUPLIST
, item
);
783 if (item
== NULL
) return -1;
785 gl
= (si_grouplist_t
*) ((uintptr_t) item
+ sizeof(si_item_t
));
788 * we can allocate enough up-front, we'll only use what we need
789 * we add one to the count that was found in case the basegid is not there
791 gids
= calloc(gl
->gl_count
+ 1, sizeof(gid_t
));
792 if (gids
== NULL
) return -1;
795 merge_gid(gids
, basegid
, &count
);
796 if (gl
->gl_gid
!= NULL
) {
797 for (i
= 0; i
< gl
->gl_count
; i
++) {
798 merge_gid(gids
, gl
->gl_gid
[i
], &count
);
809 getgrouplist_2(const char *name
, gid_t basegid
, gid_t
**groups
)
812 * Passes back a gid_t list containing all the users groups (and basegid).
813 * Caller must free the list.
814 * Returns the number of gids in the list or -1 on failure.
818 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
821 if (name
== NULL
) return 0;
822 if (groups
== NULL
) return 0;
825 _check_groups("getgrouplist_2", INT_MAX
);
828 return _getgrouplist_2_internal(name
, basegid
, groups
);
833 getgroupcount(const char *name
, gid_t basegid
)
839 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
843 _check_groups("getgroupcount", INT_MAX
);
847 count
= _getgrouplist_2_internal(name
, basegid
, &groups
);
848 if (groups
!= NULL
) free(groups
);
853 /* XXX to do: async getgrouplist_2 */
857 initgroups(const char *name
, int basegid
)
861 gid_t groups
[NGROUPS
];
869 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
872 /* KAUTH_UID_NONE tells the kernel not to fetch supplementary groups from DirectoryService */
873 uid
= KAUTH_UID_NONE
;
876 /* get the UID for this user */
877 item
= si_user_byname(si_search(), name
);
880 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
882 si_item_release(item
);
890 * A failure either means that user belongs to more than NGROUPS groups
891 * or no groups at all.
894 (void) getgrouplist_internal(name
, basegid
, groups
, &ngroups
);
896 status
= __initgroups(ngroups
, groups
, uid
);
897 if (status
< 0) return -1;
906 alias_getbyname(const char *name
)
911 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
914 item
= si_alias_byname(si_search(), name
);
915 LI_set_thread_item(CATEGORY_ALIAS
+ 100, item
);
916 if (item
== NULL
) return NULL
;
918 return (struct aliasent
*)((uintptr_t)item
+ sizeof(si_item_t
));
922 alias_getbyname_async_call(const char *name
, si_alias_async_callback callback
, void *context
)
927 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
930 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
931 if (sictx
== NULL
) return MACH_PORT_NULL
;
933 sictx
->orig_callback
= callback
;
934 sictx
->orig_context
= context
;
935 sictx
->cat
= CATEGORY_ALIAS
;
936 sictx
->key_offset
= 100;
938 return si_async_call(si_search(), SI_CALL_ALIAS_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
942 alias_getbyname_async_handle_reply(mach_msg_header_t
*msg
)
945 fprintf(stderr
, "<< %s\n", __func__
);
948 si_async_handle_reply(msg
);
956 fprintf(stderr
, "-> %s\n", __func__
);
959 LI_set_thread_list(CATEGORY_ALIAS
, NULL
);
970 fprintf(stderr
, "-> %s\n", __func__
);
973 list
= LI_get_thread_list(CATEGORY_ALIAS
);
976 list
= si_alias_all(si_search());
977 LI_set_thread_list(CATEGORY_ALIAS
, list
);
980 item
= si_list_next(list
);
981 if (item
== NULL
) return NULL
;
983 return (struct aliasent
*)((uintptr_t)item
+ sizeof(si_item_t
));
991 fprintf(stderr
, "-- %s\n", __func__
);
994 LI_set_thread_list(CATEGORY_ALIAS
, NULL
);
1001 freehostent(struct hostent
*h
)
1003 if (h
== NULL
) return;
1005 si_item_t
*item
= (si_item_t
*)((uintptr_t)h
- sizeof(si_item_t
));
1006 si_item_release(item
);
1010 gethostbynameerrno(const char *name
, int *err
)
1014 struct in_addr addr4
;
1017 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1020 memset(&addr4
, 0, sizeof(struct in_addr
));
1021 status
= SI_STATUS_NO_ERROR
;
1024 if (inet_aton(name
, &addr4
) == 1) item
= si_ipnode_byname(si_search(), name
, AF_INET
, 0, NULL
, &status
);
1025 else item
= si_host_byname(si_search(), name
, AF_INET
, NULL
, &status
);
1027 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1028 if (err
!= NULL
) *err
= status
;
1030 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
1031 if (item
== NULL
) return NULL
;
1033 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1038 gethostbyname(const char *name
)
1042 struct in_addr addr4
;
1045 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1048 memset(&addr4
, 0, sizeof(struct in_addr
));
1049 status
= SI_STATUS_NO_ERROR
;
1052 if (inet_aton(name
, &addr4
) == 1) item
= si_ipnode_byname(si_search(), name
, AF_INET
, 0, NULL
, &status
);
1053 else item
= si_host_byname(si_search(), name
, AF_INET
, NULL
, &status
);
1055 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1058 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
1059 if (item
== NULL
) return NULL
;
1061 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1065 gethostbyname_async_call(const char *name
, si_host_async_callback callback
, void *context
)
1067 si_context_t
*sictx
;
1070 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1073 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1074 if (sictx
== NULL
) return MACH_PORT_NULL
;
1076 sictx
->orig_callback
= callback
;
1077 sictx
->orig_context
= context
;
1078 sictx
->cat
= CATEGORY_HOST
;
1079 sictx
->key_offset
= 100;
1081 return si_async_call(si_search(), SI_CALL_HOST_BYNAME
, name
, NULL
, NULL
, AF_INET
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1086 gethostbyname_async_start(const char *name
, si_host_async_callback callback
, void *context
)
1088 return gethostbyname_async_call(name
, callback
, context
);
1093 gethostbyname_async_cancel(mach_port_t p
)
1096 fprintf(stderr
, "-- %s\n", __func__
);
1104 gethostbyname_async_handle_reply(void *param
)
1106 mach_msg_header_t
*msg
;
1109 fprintf(stderr
, "<< %s\n", __func__
);
1112 msg
= (mach_msg_header_t
*)param
;
1113 si_async_handle_reply(msg
);
1119 gethostbyname_async_handleReply(void *param
)
1121 mach_msg_header_t
*msg
;
1124 fprintf(stderr
, "<< %s\n", __func__
);
1127 msg
= (mach_msg_header_t
*)param
;
1128 si_async_handle_reply(msg
);
1133 gethostbyname2(const char *name
, int af
)
1137 struct in_addr addr4
;
1138 struct in6_addr addr6
;
1139 si_mod_t
*search
= si_search();
1142 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, af
);
1145 memset(&addr4
, 0, sizeof(struct in_addr
));
1146 memset(&addr6
, 0, sizeof(struct in6_addr
));
1147 status
= SI_STATUS_NO_ERROR
;
1150 if (((af
== AF_INET
) && (inet_aton(name
, &addr4
) == 1)) || ((af
== AF_INET6
) && (inet_pton(af
, name
, &addr6
) == 1)))
1152 item
= si_ipnode_byname(search
, name
, (uint32_t)af
, 0, NULL
, &status
);
1156 item
= si_host_byname(search
, name
, (uint32_t)af
, NULL
, &status
);
1159 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1162 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
1163 if (item
== NULL
) return NULL
;
1165 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1169 gethostbyname2_async_call(const char *name
, int af
, si_group_async_callback callback
, void *context
)
1171 si_context_t
*sictx
;
1174 fprintf(stderr
, ">> %s %s %d\n", __func__
, name
, af
);
1177 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1178 if (sictx
== NULL
) return MACH_PORT_NULL
;
1180 sictx
->orig_callback
= callback
;
1181 sictx
->orig_context
= context
;
1182 sictx
->cat
= CATEGORY_HOST
;
1183 sictx
->key_offset
= 100;
1185 return si_async_call(si_search(), SI_CALL_HOST_BYNAME
, name
, NULL
, NULL
, (uint32_t)af
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1189 gethostbyname2_async_cancel(mach_port_t p
)
1192 fprintf(stderr
, "-- %s\n", __func__
);
1199 gethostbyname2_async_handle_reply(mach_msg_header_t
*msg
)
1202 fprintf(stderr
, "<< %s\n", __func__
);
1205 si_async_handle_reply(msg
);
1210 gethostbyaddr(const void *addr
, socklen_t len
, int type
)
1216 fprintf(stderr
, "-> %s %s\n", __func__
, (type
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)addr
) : "-IPv6-");
1219 status
= SI_STATUS_NO_ERROR
;
1221 item
= si_host_byaddr(si_search(), addr
, (uint32_t)type
, NULL
, &status
);
1222 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1225 LI_set_thread_item(CATEGORY_HOST
+ 200, item
);
1226 if (item
== NULL
) return NULL
;
1228 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1232 gethostbyaddr_async_call(const void *addr
, socklen_t len
, int type
, si_host_async_callback callback
, void *context
)
1234 si_context_t
*sictx
;
1238 fprintf(stderr
, ">> %s %s\n", __func__
, (type
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)addr
) : "-IPv6-");
1241 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1242 if (sictx
== NULL
) return MACH_PORT_NULL
;
1244 sictx
->orig_callback
= callback
;
1245 sictx
->orig_context
= context
;
1246 sictx
->cat
= CATEGORY_HOST
;
1247 sictx
->key_offset
= 200;
1249 /* addr is not a C string - pass length in num3 */
1251 return si_async_call(si_search(), SI_CALL_HOST_BYADDR
, addr
, NULL
, NULL
, (uint32_t)type
, 0, addrlen
, 0, (void *)si_libinfo_general_callback
, sictx
);
1256 gethostbyaddr_async_start(const char *addr
, int len
, int family
, si_host_async_callback callback
, void *context
)
1258 socklen_t slen
= len
;
1260 return gethostbyaddr_async_call(addr
, slen
, family
, callback
, context
);
1265 gethostbyaddr_async_cancel(mach_port_t p
)
1268 fprintf(stderr
, "-- %s\n", __func__
);
1276 gethostbyaddr_async_handle_reply(void *param
)
1279 mach_msg_header_t
*msg
;
1282 fprintf(stderr
, "<< %s\n", __func__
);
1285 msg
= (mach_msg_header_t
*)param
;
1286 si_async_handle_reply(msg
);
1292 gethostbyaddr_async_handleReply(void *param
)
1294 mach_msg_header_t
*msg
;
1297 fprintf(stderr
, "<< %s\n", __func__
);
1300 msg
= (mach_msg_header_t
*)param
;
1301 si_async_handle_reply(msg
);
1306 getipnodebyname(const char *name
, int family
, int flags
, int *err
)
1312 fprintf(stderr
, "-> %s %s %d 0x%08x\n", __func__
, name
, family
, flags
);
1315 status
= SI_STATUS_NO_ERROR
;
1317 item
= si_ipnode_byname(si_search(), name
, family
, flags
, NULL
, &status
);
1318 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1319 if (err
!= NULL
) *err
= status
;
1321 if (item
== NULL
) return NULL
;
1323 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1328 getipnodebyname_async_call(const char *name
, int family
, int flags
, int *err
, si_host_async_callback callback
, void *context
)
1330 si_context_t
*sictx
;
1333 fprintf(stderr
, ">> %s %s %d 0x%08x\n", __func__
, name
, family
, flags
);
1336 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1337 if (sictx
== NULL
) return MACH_PORT_NULL
;
1339 sictx
->orig_callback
= callback
;
1340 sictx
->orig_context
= context
;
1341 sictx
->cat
= CATEGORY_HOST
;
1342 sictx
->key_offset
= -1;
1344 return si_async_call(si_search(), SI_CALL_IPNODE_BYNAME
, name
, NULL
, NULL
, (uint32_t)family
, (uint32_t)flags
, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1348 getipnodebyname_async_start(const char *name
, int family
, int flags
, int *err
, si_host_async_callback callback
, void *context
)
1350 return getipnodebyname_async_call(name
, family
, flags
, err
, callback
, context
);
1354 getipnodebyname_async_cancel(mach_port_t p
)
1357 fprintf(stderr
, "-- %s\n", __func__
);
1364 getipnodebyname_async_handle_reply(mach_msg_header_t
*msg
)
1367 fprintf(stderr
, "<< %s\n", __func__
);
1370 si_async_handle_reply(msg
);
1374 getipnodebyname_async_handleReply(mach_msg_header_t
*msg
)
1377 fprintf(stderr
, "<< %s\n", __func__
);
1380 si_async_handle_reply(msg
);
1385 is_a4_mapped(const char *s
)
1390 if (s
== NULL
) return 0;
1392 for (i
= 0; i
< 10; i
++)
1395 if (c
!= 0x0) return 0;
1398 for (i
= 10; i
< 12; i
++)
1401 if (c
!= 0xff) return 0;
1408 is_a4_compat(const char *s
)
1413 if (s
== NULL
) return 0;
1415 for (i
= 0; i
< 12; i
++)
1418 if (c
!= 0x0) return 0;
1421 /* Check for :: and ::1 */
1422 for (i
= 13; i
< 15; i
++)
1424 /* anything non-zero in these 3 bytes means it's a V4 address */
1426 if (c
!= 0x0) return 1;
1429 /* Leading 15 bytes are all zero */
1431 if (c
== 0x0) return 0;
1432 if (c
== 0x1) return 0;
1439 getipnodebyaddr(const void *src
, size_t len
, int family
, int *err
)
1444 fprintf(stderr
, "-> %s %s\n", __func__
, (family
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)src
) : "-IPv6-");
1447 if ((family
== AF_INET6
) && (len
== IPV6_ADDR_LEN
) && (is_a4_mapped((const char *)src
) || is_a4_compat((const char *)src
)))
1454 item
= si_host_byaddr(si_search(), src
, family
, NULL
, (uint32_t *)err
);
1455 if (item
== NULL
) return NULL
;
1457 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1462 si_libinfo_ipnode_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
1464 si_context_t
*sictx
;
1467 if (ctx
== NULL
) return;
1469 sictx
= (si_context_t
*)ctx
;
1471 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
1474 si_item_release(item
);
1478 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1482 ((si_ipnode_async_callback
)(sictx
->orig_callback
))(NULL
, status
, sictx
->orig_context
);
1486 h
= (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1487 ((si_ipnode_async_callback
)(sictx
->orig_callback
))(h
, status
, sictx
->orig_context
);
1493 getipnodebyaddr_async_call(const void *src
, socklen_t len
, int family
, int *err
, si_ipnode_async_callback callback
, void *context
)
1495 si_context_t
*sictx
;
1499 fprintf(stderr
, ">> %s %s\n", __func__
, (family
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)src
) : "-IPv6-");
1502 if ((family
== AF_INET6
) && (len
== IPV6_ADDR_LEN
) && (is_a4_mapped((const char *)src
) || is_a4_compat((const char *)src
)))
1509 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1510 if (sictx
== NULL
) return MACH_PORT_NULL
;
1512 sictx
->orig_callback
= callback
;
1513 sictx
->orig_context
= context
;
1514 sictx
->cat
= CATEGORY_HOST
;
1515 sictx
->key_offset
= -1;
1517 /* src is not a C string - pass length in num3 */
1519 return si_async_call(si_search(), SI_CALL_HOST_BYADDR
, src
, NULL
, NULL
, (uint32_t)family
, 0, srclen
, 0, (void *)si_libinfo_ipnode_callback
, sictx
);
1523 getipnodebyaddr_async_start(const void *addr
, size_t len
, int family
, int *error
, si_ipnode_async_callback callback
, void *context
)
1525 socklen_t slen
= len
;
1527 return getipnodebyaddr_async_call(addr
, slen
, family
, error
, callback
, context
);
1531 getipnodebyaddr_async_cancel(mach_port_t p
)
1534 fprintf(stderr
, "-- %s\n", __func__
);
1541 getipnodebyaddr_async_handle_reply(mach_msg_header_t
*msg
)
1544 fprintf(stderr
, "<< %s\n", __func__
);
1547 si_async_handle_reply(msg
);
1551 getipnodebyaddr_async_handleReply(mach_msg_header_t
*msg
)
1554 fprintf(stderr
, "<< %s\n", __func__
);
1557 si_async_handle_reply(msg
);
1563 sethostent(int ignored
)
1566 fprintf(stderr
, "-- %s\n", __func__
);
1569 LI_set_thread_list(CATEGORY_HOST
, NULL
);
1580 fprintf(stderr
, "-> %s\n", __func__
);
1583 list
= LI_get_thread_list(CATEGORY_HOST
);
1586 list
= si_host_all(si_search());
1587 LI_set_thread_list(CATEGORY_HOST
, list
);
1590 item
= si_list_next(list
);
1591 if (item
== NULL
) return NULL
;
1593 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1601 fprintf(stderr
, "-- %s\n", __func__
);
1604 LI_set_thread_list(CATEGORY_HOST
, NULL
);
1611 ether_hostton(const char *name
, struct ether_addr
*e
)
1619 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1622 if (name
== NULL
) return -1;
1623 if (e
== NULL
) return -1;
1625 item
= si_mac_byname(si_search(), name
);
1626 LI_set_thread_item(CATEGORY_MAC
+ 100, item
);
1627 if (item
== NULL
) return -1;
1629 mac
= (si_mac_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
1631 i
= sscanf(mac
->mac
, " %x:%x:%x:%x:%x:%x", &t
[0], &t
[1], &t
[2], &t
[3], &t
[4], &t
[5]);
1632 if (i
!= 6) return -1;
1634 for (i
= 0; i
< 6; i
++) e
->ether_addr_octet
[i
] = t
[i
];
1638 /* XXX to do? async ether_hostton */
1642 ether_ntohost(char *name
, const struct ether_addr
*e
)
1649 if (name
== NULL
) return -1;
1650 if (e
== NULL
) return -1;
1652 for (i
= 0; i
< 6; i
++) x
[i
] = e
->ether_addr_octet
[i
];
1653 snprintf(str
, sizeof(str
), "%x:%x:%x:%x:%x:%x", x
[0], x
[1], x
[2], x
[3], x
[4], x
[5]);
1656 fprintf(stderr
, "-> %s %s\n", __func__
, str
);
1659 item
= si_mac_bymac(si_search(), str
);
1660 LI_set_thread_item(CATEGORY_MAC
+ 200, item
);
1661 if (item
== NULL
) return -1;
1663 mac
= (si_mac_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
1665 memcpy(name
, mac
->host
, strlen(mac
->host
) + 1);
1669 /* XXX to do? async ether_ntohost */
1675 getnetbyname(const char *name
)
1680 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1683 item
= si_network_byname(si_search(), name
);
1684 LI_set_thread_item(CATEGORY_NETWORK
+ 100, item
);
1685 if (item
== NULL
) return NULL
;
1687 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1691 getnetbyname_async_call(const char *name
, si_network_async_callback callback
, void *context
)
1693 si_context_t
*sictx
;
1696 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1699 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1700 if (sictx
== NULL
) return MACH_PORT_NULL
;
1702 sictx
->orig_callback
= callback
;
1703 sictx
->orig_context
= context
;
1704 sictx
->cat
= CATEGORY_NETWORK
;
1705 sictx
->key_offset
= 100;
1707 return si_async_call(si_search(), SI_CALL_NETWORK_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1711 getnetbyname_async_handle_reply(mach_msg_header_t
*msg
)
1714 fprintf(stderr
, "<< %s\n", __func__
);
1717 si_async_handle_reply(msg
);
1722 getnetbyaddr(uint32_t net
, int type
)
1727 fprintf(stderr
, "-> %s 0x%08x\n", __func__
, net
);
1730 if (type
!= AF_INET
) return NULL
;
1732 item
= si_network_byaddr(si_search(), net
);
1733 LI_set_thread_item(CATEGORY_NETWORK
+ 200, item
);
1734 if (item
== NULL
) return NULL
;
1736 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1740 getnetbyaddr_async_call(uint32_t net
, int type
, si_group_async_callback callback
, void *context
)
1742 si_context_t
*sictx
;
1745 fprintf(stderr
, ">> %s 0x%08x\n", __func__
, net
);
1748 if (type
!= AF_INET
) return MACH_PORT_NULL
;
1750 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1751 if (sictx
== NULL
) return MACH_PORT_NULL
;
1753 sictx
->orig_callback
= callback
;
1754 sictx
->orig_context
= context
;
1755 sictx
->cat
= CATEGORY_NETWORK
;
1756 sictx
->key_offset
= 200;
1758 return si_async_call(si_search(), SI_CALL_NETWORK_BYADDR
, NULL
, NULL
, NULL
, net
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1762 getnetbyaddr_async_handle_reply(mach_msg_header_t
*msg
)
1765 fprintf(stderr
, "<< %s\n", __func__
);
1768 si_async_handle_reply(msg
);
1773 setnetent(int ignored
)
1776 fprintf(stderr
, "-- %s\n", __func__
);
1779 LI_set_thread_list(CATEGORY_NETWORK
, NULL
);
1790 fprintf(stderr
, "-> %s\n", __func__
);
1793 list
= LI_get_thread_list(CATEGORY_NETWORK
);
1796 list
= si_network_all(si_search());
1797 LI_set_thread_list(CATEGORY_NETWORK
, list
);
1800 item
= si_list_next(list
);
1801 if (item
== NULL
) return NULL
;
1803 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1811 fprintf(stderr
, "-- %s\n", __func__
);
1814 LI_set_thread_list(CATEGORY_NETWORK
, NULL
);
1821 getservbyname(const char *name
, const char *proto
)
1826 fprintf(stderr
, "-> %s %s %s\n", __func__
, name
, proto
);
1829 item
= si_service_byname(si_search(), name
, proto
);
1830 LI_set_thread_item(CATEGORY_SERVICE
+ 100, item
);
1831 if (item
== NULL
) return NULL
;
1833 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1837 getservbyname_async_call(const char *name
, const char *proto
, si_service_async_callback callback
, void *context
)
1839 si_context_t
*sictx
;
1842 fprintf(stderr
, ">> %s %s %s\n", __func__
, name
, proto
);
1845 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1846 if (sictx
== NULL
) return MACH_PORT_NULL
;
1848 sictx
->orig_callback
= callback
;
1849 sictx
->orig_context
= context
;
1850 sictx
->cat
= CATEGORY_SERVICE
;
1851 sictx
->key_offset
= 100;
1853 return si_async_call(si_search(), SI_CALL_SERVICE_BYNAME
, name
, proto
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1857 getservbyname_async_handle_reply(mach_msg_header_t
*msg
)
1860 fprintf(stderr
, "<< %s\n", __func__
);
1863 si_async_handle_reply(msg
);
1868 getservbyport(int port
, const char *proto
)
1873 fprintf(stderr
, "-> %s %d %s\n", __func__
, ntohs((uint16_t)port
), proto
);
1876 item
= si_service_byport(si_search(), port
, proto
);
1877 LI_set_thread_item(CATEGORY_SERVICE
+ 200, item
);
1878 if (item
== NULL
) return NULL
;
1880 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1884 getservbyport_async_call(int port
, const char *proto
, si_group_async_callback callback
, void *context
)
1886 si_context_t
*sictx
;
1889 fprintf(stderr
, ">> %s %d %s\n", __func__
, port
, proto
);
1892 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1893 if (sictx
== NULL
) return MACH_PORT_NULL
;
1895 sictx
->orig_callback
= callback
;
1896 sictx
->orig_context
= context
;
1897 sictx
->cat
= CATEGORY_SERVICE
;
1898 sictx
->key_offset
= 200;
1900 return si_async_call(si_search(), SI_CALL_SERVICE_BYPORT
, NULL
, proto
, NULL
, port
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1904 getservbyport_async_handle_reply(mach_msg_header_t
*msg
)
1907 fprintf(stderr
, "<< %s\n", __func__
);
1910 si_async_handle_reply(msg
);
1915 setservent(int ignored
)
1918 fprintf(stderr
, "-- %s\n", __func__
);
1921 LI_set_thread_list(CATEGORY_SERVICE
, NULL
);
1932 fprintf(stderr
, "-> %s\n", __func__
);
1935 list
= LI_get_thread_list(CATEGORY_SERVICE
);
1938 list
= si_service_all(si_search());
1939 LI_set_thread_list(CATEGORY_SERVICE
, list
);
1942 item
= si_list_next(list
);
1943 if (item
== NULL
) return NULL
;
1945 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1953 fprintf(stderr
, "-- %s\n", __func__
);
1956 LI_set_thread_list(CATEGORY_SERVICE
, NULL
);
1963 getprotobyname(const char *name
)
1968 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1971 item
= si_protocol_byname(si_search(), name
);
1972 LI_set_thread_item(CATEGORY_PROTOCOL
+ 100, item
);
1973 if (item
== NULL
) return NULL
;
1975 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1979 getprotobyname_async_call(const char *name
, si_protocol_async_callback callback
, void *context
)
1981 si_context_t
*sictx
;
1984 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1987 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1988 if (sictx
== NULL
) return MACH_PORT_NULL
;
1990 sictx
->orig_callback
= callback
;
1991 sictx
->orig_context
= context
;
1992 sictx
->cat
= CATEGORY_PROTOCOL
;
1993 sictx
->key_offset
= 100;
1995 return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1999 getprotobyname_async_handle_reply(mach_msg_header_t
*msg
)
2002 fprintf(stderr
, "<< %s\n", __func__
);
2005 si_async_handle_reply(msg
);
2010 getprotobynumber(int number
)
2015 fprintf(stderr
, "-> %s %d\n", __func__
, number
);
2018 item
= si_protocol_bynumber(si_search(), number
);
2019 LI_set_thread_item(CATEGORY_PROTOCOL
+ 200, item
);
2020 if (item
== NULL
) return NULL
;
2022 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2026 getprotobynumber_async_call(int number
, si_group_async_callback callback
, void *context
)
2028 si_context_t
*sictx
;
2031 fprintf(stderr
, ">> %s %d\n", __func__
, number
);
2034 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2035 if (sictx
== NULL
) return MACH_PORT_NULL
;
2037 sictx
->orig_callback
= callback
;
2038 sictx
->orig_context
= context
;
2039 sictx
->cat
= CATEGORY_PROTOCOL
;
2040 sictx
->key_offset
= 200;
2042 return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNUMBER
, NULL
, NULL
, NULL
, number
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2046 getprotobynumber_async_handle_reply(mach_msg_header_t
*msg
)
2049 fprintf(stderr
, "<< %s\n", __func__
);
2052 si_async_handle_reply(msg
);
2057 setprotoent(int ignored
)
2060 fprintf(stderr
, "-- %s\n", __func__
);
2063 LI_set_thread_list(CATEGORY_PROTOCOL
, NULL
);
2074 fprintf(stderr
, "-> %s\n", __func__
);
2077 list
= LI_get_thread_list(CATEGORY_PROTOCOL
);
2080 list
= si_protocol_all(si_search());
2081 LI_set_thread_list(CATEGORY_PROTOCOL
, list
);
2084 item
= si_list_next(list
);
2085 if (item
== NULL
) return NULL
;
2087 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2095 fprintf(stderr
, "-- %s\n", __func__
);
2098 LI_set_thread_list(CATEGORY_PROTOCOL
, NULL
);
2105 getrpcbyname(const char *name
)
2110 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
2113 item
= si_rpc_byname(si_search(), name
);
2114 LI_set_thread_item(CATEGORY_RPC
+ 100, item
);
2115 if (item
== NULL
) return NULL
;
2117 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2121 getrpcbyname_async_call(const char *name
, si_rpc_async_callback callback
, void *context
)
2123 si_context_t
*sictx
;
2126 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
2129 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2130 if (sictx
== NULL
) return MACH_PORT_NULL
;
2132 sictx
->orig_callback
= callback
;
2133 sictx
->orig_context
= context
;
2134 sictx
->cat
= CATEGORY_RPC
;
2135 sictx
->key_offset
= 100;
2137 return si_async_call(si_search(), SI_CALL_RPC_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2141 getrpcbyname_async_handle_reply(mach_msg_header_t
*msg
)
2144 fprintf(stderr
, "<< %s\n", __func__
);
2147 si_async_handle_reply(msg
);
2164 fprintf(stderr
, "-> %s %ld\n", __func__
, (long int)number
);
2167 item
= si_rpc_bynumber(si_search(), number
);
2168 LI_set_thread_item(CATEGORY_RPC
+ 200, item
);
2169 if (item
== NULL
) return NULL
;
2171 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2175 getrpcbynumber_async_call(int number
, si_group_async_callback callback
, void *context
)
2177 si_context_t
*sictx
;
2180 fprintf(stderr
, ">> %s %d\n", __func__
, number
);
2183 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2184 if (sictx
== NULL
) return MACH_PORT_NULL
;
2186 sictx
->orig_callback
= callback
;
2187 sictx
->orig_context
= context
;
2188 sictx
->cat
= CATEGORY_RPC
;
2189 sictx
->key_offset
= 200;
2191 return si_async_call(si_search(), SI_CALL_RPC_BYNUMBER
, NULL
, NULL
, NULL
, number
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2195 getrpcbynumber_async_handle_reply(mach_msg_header_t
*msg
)
2198 fprintf(stderr
, "<< %s\n", __func__
);
2201 si_async_handle_reply(msg
);
2206 setrpcent(int ignored
)
2209 fprintf(stderr
, "-- %s\n", __func__
);
2212 LI_set_thread_list(CATEGORY_RPC
, NULL
);
2223 fprintf(stderr
, "-> %s\n", __func__
);
2226 list
= LI_get_thread_list(CATEGORY_RPC
);
2229 list
= si_rpc_all(si_search());
2230 LI_set_thread_list(CATEGORY_RPC
, list
);
2233 item
= si_list_next(list
);
2234 if (item
== NULL
) return NULL
;
2236 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2244 fprintf(stderr
, "-- %s\n", __func__
);
2247 LI_set_thread_list(CATEGORY_RPC
, NULL
);
2254 getfsspec(const char *spec
)
2259 fprintf(stderr
, "-> %s %s\n", __func__
, spec
);
2262 item
= si_fs_byspec(si_search(), spec
);
2263 LI_set_thread_item(CATEGORY_FS
+ 100, item
);
2264 if (item
== NULL
) return NULL
;
2266 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2270 getfsbyname(const char *name
)
2273 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
2276 return getfsspec(name
);
2280 getfsspec_async_call(const char *spec
, si_fs_async_callback callback
, void *context
)
2282 si_context_t
*sictx
;
2285 fprintf(stderr
, ">> %s %s\n", __func__
, spec
);
2288 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2289 if (sictx
== NULL
) return MACH_PORT_NULL
;
2291 sictx
->orig_callback
= callback
;
2292 sictx
->orig_context
= context
;
2293 sictx
->cat
= CATEGORY_FS
;
2294 sictx
->key_offset
= 100;
2296 return si_async_call(si_search(), SI_CALL_FS_BYSPEC
, spec
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2300 getfsspec_async_handle_reply(mach_msg_header_t
*msg
)
2303 fprintf(stderr
, "<< %s\n", __func__
);
2306 si_async_handle_reply(msg
);
2311 getfsfile(const char *file
)
2316 fprintf(stderr
, "-> %s %s\n", __func__
, file
);
2319 item
= si_fs_byfile(si_search(), file
);
2320 LI_set_thread_item(CATEGORY_FS
+ 200, item
);
2321 if (item
== NULL
) return NULL
;
2323 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2327 getfsfile_async_call(const char *file
, si_fs_async_callback callback
, void *context
)
2329 si_context_t
*sictx
;
2332 fprintf(stderr
, ">> %s %s\n", __func__
, file
);
2335 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2336 if (sictx
== NULL
) return MACH_PORT_NULL
;
2338 sictx
->orig_callback
= callback
;
2339 sictx
->orig_context
= context
;
2340 sictx
->cat
= CATEGORY_FS
;
2341 sictx
->key_offset
= 200;
2343 return si_async_call(si_search(), SI_CALL_FS_BYFILE
, file
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2347 getfsfile_async_handle_reply(mach_msg_header_t
*msg
)
2350 fprintf(stderr
, "<< %s\n", __func__
);
2353 si_async_handle_reply(msg
);
2361 fprintf(stderr
, "-> %s\n", __func__
);
2364 LI_set_thread_list(CATEGORY_FS
, NULL
);
2376 fprintf(stderr
, "-> %s\n", __func__
);
2379 list
= LI_get_thread_list(CATEGORY_FS
);
2382 list
= si_fs_all(si_search());
2383 LI_set_thread_list(CATEGORY_FS
, list
);
2386 item
= si_list_next(list
);
2387 if (item
== NULL
) return NULL
;
2389 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2397 fprintf(stderr
, "-- %s\n", __func__
);
2400 LI_set_thread_list(CATEGORY_FS
, NULL
);
2406 _getaddrinfo_internal(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, const char *interface
, struct addrinfo
**res
)
2409 uint32_t family
, socktype
, protocol
, flags
, status
;
2410 struct addrinfo
*ai
;
2413 socktype
= SOCK_UNSPEC
;
2414 protocol
= IPPROTO_UNSPEC
;
2416 status
= SI_STATUS_NO_ERROR
;
2418 if (res
== NULL
) return 0;
2423 family
= hints
->ai_family
;
2424 socktype
= hints
->ai_socktype
;
2425 protocol
= hints
->ai_protocol
;
2426 flags
= hints
->ai_flags
;
2429 if (flags
== 0) flags
= AI_DEFAULT
;
2432 fprintf(stderr
, "-> %s %s %s %u %u %u 0x%08x %s\n", __func__
, nodename
, servname
, family
, socktype
, protocol
, flags
, (interface
== NULL
) ? "" : interface
);
2435 list
= si_addrinfo(si_search(), nodename
, servname
, family
, socktype
, protocol
, flags
, interface
, &status
);
2436 if ((status
!= SI_STATUS_NO_ERROR
) || (list
== NULL
) || (list
->count
== 0))
2438 si_list_release(list
);
2440 if (status
== SI_STATUS_NO_ERROR
) return EAI_NONAME
;
2441 else if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2442 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2443 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2447 *res
= si_list_to_addrinfo(list
);
2448 si_list_release(list
);
2449 if (*res
== NULL
) status
= EAI_MEMORY
;
2451 /* don't return the canonical name unless asked */
2452 if ((flags
& AI_CANONNAME
) == 0)
2454 for (ai
= *res
; ai
!= NULL
; ai
= ai
->ai_next
)
2456 free(ai
->ai_canonname
);
2457 ai
->ai_canonname
= NULL
;
2466 getaddrinfo(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, struct addrinfo
**res
)
2468 return _getaddrinfo_internal(nodename
, servname
, hints
, NULL
, res
);
2474 socket_name(int sock
)
2476 static char str
[16];
2480 case SOCK_UNSPEC
: return "SOCK_UNSPEC";
2481 case SOCK_STREAM
: return "SOCK_STREAM";
2482 case SOCK_DGRAM
: return "SOCK_DGRAM";
2485 sprintf(str
, "%d", sock
);
2492 static char str
[16];
2496 case PF_UNSPEC
: return "PF_UNSPEC";
2497 case PF_INET
: return "PF_INET";
2498 case PF_INET6
: return "PF_INET6";
2501 sprintf(str
, "%d", pf
);
2506 protocol_name(int p
)
2508 static char str
[16];
2512 case IPPROTO_UNSPEC
: return "IPPROTO_UNSPEC";
2513 case IPPROTO_TCP
: return "IPPROTO_TCP";
2514 case IPPROTO_UDP
: return "IPPROTO_UDP";
2517 sprintf(str
, "%d", p
);
2522 _gai_inet_ntop(struct in6_addr a
)
2524 static char buf
[128];
2530 memset(buf
, 0, 128);
2532 p
= (char *)&a
.__u6_addr
.__u6_addr32
;
2533 for (i
= 0; i
< 8; i
++, x
+= 1)
2537 sprintf(t
, "%hx", x
);
2539 if (i
< 7) strcat(buf
, ":");
2546 fprint_addrinfo(FILE *f
, struct addrinfo
*a
)
2550 struct sockaddr_in
*s4
;
2551 struct sockaddr_in6
*s6
;
2553 if (a
== NULL
) return;
2555 if (a
->ai_flags
!= 0)
2557 fprintf(f
, "flags =");
2558 if (a
->ai_flags
& AI_PASSIVE
) fprintf(f
, " AI_PASSIVE");
2559 if (a
->ai_flags
& AI_CANONNAME
) fprintf(f
, " AI_CANONNAME");
2560 if (a
->ai_flags
& AI_NUMERICHOST
) fprintf(f
, " AI_NUMERICHOST");
2561 if (a
->ai_flags
& AI_NUMERICSERV
) fprintf(f
, " AI_NUMERICSERV");
2565 fprintf(f
, "family = %s\n", family_name(a
->ai_family
));
2566 fprintf(f
, "socktype = %s\n", socket_name(a
->ai_socktype
));
2567 fprintf(f
, "protocol = %s\n", protocol_name(a
->ai_protocol
));
2569 fprintf(f
, "canonical name = ");
2570 if (a
->ai_canonname
== NULL
) fprintf(f
, "NULL\n");
2571 else fprintf(f
, "\"%s\"\n", a
->ai_canonname
);
2573 fprintf(f
, "addrlen = %ld\n", (long int)a
->ai_addrlen
);
2575 if (a
->ai_addr
== NULL
) fprintf(f
, "sockaddr = NULL\n");
2578 if (a
->ai_family
== PF_INET
)
2580 s4
= (struct sockaddr_in
*)a
->ai_addr
;
2582 fprintf(f
, "sockaddr_in len = %d\n", s4
->sin_len
);
2583 fprintf(f
, "sockaddr_in family = %s\n", family_name(s4
->sin_family
));
2584 fprintf(f
, "sockaddr_in port = %hu\n", ntohs(s4
->sin_port
));
2585 fprintf(f
, "sockaddr_in address = %s\n", inet_ntoa(s4
->sin_addr
));
2587 else if (a
->ai_family
== PF_INET6
)
2589 s6
= (struct sockaddr_in6
*)a
->ai_addr
;
2591 fprintf(f
, "sockaddr_in6 len = %d\n", s6
->sin6_len
);
2592 fprintf(f
, "sockaddr_in6 family = %s\n", family_name(s6
->sin6_family
));
2593 fprintf(f
, "sockaddr_in6 port = %hu\n", ntohs(s6
->sin6_port
));
2594 fprintf(f
, "sockaddr_in6 flowinfo = %d\n", s6
->sin6_flowinfo
);
2595 fprintf(f
, "sockaddr_in6 address = %s\n", _gai_inet_ntop(s6
->sin6_addr
));
2596 fprintf(f
, "sockaddr_in6 scope_id = %d\n", s6
->sin6_scope_id
);
2600 fprintf(f
, "sockaddr len = %d\n", a
->ai_addr
->sa_len
);
2601 fprintf(f
, "sockaddr family = %s\n", family_name(a
->ai_addr
->sa_family
));
2602 fprintf(f
, "sockaddr data = ");
2603 for (i
= 0; i
< a
->ai_addr
->sa_len
- 2; i
++)
2605 v
= a
->ai_addr
->sa_data
[i
];
2606 fprintf(f
, "%02x", v
);
2612 if (a
->ai_next
!= NULL
)
2614 fprintf(f
, "NEXT --->\n");
2615 fprint_addrinfo(f
, a
->ai_next
);
2622 si_libinfo_addrinfo_callback(si_list_t
*list
, uint32_t status
, void *ctx
)
2624 si_context_t
*sictx
;
2625 struct addrinfo
*out
;
2630 fprintf(stderr
, " %s error no context\n", __func__
);
2632 si_list_release(list
);
2636 sictx
= (si_context_t
*)ctx
;
2638 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
2641 fprintf(stderr
, " %s error no callback\n", __func__
);
2643 si_list_release(list
);
2648 if (status
!= SI_STATUS_NO_ERROR
)
2651 fprintf(stderr
, " %s original status %d\n", __func__
, status
);
2653 if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2654 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2655 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2661 fprintf(stderr
, " %s result NULL status %d (returning EAI_NONAME)\n", __func__
, status
);
2663 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(EAI_NONAME
, NULL
, sictx
->orig_context
);
2668 out
= si_list_to_addrinfo(list
);
2669 si_list_release(list
);
2673 fprintf(stderr
, " %s result conversion failed returning NULL status %d (returning EAI_MEMORY)\n", __func__
, status
);
2675 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(EAI_MEMORY
, NULL
, sictx
->orig_context
);
2681 fprintf(stderr
, " %s %d\n", __func__
, status
);
2682 fprint_addrinfo(stderr
, out
);
2684 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(status
, out
, sictx
->orig_context
);
2692 _getaddrinfo_interface_async_call(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, const char *interface
, si_addrinfo_async_callback callback
, void *context
)
2694 si_context_t
*sictx
;
2695 uint32_t family
, socktype
, protocol
, flags
;
2698 socktype
= SOCK_UNSPEC
;
2699 protocol
= IPPROTO_UNSPEC
;
2704 family
= hints
->ai_family
;
2705 socktype
= hints
->ai_socktype
;
2706 protocol
= hints
->ai_protocol
;
2707 flags
= hints
->ai_flags
;
2710 if (flags
== 0) flags
= AI_DEFAULT
;
2713 fprintf(stderr
, ">> %s %s %s %u %u %u 0x%08x\n", __func__
, nodename
, servname
, family
, socktype
, protocol
, flags
);
2716 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2717 if (sictx
== NULL
) return MACH_PORT_NULL
;
2719 sictx
->orig_callback
= callback
;
2720 sictx
->orig_context
= context
;
2721 sictx
->cat
= CATEGORY_ADDRINFO
;
2722 sictx
->key_offset
= 0;
2724 return si_async_call(si_search(), SI_CALL_ADDRINFO
, nodename
, servname
, interface
, family
, socktype
, protocol
, flags
, (void *)si_libinfo_addrinfo_callback
, sictx
);
2728 getaddrinfo_async_call(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, si_addrinfo_async_callback callback
, void *context
)
2730 return _getaddrinfo_interface_async_call(nodename
, servname
, hints
, NULL
, callback
, context
);
2735 getaddrinfo_async_start(mach_port_t
*p
, const char *nodename
, const char *servname
, const struct addrinfo
*hints
, si_addrinfo_async_callback callback
, void *context
)
2737 if (p
== NULL
) return EAI_SYSTEM
;
2739 *p
= getaddrinfo_async_call(nodename
, servname
, hints
, callback
, context
);
2741 if (*p
== MACH_PORT_NULL
) return EAI_SYSTEM
;
2747 getaddrinfo_async_send(mach_port_t
*p
, const char *nodename
, const char *servname
, const struct addrinfo
*hints
)
2749 return getaddrinfo_async_start(p
, nodename
, servname
, hints
, NULL
, NULL
);
2754 getaddrinfo_async_receive(mach_port_t p
, struct addrinfo
**res
)
2756 /* unsupported Leopard SPI */
2762 getaddrinfo_async_cancel(mach_port_t p
)
2765 fprintf(stderr
, "-- %s\n", __func__
);
2773 getaddrinfo_async_handle_reply(void *param
)
2775 mach_msg_header_t
*msg
;
2778 fprintf(stderr
, "<< %s\n", __func__
);
2781 msg
= (mach_msg_header_t
*)param
;
2782 si_async_handle_reply(msg
);
2790 _getnameinfo_interface_internal(const struct sockaddr
*sa
, socklen_t salen
, char *node
, socklen_t nodelen
, char *service
, socklen_t servicelen
, int flags
, const char *interface
)
2794 uint32_t status
, len
, wantn
, wants
;
2797 fprintf(stderr
, "-> %s\n", __func__
);
2800 status
= SI_STATUS_NO_ERROR
;
2803 if ((node
!= NULL
) && (nodelen
> 0)) wantn
= 1;
2806 if ((service
!= NULL
) && (servicelen
> 0)) wants
= 1;
2808 if ((wantn
== 0) && (wants
== 0)) return status
;
2810 if (wantn
== 0) flags
|= NI_NUMERICHOST
;
2811 if (wants
== 0) flags
|= NI_NUMERICSERV
;
2813 item
= si_nameinfo(si_search(), sa
, flags
, interface
, &status
);
2814 if ((status
!= SI_STATUS_NO_ERROR
) || (item
== NULL
))
2816 si_item_release(item
);
2818 if (status
== SI_STATUS_NO_ERROR
) status
= EAI_NONAME
;
2819 else if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2820 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2821 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2825 ni
= (si_nameinfo_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
2828 if (ni
->ni_node
!= NULL
) len
= strlen(ni
->ni_node
) + 1;
2829 if ((wantn
== 1) && (len
> 0))
2833 si_item_release(item
);
2834 return EAI_OVERFLOW
;
2837 memset(node
, 0, nodelen
);
2838 memcpy(node
, ni
->ni_node
, len
);
2842 if (ni
->ni_serv
!= NULL
) len
= strlen(ni
->ni_serv
) + 1;
2843 if ((wants
== 1) && (len
> 0))
2845 if (len
> servicelen
)
2847 si_item_release(item
);
2848 return EAI_OVERFLOW
;
2851 memset(service
, 0, servicelen
);
2852 memcpy(service
, ni
->ni_serv
, len
);
2855 si_item_release(item
);
2861 getnameinfo(const struct sockaddr
*sa
, socklen_t salen
, char *node
, socklen_t nodelen
, char *service
, socklen_t servicelen
, int flags
)
2863 if (sa
== NULL
) return EAI_FAIL
;
2865 if (sa
->sa_family
== AF_LINK
) return getnameinfo_link(sa
, salen
, node
, nodelen
, service
, servicelen
, flags
);
2866 return _getnameinfo_interface_internal(sa
, salen
, node
, nodelen
, service
, servicelen
, flags
, NULL
);
2870 si_libinfo_nameinfo_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
2872 si_context_t
*sictx
;
2876 if (ctx
== NULL
) return;
2878 sictx
= (si_context_t
*)ctx
;
2880 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
2882 si_item_release(item
);
2887 if (status
!= SI_STATUS_NO_ERROR
)
2889 if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2890 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2891 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2896 ((si_nameinfo_async_callback
)(sictx
->orig_callback
))(status
, NULL
, NULL
, sictx
->orig_context
);
2901 LI_set_thread_item(CATEGORY_NAMEINFO
, item
);
2906 ni
= (si_nameinfo_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
2907 if (ni
->ni_node
!= NULL
) node
= strdup(ni
->ni_node
);
2908 if (ni
->ni_serv
!= NULL
) serv
= strdup(ni
->ni_serv
);
2910 ((si_nameinfo_async_callback
)(sictx
->orig_callback
))(status
, node
, serv
, sictx
->orig_context
);
2917 _getnameinfo_interface_async_call(const struct sockaddr
*sa
, size_t len
, int flags
, const char *interface
, si_nameinfo_async_callback callback
, void *context
)
2919 si_context_t
*sictx
;
2923 fprintf(stderr
, ">> %s\n", __func__
);
2926 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2927 if (sictx
== NULL
) return MACH_PORT_NULL
;
2929 sictx
->orig_callback
= callback
;
2930 sictx
->orig_context
= context
;
2931 sictx
->cat
= CATEGORY_ADDRINFO
;
2932 sictx
->key_offset
= 0;
2934 /* sa is not a C string - pass length in num3 */
2936 return si_async_call(si_search(), SI_CALL_NAMEINFO
, (const char *)sa
, NULL
, interface
, flags
, 0, salen
, 0, (void *)si_libinfo_nameinfo_callback
, sictx
);
2940 getnameinfo_async_call(const struct sockaddr
*sa
, size_t len
, int flags
, si_nameinfo_async_callback callback
, void *context
)
2942 return _getnameinfo_interface_async_call(sa
, len
, flags
, NULL
, callback
, context
);
2947 getnameinfo_async_start(mach_port_t
*p
, const struct sockaddr
*sa
, size_t salen
, int flags
, si_nameinfo_async_callback callback
, void *context
)
2949 if (p
== NULL
) return EAI_SYSTEM
;
2950 *p
= getnameinfo_async_call(sa
, salen
, flags
, callback
, context
);
2952 if (*p
== MACH_PORT_NULL
) return EAI_SYSTEM
;
2958 getnameinfo_async_send(mach_port_t
*p
, const struct sockaddr
*sa
, size_t salen
, int flags
)
2960 return getnameinfo_async_start(p
, sa
, salen
, flags
, NULL
, NULL
);
2965 getnameinfo_async_cancel(mach_port_t p
)
2968 fprintf(stderr
, "-- %s\n", __func__
);
2976 getnameinfo_async_handle_reply(void *param
)
2978 mach_msg_header_t
*msg
;
2981 fprintf(stderr
, "<< %s\n", __func__
);
2984 msg
= (mach_msg_header_t
*)param
;
2985 si_async_handle_reply(msg
);
2990 /* getpwXXX_r and getgrXXX_r */
2993 copy_user_r(struct passwd
*in
, struct passwd
*out
, char *buffer
, int buflen
)
2998 if (in
== NULL
) return -1;
2999 if (out
== NULL
) return -1;
3001 if (buffer
== NULL
) buflen
= 0;
3003 /* Calculate size of input */
3005 if (in
->pw_name
!= NULL
) hsize
+= (strlen(in
->pw_name
) + 1);
3006 if (in
->pw_passwd
!= NULL
) hsize
+= (strlen(in
->pw_passwd
) + 1);
3007 if (in
->pw_class
!= NULL
) hsize
+= (strlen(in
->pw_class
) + 1);
3008 if (in
->pw_gecos
!= NULL
) hsize
+= (strlen(in
->pw_gecos
) + 1);
3009 if (in
->pw_dir
!= NULL
) hsize
+= (strlen(in
->pw_dir
) + 1);
3010 if (in
->pw_shell
!= NULL
) hsize
+= (strlen(in
->pw_shell
) + 1);
3012 /* Check buffer space */
3013 if (hsize
> buflen
) return -1;
3015 /* Copy result into caller's struct passwd, using buffer for memory */
3018 out
->pw_name
= NULL
;
3019 if (in
->pw_name
!= NULL
)
3022 hsize
= strlen(in
->pw_name
) + 1;
3023 memmove(bp
, in
->pw_name
, hsize
);
3027 out
->pw_passwd
= NULL
;
3028 if (in
->pw_passwd
!= NULL
)
3030 out
->pw_passwd
= bp
;
3031 hsize
= strlen(in
->pw_passwd
) + 1;
3032 memmove(bp
, in
->pw_passwd
, hsize
);
3036 out
->pw_uid
= in
->pw_uid
;
3038 out
->pw_gid
= in
->pw_gid
;
3040 out
->pw_change
= in
->pw_change
;
3042 out
->pw_class
= NULL
;
3043 if (in
->pw_class
!= NULL
)
3046 hsize
= strlen(in
->pw_class
) + 1;
3047 memmove(bp
, in
->pw_class
, hsize
);
3051 out
->pw_gecos
= NULL
;
3052 if (in
->pw_gecos
!= NULL
)
3055 hsize
= strlen(in
->pw_gecos
) + 1;
3056 memmove(bp
, in
->pw_gecos
, hsize
);
3061 if (in
->pw_dir
!= NULL
)
3064 hsize
= strlen(in
->pw_dir
) + 1;
3065 memmove(bp
, in
->pw_dir
, hsize
);
3069 out
->pw_shell
= NULL
;
3070 if (in
->pw_shell
!= NULL
)
3073 hsize
= strlen(in
->pw_shell
) + 1;
3074 memmove(bp
, in
->pw_shell
, hsize
);
3078 out
->pw_expire
= in
->pw_expire
;
3084 copy_group_r(struct group
*in
, struct group
*out
, char *buffer
, int buflen
)
3090 if (in
== NULL
) return -1;
3091 if (out
== NULL
) return -1;
3093 if (buffer
== NULL
) buflen
= 0;
3095 /* Calculate size of input */
3097 if (in
->gr_name
!= NULL
) hsize
+= (strlen(in
->gr_name
) + 1);
3098 if (in
->gr_passwd
!= NULL
) hsize
+= (strlen(in
->gr_passwd
) + 1);
3100 /* NULL pointer at end of list */
3101 hsize
+= sizeof(char *);
3104 if (in
->gr_mem
!= NULL
)
3106 for (len
= 0; in
->gr_mem
[len
] != NULL
; len
++)
3108 hsize
+= sizeof(char *);
3109 hsize
+= (strlen(in
->gr_mem
[len
]) + 1);
3113 /* Check buffer space */
3114 if (hsize
> buflen
) return -1;
3116 /* Copy result into caller's struct group, using buffer for memory */
3119 out
->gr_name
= NULL
;
3120 if (in
->gr_name
!= NULL
)
3123 hsize
= strlen(in
->gr_name
) + 1;
3124 memmove(bp
, in
->gr_name
, hsize
);
3128 out
->gr_passwd
= NULL
;
3129 if (in
->gr_passwd
!= NULL
)
3131 out
->gr_passwd
= bp
;
3132 hsize
= strlen(in
->gr_passwd
) + 1;
3133 memmove(bp
, in
->gr_passwd
, hsize
);
3137 out
->gr_gid
= in
->gr_gid
;
3140 ap
= bp
+ ((len
+ 1) * sizeof(char *));
3142 if (in
->gr_mem
!= NULL
)
3144 out
->gr_mem
= (char **)bp
;
3145 for (i
= 0; i
< len
; i
++)
3147 addr
= (unsigned long)ap
;
3148 memmove(bp
, &addr
, sizeof(unsigned long));
3149 bp
+= sizeof(unsigned long);
3151 hsize
= strlen(in
->gr_mem
[i
]) + 1;
3152 memmove(ap
, in
->gr_mem
[i
], hsize
);
3157 memset(bp
, 0, sizeof(unsigned long));
3165 getgrnam_r(const char *name
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
3172 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
3175 if (result
!= NULL
) *result
= NULL
;
3177 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3179 item
= si_group_byname(si_search(), name
);
3180 if (item
== NULL
) return 0;
3182 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
3184 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
3185 si_item_release(item
);
3187 if (status
!= 0) return ERANGE
;
3195 getgrgid_r(gid_t gid
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
3202 fprintf(stderr
, "-> %s %d\n", __func__
, gid
);
3205 if (result
!= NULL
) *result
= NULL
;
3207 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3209 item
= si_group_bygid(si_search(), gid
);
3210 if (item
== NULL
) return 0;
3212 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
3214 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
3215 si_item_release(item
);
3217 if (status
!= 0) return ERANGE
;
3225 getgruuid_r(uuid_t uuid
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
3232 uuid_string_t uuidstr
;
3233 uuid_unparse_upper(uuid
, uuidstr
);
3234 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
3237 if (result
!= NULL
) *result
= NULL
;
3239 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3241 item
= si_group_byuuid(si_search(), uuid
);
3242 if (item
== NULL
) return 0;
3244 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
3246 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
3247 si_item_release(item
);
3249 if (status
!= 0) return ERANGE
;
3257 getpwnam_r(const char *name
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3264 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
3267 if (result
!= NULL
) *result
= NULL
;
3269 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3271 item
= si_user_byname(si_search(), name
);
3272 if (item
== NULL
) return 0;
3274 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3276 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3277 si_item_release(item
);
3279 if (status
!= 0) return ERANGE
;
3287 getpwuid_r(uid_t uid
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3289 si_item_t
*item
= NULL
;
3294 fprintf(stderr
, "-> %s %d\n", __func__
, uid
);
3297 if (result
!= NULL
) *result
= NULL
;
3299 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3301 // Search the file module first for all system uids
3302 // (ie, uid value < 500) since they should all be
3303 // in the /etc/*passwd file.
3304 if (uid
< SYSTEM_UID_LIMIT
)
3305 item
= si_user_byuid(si_search_file(), uid
);
3308 item
= si_user_byuid(si_search(), uid
);
3309 if (item
== NULL
) return 0;
3311 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3313 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3314 si_item_release(item
);
3316 if (status
!= 0) return ERANGE
;
3324 getpwuuid_r(uuid_t uuid
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3331 uuid_string_t uuidstr
;
3332 uuid_unparse_upper(uuid
, uuidstr
);
3333 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
3336 if (result
!= NULL
) *result
= NULL
;
3338 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3340 item
= si_user_byuuid(si_search(), uuid
);
3341 if (item
== NULL
) return 0;
3343 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3345 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3346 si_item_release(item
);
3348 if (status
!= 0) return ERANGE
;
3358 user_from_uid(uid_t uid
, int nouser
)
3361 static char buf
[16];
3364 if (pw
!= NULL
) return pw
->pw_name
;
3366 if (nouser
) return NULL
;
3368 snprintf(buf
, sizeof(buf
), "%u", uid
);
3374 group_from_gid(gid_t gid
, int nogroup
)
3377 static char buf
[16];
3380 if (gr
!= NULL
) return gr
->gr_name
;
3382 if (nogroup
) return NULL
;
3384 snprintf(buf
, sizeof(buf
), "%u", gid
);
3388 /* no longer supported */
3392 prdb_getbyname(const char *name
)
3395 fprintf(stderr
, "~~ %s\n", __func__
);
3405 fprintf(stderr
, "~~ %s\n", __func__
);
3412 prdb_set(const char *name
)
3415 fprintf(stderr
, "~~ %s\n", __func__
);
3424 fprintf(stderr
, "~~ %s\n", __func__
);
3429 struct bootparamsent
*
3430 bootparams_getbyname(const char *name
)
3433 fprintf(stderr
, "~~ %s\n", __func__
);
3439 struct bootparamsent
*
3440 bootparams_getent(void)
3443 fprintf(stderr
, "~~ %s\n", __func__
);
3450 bootparams_setent(void)
3453 fprintf(stderr
, "~~ %s\n", __func__
);
3459 bootparams_endent(void)
3462 fprintf(stderr
, "~~ %s\n", __func__
);
3467 bootp_getbyether(struct ether_addr
*enaddr
, char **name
,struct in_addr
*ipaddr
, char **bootfile
)
3470 fprintf(stderr
, "~~ %s\n", __func__
);
3476 bootp_getbyip(struct ether_addr
*enaddr
, char **name
, struct in_addr
*ipaddr
, char **bootfile
)
3479 fprintf(stderr
, "~~ %s\n", __func__
);