2 * Copyright (c) 2008-2011 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>
45 #define IPPROTO_UNSPEC 0
46 #define IPV6_ADDR_LEN 16
47 #define IPV4_ADDR_LEN 4
49 /* The kernel's initgroups call */
50 extern int __initgroups(u_int gidsetsize
, gid_t
*gidset
, int gmuid
);
52 /* SPI from long ago */
55 extern struct addrinfo
*si_list_to_addrinfo(si_list_t
*list
);
56 extern int getnameinfo_link(const struct sockaddr
*sa
, socklen_t salen
, char *host
, size_t hostlen
, char *serv
, size_t servlen
, int flags
);
57 __private_extern__
void search_set_flags(si_mod_t
*si
, const char *name
, uint32_t flag
);
60 * Impedence matching for async calls.
62 * This layer holds on to the caller's callback and context in this
63 * structure, which gets passed to the si_module async routines along
64 * with a callbac in this layer. When this layer gets a callback,
65 * it can save the item or list in thread-specific memory and then
66 * invoke the caller's callback with the appropriate data type.
80 static si_mod_t
*search
= NULL
;
82 if (search
== NULL
) search
= si_module_with_name("search");
88 si_search_module_set_flags(const char *name
, uint32_t flag
)
90 search_set_flags(si_search(), name
, flag
);
94 si_libinfo_general_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
102 struct grouplist_s
*l
;
111 if (ctx
== NULL
) return;
113 sictx
= (si_context_t
*)ctx
;
115 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
118 si_item_release(item
);
122 if (sictx
->key_offset
>= 0)
124 LI_set_thread_item(sictx
->cat
+ sictx
->key_offset
, item
);
128 if (item
!= NULL
) res
.x
= (char*)((uintptr_t)item
+ sizeof(si_item_t
));
134 ((si_user_async_callback
)(sictx
->orig_callback
))(res
.u
, sictx
->orig_context
);
139 ((si_group_async_callback
)(sictx
->orig_callback
))(res
.g
, sictx
->orig_context
);
142 case CATEGORY_GROUPLIST
:
144 ((si_grouplist_async_callback
)(sictx
->orig_callback
))(res
.l
, sictx
->orig_context
);
147 case CATEGORY_HOST_IPV4
:
148 case CATEGORY_HOST_IPV6
:
150 ((si_host_async_callback
)(sictx
->orig_callback
))(res
.h
, sictx
->orig_context
);
153 case CATEGORY_NETWORK
:
155 ((si_network_async_callback
)(sictx
->orig_callback
))(res
.n
, sictx
->orig_context
);
158 case CATEGORY_SERVICE
:
160 ((si_service_async_callback
)(sictx
->orig_callback
))(res
.s
, sictx
->orig_context
);
163 case CATEGORY_PROTOCOL
:
165 ((si_protocol_async_callback
)(sictx
->orig_callback
))(res
.p
, sictx
->orig_context
);
170 ((si_rpc_async_callback
)(sictx
->orig_callback
))(res
.r
, sictx
->orig_context
);
175 ((si_fs_async_callback
)(sictx
->orig_callback
))(res
.f
, sictx
->orig_context
);
186 getpwnam(const char *name
)
191 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
194 item
= si_user_byname(si_search(), name
);
195 LI_set_thread_item(CATEGORY_USER
+ 100, item
);
197 if (item
== NULL
) return NULL
;
198 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
202 getpwnam_async_call(const char *name
, si_user_async_callback callback
, void *context
)
207 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
210 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
211 if (sictx
== NULL
) return MACH_PORT_NULL
;
213 sictx
->orig_callback
= callback
;
214 sictx
->orig_context
= context
;
215 sictx
->cat
= CATEGORY_USER
;
216 sictx
->key_offset
= 100;
218 return si_async_call(si_search(), SI_CALL_USER_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
222 getpwnam_async_handle_reply(mach_msg_header_t
*msg
)
225 fprintf(stderr
, "<< %s\n", __func__
);
228 si_async_handle_reply(msg
);
237 fprintf(stderr
, "-> %s %d\n", __func__
, uid
);
240 item
= si_user_byuid(si_search(), uid
);
241 LI_set_thread_item(CATEGORY_USER
+ 200, item
);
243 if (item
== NULL
) return NULL
;
244 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
248 getpwuid_async_call(uid_t uid
, si_user_async_callback callback
, void *context
)
253 fprintf(stderr
, ">> %s %d\n", __func__
, uid
);
256 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
257 if (sictx
== NULL
) return MACH_PORT_NULL
;
259 sictx
->orig_callback
= callback
;
260 sictx
->orig_context
= context
;
261 sictx
->cat
= CATEGORY_USER
;
262 sictx
->key_offset
= 200;
264 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
);
268 getpwuid_async_handle_reply(mach_msg_header_t
*msg
)
271 fprintf(stderr
, "<< %s\n", __func__
);
274 si_async_handle_reply(msg
);
278 getpwuuid(uuid_t uuid
)
283 uuid_string_t uuidstr
;
284 uuid_unparse_upper(uuid
, uuidstr
);
285 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
288 item
= si_user_byuuid(si_search(), uuid
);
289 LI_set_thread_item(CATEGORY_USER
+ 300, item
);
291 if (item
== NULL
) return NULL
;
292 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
299 fprintf(stderr
, "-- %s\n", __func__
);
302 LI_set_thread_list(CATEGORY_USER
, NULL
);
312 fprintf(stderr
, "-> %s\n", __func__
);
315 list
= LI_get_thread_list(CATEGORY_USER
);
318 list
= si_user_all(si_search());
319 LI_set_thread_list(CATEGORY_USER
, list
);
322 item
= si_list_next(list
);
323 if (item
== NULL
) return NULL
;
325 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
332 fprintf(stderr
, "-- %s\n", __func__
);
335 LI_set_thread_list(CATEGORY_USER
, NULL
);
339 setpassent(int ignored
)
344 fprintf(stderr
, "-> %s\n", __func__
);
347 list
= LI_get_thread_list(CATEGORY_USER
);
350 if (list
== NULL
) return 0;
357 getgrnam(const char *name
)
362 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
365 item
= si_group_byname(si_search(), name
);
366 LI_set_thread_item(CATEGORY_GROUP
+ 100, item
);
368 if (item
== NULL
) return NULL
;
369 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
373 getgrnam_async_call(const char *name
, si_group_async_callback callback
, void *context
)
378 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
381 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
382 if (sictx
== NULL
) return MACH_PORT_NULL
;
384 sictx
->orig_callback
= callback
;
385 sictx
->orig_context
= context
;
386 sictx
->cat
= CATEGORY_GROUP
;
387 sictx
->key_offset
= 100;
389 return si_async_call(si_search(), SI_CALL_GROUP_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
393 getgrnam_async_handle_reply(mach_msg_header_t
*msg
)
396 fprintf(stderr
, "<< %s\n", __func__
);
399 si_async_handle_reply(msg
);
408 fprintf(stderr
, "-> %s %d\n", __func__
, gid
);
411 item
= si_group_bygid(si_search(), gid
);
412 LI_set_thread_item(CATEGORY_GROUP
+ 200, item
);
414 if (item
== NULL
) return NULL
;
415 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
419 getgrgid_async_call(gid_t gid
, si_group_async_callback callback
, void *context
)
424 fprintf(stderr
, ">> %s %d\n", __func__
, gid
);
427 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
428 if (sictx
== NULL
) return MACH_PORT_NULL
;
430 sictx
->orig_callback
= callback
;
431 sictx
->orig_context
= context
;
432 sictx
->cat
= CATEGORY_GROUP
;
433 sictx
->key_offset
= 200;
435 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
);
439 getgruid_async_handle_reply(mach_msg_header_t
*msg
)
442 fprintf(stderr
, "<< %s\n", __func__
);
445 si_async_handle_reply(msg
);
449 getgruuid(uuid_t uuid
)
454 uuid_string_t uuidstr
;
455 uuid_unparse_upper(uuid
, uuidstr
);
456 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
459 item
= si_group_byuuid(si_search(), uuid
);
460 LI_set_thread_item(CATEGORY_GROUP
+ 300, item
);
462 if (item
== NULL
) return NULL
;
463 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
470 fprintf(stderr
, "-- %s\n", __func__
);
473 LI_set_thread_list(CATEGORY_GROUP
, NULL
);
483 fprintf(stderr
, "-> %s\n", __func__
);
486 list
= LI_get_thread_list(CATEGORY_GROUP
);
489 list
= si_group_all(si_search());
490 LI_set_thread_list(CATEGORY_GROUP
, list
);
493 item
= si_list_next(list
);
494 if (item
== NULL
) return NULL
;
496 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
503 fprintf(stderr
, "-- %s\n", __func__
);
506 LI_set_thread_list(CATEGORY_GROUP
, NULL
);
510 setgroupent(int ignored
)
515 fprintf(stderr
, "-> %s\n", __func__
);
518 list
= LI_get_thread_list(CATEGORY_GROUP
);
521 if (list
== NULL
) return 0;
527 innetgr(const char *group
, const char *host
, const char *user
, const char *domain
)
531 fprintf(stderr
, "-> %s %s %s %s %s\n", __func__
, group
, host
, user
, domain
);
534 res
= si_in_netgroup(si_search(), group
, host
, user
, domain
);
537 fprintf(stderr
, "<- %s %d\n", __func__
, res
);
543 /* N.B. there is no async innetgr */
546 * setnetgrent is really more like a getXXXbyname routine than a
547 * setXXXent routine, since we are looking up a netgroup by name.
550 setnetgrent(const char *name
)
555 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
558 list
= si_netgroup_byname(si_search(), name
);
559 LI_set_thread_list(CATEGORY_NETGROUP
, list
);
562 /* N.B. there is no async getnetgrent */
565 getnetgrent(char **host
, char **user
, char **domain
)
569 struct netgrent_s
*ng
;
572 fprintf(stderr
, "-> %s\n", __func__
);
575 list
= LI_get_thread_list(CATEGORY_NETGROUP
);
576 item
= si_list_next(list
);
577 if (item
== NULL
) return 0;
579 ng
= (struct netgrent_s
*)((uintptr_t)item
+ sizeof(si_item_t
));
583 *domain
= ng
->ng_domain
;
592 fprintf(stderr
, "-- %s\n", __func__
);
595 LI_set_thread_list(CATEGORY_NETGROUP
, NULL
);
600 _check_groups(const char *function
, int32_t ngroups
)
602 static dispatch_once_t once
;
604 if (ngroups
> 0 && ngroups
< NGROUPS_MAX
) {
608 /* only log once per process */
609 dispatch_once(&once
, ^(void) {
610 const char *proc_name
= getprogname();
611 if (strcmp(proc_name
, "id") != 0 && strcmp(proc_name
, "smbd") != 0 && strcmp(proc_name
, "rpcsvchost") != 0) {
612 aslmsg msg
= asl_new(ASL_TYPE_MSG
);
615 snprintf(buffer
, sizeof(buffer
), "%d", (ngroups
== 0 ? INT_MAX
: ngroups
));
616 asl_set(msg
, "com.apple.message.value", buffer
);
618 asl_set(msg
, "com.apple.message.domain", "com.apple.system.libinfo");
619 asl_set(msg
, "com.apple.message.result", "noop");
620 asl_set(msg
, "com.apple.message.signature", function
);
622 asl_log(NULL
, msg
, ASL_LEVEL_NOTICE
, "%s called triggering group enumeration", function
);
633 getgrouplist_internal(const char *name
, int basegid
, gid_t
*groups
, uint32_t *ngroups
)
635 int i
, j
, x
, g
, add
, max
;
640 * On input, ngroups specifies the size of the groups array.
641 * On output, it is set to the number of groups that are being returned.
642 * Returns -1 if the size is too small to fit all the groups that were found.
646 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
649 if (name
== NULL
) return 0;
650 if (groups
== NULL
) return 0;
651 if (ngroups
== NULL
) return 0;
655 if (max
<= 0) return 0;
660 item
= si_grouplist(si_search(), name
, max
);
661 LI_set_thread_item(CATEGORY_GROUPLIST
, item
);
662 if (item
== NULL
) return 0;
664 gl
= (si_grouplist_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
668 for (i
= 0; i
< gl
->gl_count
; i
++)
672 for (j
= 0; j
< x
; j
++) {
673 if (groups
[j
] == g
) {
678 if (add
== 0) continue;
680 if (x
>= max
) return -1;
690 getgrouplist(const char *name
, int basegid
, int *groups
, int *ngroups
)
693 _check_groups("getgrouplist", *ngroups
);
696 return getgrouplist_internal(name
, basegid
, (gid_t
*)groups
, (uint32_t *)ngroups
);
700 merge_gid(gid_t
*list
, gid_t g
, int32_t *count
)
706 for (i
= 0; i
< cnt
; i
++) {
707 if (list
[i
] == g
) return;
715 _getgrouplist_2_internal(const char *name
, gid_t basegid
, gid_t
**groups
)
722 item
= si_grouplist(si_search(), name
, INT_MAX
);
723 LI_set_thread_item(CATEGORY_GROUPLIST
, item
);
724 if (item
== NULL
) return -1;
726 gl
= (si_grouplist_t
*) ((uintptr_t) item
+ sizeof(si_item_t
));
729 * we can allocate enough up-front, we'll only use what we need
730 * we add one to the count that was found in case the basegid is not there
732 gids
= calloc(gl
->gl_count
+ 1, sizeof(gid_t
));
735 merge_gid(gids
, basegid
, &count
);
736 if (gl
->gl_gid
!= NULL
) {
737 for (i
= 0; i
< gl
->gl_count
; i
++) {
738 merge_gid(gids
, gl
->gl_gid
[i
], &count
);
748 getgrouplist_2(const char *name
, gid_t basegid
, gid_t
**groups
)
751 * Passes back a gid_t list containing all the users groups (and basegid).
752 * Caller must free the list.
753 * Returns the number of gids in the list or -1 on failure.
757 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
760 if (name
== NULL
) return 0;
761 if (groups
== NULL
) return 0;
764 _check_groups("getgrouplist_2", INT_MAX
);
767 return _getgrouplist_2_internal(name
, basegid
, groups
);
771 getgroupcount(const char *name
, gid_t basegid
)
777 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
781 _check_groups("getgroupcount", INT_MAX
);
785 count
= _getgrouplist_2_internal(name
, basegid
, &groups
);
786 if (groups
!= NULL
) free(groups
);
791 /* XXX to do: async getgrouplist_2 */
794 initgroups(const char *name
, int basegid
)
798 gid_t groups
[NGROUPS
];
806 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
809 /* KAUTH_UID_NONE tells the kernel not to fetch supplementary groups from DirectoryService */
810 uid
= KAUTH_UID_NONE
;
813 /* get the UID for this user */
814 item
= si_user_byname(si_search(), name
);
817 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
819 si_item_release(item
);
827 * A failure either means that user belongs to more than NGROUPS groups
828 * or no groups at all.
831 (void) getgrouplist_internal(name
, basegid
, groups
, &ngroups
);
833 status
= __initgroups(ngroups
, groups
, uid
);
834 if (status
< 0) return -1;
842 alias_getbyname(const char *name
)
847 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
850 item
= si_alias_byname(si_search(), name
);
851 LI_set_thread_item(CATEGORY_ALIAS
+ 100, item
);
852 if (item
== NULL
) return NULL
;
854 return (struct aliasent
*)((uintptr_t)item
+ sizeof(si_item_t
));
858 alias_getbyname_async_call(const char *name
, si_alias_async_callback callback
, void *context
)
863 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
866 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
867 if (sictx
== NULL
) return MACH_PORT_NULL
;
869 sictx
->orig_callback
= callback
;
870 sictx
->orig_context
= context
;
871 sictx
->cat
= CATEGORY_ALIAS
;
872 sictx
->key_offset
= 100;
874 return si_async_call(si_search(), SI_CALL_ALIAS_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
878 alias_getbyname_async_handle_reply(mach_msg_header_t
*msg
)
881 fprintf(stderr
, "<< %s\n", __func__
);
884 si_async_handle_reply(msg
);
891 fprintf(stderr
, "-> %s\n", __func__
);
894 LI_set_thread_list(CATEGORY_ALIAS
, NULL
);
904 fprintf(stderr
, "-> %s\n", __func__
);
907 list
= LI_get_thread_list(CATEGORY_ALIAS
);
910 list
= si_alias_all(si_search());
911 LI_set_thread_list(CATEGORY_ALIAS
, list
);
914 item
= si_list_next(list
);
915 if (item
== NULL
) return NULL
;
917 return (struct aliasent
*)((uintptr_t)item
+ sizeof(si_item_t
));
924 fprintf(stderr
, "-- %s\n", __func__
);
927 LI_set_thread_list(CATEGORY_ALIAS
, NULL
);
933 freehostent(struct hostent
*h
)
935 if (h
== NULL
) return;
937 si_item_t
*item
= (si_item_t
*)((uintptr_t)h
- sizeof(si_item_t
));
938 si_item_release(item
);
942 gethostbynameerrno(const char *name
, int *err
)
946 struct in_addr addr4
;
949 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
952 memset(&addr4
, 0, sizeof(struct in_addr
));
953 status
= SI_STATUS_NO_ERROR
;
956 if (inet_aton(name
, &addr4
) == 1) item
= si_ipnode_byname(si_search(), name
, AF_INET
, 0, NULL
, &status
);
957 else item
= si_host_byname(si_search(), name
, AF_INET
, NULL
, &status
);
959 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
960 if (err
!= NULL
) *err
= status
;
962 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
963 if (item
== NULL
) return NULL
;
965 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
969 gethostbyname(const char *name
)
973 struct in_addr addr4
;
976 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
979 memset(&addr4
, 0, sizeof(struct in_addr
));
980 status
= SI_STATUS_NO_ERROR
;
983 if (inet_aton(name
, &addr4
) == 1) item
= si_ipnode_byname(si_search(), name
, AF_INET
, 0, NULL
, &status
);
984 else item
= si_host_byname(si_search(), name
, AF_INET
, NULL
, &status
);
986 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
989 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
990 if (item
== NULL
) return NULL
;
992 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
996 gethostbyname_async_call(const char *name
, si_host_async_callback callback
, void *context
)
1001 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1004 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1005 if (sictx
== NULL
) return MACH_PORT_NULL
;
1007 sictx
->orig_callback
= callback
;
1008 sictx
->orig_context
= context
;
1009 sictx
->cat
= CATEGORY_HOST
;
1010 sictx
->key_offset
= 100;
1012 return si_async_call(si_search(), SI_CALL_HOST_BYNAME
, name
, NULL
, NULL
, AF_INET
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1016 gethostbyname_async_start(const char *name
, si_host_async_callback callback
, void *context
)
1018 return gethostbyname_async_call(name
, callback
, context
);
1022 gethostbyname_async_cancel(mach_port_t p
)
1025 fprintf(stderr
, "-- %s\n", __func__
);
1033 gethostbyname_async_handle_reply(void *param
)
1035 mach_msg_header_t
*msg
;
1038 fprintf(stderr
, "<< %s\n", __func__
);
1041 msg
= (mach_msg_header_t
*)param
;
1042 si_async_handle_reply(msg
);
1047 gethostbyname_async_handleReply(void *param
)
1049 mach_msg_header_t
*msg
;
1052 fprintf(stderr
, "<< %s\n", __func__
);
1055 msg
= (mach_msg_header_t
*)param
;
1056 si_async_handle_reply(msg
);
1060 gethostbyname2(const char *name
, int af
)
1064 struct in_addr addr4
;
1065 struct in6_addr addr6
;
1066 si_mod_t
*search
= si_search();
1069 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, af
);
1072 memset(&addr4
, 0, sizeof(struct in_addr
));
1073 memset(&addr6
, 0, sizeof(struct in6_addr
));
1074 status
= SI_STATUS_NO_ERROR
;
1077 if (((af
== AF_INET
) && (inet_aton(name
, &addr4
) == 1)) || ((af
== AF_INET6
) && (inet_pton(af
, name
, &addr6
) == 1)))
1079 item
= si_ipnode_byname(search
, name
, (uint32_t)af
, 0, NULL
, &status
);
1083 item
= si_host_byname(search
, name
, (uint32_t)af
, NULL
, &status
);
1086 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1089 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
1090 if (item
== NULL
) return NULL
;
1092 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1096 gethostbyname2_async_call(const char *name
, int af
, si_group_async_callback callback
, void *context
)
1098 si_context_t
*sictx
;
1101 fprintf(stderr
, ">> %s %s %d\n", __func__
, name
, af
);
1104 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1105 if (sictx
== NULL
) return MACH_PORT_NULL
;
1107 sictx
->orig_callback
= callback
;
1108 sictx
->orig_context
= context
;
1109 sictx
->cat
= CATEGORY_HOST
;
1110 sictx
->key_offset
= 100;
1112 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
);
1116 gethostbyname2_async_cancel(mach_port_t p
)
1119 fprintf(stderr
, "-- %s\n", __func__
);
1126 gethostbyname2_async_handle_reply(mach_msg_header_t
*msg
)
1129 fprintf(stderr
, "<< %s\n", __func__
);
1132 si_async_handle_reply(msg
);
1136 gethostbyaddr(const void *addr
, socklen_t len
, int type
)
1142 fprintf(stderr
, "-> %s %s\n", __func__
, (type
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)addr
) : "-IPv6-");
1145 status
= SI_STATUS_NO_ERROR
;
1147 item
= si_host_byaddr(si_search(), addr
, (uint32_t)type
, NULL
, &status
);
1148 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1151 LI_set_thread_item(CATEGORY_HOST
+ 200, item
);
1152 if (item
== NULL
) return NULL
;
1154 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1158 gethostbyaddr_async_call(const void *addr
, socklen_t len
, int type
, si_host_async_callback callback
, void *context
)
1160 si_context_t
*sictx
;
1164 fprintf(stderr
, ">> %s %s\n", __func__
, (type
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)addr
) : "-IPv6-");
1167 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1168 if (sictx
== NULL
) return MACH_PORT_NULL
;
1170 sictx
->orig_callback
= callback
;
1171 sictx
->orig_context
= context
;
1172 sictx
->cat
= CATEGORY_HOST
;
1173 sictx
->key_offset
= 200;
1175 /* addr is not a C string - pass length in num3 */
1177 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
);
1181 gethostbyaddr_async_start(const char *addr
, int len
, int family
, si_host_async_callback callback
, void *context
)
1183 socklen_t slen
= len
;
1185 return gethostbyaddr_async_call(addr
, slen
, family
, callback
, context
);
1189 gethostbyaddr_async_cancel(mach_port_t p
)
1192 fprintf(stderr
, "-- %s\n", __func__
);
1200 gethostbyaddr_async_handle_reply(void *param
)
1203 mach_msg_header_t
*msg
;
1206 fprintf(stderr
, "<< %s\n", __func__
);
1209 msg
= (mach_msg_header_t
*)param
;
1210 si_async_handle_reply(msg
);
1215 gethostbyaddr_async_handleReply(void *param
)
1217 mach_msg_header_t
*msg
;
1220 fprintf(stderr
, "<< %s\n", __func__
);
1223 msg
= (mach_msg_header_t
*)param
;
1224 si_async_handle_reply(msg
);
1228 getipnodebyname(const char *name
, int family
, int flags
, int *err
)
1234 fprintf(stderr
, "-> %s %s %d 0x%08x\n", __func__
, name
, family
, flags
);
1237 status
= SI_STATUS_NO_ERROR
;
1239 item
= si_ipnode_byname(si_search(), name
, family
, flags
, NULL
, &status
);
1240 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1241 if (err
!= NULL
) *err
= status
;
1243 if (item
== NULL
) return NULL
;
1245 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1250 getipnodebyname_async_call(const char *name
, int family
, int flags
, int *err
, si_host_async_callback callback
, void *context
)
1252 si_context_t
*sictx
;
1255 fprintf(stderr
, ">> %s %s %d 0x%08x\n", __func__
, name
, family
, flags
);
1258 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1259 if (sictx
== NULL
) return MACH_PORT_NULL
;
1261 sictx
->orig_callback
= callback
;
1262 sictx
->orig_context
= context
;
1263 sictx
->cat
= CATEGORY_HOST
;
1264 sictx
->key_offset
= -1;
1266 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
);
1270 getipnodebyname_async_start(const char *name
, int family
, int flags
, int *err
, si_host_async_callback callback
, void *context
)
1272 return getipnodebyname_async_call(name
, family
, flags
, err
, callback
, context
);
1276 getipnodebyname_async_cancel(mach_port_t p
)
1279 fprintf(stderr
, "-- %s\n", __func__
);
1286 getipnodebyname_async_handle_reply(mach_msg_header_t
*msg
)
1289 fprintf(stderr
, "<< %s\n", __func__
);
1292 si_async_handle_reply(msg
);
1296 getipnodebyname_async_handleReply(mach_msg_header_t
*msg
)
1299 fprintf(stderr
, "<< %s\n", __func__
);
1302 si_async_handle_reply(msg
);
1307 is_a4_mapped(const char *s
)
1312 if (s
== NULL
) return 0;
1314 for (i
= 0; i
< 10; i
++)
1317 if (c
!= 0x0) return 0;
1320 for (i
= 10; i
< 12; i
++)
1323 if (c
!= 0xff) return 0;
1330 is_a4_compat(const char *s
)
1335 if (s
== NULL
) return 0;
1337 for (i
= 0; i
< 12; i
++)
1340 if (c
!= 0x0) return 0;
1343 /* Check for :: and ::1 */
1344 for (i
= 13; i
< 15; i
++)
1346 /* anything non-zero in these 3 bytes means it's a V4 address */
1348 if (c
!= 0x0) return 1;
1351 /* Leading 15 bytes are all zero */
1353 if (c
== 0x0) return 0;
1354 if (c
== 0x1) return 0;
1360 getipnodebyaddr(const void *src
, size_t len
, int family
, int *err
)
1365 fprintf(stderr
, "-> %s %s\n", __func__
, (family
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)src
) : "-IPv6-");
1368 if ((family
== AF_INET6
) && (len
== IPV6_ADDR_LEN
) && (is_a4_mapped((const char *)src
) || is_a4_compat((const char *)src
)))
1375 item
= si_host_byaddr(si_search(), src
, family
, NULL
, (uint32_t *)err
);
1376 if (item
== NULL
) return NULL
;
1378 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1383 si_libinfo_ipnode_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
1385 si_context_t
*sictx
;
1388 if (ctx
== NULL
) return;
1390 sictx
= (si_context_t
*)ctx
;
1392 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
1395 si_item_release(item
);
1399 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1403 ((si_ipnode_async_callback
)(sictx
->orig_callback
))(NULL
, status
, sictx
->orig_context
);
1407 h
= (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1408 ((si_ipnode_async_callback
)(sictx
->orig_callback
))(h
, status
, sictx
->orig_context
);
1414 getipnodebyaddr_async_call(const void *src
, socklen_t len
, int family
, int *err
, si_ipnode_async_callback callback
, void *context
)
1416 si_context_t
*sictx
;
1420 fprintf(stderr
, ">> %s %s\n", __func__
, (family
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)src
) : "-IPv6-");
1423 if ((family
== AF_INET6
) && (len
== IPV6_ADDR_LEN
) && (is_a4_mapped((const char *)src
) || is_a4_compat((const char *)src
)))
1430 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1431 if (sictx
== NULL
) return MACH_PORT_NULL
;
1433 sictx
->orig_callback
= callback
;
1434 sictx
->orig_context
= context
;
1435 sictx
->cat
= CATEGORY_HOST
;
1436 sictx
->key_offset
= -1;
1438 /* src is not a C string - pass length in num3 */
1440 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
);
1444 getipnodebyaddr_async_start(const void *addr
, size_t len
, int family
, int *error
, si_ipnode_async_callback callback
, void *context
)
1446 socklen_t slen
= len
;
1448 return getipnodebyaddr_async_call(addr
, slen
, family
, error
, callback
, context
);
1452 getipnodebyaddr_async_cancel(mach_port_t p
)
1455 fprintf(stderr
, "-- %s\n", __func__
);
1462 getipnodebyaddr_async_handle_reply(mach_msg_header_t
*msg
)
1465 fprintf(stderr
, "<< %s\n", __func__
);
1468 si_async_handle_reply(msg
);
1472 getipnodebyaddr_async_handleReply(mach_msg_header_t
*msg
)
1475 fprintf(stderr
, "<< %s\n", __func__
);
1478 si_async_handle_reply(msg
);
1483 sethostent(int ignored
)
1486 fprintf(stderr
, "-- %s\n", __func__
);
1489 LI_set_thread_list(CATEGORY_HOST
, NULL
);
1499 fprintf(stderr
, "-> %s\n", __func__
);
1502 list
= LI_get_thread_list(CATEGORY_HOST
);
1505 list
= si_host_all(si_search());
1506 LI_set_thread_list(CATEGORY_HOST
, list
);
1509 item
= si_list_next(list
);
1510 if (item
== NULL
) return NULL
;
1512 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1519 fprintf(stderr
, "-- %s\n", __func__
);
1522 LI_set_thread_list(CATEGORY_HOST
, NULL
);
1528 ether_hostton(const char *name
, struct ether_addr
*e
)
1536 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1539 if (name
== NULL
) return -1;
1540 if (e
== NULL
) return -1;
1542 item
= si_mac_byname(si_search(), name
);
1543 LI_set_thread_item(CATEGORY_MAC
+ 100, item
);
1544 if (item
== NULL
) return -1;
1546 mac
= (si_mac_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
1548 i
= sscanf(mac
->mac
, " %x:%x:%x:%x:%x:%x", &t
[0], &t
[1], &t
[2], &t
[3], &t
[4], &t
[5]);
1549 if (i
!= 6) return -1;
1551 for (i
= 0; i
< 6; i
++) e
->ether_addr_octet
[i
] = t
[i
];
1555 /* XXX to do? async ether_hostton */
1558 ether_ntohost(char *name
, const struct ether_addr
*e
)
1565 if (name
== NULL
) return -1;
1566 if (e
== NULL
) return -1;
1568 for (i
= 0; i
< 6; i
++) x
[i
] = e
->ether_addr_octet
[i
];
1569 snprintf(str
, sizeof(str
), "%x:%x:%x:%x:%x:%x", x
[0], x
[1], x
[2], x
[3], x
[4], x
[5]);
1572 fprintf(stderr
, "-> %s %s\n", __func__
, str
);
1575 item
= si_mac_bymac(si_search(), str
);
1576 LI_set_thread_item(CATEGORY_MAC
+ 200, item
);
1577 if (item
== NULL
) return -1;
1579 mac
= (si_mac_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
1581 memcpy(name
, mac
->host
, strlen(mac
->host
) + 1);
1585 /* XXX to do? async ether_ntohost */
1590 getnetbyname(const char *name
)
1595 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1598 item
= si_network_byname(si_search(), name
);
1599 LI_set_thread_item(CATEGORY_NETWORK
+ 100, item
);
1600 if (item
== NULL
) return NULL
;
1602 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1606 getnetbyname_async_call(const char *name
, si_network_async_callback callback
, void *context
)
1608 si_context_t
*sictx
;
1611 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1614 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1615 if (sictx
== NULL
) return MACH_PORT_NULL
;
1617 sictx
->orig_callback
= callback
;
1618 sictx
->orig_context
= context
;
1619 sictx
->cat
= CATEGORY_NETWORK
;
1620 sictx
->key_offset
= 100;
1622 return si_async_call(si_search(), SI_CALL_NETWORK_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1626 getnetbyname_async_handle_reply(mach_msg_header_t
*msg
)
1629 fprintf(stderr
, "<< %s\n", __func__
);
1632 si_async_handle_reply(msg
);
1636 getnetbyaddr(uint32_t net
, int type
)
1641 fprintf(stderr
, "-> %s 0x%08x\n", __func__
, net
);
1644 if (type
!= AF_INET
) return NULL
;
1646 item
= si_network_byaddr(si_search(), net
);
1647 LI_set_thread_item(CATEGORY_NETWORK
+ 200, item
);
1648 if (item
== NULL
) return NULL
;
1650 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1654 getnetbyaddr_async_call(uint32_t net
, int type
, si_group_async_callback callback
, void *context
)
1656 si_context_t
*sictx
;
1659 fprintf(stderr
, ">> %s 0x%08x\n", __func__
, net
);
1662 if (type
!= AF_INET
) return MACH_PORT_NULL
;
1664 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1665 if (sictx
== NULL
) return MACH_PORT_NULL
;
1667 sictx
->orig_callback
= callback
;
1668 sictx
->orig_context
= context
;
1669 sictx
->cat
= CATEGORY_NETWORK
;
1670 sictx
->key_offset
= 200;
1672 return si_async_call(si_search(), SI_CALL_NETWORK_BYADDR
, NULL
, NULL
, NULL
, net
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1676 getnetbyaddr_async_handle_reply(mach_msg_header_t
*msg
)
1679 fprintf(stderr
, "<< %s\n", __func__
);
1682 si_async_handle_reply(msg
);
1686 setnetent(int ignored
)
1689 fprintf(stderr
, "-- %s\n", __func__
);
1692 LI_set_thread_list(CATEGORY_NETWORK
, NULL
);
1702 fprintf(stderr
, "-> %s\n", __func__
);
1705 list
= LI_get_thread_list(CATEGORY_NETWORK
);
1708 list
= si_network_all(si_search());
1709 LI_set_thread_list(CATEGORY_NETWORK
, list
);
1712 item
= si_list_next(list
);
1713 if (item
== NULL
) return NULL
;
1715 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1722 fprintf(stderr
, "-- %s\n", __func__
);
1725 LI_set_thread_list(CATEGORY_NETWORK
, NULL
);
1731 getservbyname(const char *name
, const char *proto
)
1736 fprintf(stderr
, "-> %s %s %s\n", __func__
, name
, proto
);
1739 item
= si_service_byname(si_search(), name
, proto
);
1740 LI_set_thread_item(CATEGORY_SERVICE
+ 100, item
);
1741 if (item
== NULL
) return NULL
;
1743 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1747 getservbyname_async_call(const char *name
, const char *proto
, si_service_async_callback callback
, void *context
)
1749 si_context_t
*sictx
;
1752 fprintf(stderr
, ">> %s %s %s\n", __func__
, name
, proto
);
1755 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1756 if (sictx
== NULL
) return MACH_PORT_NULL
;
1758 sictx
->orig_callback
= callback
;
1759 sictx
->orig_context
= context
;
1760 sictx
->cat
= CATEGORY_SERVICE
;
1761 sictx
->key_offset
= 100;
1763 return si_async_call(si_search(), SI_CALL_SERVICE_BYNAME
, name
, proto
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1767 getservbyname_async_handle_reply(mach_msg_header_t
*msg
)
1770 fprintf(stderr
, "<< %s\n", __func__
);
1773 si_async_handle_reply(msg
);
1777 getservbyport(int port
, const char *proto
)
1782 fprintf(stderr
, "-> %s %d %s\n", __func__
, ntohs((uint16_t)port
), proto
);
1785 item
= si_service_byport(si_search(), port
, proto
);
1786 LI_set_thread_item(CATEGORY_SERVICE
+ 200, item
);
1787 if (item
== NULL
) return NULL
;
1789 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1793 getservbyport_async_call(int port
, const char *proto
, si_group_async_callback callback
, void *context
)
1795 si_context_t
*sictx
;
1798 fprintf(stderr
, ">> %s %d %s\n", __func__
, port
, proto
);
1801 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1802 if (sictx
== NULL
) return MACH_PORT_NULL
;
1804 sictx
->orig_callback
= callback
;
1805 sictx
->orig_context
= context
;
1806 sictx
->cat
= CATEGORY_SERVICE
;
1807 sictx
->key_offset
= 200;
1809 return si_async_call(si_search(), SI_CALL_SERVICE_BYPORT
, NULL
, proto
, NULL
, port
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1813 getservbyport_async_handle_reply(mach_msg_header_t
*msg
)
1816 fprintf(stderr
, "<< %s\n", __func__
);
1819 si_async_handle_reply(msg
);
1823 setservent(int ignored
)
1826 fprintf(stderr
, "-- %s\n", __func__
);
1829 LI_set_thread_list(CATEGORY_SERVICE
, NULL
);
1839 fprintf(stderr
, "-> %s\n", __func__
);
1842 list
= LI_get_thread_list(CATEGORY_SERVICE
);
1845 list
= si_service_all(si_search());
1846 LI_set_thread_list(CATEGORY_SERVICE
, list
);
1849 item
= si_list_next(list
);
1850 if (item
== NULL
) return NULL
;
1852 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1859 fprintf(stderr
, "-- %s\n", __func__
);
1862 LI_set_thread_list(CATEGORY_SERVICE
, NULL
);
1868 getprotobyname(const char *name
)
1873 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1876 item
= si_protocol_byname(si_search(), name
);
1877 LI_set_thread_item(CATEGORY_PROTOCOL
+ 100, item
);
1878 if (item
== NULL
) return NULL
;
1880 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1884 getprotobyname_async_call(const char *name
, si_protocol_async_callback callback
, void *context
)
1886 si_context_t
*sictx
;
1889 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
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_PROTOCOL
;
1898 sictx
->key_offset
= 100;
1900 return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1904 getprotobyname_async_handle_reply(mach_msg_header_t
*msg
)
1907 fprintf(stderr
, "<< %s\n", __func__
);
1910 si_async_handle_reply(msg
);
1914 getprotobynumber(int number
)
1919 fprintf(stderr
, "-> %s %d\n", __func__
, number
);
1922 item
= si_protocol_bynumber(si_search(), number
);
1923 LI_set_thread_item(CATEGORY_PROTOCOL
+ 200, item
);
1924 if (item
== NULL
) return NULL
;
1926 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1930 getprotobynumber_async_call(int number
, si_group_async_callback callback
, void *context
)
1932 si_context_t
*sictx
;
1935 fprintf(stderr
, ">> %s %d\n", __func__
, number
);
1938 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1939 if (sictx
== NULL
) return MACH_PORT_NULL
;
1941 sictx
->orig_callback
= callback
;
1942 sictx
->orig_context
= context
;
1943 sictx
->cat
= CATEGORY_PROTOCOL
;
1944 sictx
->key_offset
= 200;
1946 return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNUMBER
, NULL
, NULL
, NULL
, number
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1950 getprotobynumber_async_handle_reply(mach_msg_header_t
*msg
)
1953 fprintf(stderr
, "<< %s\n", __func__
);
1956 si_async_handle_reply(msg
);
1960 setprotoent(int ignored
)
1963 fprintf(stderr
, "-- %s\n", __func__
);
1966 LI_set_thread_list(CATEGORY_PROTOCOL
, NULL
);
1976 fprintf(stderr
, "-> %s\n", __func__
);
1979 list
= LI_get_thread_list(CATEGORY_PROTOCOL
);
1982 list
= si_protocol_all(si_search());
1983 LI_set_thread_list(CATEGORY_PROTOCOL
, list
);
1986 item
= si_list_next(list
);
1987 if (item
== NULL
) return NULL
;
1989 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1996 fprintf(stderr
, "-- %s\n", __func__
);
1999 LI_set_thread_list(CATEGORY_PROTOCOL
, NULL
);
2005 getrpcbyname(const char *name
)
2010 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
2013 item
= si_rpc_byname(si_search(), name
);
2014 LI_set_thread_item(CATEGORY_RPC
+ 100, item
);
2015 if (item
== NULL
) return NULL
;
2017 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2021 getrpcbyname_async_call(const char *name
, si_rpc_async_callback callback
, void *context
)
2023 si_context_t
*sictx
;
2026 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
2029 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2030 if (sictx
== NULL
) return MACH_PORT_NULL
;
2032 sictx
->orig_callback
= callback
;
2033 sictx
->orig_context
= context
;
2034 sictx
->cat
= CATEGORY_RPC
;
2035 sictx
->key_offset
= 100;
2037 return si_async_call(si_search(), SI_CALL_RPC_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2041 getrpcbyname_async_handle_reply(mach_msg_header_t
*msg
)
2044 fprintf(stderr
, "<< %s\n", __func__
);
2047 si_async_handle_reply(msg
);
2063 fprintf(stderr
, "-> %s %ld\n", __func__
, (long int)number
);
2066 item
= si_rpc_bynumber(si_search(), number
);
2067 LI_set_thread_item(CATEGORY_RPC
+ 200, item
);
2068 if (item
== NULL
) return NULL
;
2070 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2074 getrpcbynumber_async_call(int number
, si_group_async_callback callback
, void *context
)
2076 si_context_t
*sictx
;
2079 fprintf(stderr
, ">> %s %d\n", __func__
, number
);
2082 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2083 if (sictx
== NULL
) return MACH_PORT_NULL
;
2085 sictx
->orig_callback
= callback
;
2086 sictx
->orig_context
= context
;
2087 sictx
->cat
= CATEGORY_RPC
;
2088 sictx
->key_offset
= 200;
2090 return si_async_call(si_search(), SI_CALL_RPC_BYNUMBER
, NULL
, NULL
, NULL
, number
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2094 getrpcbynumber_async_handle_reply(mach_msg_header_t
*msg
)
2097 fprintf(stderr
, "<< %s\n", __func__
);
2100 si_async_handle_reply(msg
);
2104 setrpcent(int ignored
)
2107 fprintf(stderr
, "-- %s\n", __func__
);
2110 LI_set_thread_list(CATEGORY_RPC
, NULL
);
2120 fprintf(stderr
, "-> %s\n", __func__
);
2123 list
= LI_get_thread_list(CATEGORY_RPC
);
2126 list
= si_rpc_all(si_search());
2127 LI_set_thread_list(CATEGORY_RPC
, list
);
2130 item
= si_list_next(list
);
2131 if (item
== NULL
) return NULL
;
2133 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2140 fprintf(stderr
, "-- %s\n", __func__
);
2143 LI_set_thread_list(CATEGORY_RPC
, NULL
);
2149 getfsspec(const char *spec
)
2154 fprintf(stderr
, "-> %s %s\n", __func__
, spec
);
2157 item
= si_fs_byspec(si_search(), spec
);
2158 LI_set_thread_item(CATEGORY_FS
+ 100, item
);
2159 if (item
== NULL
) return NULL
;
2161 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2165 getfsbyname(const char *name
)
2168 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
2171 return getfsspec(name
);
2175 getfsspec_async_call(const char *spec
, si_fs_async_callback callback
, void *context
)
2177 si_context_t
*sictx
;
2180 fprintf(stderr
, ">> %s %s\n", __func__
, spec
);
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_FS
;
2189 sictx
->key_offset
= 100;
2191 return si_async_call(si_search(), SI_CALL_FS_BYSPEC
, spec
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2195 getfsspec_async_handle_reply(mach_msg_header_t
*msg
)
2198 fprintf(stderr
, "<< %s\n", __func__
);
2201 si_async_handle_reply(msg
);
2205 getfsfile(const char *file
)
2210 fprintf(stderr
, "-> %s %s\n", __func__
, file
);
2213 item
= si_fs_byfile(si_search(), file
);
2214 LI_set_thread_item(CATEGORY_FS
+ 200, item
);
2215 if (item
== NULL
) return NULL
;
2217 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2221 getfsfile_async_call(const char *file
, si_fs_async_callback callback
, void *context
)
2223 si_context_t
*sictx
;
2226 fprintf(stderr
, ">> %s %s\n", __func__
, file
);
2229 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2230 if (sictx
== NULL
) return MACH_PORT_NULL
;
2232 sictx
->orig_callback
= callback
;
2233 sictx
->orig_context
= context
;
2234 sictx
->cat
= CATEGORY_FS
;
2235 sictx
->key_offset
= 200;
2237 return si_async_call(si_search(), SI_CALL_FS_BYFILE
, file
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2241 getfsfile_async_handle_reply(mach_msg_header_t
*msg
)
2244 fprintf(stderr
, "<< %s\n", __func__
);
2247 si_async_handle_reply(msg
);
2254 fprintf(stderr
, "-> %s\n", __func__
);
2257 LI_set_thread_list(CATEGORY_FS
, NULL
);
2268 fprintf(stderr
, "-> %s\n", __func__
);
2271 list
= LI_get_thread_list(CATEGORY_FS
);
2274 list
= si_fs_all(si_search());
2275 LI_set_thread_list(CATEGORY_FS
, list
);
2278 item
= si_list_next(list
);
2279 if (item
== NULL
) return NULL
;
2281 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2288 fprintf(stderr
, "-- %s\n", __func__
);
2291 LI_set_thread_list(CATEGORY_FS
, NULL
);
2297 _getaddrinfo_internal(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, const char *interface
, struct addrinfo
**res
)
2300 uint32_t family
, socktype
, protocol
, flags
, status
;
2301 struct addrinfo
*ai
;
2304 socktype
= SOCK_UNSPEC
;
2305 protocol
= IPPROTO_UNSPEC
;
2307 status
= SI_STATUS_NO_ERROR
;
2309 if (res
== NULL
) return 0;
2314 family
= hints
->ai_family
;
2315 socktype
= hints
->ai_socktype
;
2316 protocol
= hints
->ai_protocol
;
2317 flags
= hints
->ai_flags
;
2321 fprintf(stderr
, "-> %s %s %s %u %u %u 0x%08x %s\n", __func__
, nodename
, servname
, family
, socktype
, protocol
, flags
, (interface
== NULL
) ? "" : interface
);
2324 list
= si_addrinfo(si_search(), nodename
, servname
, family
, socktype
, protocol
, flags
, interface
, &status
);
2325 if ((status
!= SI_STATUS_NO_ERROR
) || (list
== NULL
) || (list
->count
== 0))
2327 si_list_release(list
);
2329 if (status
== SI_STATUS_NO_ERROR
) return EAI_NONAME
;
2330 else if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2331 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2332 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2336 *res
= si_list_to_addrinfo(list
);
2337 si_list_release(list
);
2338 if (*res
== NULL
) status
= EAI_MEMORY
;
2340 /* don't return the canonical name unless asked */
2341 if ((flags
& AI_CANONNAME
) == 0)
2343 for (ai
= *res
; ai
!= NULL
; ai
= ai
->ai_next
)
2345 free(ai
->ai_canonname
);
2346 ai
->ai_canonname
= NULL
;
2354 getaddrinfo(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, struct addrinfo
**res
)
2356 return _getaddrinfo_internal(nodename
, servname
, hints
, NULL
, res
);
2362 socket_name(int sock
)
2364 static char str
[16];
2368 case SOCK_UNSPEC
: return "SOCK_UNSPEC";
2369 case SOCK_STREAM
: return "SOCK_STREAM";
2370 case SOCK_DGRAM
: return "SOCK_DGRAM";
2373 sprintf(str
, "%d", sock
);
2380 static char str
[16];
2384 case PF_UNSPEC
: return "PF_UNSPEC";
2385 case PF_INET
: return "PF_INET";
2386 case PF_INET6
: return "PF_INET6";
2389 sprintf(str
, "%d", pf
);
2394 protocol_name(int p
)
2396 static char str
[16];
2400 case IPPROTO_UNSPEC
: return "IPPROTO_UNSPEC";
2401 case IPPROTO_TCP
: return "IPPROTO_TCP";
2402 case IPPROTO_UDP
: return "IPPROTO_UDP";
2405 sprintf(str
, "%d", p
);
2410 _gai_inet_ntop(struct in6_addr a
)
2412 static char buf
[128];
2418 memset(buf
, 0, 128);
2420 p
= (char *)&a
.__u6_addr
.__u6_addr32
;
2421 for (i
= 0; i
< 8; i
++, x
+= 1)
2425 sprintf(t
, "%hx", x
);
2427 if (i
< 7) strcat(buf
, ":");
2434 fprint_addrinfo(FILE *f
, struct addrinfo
*a
)
2438 struct sockaddr_in
*s4
;
2439 struct sockaddr_in6
*s6
;
2441 if (a
== NULL
) return;
2443 if (a
->ai_flags
!= 0)
2445 fprintf(f
, "flags =");
2446 if (a
->ai_flags
& AI_PASSIVE
) fprintf(f
, " AI_PASSIVE");
2447 if (a
->ai_flags
& AI_CANONNAME
) fprintf(f
, " AI_CANONNAME");
2448 if (a
->ai_flags
& AI_NUMERICHOST
) fprintf(f
, " AI_NUMERICHOST");
2449 if (a
->ai_flags
& AI_NUMERICSERV
) fprintf(f
, " AI_NUMERICSERV");
2453 fprintf(f
, "family = %s\n", family_name(a
->ai_family
));
2454 fprintf(f
, "socktype = %s\n", socket_name(a
->ai_socktype
));
2455 fprintf(f
, "protocol = %s\n", protocol_name(a
->ai_protocol
));
2457 fprintf(f
, "canonical name = ");
2458 if (a
->ai_canonname
== NULL
) fprintf(f
, "NULL\n");
2459 else fprintf(f
, "\"%s\"\n", a
->ai_canonname
);
2461 fprintf(f
, "addrlen = %ld\n", (long int)a
->ai_addrlen
);
2463 if (a
->ai_addr
== NULL
) fprintf(f
, "sockaddr = NULL\n");
2466 if (a
->ai_family
== PF_INET
)
2468 s4
= (struct sockaddr_in
*)a
->ai_addr
;
2470 fprintf(f
, "sockaddr_in len = %d\n", s4
->sin_len
);
2471 fprintf(f
, "sockaddr_in family = %s\n", family_name(s4
->sin_family
));
2472 fprintf(f
, "sockaddr_in port = %hu\n", ntohs(s4
->sin_port
));
2473 fprintf(f
, "sockaddr_in address = %s\n", inet_ntoa(s4
->sin_addr
));
2475 else if (a
->ai_family
== PF_INET6
)
2477 s6
= (struct sockaddr_in6
*)a
->ai_addr
;
2479 fprintf(f
, "sockaddr_in6 len = %d\n", s6
->sin6_len
);
2480 fprintf(f
, "sockaddr_in6 family = %s\n", family_name(s6
->sin6_family
));
2481 fprintf(f
, "sockaddr_in6 port = %hu\n", ntohs(s6
->sin6_port
));
2482 fprintf(f
, "sockaddr_in6 flowinfo = %d\n", s6
->sin6_flowinfo
);
2483 fprintf(f
, "sockaddr_in6 address = %s\n", _gai_inet_ntop(s6
->sin6_addr
));
2484 fprintf(f
, "sockaddr_in6 scope_id = %d\n", s6
->sin6_scope_id
);
2488 fprintf(f
, "sockaddr len = %d\n", a
->ai_addr
->sa_len
);
2489 fprintf(f
, "sockaddr family = %s\n", family_name(a
->ai_addr
->sa_family
));
2490 fprintf(f
, "sockaddr data = ");
2491 for (i
= 0; i
< a
->ai_addr
->sa_len
- 2; i
++)
2493 v
= a
->ai_addr
->sa_data
[i
];
2494 fprintf(f
, "%02x", v
);
2500 if (a
->ai_next
!= NULL
)
2502 fprintf(f
, "NEXT --->\n");
2503 fprint_addrinfo(f
, a
->ai_next
);
2510 si_libinfo_addrinfo_callback(si_list_t
*list
, uint32_t status
, void *ctx
)
2512 si_context_t
*sictx
;
2513 struct addrinfo
*out
;
2518 fprintf(stderr
, " %s error no context\n", __func__
);
2520 si_list_release(list
);
2524 sictx
= (si_context_t
*)ctx
;
2526 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
2529 fprintf(stderr
, " %s error no callback\n", __func__
);
2531 si_list_release(list
);
2536 if (status
!= SI_STATUS_NO_ERROR
)
2539 fprintf(stderr
, " %s original status %d\n", __func__
, status
);
2541 if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2542 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2543 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2549 fprintf(stderr
, " %s result NULL status %d (returning EAI_NONAME)\n", __func__
, status
);
2551 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(EAI_NONAME
, NULL
, sictx
->orig_context
);
2556 out
= si_list_to_addrinfo(list
);
2557 si_list_release(list
);
2561 fprintf(stderr
, " %s result conversion failed returning NULL status %d (returning EAI_MEMORY)\n", __func__
, status
);
2563 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(EAI_MEMORY
, NULL
, sictx
->orig_context
);
2569 fprintf(stderr
, " %s %d\n", __func__
, status
);
2570 fprint_addrinfo(stderr
, out
);
2572 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(status
, out
, sictx
->orig_context
);
2579 _getaddrinfo_interface_async_call(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, const char *interface
, si_addrinfo_async_callback callback
, void *context
)
2581 si_context_t
*sictx
;
2582 uint32_t family
, socktype
, protocol
, flags
;
2585 socktype
= SOCK_UNSPEC
;
2586 protocol
= IPPROTO_UNSPEC
;
2591 family
= hints
->ai_family
;
2592 socktype
= hints
->ai_socktype
;
2593 protocol
= hints
->ai_protocol
;
2594 flags
= hints
->ai_flags
;
2598 fprintf(stderr
, ">> %s %s %s %u %u %u 0x%08x\n", __func__
, nodename
, servname
, family
, socktype
, protocol
, flags
);
2601 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2602 if (sictx
== NULL
) return MACH_PORT_NULL
;
2604 sictx
->orig_callback
= callback
;
2605 sictx
->orig_context
= context
;
2606 sictx
->cat
= CATEGORY_ADDRINFO
;
2607 sictx
->key_offset
= 0;
2609 return si_async_call(si_search(), SI_CALL_ADDRINFO
, nodename
, servname
, interface
, family
, socktype
, protocol
, flags
, (void *)si_libinfo_addrinfo_callback
, sictx
);
2613 getaddrinfo_async_call(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, si_addrinfo_async_callback callback
, void *context
)
2615 return _getaddrinfo_interface_async_call(nodename
, servname
, hints
, NULL
, callback
, context
);
2619 getaddrinfo_async_start(mach_port_t
*p
, const char *nodename
, const char *servname
, const struct addrinfo
*hints
, si_addrinfo_async_callback callback
, void *context
)
2621 if (p
== NULL
) return EAI_SYSTEM
;
2623 *p
= getaddrinfo_async_call(nodename
, servname
, hints
, callback
, context
);
2625 if (*p
== MACH_PORT_NULL
) return EAI_SYSTEM
;
2630 getaddrinfo_async_send(mach_port_t
*p
, const char *nodename
, const char *servname
, const struct addrinfo
*hints
)
2632 return getaddrinfo_async_start(p
, nodename
, servname
, hints
, NULL
, NULL
);
2636 getaddrinfo_async_receive(mach_port_t p
, struct addrinfo
**res
)
2638 /* unsupported Leopard SPI */
2643 getaddrinfo_async_cancel(mach_port_t p
)
2646 fprintf(stderr
, "-- %s\n", __func__
);
2653 getaddrinfo_async_handle_reply(void *param
)
2655 mach_msg_header_t
*msg
;
2658 fprintf(stderr
, "<< %s\n", __func__
);
2661 msg
= (mach_msg_header_t
*)param
;
2662 si_async_handle_reply(msg
);
2670 _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
)
2674 uint32_t status
, len
, wantn
, wants
;
2677 fprintf(stderr
, "-> %s\n", __func__
);
2680 status
= SI_STATUS_NO_ERROR
;
2683 if ((node
!= NULL
) && (nodelen
> 0)) wantn
= 1;
2686 if ((service
!= NULL
) && (servicelen
> 0)) wants
= 1;
2688 if ((wantn
== 0) && (wants
== 0)) return status
;
2690 if (wantn
== 0) flags
|= NI_NUMERICHOST
;
2691 if (wants
== 0) flags
|= NI_NUMERICSERV
;
2693 item
= si_nameinfo(si_search(), sa
, flags
, interface
, &status
);
2694 if ((status
!= SI_STATUS_NO_ERROR
) || (item
== NULL
))
2696 si_item_release(item
);
2698 if (status
== SI_STATUS_NO_ERROR
) status
= EAI_NONAME
;
2699 else if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2700 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2701 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2705 ni
= (si_nameinfo_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
2708 if (ni
->ni_node
!= NULL
) len
= strlen(ni
->ni_node
) + 1;
2709 if ((wantn
== 1) && (len
> 0))
2713 si_item_release(item
);
2714 return EAI_OVERFLOW
;
2717 memset(node
, 0, nodelen
);
2718 memcpy(node
, ni
->ni_node
, len
);
2722 if (ni
->ni_serv
!= NULL
) len
= strlen(ni
->ni_serv
) + 1;
2723 if ((wants
== 1) && (len
> 0))
2725 if (len
> servicelen
)
2727 si_item_release(item
);
2728 return EAI_OVERFLOW
;
2731 memset(service
, 0, servicelen
);
2732 memcpy(service
, ni
->ni_serv
, len
);
2735 si_item_release(item
);
2740 getnameinfo(const struct sockaddr
*sa
, socklen_t salen
, char *node
, socklen_t nodelen
, char *service
, socklen_t servicelen
, int flags
)
2742 if (sa
== NULL
) return EAI_FAIL
;
2744 if (sa
->sa_family
== AF_LINK
) return getnameinfo_link(sa
, salen
, node
, nodelen
, service
, servicelen
, flags
);
2745 return _getnameinfo_interface_internal(sa
, salen
, node
, nodelen
, service
, servicelen
, flags
, NULL
);
2749 si_libinfo_nameinfo_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
2751 si_context_t
*sictx
;
2755 if (ctx
== NULL
) return;
2757 sictx
= (si_context_t
*)ctx
;
2759 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
2761 si_item_release(item
);
2766 if (status
!= SI_STATUS_NO_ERROR
)
2768 if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2769 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2770 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2775 ((si_nameinfo_async_callback
)(sictx
->orig_callback
))(status
, NULL
, NULL
, sictx
->orig_context
);
2780 LI_set_thread_item(CATEGORY_NAMEINFO
, item
);
2785 ni
= (si_nameinfo_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
2786 if (ni
->ni_node
!= NULL
) node
= strdup(ni
->ni_node
);
2787 if (ni
->ni_serv
!= NULL
) serv
= strdup(ni
->ni_serv
);
2789 ((si_nameinfo_async_callback
)(sictx
->orig_callback
))(status
, node
, serv
, sictx
->orig_context
);
2795 _getnameinfo_interface_async_call(const struct sockaddr
*sa
, size_t len
, int flags
, const char *interface
, si_nameinfo_async_callback callback
, void *context
)
2797 si_context_t
*sictx
;
2801 fprintf(stderr
, ">> %s\n", __func__
);
2804 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2805 if (sictx
== NULL
) return MACH_PORT_NULL
;
2807 sictx
->orig_callback
= callback
;
2808 sictx
->orig_context
= context
;
2809 sictx
->cat
= CATEGORY_ADDRINFO
;
2810 sictx
->key_offset
= 0;
2812 /* sa is not a C string - pass length in num3 */
2814 return si_async_call(si_search(), SI_CALL_NAMEINFO
, (const char *)sa
, NULL
, interface
, flags
, 0, salen
, 0, (void *)si_libinfo_nameinfo_callback
, sictx
);
2818 getnameinfo_async_call(const struct sockaddr
*sa
, size_t len
, int flags
, si_nameinfo_async_callback callback
, void *context
)
2820 return _getnameinfo_interface_async_call(sa
, len
, flags
, NULL
, callback
, context
);
2824 getnameinfo_async_start(mach_port_t
*p
, const struct sockaddr
*sa
, size_t salen
, int flags
, si_nameinfo_async_callback callback
, void *context
)
2826 if (p
== NULL
) return EAI_SYSTEM
;
2827 *p
= getnameinfo_async_call(sa
, salen
, flags
, callback
, context
);
2829 if (*p
== MACH_PORT_NULL
) return EAI_SYSTEM
;
2834 getnameinfo_async_send(mach_port_t
*p
, const struct sockaddr
*sa
, size_t salen
, int flags
)
2836 return getnameinfo_async_start(p
, sa
, salen
, flags
, NULL
, NULL
);
2840 getnameinfo_async_cancel(mach_port_t p
)
2843 fprintf(stderr
, "-- %s\n", __func__
);
2850 getnameinfo_async_handle_reply(void *param
)
2852 mach_msg_header_t
*msg
;
2855 fprintf(stderr
, "<< %s\n", __func__
);
2858 msg
= (mach_msg_header_t
*)param
;
2859 si_async_handle_reply(msg
);
2864 /* getpwXXX_r and getgrXXX_r */
2867 copy_user_r(struct passwd
*in
, struct passwd
*out
, char *buffer
, int buflen
)
2872 if (in
== NULL
) return -1;
2873 if (out
== NULL
) return -1;
2875 if (buffer
== NULL
) buflen
= 0;
2877 /* Calculate size of input */
2879 if (in
->pw_name
!= NULL
) hsize
+= (strlen(in
->pw_name
) + 1);
2880 if (in
->pw_passwd
!= NULL
) hsize
+= (strlen(in
->pw_passwd
) + 1);
2881 if (in
->pw_class
!= NULL
) hsize
+= (strlen(in
->pw_class
) + 1);
2882 if (in
->pw_gecos
!= NULL
) hsize
+= (strlen(in
->pw_gecos
) + 1);
2883 if (in
->pw_dir
!= NULL
) hsize
+= (strlen(in
->pw_dir
) + 1);
2884 if (in
->pw_shell
!= NULL
) hsize
+= (strlen(in
->pw_shell
) + 1);
2886 /* Check buffer space */
2887 if (hsize
> buflen
) return -1;
2889 /* Copy result into caller's struct passwd, using buffer for memory */
2892 out
->pw_name
= NULL
;
2893 if (in
->pw_name
!= NULL
)
2896 hsize
= strlen(in
->pw_name
) + 1;
2897 memmove(bp
, in
->pw_name
, hsize
);
2901 out
->pw_passwd
= NULL
;
2902 if (in
->pw_passwd
!= NULL
)
2904 out
->pw_passwd
= bp
;
2905 hsize
= strlen(in
->pw_passwd
) + 1;
2906 memmove(bp
, in
->pw_passwd
, hsize
);
2910 out
->pw_uid
= in
->pw_uid
;
2912 out
->pw_gid
= in
->pw_gid
;
2914 out
->pw_change
= in
->pw_change
;
2916 out
->pw_class
= NULL
;
2917 if (in
->pw_class
!= NULL
)
2920 hsize
= strlen(in
->pw_class
) + 1;
2921 memmove(bp
, in
->pw_class
, hsize
);
2925 out
->pw_gecos
= NULL
;
2926 if (in
->pw_gecos
!= NULL
)
2929 hsize
= strlen(in
->pw_gecos
) + 1;
2930 memmove(bp
, in
->pw_gecos
, hsize
);
2935 if (in
->pw_dir
!= NULL
)
2938 hsize
= strlen(in
->pw_dir
) + 1;
2939 memmove(bp
, in
->pw_dir
, hsize
);
2943 out
->pw_shell
= NULL
;
2944 if (in
->pw_shell
!= NULL
)
2947 hsize
= strlen(in
->pw_shell
) + 1;
2948 memmove(bp
, in
->pw_shell
, hsize
);
2952 out
->pw_expire
= in
->pw_expire
;
2958 copy_group_r(struct group
*in
, struct group
*out
, char *buffer
, int buflen
)
2964 if (in
== NULL
) return -1;
2965 if (out
== NULL
) return -1;
2967 if (buffer
== NULL
) buflen
= 0;
2969 /* Calculate size of input */
2971 if (in
->gr_name
!= NULL
) hsize
+= (strlen(in
->gr_name
) + 1);
2972 if (in
->gr_passwd
!= NULL
) hsize
+= (strlen(in
->gr_passwd
) + 1);
2974 /* NULL pointer at end of list */
2975 hsize
+= sizeof(char *);
2978 if (in
->gr_mem
!= NULL
)
2980 for (len
= 0; in
->gr_mem
[len
] != NULL
; len
++)
2982 hsize
+= sizeof(char *);
2983 hsize
+= (strlen(in
->gr_mem
[len
]) + 1);
2987 /* Check buffer space */
2988 if (hsize
> buflen
) return -1;
2990 /* Copy result into caller's struct group, using buffer for memory */
2993 out
->gr_name
= NULL
;
2994 if (in
->gr_name
!= NULL
)
2997 hsize
= strlen(in
->gr_name
) + 1;
2998 memmove(bp
, in
->gr_name
, hsize
);
3002 out
->gr_passwd
= NULL
;
3003 if (in
->gr_passwd
!= NULL
)
3005 out
->gr_passwd
= bp
;
3006 hsize
= strlen(in
->gr_passwd
) + 1;
3007 memmove(bp
, in
->gr_passwd
, hsize
);
3011 out
->gr_gid
= in
->gr_gid
;
3014 ap
= bp
+ ((len
+ 1) * sizeof(char *));
3016 if (in
->gr_mem
!= NULL
)
3018 out
->gr_mem
= (char **)bp
;
3019 for (i
= 0; i
< len
; i
++)
3021 addr
= (unsigned long)ap
;
3022 memmove(bp
, &addr
, sizeof(unsigned long));
3023 bp
+= sizeof(unsigned long);
3025 hsize
= strlen(in
->gr_mem
[i
]) + 1;
3026 memmove(ap
, in
->gr_mem
[i
], hsize
);
3031 memset(bp
, 0, sizeof(unsigned long));
3038 getgrnam_r(const char *name
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
3045 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
3048 if (result
!= NULL
) *result
= NULL
;
3050 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3052 item
= si_group_byname(si_search(), name
);
3053 if (item
== NULL
) return 0;
3055 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
3057 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
3058 si_item_release(item
);
3060 if (status
!= 0) return ERANGE
;
3067 getgrgid_r(gid_t gid
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
3074 fprintf(stderr
, "-> %s %d\n", __func__
, gid
);
3077 if (result
!= NULL
) *result
= NULL
;
3079 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3081 item
= si_group_bygid(si_search(), gid
);
3082 if (item
== NULL
) return 0;
3084 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
3086 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
3087 si_item_release(item
);
3089 if (status
!= 0) return ERANGE
;
3096 getgruuid_r(uuid_t uuid
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
3103 uuid_string_t uuidstr
;
3104 uuid_unparse_upper(uuid
, uuidstr
);
3105 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
3108 if (result
!= NULL
) *result
= NULL
;
3110 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3112 item
= si_group_byuuid(si_search(), uuid
);
3113 if (item
== NULL
) return 0;
3115 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
3117 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
3118 si_item_release(item
);
3120 if (status
!= 0) return ERANGE
;
3127 getpwnam_r(const char *name
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3134 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
3137 if (result
!= NULL
) *result
= NULL
;
3139 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3141 item
= si_user_byname(si_search(), name
);
3142 if (item
== NULL
) return 0;
3144 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3146 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3147 si_item_release(item
);
3149 if (status
!= 0) return ERANGE
;
3156 getpwuid_r(uid_t uid
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3163 fprintf(stderr
, "-> %s %d\n", __func__
, uid
);
3166 if (result
!= NULL
) *result
= NULL
;
3168 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3170 item
= si_user_byuid(si_search(), uid
);
3171 if (item
== NULL
) return 0;
3173 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3175 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3176 si_item_release(item
);
3178 if (status
!= 0) return ERANGE
;
3185 getpwuuid_r(uuid_t uuid
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3192 uuid_string_t uuidstr
;
3193 uuid_unparse_upper(uuid
, uuidstr
);
3194 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
3197 if (result
!= NULL
) *result
= NULL
;
3199 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3201 item
= si_user_byuuid(si_search(), uuid
);
3202 if (item
== NULL
) return 0;
3204 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3206 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3207 si_item_release(item
);
3209 if (status
!= 0) return ERANGE
;
3218 user_from_uid(uid_t uid
, int nouser
)
3221 static char buf
[16];
3224 if (pw
!= NULL
) return pw
->pw_name
;
3226 if (nouser
) return NULL
;
3228 snprintf(buf
, sizeof(buf
), "%u", uid
);
3233 group_from_gid(gid_t gid
, int nogroup
)
3236 static char buf
[16];
3239 if (gr
!= NULL
) return gr
->gr_name
;
3241 if (nogroup
) return NULL
;
3243 snprintf(buf
, sizeof(buf
), "%u", gid
);
3247 /* no longer supported */
3250 prdb_getbyname(const char *name
)
3253 fprintf(stderr
, "~~ %s\n", __func__
);
3262 fprintf(stderr
, "~~ %s\n", __func__
);
3268 prdb_set(const char *name
)
3271 fprintf(stderr
, "~~ %s\n", __func__
);
3279 fprintf(stderr
, "~~ %s\n", __func__
);
3283 struct bootparamsent
*
3284 bootparams_getbyname(const char *name
)
3287 fprintf(stderr
, "~~ %s\n", __func__
);
3292 struct bootparamsent
*
3293 bootparams_getent(void)
3296 fprintf(stderr
, "~~ %s\n", __func__
);
3302 bootparams_setent(void)
3305 fprintf(stderr
, "~~ %s\n", __func__
);
3310 bootparams_endent(void)
3313 fprintf(stderr
, "~~ %s\n", __func__
);
3318 bootp_getbyether(struct ether_addr
*enaddr
, char **name
,struct in_addr
*ipaddr
, char **bootfile
)
3321 fprintf(stderr
, "~~ %s\n", __func__
);
3327 bootp_getbyip(struct ether_addr
*enaddr
, char **name
, struct in_addr
*ipaddr
, char **bootfile
)
3330 fprintf(stderr
, "~~ %s\n", __func__
);