2 * Copyright (c) 2008-2015 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@
31 #include <printerdb.h>
32 #include <sys/param.h>
33 #include <sys/syscall.h>
35 #include <arpa/inet.h>
36 #include <netinet/if_ether.h>
37 #include "si_module.h"
39 #include <thread_data.h>
40 #include <sys/kauth.h>
41 #include "netdb_async.h"
42 #include <dispatch/dispatch.h>
43 #include <mach-o/dyld_priv.h>
47 #define IPPROTO_UNSPEC 0
48 #define IPV6_ADDR_LEN 16
49 #define IPV4_ADDR_LEN 4
52 extern int __initgroups(u_int gidsetsize
, gid_t
*gidset
, int gmuid
);
54 /* SPI from long ago */
57 extern struct addrinfo
*si_list_to_addrinfo(si_list_t
*list
);
58 extern int getnameinfo_link(const struct sockaddr
*sa
, socklen_t salen
, char *host
, size_t hostlen
, char *serv
, size_t servlen
, int flags
);
59 __private_extern__
void search_set_flags(si_mod_t
*si
, const char *name
, uint32_t flag
);
62 * Impedence matching for async calls.
64 * This layer holds on to the caller's callback and context in this
65 * structure, which gets passed to the si_module async routines along
66 * with a callbac in this layer. When this layer gets a callback,
67 * it can save the item or list in thread-specific memory and then
68 * invoke the caller's callback with the appropriate data type.
82 static si_mod_t
*search
= NULL
;
84 if (search
== NULL
) search
= si_module_with_name("search");
90 si_search_module_set_flags(const char *name
, uint32_t flag
)
92 search_set_flags(si_search(), name
, flag
);
96 si_libinfo_general_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
104 struct grouplist_s
*l
;
113 if (ctx
== NULL
) return;
115 sictx
= (si_context_t
*)ctx
;
117 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
120 si_item_release(item
);
124 if (sictx
->key_offset
>= 0)
126 LI_set_thread_item(sictx
->cat
+ sictx
->key_offset
, item
);
130 if (item
!= NULL
) res
.x
= (char*)((uintptr_t)item
+ sizeof(si_item_t
));
136 ((si_user_async_callback
)(sictx
->orig_callback
))(res
.u
, sictx
->orig_context
);
141 ((si_group_async_callback
)(sictx
->orig_callback
))(res
.g
, sictx
->orig_context
);
144 case CATEGORY_GROUPLIST
:
146 ((si_grouplist_async_callback
)(sictx
->orig_callback
))(res
.l
, sictx
->orig_context
);
149 case CATEGORY_HOST_IPV4
:
150 case CATEGORY_HOST_IPV6
:
152 ((si_host_async_callback
)(sictx
->orig_callback
))(res
.h
, sictx
->orig_context
);
155 case CATEGORY_NETWORK
:
157 ((si_network_async_callback
)(sictx
->orig_callback
))(res
.n
, sictx
->orig_context
);
160 case CATEGORY_SERVICE
:
162 ((si_service_async_callback
)(sictx
->orig_callback
))(res
.s
, sictx
->orig_context
);
165 case CATEGORY_PROTOCOL
:
167 ((si_protocol_async_callback
)(sictx
->orig_callback
))(res
.p
, sictx
->orig_context
);
172 ((si_rpc_async_callback
)(sictx
->orig_callback
))(res
.r
, sictx
->orig_context
);
177 ((si_fs_async_callback
)(sictx
->orig_callback
))(res
.f
, sictx
->orig_context
);
188 getpwnam(const char *name
)
193 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
195 #if TARGET_OS_EMBEDDED
196 if (strcmp(name
,"mobile") == 0) {
198 struct passwd
* pw
= NULL
;
200 if (lstat("/private/var/mobile",&buf
) == 0) {
201 if ((pw
= getpwuid(buf
.st_uid
)) != NULL
) {
206 #endif /* TARGET_OS_EMBEDDED */
207 item
= si_user_byname(si_search(), name
);
208 LI_set_thread_item(CATEGORY_USER
+ 100, item
);
210 if (item
== NULL
) return NULL
;
211 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
215 getpwnam_async_call(const char *name
, si_user_async_callback callback
, void *context
)
220 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
223 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
224 if (sictx
== NULL
) return MACH_PORT_NULL
;
226 sictx
->orig_callback
= callback
;
227 sictx
->orig_context
= context
;
228 sictx
->cat
= CATEGORY_USER
;
229 sictx
->key_offset
= 100;
231 return si_async_call(si_search(), SI_CALL_USER_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
235 getpwnam_async_handle_reply(mach_msg_header_t
*msg
)
238 fprintf(stderr
, "<< %s\n", __func__
);
241 si_async_handle_reply(msg
);
250 fprintf(stderr
, "-> %s %d\n", __func__
, uid
);
254 #if TARGET_OS_EMBEDDED
255 uid_t localuid
= uid
;
260 if (lstat("/private/var/mobile",&buf
) == 0) {
261 localuid
= buf
.st_uid
;
264 item
= si_user_byuid(si_search(), localuid
);
265 #else /* TARGET_OS_EMBEDDED */
266 item
= si_user_byuid(si_search(), uid
);
267 #endif /* TARGET_OS_EMBEDDED */
268 LI_set_thread_item(CATEGORY_USER
+ 200, item
);
270 if (item
== NULL
) return NULL
;
271 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
275 getpwuid_async_call(uid_t uid
, si_user_async_callback callback
, void *context
)
280 fprintf(stderr
, ">> %s %d\n", __func__
, uid
);
283 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
284 if (sictx
== NULL
) return MACH_PORT_NULL
;
286 sictx
->orig_callback
= callback
;
287 sictx
->orig_context
= context
;
288 sictx
->cat
= CATEGORY_USER
;
289 sictx
->key_offset
= 200;
291 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
);
295 getpwuid_async_handle_reply(mach_msg_header_t
*msg
)
298 fprintf(stderr
, "<< %s\n", __func__
);
301 si_async_handle_reply(msg
);
305 getpwuuid(uuid_t uuid
)
310 uuid_string_t uuidstr
;
311 uuid_unparse_upper(uuid
, uuidstr
);
312 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
315 item
= si_user_byuuid(si_search(), uuid
);
316 LI_set_thread_item(CATEGORY_USER
+ 300, item
);
318 if (item
== NULL
) return NULL
;
319 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
326 fprintf(stderr
, "-- %s\n", __func__
);
329 LI_set_thread_list(CATEGORY_USER
, NULL
);
339 fprintf(stderr
, "-> %s\n", __func__
);
342 list
= LI_get_thread_list(CATEGORY_USER
);
345 list
= si_user_all(si_search());
346 LI_set_thread_list(CATEGORY_USER
, list
);
349 item
= si_list_next(list
);
350 if (item
== NULL
) return NULL
;
352 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
359 fprintf(stderr
, "-- %s\n", __func__
);
362 LI_set_thread_list(CATEGORY_USER
, NULL
);
366 setpassent(int ignored
)
371 fprintf(stderr
, "-> %s\n", __func__
);
374 list
= LI_get_thread_list(CATEGORY_USER
);
377 if (list
== NULL
) return 0;
384 getgrnam(const char *name
)
389 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
392 item
= si_group_byname(si_search(), name
);
393 LI_set_thread_item(CATEGORY_GROUP
+ 100, item
);
395 if (item
== NULL
) return NULL
;
396 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
400 getgrnam_async_call(const char *name
, si_group_async_callback callback
, void *context
)
405 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
408 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
409 if (sictx
== NULL
) return MACH_PORT_NULL
;
411 sictx
->orig_callback
= callback
;
412 sictx
->orig_context
= context
;
413 sictx
->cat
= CATEGORY_GROUP
;
414 sictx
->key_offset
= 100;
416 return si_async_call(si_search(), SI_CALL_GROUP_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
420 getgrnam_async_handle_reply(mach_msg_header_t
*msg
)
423 fprintf(stderr
, "<< %s\n", __func__
);
426 si_async_handle_reply(msg
);
435 fprintf(stderr
, "-> %s %d\n", __func__
, gid
);
438 item
= si_group_bygid(si_search(), gid
);
439 LI_set_thread_item(CATEGORY_GROUP
+ 200, item
);
441 if (item
== NULL
) return NULL
;
442 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
446 getgrgid_async_call(gid_t gid
, si_group_async_callback callback
, void *context
)
451 fprintf(stderr
, ">> %s %d\n", __func__
, gid
);
454 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
455 if (sictx
== NULL
) return MACH_PORT_NULL
;
457 sictx
->orig_callback
= callback
;
458 sictx
->orig_context
= context
;
459 sictx
->cat
= CATEGORY_GROUP
;
460 sictx
->key_offset
= 200;
462 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
);
466 getgruid_async_handle_reply(mach_msg_header_t
*msg
)
469 fprintf(stderr
, "<< %s\n", __func__
);
472 si_async_handle_reply(msg
);
476 getgruuid(uuid_t uuid
)
481 uuid_string_t uuidstr
;
482 uuid_unparse_upper(uuid
, uuidstr
);
483 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
486 item
= si_group_byuuid(si_search(), uuid
);
487 LI_set_thread_item(CATEGORY_GROUP
+ 300, item
);
489 if (item
== NULL
) return NULL
;
490 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
497 fprintf(stderr
, "-- %s\n", __func__
);
500 LI_set_thread_list(CATEGORY_GROUP
, NULL
);
510 fprintf(stderr
, "-> %s\n", __func__
);
513 list
= LI_get_thread_list(CATEGORY_GROUP
);
516 list
= si_group_all(si_search());
517 LI_set_thread_list(CATEGORY_GROUP
, list
);
520 item
= si_list_next(list
);
521 if (item
== NULL
) return NULL
;
523 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
530 fprintf(stderr
, "-- %s\n", __func__
);
533 LI_set_thread_list(CATEGORY_GROUP
, NULL
);
537 setgroupent(int ignored
)
542 fprintf(stderr
, "-> %s\n", __func__
);
545 list
= LI_get_thread_list(CATEGORY_GROUP
);
548 if (list
== NULL
) return 0;
554 innetgr(const char *group
, const char *host
, const char *user
, const char *domain
)
558 fprintf(stderr
, "-> %s %s %s %s %s\n", __func__
, group
, host
, user
, domain
);
561 res
= si_in_netgroup(si_search(), group
, host
, user
, domain
);
564 fprintf(stderr
, "<- %s %d\n", __func__
, res
);
570 /* N.B. there is no async innetgr */
573 * setnetgrent is really more like a getXXXbyname routine than a
574 * setXXXent routine, since we are looking up a netgroup by name.
577 setnetgrent(const char *name
)
582 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
585 list
= si_netgroup_byname(si_search(), name
);
586 LI_set_thread_list(CATEGORY_NETGROUP
, list
);
589 /* N.B. there is no async getnetgrent */
592 getnetgrent(char **host
, char **user
, char **domain
)
596 struct netgrent_s
*ng
;
599 fprintf(stderr
, "-> %s\n", __func__
);
602 list
= LI_get_thread_list(CATEGORY_NETGROUP
);
603 item
= si_list_next(list
);
604 if (item
== NULL
) return 0;
606 ng
= (struct netgrent_s
*)((uintptr_t)item
+ sizeof(si_item_t
));
610 *domain
= ng
->ng_domain
;
619 fprintf(stderr
, "-- %s\n", __func__
);
622 LI_set_thread_list(CATEGORY_NETGROUP
, NULL
);
627 _check_groups(const char *function
, int32_t ngroups
)
629 static dispatch_once_t once
;
631 if (ngroups
> 0 && ngroups
< NGROUPS_MAX
) {
635 /* only log once per process */
636 dispatch_once(&once
, ^(void) {
637 const char *proc_name
= getprogname();
638 if (strcmp(proc_name
, "id") != 0 && strcmp(proc_name
, "smbd") != 0 && strcmp(proc_name
, "rpcsvchost") != 0) {
639 aslmsg msg
= asl_new(ASL_TYPE_MSG
);
642 snprintf(buffer
, sizeof(buffer
), "%d", (ngroups
== 0 ? INT_MAX
: ngroups
));
643 asl_set(msg
, "com.apple.message.value", buffer
);
645 asl_set(msg
, "com.apple.message.domain", "com.apple.system.libinfo");
646 asl_set(msg
, "com.apple.message.result", "noop");
647 asl_set(msg
, "com.apple.message.signature", function
);
649 asl_log(NULL
, msg
, ASL_LEVEL_NOTICE
, "%s called triggering group enumeration", function
);
660 getgrouplist_internal(const char *name
, int basegid
, gid_t
*groups
, uint32_t *ngroups
)
662 int i
, j
, x
, g
, add
, max
;
667 * On input, ngroups specifies the size of the groups array.
668 * On output, it is set to the number of groups that are being returned.
669 * Returns -1 if the size is too small to fit all the groups that were found.
673 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
676 if (name
== NULL
) return 0;
677 if (groups
== NULL
) return 0;
678 if (ngroups
== NULL
) return 0;
682 if (max
<= 0) return 0;
687 item
= si_grouplist(si_search(), name
, max
);
688 LI_set_thread_item(CATEGORY_GROUPLIST
, item
);
689 if (item
== NULL
) return 0;
691 gl
= (si_grouplist_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
695 for (i
= 0; i
< gl
->gl_count
; i
++)
699 for (j
= 0; j
< x
; j
++) {
700 if (groups
[j
] == g
) {
705 if (add
== 0) continue;
707 if (x
>= max
) return -1;
717 getgrouplist(const char *name
, int basegid
, int *groups
, int *ngroups
)
720 _check_groups("getgrouplist", *ngroups
);
723 return getgrouplist_internal(name
, basegid
, (gid_t
*)groups
, (uint32_t *)ngroups
);
727 merge_gid(gid_t
*list
, gid_t g
, int32_t *count
)
733 for (i
= 0; i
< cnt
; i
++) {
734 if (list
[i
] == g
) return;
742 _getgrouplist_2_internal(const char *name
, gid_t basegid
, gid_t
**groups
)
749 item
= si_grouplist(si_search(), name
, INT_MAX
);
750 LI_set_thread_item(CATEGORY_GROUPLIST
, item
);
751 if (item
== NULL
) return -1;
753 gl
= (si_grouplist_t
*) ((uintptr_t) item
+ sizeof(si_item_t
));
756 * we can allocate enough up-front, we'll only use what we need
757 * we add one to the count that was found in case the basegid is not there
759 gids
= calloc(gl
->gl_count
+ 1, sizeof(gid_t
));
760 if (gids
== NULL
) return -1;
763 merge_gid(gids
, basegid
, &count
);
764 if (gl
->gl_gid
!= NULL
) {
765 for (i
= 0; i
< gl
->gl_count
; i
++) {
766 merge_gid(gids
, gl
->gl_gid
[i
], &count
);
776 getgrouplist_2(const char *name
, gid_t basegid
, gid_t
**groups
)
779 * Passes back a gid_t list containing all the users groups (and basegid).
780 * Caller must free the list.
781 * Returns the number of gids in the list or -1 on failure.
785 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
788 if (name
== NULL
) return 0;
789 if (groups
== NULL
) return 0;
792 _check_groups("getgrouplist_2", INT_MAX
);
795 return _getgrouplist_2_internal(name
, basegid
, groups
);
799 getgroupcount(const char *name
, gid_t basegid
)
805 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
809 _check_groups("getgroupcount", INT_MAX
);
813 count
= _getgrouplist_2_internal(name
, basegid
, &groups
);
814 if (groups
!= NULL
) free(groups
);
819 /* XXX to do: async getgrouplist_2 */
822 initgroups(const char *name
, int basegid
)
826 gid_t groups
[NGROUPS
];
834 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
837 /* KAUTH_UID_NONE tells the kernel not to fetch supplementary groups from DirectoryService */
838 uid
= KAUTH_UID_NONE
;
841 /* get the UID for this user */
842 item
= si_user_byname(si_search(), name
);
845 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
847 si_item_release(item
);
855 * A failure either means that user belongs to more than NGROUPS groups
856 * or no groups at all.
859 (void) getgrouplist_internal(name
, basegid
, groups
, &ngroups
);
861 status
= __initgroups(ngroups
, groups
, uid
);
862 if (status
< 0) return -1;
870 alias_getbyname(const char *name
)
875 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
878 item
= si_alias_byname(si_search(), name
);
879 LI_set_thread_item(CATEGORY_ALIAS
+ 100, item
);
880 if (item
== NULL
) return NULL
;
882 return (struct aliasent
*)((uintptr_t)item
+ sizeof(si_item_t
));
886 alias_getbyname_async_call(const char *name
, si_alias_async_callback callback
, void *context
)
891 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
894 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
895 if (sictx
== NULL
) return MACH_PORT_NULL
;
897 sictx
->orig_callback
= callback
;
898 sictx
->orig_context
= context
;
899 sictx
->cat
= CATEGORY_ALIAS
;
900 sictx
->key_offset
= 100;
902 return si_async_call(si_search(), SI_CALL_ALIAS_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
906 alias_getbyname_async_handle_reply(mach_msg_header_t
*msg
)
909 fprintf(stderr
, "<< %s\n", __func__
);
912 si_async_handle_reply(msg
);
919 fprintf(stderr
, "-> %s\n", __func__
);
922 LI_set_thread_list(CATEGORY_ALIAS
, NULL
);
932 fprintf(stderr
, "-> %s\n", __func__
);
935 list
= LI_get_thread_list(CATEGORY_ALIAS
);
938 list
= si_alias_all(si_search());
939 LI_set_thread_list(CATEGORY_ALIAS
, list
);
942 item
= si_list_next(list
);
943 if (item
== NULL
) return NULL
;
945 return (struct aliasent
*)((uintptr_t)item
+ sizeof(si_item_t
));
952 fprintf(stderr
, "-- %s\n", __func__
);
955 LI_set_thread_list(CATEGORY_ALIAS
, NULL
);
961 freehostent(struct hostent
*h
)
963 if (h
== NULL
) return;
965 si_item_t
*item
= (si_item_t
*)((uintptr_t)h
- sizeof(si_item_t
));
966 si_item_release(item
);
970 gethostbynameerrno(const char *name
, int *err
)
974 struct in_addr addr4
;
977 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
980 memset(&addr4
, 0, sizeof(struct in_addr
));
981 status
= SI_STATUS_NO_ERROR
;
984 if (inet_aton(name
, &addr4
) == 1) item
= si_ipnode_byname(si_search(), name
, AF_INET
, 0, NULL
, &status
);
985 else item
= si_host_byname(si_search(), name
, AF_INET
, NULL
, &status
);
987 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
988 if (err
!= NULL
) *err
= status
;
990 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
991 if (item
== NULL
) return NULL
;
993 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
997 gethostbyname(const char *name
)
1001 struct in_addr addr4
;
1004 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1007 memset(&addr4
, 0, sizeof(struct in_addr
));
1008 status
= SI_STATUS_NO_ERROR
;
1011 if (inet_aton(name
, &addr4
) == 1) item
= si_ipnode_byname(si_search(), name
, AF_INET
, 0, NULL
, &status
);
1012 else item
= si_host_byname(si_search(), name
, AF_INET
, NULL
, &status
);
1014 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1017 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
1018 if (item
== NULL
) return NULL
;
1020 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1024 gethostbyname_async_call(const char *name
, si_host_async_callback callback
, void *context
)
1026 si_context_t
*sictx
;
1029 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1032 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1033 if (sictx
== NULL
) return MACH_PORT_NULL
;
1035 sictx
->orig_callback
= callback
;
1036 sictx
->orig_context
= context
;
1037 sictx
->cat
= CATEGORY_HOST
;
1038 sictx
->key_offset
= 100;
1040 return si_async_call(si_search(), SI_CALL_HOST_BYNAME
, name
, NULL
, NULL
, AF_INET
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1044 gethostbyname_async_start(const char *name
, si_host_async_callback callback
, void *context
)
1046 return gethostbyname_async_call(name
, callback
, context
);
1050 gethostbyname_async_cancel(mach_port_t p
)
1053 fprintf(stderr
, "-- %s\n", __func__
);
1061 gethostbyname_async_handle_reply(void *param
)
1063 mach_msg_header_t
*msg
;
1066 fprintf(stderr
, "<< %s\n", __func__
);
1069 msg
= (mach_msg_header_t
*)param
;
1070 si_async_handle_reply(msg
);
1075 gethostbyname_async_handleReply(void *param
)
1077 mach_msg_header_t
*msg
;
1080 fprintf(stderr
, "<< %s\n", __func__
);
1083 msg
= (mach_msg_header_t
*)param
;
1084 si_async_handle_reply(msg
);
1088 gethostbyname2(const char *name
, int af
)
1092 struct in_addr addr4
;
1093 struct in6_addr addr6
;
1094 si_mod_t
*search
= si_search();
1097 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, af
);
1100 memset(&addr4
, 0, sizeof(struct in_addr
));
1101 memset(&addr6
, 0, sizeof(struct in6_addr
));
1102 status
= SI_STATUS_NO_ERROR
;
1105 if (((af
== AF_INET
) && (inet_aton(name
, &addr4
) == 1)) || ((af
== AF_INET6
) && (inet_pton(af
, name
, &addr6
) == 1)))
1107 item
= si_ipnode_byname(search
, name
, (uint32_t)af
, 0, NULL
, &status
);
1111 item
= si_host_byname(search
, name
, (uint32_t)af
, NULL
, &status
);
1114 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1117 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
1118 if (item
== NULL
) return NULL
;
1120 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1124 gethostbyname2_async_call(const char *name
, int af
, si_group_async_callback callback
, void *context
)
1126 si_context_t
*sictx
;
1129 fprintf(stderr
, ">> %s %s %d\n", __func__
, name
, af
);
1132 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1133 if (sictx
== NULL
) return MACH_PORT_NULL
;
1135 sictx
->orig_callback
= callback
;
1136 sictx
->orig_context
= context
;
1137 sictx
->cat
= CATEGORY_HOST
;
1138 sictx
->key_offset
= 100;
1140 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
);
1144 gethostbyname2_async_cancel(mach_port_t p
)
1147 fprintf(stderr
, "-- %s\n", __func__
);
1154 gethostbyname2_async_handle_reply(mach_msg_header_t
*msg
)
1157 fprintf(stderr
, "<< %s\n", __func__
);
1160 si_async_handle_reply(msg
);
1164 gethostbyaddr(const void *addr
, socklen_t len
, int type
)
1170 fprintf(stderr
, "-> %s %s\n", __func__
, (type
== AF_INET
) ?
inet_ntoa(*(struct in_addr
*)addr
) : "-IPv6-");
1173 status
= SI_STATUS_NO_ERROR
;
1175 item
= si_host_byaddr(si_search(), addr
, (uint32_t)type
, NULL
, &status
);
1176 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1179 LI_set_thread_item(CATEGORY_HOST
+ 200, item
);
1180 if (item
== NULL
) return NULL
;
1182 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1186 gethostbyaddr_async_call(const void *addr
, socklen_t len
, int type
, si_host_async_callback callback
, void *context
)
1188 si_context_t
*sictx
;
1192 fprintf(stderr
, ">> %s %s\n", __func__
, (type
== AF_INET
) ?
inet_ntoa(*(struct in_addr
*)addr
) : "-IPv6-");
1195 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1196 if (sictx
== NULL
) return MACH_PORT_NULL
;
1198 sictx
->orig_callback
= callback
;
1199 sictx
->orig_context
= context
;
1200 sictx
->cat
= CATEGORY_HOST
;
1201 sictx
->key_offset
= 200;
1203 /* addr is not a C string - pass length in num3 */
1205 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
);
1209 gethostbyaddr_async_start(const char *addr
, int len
, int family
, si_host_async_callback callback
, void *context
)
1211 socklen_t slen
= len
;
1213 return gethostbyaddr_async_call(addr
, slen
, family
, callback
, context
);
1217 gethostbyaddr_async_cancel(mach_port_t p
)
1220 fprintf(stderr
, "-- %s\n", __func__
);
1228 gethostbyaddr_async_handle_reply(void *param
)
1231 mach_msg_header_t
*msg
;
1234 fprintf(stderr
, "<< %s\n", __func__
);
1237 msg
= (mach_msg_header_t
*)param
;
1238 si_async_handle_reply(msg
);
1243 gethostbyaddr_async_handleReply(void *param
)
1245 mach_msg_header_t
*msg
;
1248 fprintf(stderr
, "<< %s\n", __func__
);
1251 msg
= (mach_msg_header_t
*)param
;
1252 si_async_handle_reply(msg
);
1256 getipnodebyname(const char *name
, int family
, int flags
, int *err
)
1262 fprintf(stderr
, "-> %s %s %d 0x%08x\n", __func__
, name
, family
, flags
);
1265 status
= SI_STATUS_NO_ERROR
;
1267 item
= si_ipnode_byname(si_search(), name
, family
, flags
, NULL
, &status
);
1268 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1269 if (err
!= NULL
) *err
= status
;
1271 if (item
== NULL
) return NULL
;
1273 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1278 getipnodebyname_async_call(const char *name
, int family
, int flags
, int *err
, si_host_async_callback callback
, void *context
)
1280 si_context_t
*sictx
;
1283 fprintf(stderr
, ">> %s %s %d 0x%08x\n", __func__
, name
, family
, flags
);
1286 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1287 if (sictx
== NULL
) return MACH_PORT_NULL
;
1289 sictx
->orig_callback
= callback
;
1290 sictx
->orig_context
= context
;
1291 sictx
->cat
= CATEGORY_HOST
;
1292 sictx
->key_offset
= -1;
1294 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
);
1298 getipnodebyname_async_start(const char *name
, int family
, int flags
, int *err
, si_host_async_callback callback
, void *context
)
1300 return getipnodebyname_async_call(name
, family
, flags
, err
, callback
, context
);
1304 getipnodebyname_async_cancel(mach_port_t p
)
1307 fprintf(stderr
, "-- %s\n", __func__
);
1314 getipnodebyname_async_handle_reply(mach_msg_header_t
*msg
)
1317 fprintf(stderr
, "<< %s\n", __func__
);
1320 si_async_handle_reply(msg
);
1324 getipnodebyname_async_handleReply(mach_msg_header_t
*msg
)
1327 fprintf(stderr
, "<< %s\n", __func__
);
1330 si_async_handle_reply(msg
);
1335 is_a4_mapped(const char *s
)
1340 if (s
== NULL
) return 0;
1342 for (i
= 0; i
< 10; i
++)
1345 if (c
!= 0x0) return 0;
1348 for (i
= 10; i
< 12; i
++)
1351 if (c
!= 0xff) return 0;
1358 is_a4_compat(const char *s
)
1363 if (s
== NULL
) return 0;
1365 for (i
= 0; i
< 12; i
++)
1368 if (c
!= 0x0) return 0;
1371 /* Check for :: and ::1 */
1372 for (i
= 13; i
< 15; i
++)
1374 /* anything non-zero in these 3 bytes means it's a V4 address */
1376 if (c
!= 0x0) return 1;
1379 /* Leading 15 bytes are all zero */
1381 if (c
== 0x0) return 0;
1382 if (c
== 0x1) return 0;
1388 getipnodebyaddr(const void *src
, size_t len
, int family
, int *err
)
1393 fprintf(stderr
, "-> %s %s\n", __func__
, (family
== AF_INET
) ?
inet_ntoa(*(struct in_addr
*)src
) : "-IPv6-");
1396 if ((family
== AF_INET6
) && (len
== IPV6_ADDR_LEN
) && (is_a4_mapped((const char *)src
) || is_a4_compat((const char *)src
)))
1403 item
= si_host_byaddr(si_search(), src
, family
, NULL
, (uint32_t *)err
);
1404 if (item
== NULL
) return NULL
;
1406 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1411 si_libinfo_ipnode_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
1413 si_context_t
*sictx
;
1416 if (ctx
== NULL
) return;
1418 sictx
= (si_context_t
*)ctx
;
1420 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
1423 si_item_release(item
);
1427 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1431 ((si_ipnode_async_callback
)(sictx
->orig_callback
))(NULL
, status
, sictx
->orig_context
);
1435 h
= (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1436 ((si_ipnode_async_callback
)(sictx
->orig_callback
))(h
, status
, sictx
->orig_context
);
1442 getipnodebyaddr_async_call(const void *src
, socklen_t len
, int family
, int *err
, si_ipnode_async_callback callback
, void *context
)
1444 si_context_t
*sictx
;
1448 fprintf(stderr
, ">> %s %s\n", __func__
, (family
== AF_INET
) ?
inet_ntoa(*(struct in_addr
*)src
) : "-IPv6-");
1451 if ((family
== AF_INET6
) && (len
== IPV6_ADDR_LEN
) && (is_a4_mapped((const char *)src
) || is_a4_compat((const char *)src
)))
1458 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1459 if (sictx
== NULL
) return MACH_PORT_NULL
;
1461 sictx
->orig_callback
= callback
;
1462 sictx
->orig_context
= context
;
1463 sictx
->cat
= CATEGORY_HOST
;
1464 sictx
->key_offset
= -1;
1466 /* src is not a C string - pass length in num3 */
1468 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
);
1472 getipnodebyaddr_async_start(const void *addr
, size_t len
, int family
, int *error
, si_ipnode_async_callback callback
, void *context
)
1474 socklen_t slen
= len
;
1476 return getipnodebyaddr_async_call(addr
, slen
, family
, error
, callback
, context
);
1480 getipnodebyaddr_async_cancel(mach_port_t p
)
1483 fprintf(stderr
, "-- %s\n", __func__
);
1490 getipnodebyaddr_async_handle_reply(mach_msg_header_t
*msg
)
1493 fprintf(stderr
, "<< %s\n", __func__
);
1496 si_async_handle_reply(msg
);
1500 getipnodebyaddr_async_handleReply(mach_msg_header_t
*msg
)
1503 fprintf(stderr
, "<< %s\n", __func__
);
1506 si_async_handle_reply(msg
);
1511 sethostent(int ignored
)
1514 fprintf(stderr
, "-- %s\n", __func__
);
1517 LI_set_thread_list(CATEGORY_HOST
, NULL
);
1527 fprintf(stderr
, "-> %s\n", __func__
);
1530 list
= LI_get_thread_list(CATEGORY_HOST
);
1533 list
= si_host_all(si_search());
1534 LI_set_thread_list(CATEGORY_HOST
, list
);
1537 item
= si_list_next(list
);
1538 if (item
== NULL
) return NULL
;
1540 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1547 fprintf(stderr
, "-- %s\n", __func__
);
1550 LI_set_thread_list(CATEGORY_HOST
, NULL
);
1556 ether_hostton(const char *name
, struct ether_addr
*e
)
1564 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1567 if (name
== NULL
) return -1;
1568 if (e
== NULL
) return -1;
1570 item
= si_mac_byname(si_search(), name
);
1571 LI_set_thread_item(CATEGORY_MAC
+ 100, item
);
1572 if (item
== NULL
) return -1;
1574 mac
= (si_mac_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
1576 i
= sscanf(mac
->mac
, " %x:%x:%x:%x:%x:%x", &t
[0], &t
[1], &t
[2], &t
[3], &t
[4], &t
[5]);
1577 if (i
!= 6) return -1;
1579 for (i
= 0; i
< 6; i
++) e
->ether_addr_octet
[i
] = t
[i
];
1583 /* XXX to do? async ether_hostton */
1586 ether_ntohost(char *name
, const struct ether_addr
*e
)
1593 if (name
== NULL
) return -1;
1594 if (e
== NULL
) return -1;
1596 for (i
= 0; i
< 6; i
++) x
[i
] = e
->ether_addr_octet
[i
];
1597 snprintf(str
, sizeof(str
), "%x:%x:%x:%x:%x:%x", x
[0], x
[1], x
[2], x
[3], x
[4], x
[5]);
1600 fprintf(stderr
, "-> %s %s\n", __func__
, str
);
1603 item
= si_mac_bymac(si_search(), str
);
1604 LI_set_thread_item(CATEGORY_MAC
+ 200, item
);
1605 if (item
== NULL
) return -1;
1607 mac
= (si_mac_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
1609 memcpy(name
, mac
->host
, strlen(mac
->host
) + 1);
1613 /* XXX to do? async ether_ntohost */
1618 getnetbyname(const char *name
)
1623 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1626 item
= si_network_byname(si_search(), name
);
1627 LI_set_thread_item(CATEGORY_NETWORK
+ 100, item
);
1628 if (item
== NULL
) return NULL
;
1630 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1634 getnetbyname_async_call(const char *name
, si_network_async_callback callback
, void *context
)
1636 si_context_t
*sictx
;
1639 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1642 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1643 if (sictx
== NULL
) return MACH_PORT_NULL
;
1645 sictx
->orig_callback
= callback
;
1646 sictx
->orig_context
= context
;
1647 sictx
->cat
= CATEGORY_NETWORK
;
1648 sictx
->key_offset
= 100;
1650 return si_async_call(si_search(), SI_CALL_NETWORK_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1654 getnetbyname_async_handle_reply(mach_msg_header_t
*msg
)
1657 fprintf(stderr
, "<< %s\n", __func__
);
1660 si_async_handle_reply(msg
);
1664 getnetbyaddr(uint32_t net
, int type
)
1669 fprintf(stderr
, "-> %s 0x%08x\n", __func__
, net
);
1672 if (type
!= AF_INET
) return NULL
;
1674 item
= si_network_byaddr(si_search(), net
);
1675 LI_set_thread_item(CATEGORY_NETWORK
+ 200, item
);
1676 if (item
== NULL
) return NULL
;
1678 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1682 getnetbyaddr_async_call(uint32_t net
, int type
, si_group_async_callback callback
, void *context
)
1684 si_context_t
*sictx
;
1687 fprintf(stderr
, ">> %s 0x%08x\n", __func__
, net
);
1690 if (type
!= AF_INET
) return MACH_PORT_NULL
;
1692 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1693 if (sictx
== NULL
) return MACH_PORT_NULL
;
1695 sictx
->orig_callback
= callback
;
1696 sictx
->orig_context
= context
;
1697 sictx
->cat
= CATEGORY_NETWORK
;
1698 sictx
->key_offset
= 200;
1700 return si_async_call(si_search(), SI_CALL_NETWORK_BYADDR
, NULL
, NULL
, NULL
, net
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1704 getnetbyaddr_async_handle_reply(mach_msg_header_t
*msg
)
1707 fprintf(stderr
, "<< %s\n", __func__
);
1710 si_async_handle_reply(msg
);
1714 setnetent(int ignored
)
1717 fprintf(stderr
, "-- %s\n", __func__
);
1720 LI_set_thread_list(CATEGORY_NETWORK
, NULL
);
1730 fprintf(stderr
, "-> %s\n", __func__
);
1733 list
= LI_get_thread_list(CATEGORY_NETWORK
);
1736 list
= si_network_all(si_search());
1737 LI_set_thread_list(CATEGORY_NETWORK
, list
);
1740 item
= si_list_next(list
);
1741 if (item
== NULL
) return NULL
;
1743 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1750 fprintf(stderr
, "-- %s\n", __func__
);
1753 LI_set_thread_list(CATEGORY_NETWORK
, NULL
);
1759 getservbyname(const char *name
, const char *proto
)
1764 fprintf(stderr
, "-> %s %s %s\n", __func__
, name
, proto
);
1767 item
= si_service_byname(si_search(), name
, proto
);
1768 LI_set_thread_item(CATEGORY_SERVICE
+ 100, item
);
1769 if (item
== NULL
) return NULL
;
1771 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1775 getservbyname_async_call(const char *name
, const char *proto
, si_service_async_callback callback
, void *context
)
1777 si_context_t
*sictx
;
1780 fprintf(stderr
, ">> %s %s %s\n", __func__
, name
, proto
);
1783 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1784 if (sictx
== NULL
) return MACH_PORT_NULL
;
1786 sictx
->orig_callback
= callback
;
1787 sictx
->orig_context
= context
;
1788 sictx
->cat
= CATEGORY_SERVICE
;
1789 sictx
->key_offset
= 100;
1791 return si_async_call(si_search(), SI_CALL_SERVICE_BYNAME
, name
, proto
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1795 getservbyname_async_handle_reply(mach_msg_header_t
*msg
)
1798 fprintf(stderr
, "<< %s\n", __func__
);
1801 si_async_handle_reply(msg
);
1805 getservbyport(int port
, const char *proto
)
1810 fprintf(stderr
, "-> %s %d %s\n", __func__
, ntohs((uint16_t)port
), proto
);
1813 item
= si_service_byport(si_search(), port
, proto
);
1814 LI_set_thread_item(CATEGORY_SERVICE
+ 200, item
);
1815 if (item
== NULL
) return NULL
;
1817 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1821 getservbyport_async_call(int port
, const char *proto
, si_group_async_callback callback
, void *context
)
1823 si_context_t
*sictx
;
1826 fprintf(stderr
, ">> %s %d %s\n", __func__
, port
, proto
);
1829 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1830 if (sictx
== NULL
) return MACH_PORT_NULL
;
1832 sictx
->orig_callback
= callback
;
1833 sictx
->orig_context
= context
;
1834 sictx
->cat
= CATEGORY_SERVICE
;
1835 sictx
->key_offset
= 200;
1837 return si_async_call(si_search(), SI_CALL_SERVICE_BYPORT
, NULL
, proto
, NULL
, port
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1841 getservbyport_async_handle_reply(mach_msg_header_t
*msg
)
1844 fprintf(stderr
, "<< %s\n", __func__
);
1847 si_async_handle_reply(msg
);
1851 setservent(int ignored
)
1854 fprintf(stderr
, "-- %s\n", __func__
);
1857 LI_set_thread_list(CATEGORY_SERVICE
, NULL
);
1867 fprintf(stderr
, "-> %s\n", __func__
);
1870 list
= LI_get_thread_list(CATEGORY_SERVICE
);
1873 list
= si_service_all(si_search());
1874 LI_set_thread_list(CATEGORY_SERVICE
, list
);
1877 item
= si_list_next(list
);
1878 if (item
== NULL
) return NULL
;
1880 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1887 fprintf(stderr
, "-- %s\n", __func__
);
1890 LI_set_thread_list(CATEGORY_SERVICE
, NULL
);
1896 getprotobyname(const char *name
)
1901 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1904 item
= si_protocol_byname(si_search(), name
);
1905 LI_set_thread_item(CATEGORY_PROTOCOL
+ 100, item
);
1906 if (item
== NULL
) return NULL
;
1908 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1912 getprotobyname_async_call(const char *name
, si_protocol_async_callback callback
, void *context
)
1914 si_context_t
*sictx
;
1917 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1920 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1921 if (sictx
== NULL
) return MACH_PORT_NULL
;
1923 sictx
->orig_callback
= callback
;
1924 sictx
->orig_context
= context
;
1925 sictx
->cat
= CATEGORY_PROTOCOL
;
1926 sictx
->key_offset
= 100;
1928 return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1932 getprotobyname_async_handle_reply(mach_msg_header_t
*msg
)
1935 fprintf(stderr
, "<< %s\n", __func__
);
1938 si_async_handle_reply(msg
);
1942 getprotobynumber(int number
)
1947 fprintf(stderr
, "-> %s %d\n", __func__
, number
);
1950 item
= si_protocol_bynumber(si_search(), number
);
1951 LI_set_thread_item(CATEGORY_PROTOCOL
+ 200, item
);
1952 if (item
== NULL
) return NULL
;
1954 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1958 getprotobynumber_async_call(int number
, si_group_async_callback callback
, void *context
)
1960 si_context_t
*sictx
;
1963 fprintf(stderr
, ">> %s %d\n", __func__
, number
);
1966 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1967 if (sictx
== NULL
) return MACH_PORT_NULL
;
1969 sictx
->orig_callback
= callback
;
1970 sictx
->orig_context
= context
;
1971 sictx
->cat
= CATEGORY_PROTOCOL
;
1972 sictx
->key_offset
= 200;
1974 return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNUMBER
, NULL
, NULL
, NULL
, number
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1978 getprotobynumber_async_handle_reply(mach_msg_header_t
*msg
)
1981 fprintf(stderr
, "<< %s\n", __func__
);
1984 si_async_handle_reply(msg
);
1988 setprotoent(int ignored
)
1991 fprintf(stderr
, "-- %s\n", __func__
);
1994 LI_set_thread_list(CATEGORY_PROTOCOL
, NULL
);
2004 fprintf(stderr
, "-> %s\n", __func__
);
2007 list
= LI_get_thread_list(CATEGORY_PROTOCOL
);
2010 list
= si_protocol_all(si_search());
2011 LI_set_thread_list(CATEGORY_PROTOCOL
, list
);
2014 item
= si_list_next(list
);
2015 if (item
== NULL
) return NULL
;
2017 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2024 fprintf(stderr
, "-- %s\n", __func__
);
2027 LI_set_thread_list(CATEGORY_PROTOCOL
, NULL
);
2033 getrpcbyname(const char *name
)
2038 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
2041 item
= si_rpc_byname(si_search(), name
);
2042 LI_set_thread_item(CATEGORY_RPC
+ 100, item
);
2043 if (item
== NULL
) return NULL
;
2045 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2049 getrpcbyname_async_call(const char *name
, si_rpc_async_callback callback
, void *context
)
2051 si_context_t
*sictx
;
2054 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
2057 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2058 if (sictx
== NULL
) return MACH_PORT_NULL
;
2060 sictx
->orig_callback
= callback
;
2061 sictx
->orig_context
= context
;
2062 sictx
->cat
= CATEGORY_RPC
;
2063 sictx
->key_offset
= 100;
2065 return si_async_call(si_search(), SI_CALL_RPC_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2069 getrpcbyname_async_handle_reply(mach_msg_header_t
*msg
)
2072 fprintf(stderr
, "<< %s\n", __func__
);
2075 si_async_handle_reply(msg
);
2091 fprintf(stderr
, "-> %s %ld\n", __func__
, (long int)number
);
2094 item
= si_rpc_bynumber(si_search(), number
);
2095 LI_set_thread_item(CATEGORY_RPC
+ 200, item
);
2096 if (item
== NULL
) return NULL
;
2098 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2102 getrpcbynumber_async_call(int number
, si_group_async_callback callback
, void *context
)
2104 si_context_t
*sictx
;
2107 fprintf(stderr
, ">> %s %d\n", __func__
, number
);
2110 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2111 if (sictx
== NULL
) return MACH_PORT_NULL
;
2113 sictx
->orig_callback
= callback
;
2114 sictx
->orig_context
= context
;
2115 sictx
->cat
= CATEGORY_RPC
;
2116 sictx
->key_offset
= 200;
2118 return si_async_call(si_search(), SI_CALL_RPC_BYNUMBER
, NULL
, NULL
, NULL
, number
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2122 getrpcbynumber_async_handle_reply(mach_msg_header_t
*msg
)
2125 fprintf(stderr
, "<< %s\n", __func__
);
2128 si_async_handle_reply(msg
);
2132 setrpcent(int ignored
)
2135 fprintf(stderr
, "-- %s\n", __func__
);
2138 LI_set_thread_list(CATEGORY_RPC
, NULL
);
2148 fprintf(stderr
, "-> %s\n", __func__
);
2151 list
= LI_get_thread_list(CATEGORY_RPC
);
2154 list
= si_rpc_all(si_search());
2155 LI_set_thread_list(CATEGORY_RPC
, list
);
2158 item
= si_list_next(list
);
2159 if (item
== NULL
) return NULL
;
2161 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2168 fprintf(stderr
, "-- %s\n", __func__
);
2171 LI_set_thread_list(CATEGORY_RPC
, NULL
);
2177 getfsspec(const char *spec
)
2182 fprintf(stderr
, "-> %s %s\n", __func__
, spec
);
2185 item
= si_fs_byspec(si_search(), spec
);
2186 LI_set_thread_item(CATEGORY_FS
+ 100, item
);
2187 if (item
== NULL
) return NULL
;
2189 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2193 getfsbyname(const char *name
)
2196 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
2199 return getfsspec(name
);
2203 getfsspec_async_call(const char *spec
, si_fs_async_callback callback
, void *context
)
2205 si_context_t
*sictx
;
2208 fprintf(stderr
, ">> %s %s\n", __func__
, spec
);
2211 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2212 if (sictx
== NULL
) return MACH_PORT_NULL
;
2214 sictx
->orig_callback
= callback
;
2215 sictx
->orig_context
= context
;
2216 sictx
->cat
= CATEGORY_FS
;
2217 sictx
->key_offset
= 100;
2219 return si_async_call(si_search(), SI_CALL_FS_BYSPEC
, spec
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2223 getfsspec_async_handle_reply(mach_msg_header_t
*msg
)
2226 fprintf(stderr
, "<< %s\n", __func__
);
2229 si_async_handle_reply(msg
);
2233 getfsfile(const char *file
)
2238 fprintf(stderr
, "-> %s %s\n", __func__
, file
);
2241 item
= si_fs_byfile(si_search(), file
);
2242 LI_set_thread_item(CATEGORY_FS
+ 200, item
);
2243 if (item
== NULL
) return NULL
;
2245 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2249 getfsfile_async_call(const char *file
, si_fs_async_callback callback
, void *context
)
2251 si_context_t
*sictx
;
2254 fprintf(stderr
, ">> %s %s\n", __func__
, file
);
2257 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2258 if (sictx
== NULL
) return MACH_PORT_NULL
;
2260 sictx
->orig_callback
= callback
;
2261 sictx
->orig_context
= context
;
2262 sictx
->cat
= CATEGORY_FS
;
2263 sictx
->key_offset
= 200;
2265 return si_async_call(si_search(), SI_CALL_FS_BYFILE
, file
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2269 getfsfile_async_handle_reply(mach_msg_header_t
*msg
)
2272 fprintf(stderr
, "<< %s\n", __func__
);
2275 si_async_handle_reply(msg
);
2282 fprintf(stderr
, "-> %s\n", __func__
);
2285 LI_set_thread_list(CATEGORY_FS
, NULL
);
2296 fprintf(stderr
, "-> %s\n", __func__
);
2299 list
= LI_get_thread_list(CATEGORY_FS
);
2302 list
= si_fs_all(si_search());
2303 LI_set_thread_list(CATEGORY_FS
, list
);
2306 item
= si_list_next(list
);
2307 if (item
== NULL
) return NULL
;
2309 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2316 fprintf(stderr
, "-- %s\n", __func__
);
2319 LI_set_thread_list(CATEGORY_FS
, NULL
);
2325 _getaddrinfo_internal(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, const char *interface
, struct addrinfo
**res
)
2328 uint32_t family
, socktype
, protocol
, flags
, status
;
2329 struct addrinfo
*ai
;
2332 socktype
= SOCK_UNSPEC
;
2333 protocol
= IPPROTO_UNSPEC
;
2335 status
= SI_STATUS_NO_ERROR
;
2337 if (res
== NULL
) return 0;
2342 family
= hints
->ai_family
;
2343 socktype
= hints
->ai_socktype
;
2344 protocol
= hints
->ai_protocol
;
2345 flags
= hints
->ai_flags
;
2349 fprintf(stderr
, "-> %s %s %s %u %u %u 0x%08x %s\n", __func__
, nodename
, servname
, family
, socktype
, protocol
, flags
, (interface
== NULL
) ?
"" : interface
);
2352 list
= si_addrinfo(si_search(), nodename
, servname
, family
, socktype
, protocol
, flags
, interface
, &status
);
2353 if ((status
!= SI_STATUS_NO_ERROR
) || (list
== NULL
) || (list
->count
== 0))
2355 si_list_release(list
);
2357 if (status
== SI_STATUS_NO_ERROR
) return EAI_NONAME
;
2358 else if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2359 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2360 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2364 *res
= si_list_to_addrinfo(list
);
2365 si_list_release(list
);
2366 if (*res
== NULL
) status
= EAI_MEMORY
;
2368 /* don't return the canonical name unless asked */
2369 if ((flags
& AI_CANONNAME
) == 0)
2371 for (ai
= *res
; ai
!= NULL
; ai
= ai
->ai_next
)
2373 free(ai
->ai_canonname
);
2374 ai
->ai_canonname
= NULL
;
2382 getaddrinfo(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, struct addrinfo
**res
)
2384 return _getaddrinfo_internal(nodename
, servname
, hints
, NULL
, res
);
2390 socket_name(int sock
)
2392 static char str
[16];
2396 case SOCK_UNSPEC
: return "SOCK_UNSPEC";
2397 case SOCK_STREAM
: return "SOCK_STREAM";
2398 case SOCK_DGRAM
: return "SOCK_DGRAM";
2401 sprintf(str
, "%d", sock
);
2408 static char str
[16];
2412 case PF_UNSPEC
: return "PF_UNSPEC";
2413 case PF_INET
: return "PF_INET";
2414 case PF_INET6
: return "PF_INET6";
2417 sprintf(str
, "%d", pf
);
2422 protocol_name(int p
)
2424 static char str
[16];
2428 case IPPROTO_UNSPEC
: return "IPPROTO_UNSPEC";
2429 case IPPROTO_TCP
: return "IPPROTO_TCP";
2430 case IPPROTO_UDP
: return "IPPROTO_UDP";
2433 sprintf(str
, "%d", p
);
2438 _gai_inet_ntop(struct in6_addr a
)
2440 static char buf
[128];
2446 memset(buf
, 0, 128);
2448 p
= (char *)&a
.__u6_addr
.__u6_addr32
;
2449 for (i
= 0; i
< 8; i
++, x
+= 1)
2453 sprintf(t
, "%hx", x
);
2455 if (i
< 7) strcat(buf
, ":");
2462 fprint_addrinfo(FILE *f
, struct addrinfo
*a
)
2466 struct sockaddr_in
*s4
;
2467 struct sockaddr_in6
*s6
;
2469 if (a
== NULL
) return;
2471 if (a
->ai_flags
!= 0)
2473 fprintf(f
, "flags =");
2474 if (a
->ai_flags
& AI_PASSIVE
) fprintf(f
, " AI_PASSIVE");
2475 if (a
->ai_flags
& AI_CANONNAME
) fprintf(f
, " AI_CANONNAME");
2476 if (a
->ai_flags
& AI_NUMERICHOST
) fprintf(f
, " AI_NUMERICHOST");
2477 if (a
->ai_flags
& AI_NUMERICSERV
) fprintf(f
, " AI_NUMERICSERV");
2481 fprintf(f
, "family = %s\n", family_name(a
->ai_family
));
2482 fprintf(f
, "socktype = %s\n", socket_name(a
->ai_socktype
));
2483 fprintf(f
, "protocol = %s\n", protocol_name(a
->ai_protocol
));
2485 fprintf(f
, "canonical name = ");
2486 if (a
->ai_canonname
== NULL
) fprintf(f
, "NULL\n");
2487 else fprintf(f
, "\"%s\"\n", a
->ai_canonname
);
2489 fprintf(f
, "addrlen = %ld\n", (long int)a
->ai_addrlen
);
2491 if (a
->ai_addr
== NULL
) fprintf(f
, "sockaddr = NULL\n");
2494 if (a
->ai_family
== PF_INET
)
2496 s4
= (struct sockaddr_in
*)a
->ai_addr
;
2498 fprintf(f
, "sockaddr_in len = %d\n", s4
->sin_len
);
2499 fprintf(f
, "sockaddr_in family = %s\n", family_name(s4
->sin_family
));
2500 fprintf(f
, "sockaddr_in port = %hu\n", ntohs(s4
->sin_port
));
2501 fprintf(f
, "sockaddr_in address = %s\n", inet_ntoa(s4
->sin_addr
));
2503 else if (a
->ai_family
== PF_INET6
)
2505 s6
= (struct sockaddr_in6
*)a
->ai_addr
;
2507 fprintf(f
, "sockaddr_in6 len = %d\n", s6
->sin6_len
);
2508 fprintf(f
, "sockaddr_in6 family = %s\n", family_name(s6
->sin6_family
));
2509 fprintf(f
, "sockaddr_in6 port = %hu\n", ntohs(s6
->sin6_port
));
2510 fprintf(f
, "sockaddr_in6 flowinfo = %d\n", s6
->sin6_flowinfo
);
2511 fprintf(f
, "sockaddr_in6 address = %s\n", _gai_inet_ntop(s6
->sin6_addr
));
2512 fprintf(f
, "sockaddr_in6 scope_id = %d\n", s6
->sin6_scope_id
);
2516 fprintf(f
, "sockaddr len = %d\n", a
->ai_addr
->sa_len
);
2517 fprintf(f
, "sockaddr family = %s\n", family_name(a
->ai_addr
->sa_family
));
2518 fprintf(f
, "sockaddr data = ");
2519 for (i
= 0; i
< a
->ai_addr
->sa_len
- 2; i
++)
2521 v
= a
->ai_addr
->sa_data
[i
];
2522 fprintf(f
, "%02x", v
);
2528 if (a
->ai_next
!= NULL
)
2530 fprintf(f
, "NEXT --->\n");
2531 fprint_addrinfo(f
, a
->ai_next
);
2538 si_libinfo_addrinfo_callback(si_list_t
*list
, uint32_t status
, void *ctx
)
2540 si_context_t
*sictx
;
2541 struct addrinfo
*out
;
2546 fprintf(stderr
, " %s error no context\n", __func__
);
2548 si_list_release(list
);
2552 sictx
= (si_context_t
*)ctx
;
2554 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
2557 fprintf(stderr
, " %s error no callback\n", __func__
);
2559 si_list_release(list
);
2564 if (status
!= SI_STATUS_NO_ERROR
)
2567 fprintf(stderr
, " %s original status %d\n", __func__
, status
);
2569 if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2570 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2571 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2577 fprintf(stderr
, " %s result NULL status %d (returning EAI_NONAME)\n", __func__
, status
);
2579 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(EAI_NONAME
, NULL
, sictx
->orig_context
);
2584 out
= si_list_to_addrinfo(list
);
2585 si_list_release(list
);
2589 fprintf(stderr
, " %s result conversion failed returning NULL status %d (returning EAI_MEMORY)\n", __func__
, status
);
2591 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(EAI_MEMORY
, NULL
, sictx
->orig_context
);
2597 fprintf(stderr
, " %s %d\n", __func__
, status
);
2598 fprint_addrinfo(stderr
, out
);
2600 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(status
, out
, sictx
->orig_context
);
2607 _getaddrinfo_interface_async_call(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, const char *interface
, si_addrinfo_async_callback callback
, void *context
)
2609 si_context_t
*sictx
;
2610 uint32_t family
, socktype
, protocol
, flags
;
2613 socktype
= SOCK_UNSPEC
;
2614 protocol
= IPPROTO_UNSPEC
;
2619 family
= hints
->ai_family
;
2620 socktype
= hints
->ai_socktype
;
2621 protocol
= hints
->ai_protocol
;
2622 flags
= hints
->ai_flags
;
2626 fprintf(stderr
, ">> %s %s %s %u %u %u 0x%08x\n", __func__
, nodename
, servname
, family
, socktype
, protocol
, flags
);
2629 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2630 if (sictx
== NULL
) return MACH_PORT_NULL
;
2632 sictx
->orig_callback
= callback
;
2633 sictx
->orig_context
= context
;
2634 sictx
->cat
= CATEGORY_ADDRINFO
;
2635 sictx
->key_offset
= 0;
2637 return si_async_call(si_search(), SI_CALL_ADDRINFO
, nodename
, servname
, interface
, family
, socktype
, protocol
, flags
, (void *)si_libinfo_addrinfo_callback
, sictx
);
2641 getaddrinfo_async_call(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, si_addrinfo_async_callback callback
, void *context
)
2643 return _getaddrinfo_interface_async_call(nodename
, servname
, hints
, NULL
, callback
, context
);
2647 getaddrinfo_async_start(mach_port_t
*p
, const char *nodename
, const char *servname
, const struct addrinfo
*hints
, si_addrinfo_async_callback callback
, void *context
)
2649 if (p
== NULL
) return EAI_SYSTEM
;
2651 *p
= getaddrinfo_async_call(nodename
, servname
, hints
, callback
, context
);
2653 if (*p
== MACH_PORT_NULL
) return EAI_SYSTEM
;
2658 getaddrinfo_async_send(mach_port_t
*p
, const char *nodename
, const char *servname
, const struct addrinfo
*hints
)
2660 return getaddrinfo_async_start(p
, nodename
, servname
, hints
, NULL
, NULL
);
2664 getaddrinfo_async_receive(mach_port_t p
, struct addrinfo
**res
)
2666 /* unsupported Leopard SPI */
2671 getaddrinfo_async_cancel(mach_port_t p
)
2674 fprintf(stderr
, "-- %s\n", __func__
);
2681 getaddrinfo_async_handle_reply(void *param
)
2683 mach_msg_header_t
*msg
;
2686 fprintf(stderr
, "<< %s\n", __func__
);
2689 msg
= (mach_msg_header_t
*)param
;
2690 si_async_handle_reply(msg
);
2698 _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
)
2702 uint32_t status
, len
, wantn
, wants
;
2705 fprintf(stderr
, "-> %s\n", __func__
);
2708 status
= SI_STATUS_NO_ERROR
;
2711 if ((node
!= NULL
) && (nodelen
> 0)) wantn
= 1;
2714 if ((service
!= NULL
) && (servicelen
> 0)) wants
= 1;
2716 if ((wantn
== 0) && (wants
== 0)) return status
;
2718 if (wantn
== 0) flags
|= NI_NUMERICHOST
;
2719 if (wants
== 0) flags
|= NI_NUMERICSERV
;
2721 item
= si_nameinfo(si_search(), sa
, flags
, interface
, &status
);
2722 if ((status
!= SI_STATUS_NO_ERROR
) || (item
== NULL
))
2724 si_item_release(item
);
2726 if (status
== SI_STATUS_NO_ERROR
) status
= EAI_NONAME
;
2727 else if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2728 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2729 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2733 ni
= (si_nameinfo_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
2736 if (ni
->ni_node
!= NULL
) len
= strlen(ni
->ni_node
) + 1;
2737 if ((wantn
== 1) && (len
> 0))
2741 si_item_release(item
);
2742 return EAI_OVERFLOW
;
2745 memset(node
, 0, nodelen
);
2746 memcpy(node
, ni
->ni_node
, len
);
2750 if (ni
->ni_serv
!= NULL
) len
= strlen(ni
->ni_serv
) + 1;
2751 if ((wants
== 1) && (len
> 0))
2753 if (len
> servicelen
)
2755 si_item_release(item
);
2756 return EAI_OVERFLOW
;
2759 memset(service
, 0, servicelen
);
2760 memcpy(service
, ni
->ni_serv
, len
);
2763 si_item_release(item
);
2768 getnameinfo(const struct sockaddr
*sa
, socklen_t salen
, char *node
, socklen_t nodelen
, char *service
, socklen_t servicelen
, int flags
)
2770 if (sa
== NULL
) return EAI_FAIL
;
2772 if (sa
->sa_family
== AF_LINK
) return getnameinfo_link(sa
, salen
, node
, nodelen
, service
, servicelen
, flags
);
2773 return _getnameinfo_interface_internal(sa
, salen
, node
, nodelen
, service
, servicelen
, flags
, NULL
);
2777 si_libinfo_nameinfo_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
2779 si_context_t
*sictx
;
2783 if (ctx
== NULL
) return;
2785 sictx
= (si_context_t
*)ctx
;
2787 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
2789 si_item_release(item
);
2794 if (status
!= SI_STATUS_NO_ERROR
)
2796 if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2797 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2798 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2803 ((si_nameinfo_async_callback
)(sictx
->orig_callback
))(status
, NULL
, NULL
, sictx
->orig_context
);
2808 LI_set_thread_item(CATEGORY_NAMEINFO
, item
);
2813 ni
= (si_nameinfo_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
2814 if (ni
->ni_node
!= NULL
) node
= strdup(ni
->ni_node
);
2815 if (ni
->ni_serv
!= NULL
) serv
= strdup(ni
->ni_serv
);
2817 ((si_nameinfo_async_callback
)(sictx
->orig_callback
))(status
, node
, serv
, sictx
->orig_context
);
2823 _getnameinfo_interface_async_call(const struct sockaddr
*sa
, size_t len
, int flags
, const char *interface
, si_nameinfo_async_callback callback
, void *context
)
2825 si_context_t
*sictx
;
2829 fprintf(stderr
, ">> %s\n", __func__
);
2832 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2833 if (sictx
== NULL
) return MACH_PORT_NULL
;
2835 sictx
->orig_callback
= callback
;
2836 sictx
->orig_context
= context
;
2837 sictx
->cat
= CATEGORY_ADDRINFO
;
2838 sictx
->key_offset
= 0;
2840 /* sa is not a C string - pass length in num3 */
2842 return si_async_call(si_search(), SI_CALL_NAMEINFO
, (const char *)sa
, NULL
, interface
, flags
, 0, salen
, 0, (void *)si_libinfo_nameinfo_callback
, sictx
);
2846 getnameinfo_async_call(const struct sockaddr
*sa
, size_t len
, int flags
, si_nameinfo_async_callback callback
, void *context
)
2848 return _getnameinfo_interface_async_call(sa
, len
, flags
, NULL
, callback
, context
);
2852 getnameinfo_async_start(mach_port_t
*p
, const struct sockaddr
*sa
, size_t salen
, int flags
, si_nameinfo_async_callback callback
, void *context
)
2854 if (p
== NULL
) return EAI_SYSTEM
;
2855 *p
= getnameinfo_async_call(sa
, salen
, flags
, callback
, context
);
2857 if (*p
== MACH_PORT_NULL
) return EAI_SYSTEM
;
2862 getnameinfo_async_send(mach_port_t
*p
, const struct sockaddr
*sa
, size_t salen
, int flags
)
2864 return getnameinfo_async_start(p
, sa
, salen
, flags
, NULL
, NULL
);
2868 getnameinfo_async_cancel(mach_port_t p
)
2871 fprintf(stderr
, "-- %s\n", __func__
);
2878 getnameinfo_async_handle_reply(void *param
)
2880 mach_msg_header_t
*msg
;
2883 fprintf(stderr
, "<< %s\n", __func__
);
2886 msg
= (mach_msg_header_t
*)param
;
2887 si_async_handle_reply(msg
);
2892 /* getpwXXX_r and getgrXXX_r */
2895 copy_user_r(struct passwd
*in
, struct passwd
*out
, char *buffer
, int buflen
)
2900 if (in
== NULL
) return -1;
2901 if (out
== NULL
) return -1;
2903 if (buffer
== NULL
) buflen
= 0;
2905 /* Calculate size of input */
2907 if (in
->pw_name
!= NULL
) hsize
+= (strlen(in
->pw_name
) + 1);
2908 if (in
->pw_passwd
!= NULL
) hsize
+= (strlen(in
->pw_passwd
) + 1);
2909 if (in
->pw_class
!= NULL
) hsize
+= (strlen(in
->pw_class
) + 1);
2910 if (in
->pw_gecos
!= NULL
) hsize
+= (strlen(in
->pw_gecos
) + 1);
2911 if (in
->pw_dir
!= NULL
) hsize
+= (strlen(in
->pw_dir
) + 1);
2912 if (in
->pw_shell
!= NULL
) hsize
+= (strlen(in
->pw_shell
) + 1);
2914 /* Check buffer space */
2915 if (hsize
> buflen
) return -1;
2917 /* Copy result into caller's struct passwd, using buffer for memory */
2920 out
->pw_name
= NULL
;
2921 if (in
->pw_name
!= NULL
)
2924 hsize
= strlen(in
->pw_name
) + 1;
2925 memmove(bp
, in
->pw_name
, hsize
);
2929 out
->pw_passwd
= NULL
;
2930 if (in
->pw_passwd
!= NULL
)
2932 out
->pw_passwd
= bp
;
2933 hsize
= strlen(in
->pw_passwd
) + 1;
2934 memmove(bp
, in
->pw_passwd
, hsize
);
2938 out
->pw_uid
= in
->pw_uid
;
2940 out
->pw_gid
= in
->pw_gid
;
2942 out
->pw_change
= in
->pw_change
;
2944 out
->pw_class
= NULL
;
2945 if (in
->pw_class
!= NULL
)
2948 hsize
= strlen(in
->pw_class
) + 1;
2949 memmove(bp
, in
->pw_class
, hsize
);
2953 out
->pw_gecos
= NULL
;
2954 if (in
->pw_gecos
!= NULL
)
2957 hsize
= strlen(in
->pw_gecos
) + 1;
2958 memmove(bp
, in
->pw_gecos
, hsize
);
2963 if (in
->pw_dir
!= NULL
)
2966 hsize
= strlen(in
->pw_dir
) + 1;
2967 memmove(bp
, in
->pw_dir
, hsize
);
2971 out
->pw_shell
= NULL
;
2972 if (in
->pw_shell
!= NULL
)
2975 hsize
= strlen(in
->pw_shell
) + 1;
2976 memmove(bp
, in
->pw_shell
, hsize
);
2980 out
->pw_expire
= in
->pw_expire
;
2986 copy_group_r(struct group
*in
, struct group
*out
, char *buffer
, int buflen
)
2992 if (in
== NULL
) return -1;
2993 if (out
== NULL
) return -1;
2995 if (buffer
== NULL
) buflen
= 0;
2997 /* Calculate size of input */
2999 if (in
->gr_name
!= NULL
) hsize
+= (strlen(in
->gr_name
) + 1);
3000 if (in
->gr_passwd
!= NULL
) hsize
+= (strlen(in
->gr_passwd
) + 1);
3002 /* NULL pointer at end of list */
3003 hsize
+= sizeof(char *);
3006 if (in
->gr_mem
!= NULL
)
3008 for (len
= 0; in
->gr_mem
[len
] != NULL
; len
++)
3010 hsize
+= sizeof(char *);
3011 hsize
+= (strlen(in
->gr_mem
[len
]) + 1);
3015 /* Check buffer space */
3016 if (hsize
> buflen
) return -1;
3018 /* Copy result into caller's struct group, using buffer for memory */
3021 out
->gr_name
= NULL
;
3022 if (in
->gr_name
!= NULL
)
3025 hsize
= strlen(in
->gr_name
) + 1;
3026 memmove(bp
, in
->gr_name
, hsize
);
3030 out
->gr_passwd
= NULL
;
3031 if (in
->gr_passwd
!= NULL
)
3033 out
->gr_passwd
= bp
;
3034 hsize
= strlen(in
->gr_passwd
) + 1;
3035 memmove(bp
, in
->gr_passwd
, hsize
);
3039 out
->gr_gid
= in
->gr_gid
;
3042 ap
= bp
+ ((len
+ 1) * sizeof(char *));
3044 if (in
->gr_mem
!= NULL
)
3046 out
->gr_mem
= (char **)bp
;
3047 for (i
= 0; i
< len
; i
++)
3049 addr
= (unsigned long)ap
;
3050 memmove(bp
, &addr
, sizeof(unsigned long));
3051 bp
+= sizeof(unsigned long);
3053 hsize
= strlen(in
->gr_mem
[i
]) + 1;
3054 memmove(ap
, in
->gr_mem
[i
], hsize
);
3059 memset(bp
, 0, sizeof(unsigned long));
3066 getgrnam_r(const char *name
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
3073 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
3076 if (result
!= NULL
) *result
= NULL
;
3078 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3080 item
= si_group_byname(si_search(), name
);
3081 if (item
== NULL
) return 0;
3083 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
3085 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
3086 si_item_release(item
);
3088 if (status
!= 0) return ERANGE
;
3095 getgrgid_r(gid_t gid
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
3102 fprintf(stderr
, "-> %s %d\n", __func__
, gid
);
3105 if (result
!= NULL
) *result
= NULL
;
3107 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3109 item
= si_group_bygid(si_search(), gid
);
3110 if (item
== NULL
) return 0;
3112 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
3114 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
3115 si_item_release(item
);
3117 if (status
!= 0) return ERANGE
;
3124 getgruuid_r(uuid_t uuid
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
3131 uuid_string_t uuidstr
;
3132 uuid_unparse_upper(uuid
, uuidstr
);
3133 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
3136 if (result
!= NULL
) *result
= NULL
;
3138 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3140 item
= si_group_byuuid(si_search(), uuid
);
3141 if (item
== NULL
) return 0;
3143 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
3145 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
3146 si_item_release(item
);
3148 if (status
!= 0) return ERANGE
;
3155 getpwnam_r(const char *name
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3162 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
3165 if (result
!= NULL
) *result
= NULL
;
3167 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3169 #if TARGET_OS_EMBEDDED
3170 if (strcmp(name
,"mobile") == 0) {
3173 if (lstat("/private/var/mobile",&buf
) == 0) {
3174 if ((getpwuid_r(buf
.st_uid
, pw
,buffer
, bufsize
, result
)) == 0) {
3179 #endif /* TARGET_OS_EMBEDDED */
3181 item
= si_user_byname(si_search(), name
);
3182 if (item
== NULL
) return 0;
3184 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3186 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3187 si_item_release(item
);
3189 if (status
!= 0) return ERANGE
;
3196 getpwuid_r(uid_t uid
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3201 uid_t localuid
= uid
;
3204 fprintf(stderr
, "-> %s %d\n", __func__
, uid
);
3207 if (result
!= NULL
) *result
= NULL
;
3209 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3211 #if TARGET_OS_EMBEDDED
3215 if (lstat("/private/var/mobile", &buf
) == 0) {
3216 localuid
= buf
.st_uid
;
3219 #endif /* TARGET_OS_EMBEDDED*/
3221 item
= si_user_byuid(si_search(), localuid
);
3222 if (item
== NULL
) return 0;
3224 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3226 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3227 si_item_release(item
);
3229 if (status
!= 0) return ERANGE
;
3236 getpwuuid_r(uuid_t uuid
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3243 uuid_string_t uuidstr
;
3244 uuid_unparse_upper(uuid
, uuidstr
);
3245 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
3248 if (result
!= NULL
) *result
= NULL
;
3250 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3252 item
= si_user_byuuid(si_search(), uuid
);
3253 if (item
== NULL
) return 0;
3255 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3257 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3258 si_item_release(item
);
3260 if (status
!= 0) return ERANGE
;
3269 user_from_uid(uid_t uid
, int nouser
)
3272 static char buf
[16];
3275 if (pw
!= NULL
) return pw
->pw_name
;
3277 if (nouser
) return NULL
;
3279 snprintf(buf
, sizeof(buf
), "%u", uid
);
3284 group_from_gid(gid_t gid
, int nogroup
)
3287 static char buf
[16];
3290 if (gr
!= NULL
) return gr
->gr_name
;
3292 if (nogroup
) return NULL
;
3294 snprintf(buf
, sizeof(buf
), "%u", gid
);
3298 /* no longer supported */
3301 prdb_getbyname(const char *name
)
3304 fprintf(stderr
, "~~ %s\n", __func__
);
3313 fprintf(stderr
, "~~ %s\n", __func__
);
3319 prdb_set(const char *name
)
3322 fprintf(stderr
, "~~ %s\n", __func__
);
3330 fprintf(stderr
, "~~ %s\n", __func__
);
3334 struct bootparamsent
*
3335 bootparams_getbyname(const char *name
)
3338 fprintf(stderr
, "~~ %s\n", __func__
);
3343 struct bootparamsent
*
3344 bootparams_getent(void)
3347 fprintf(stderr
, "~~ %s\n", __func__
);
3353 bootparams_setent(void)
3356 fprintf(stderr
, "~~ %s\n", __func__
);
3361 bootparams_endent(void)
3364 fprintf(stderr
, "~~ %s\n", __func__
);
3369 bootp_getbyether(struct ether_addr
*enaddr
, char **name
,struct in_addr
*ipaddr
, char **bootfile
)
3372 fprintf(stderr
, "~~ %s\n", __func__
);
3378 bootp_getbyip(struct ether_addr
*enaddr
, char **name
, struct in_addr
*ipaddr
, char **bootfile
)
3381 fprintf(stderr
, "~~ %s\n", __func__
);