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 item
= si_user_byname(si_search(), name
);
196 LI_set_thread_item(CATEGORY_USER
+ 100, item
);
198 if (item
== NULL
) return NULL
;
199 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
203 getpwnam_async_call(const char *name
, si_user_async_callback callback
, void *context
)
208 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
211 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
212 if (sictx
== NULL
) return MACH_PORT_NULL
;
214 sictx
->orig_callback
= callback
;
215 sictx
->orig_context
= context
;
216 sictx
->cat
= CATEGORY_USER
;
217 sictx
->key_offset
= 100;
219 return si_async_call(si_search(), SI_CALL_USER_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
223 getpwnam_async_handle_reply(mach_msg_header_t
*msg
)
226 fprintf(stderr
, "<< %s\n", __func__
);
229 si_async_handle_reply(msg
);
238 fprintf(stderr
, "-> %s %d\n", __func__
, uid
);
242 item
= si_user_byuid(si_search(), uid
);
243 LI_set_thread_item(CATEGORY_USER
+ 200, item
);
245 if (item
== NULL
) return NULL
;
246 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
250 getpwuid_async_call(uid_t uid
, si_user_async_callback callback
, void *context
)
255 fprintf(stderr
, ">> %s %d\n", __func__
, uid
);
258 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
259 if (sictx
== NULL
) return MACH_PORT_NULL
;
261 sictx
->orig_callback
= callback
;
262 sictx
->orig_context
= context
;
263 sictx
->cat
= CATEGORY_USER
;
264 sictx
->key_offset
= 200;
266 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
);
270 getpwuid_async_handle_reply(mach_msg_header_t
*msg
)
273 fprintf(stderr
, "<< %s\n", __func__
);
276 si_async_handle_reply(msg
);
280 getpwuuid(uuid_t uuid
)
285 uuid_string_t uuidstr
;
286 uuid_unparse_upper(uuid
, uuidstr
);
287 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
290 item
= si_user_byuuid(si_search(), uuid
);
291 LI_set_thread_item(CATEGORY_USER
+ 300, item
);
293 if (item
== NULL
) return NULL
;
294 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
301 fprintf(stderr
, "-- %s\n", __func__
);
304 LI_set_thread_list(CATEGORY_USER
, NULL
);
314 fprintf(stderr
, "-> %s\n", __func__
);
317 list
= LI_get_thread_list(CATEGORY_USER
);
320 list
= si_user_all(si_search());
321 LI_set_thread_list(CATEGORY_USER
, list
);
324 item
= si_list_next(list
);
325 if (item
== NULL
) return NULL
;
327 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
334 fprintf(stderr
, "-- %s\n", __func__
);
337 LI_set_thread_list(CATEGORY_USER
, NULL
);
341 setpassent(int ignored
)
346 fprintf(stderr
, "-> %s\n", __func__
);
349 list
= LI_get_thread_list(CATEGORY_USER
);
352 if (list
== NULL
) return 0;
359 getgrnam(const char *name
)
364 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
367 item
= si_group_byname(si_search(), name
);
368 LI_set_thread_item(CATEGORY_GROUP
+ 100, item
);
370 if (item
== NULL
) return NULL
;
371 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
375 getgrnam_async_call(const char *name
, si_group_async_callback callback
, void *context
)
380 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
383 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
384 if (sictx
== NULL
) return MACH_PORT_NULL
;
386 sictx
->orig_callback
= callback
;
387 sictx
->orig_context
= context
;
388 sictx
->cat
= CATEGORY_GROUP
;
389 sictx
->key_offset
= 100;
391 return si_async_call(si_search(), SI_CALL_GROUP_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
395 getgrnam_async_handle_reply(mach_msg_header_t
*msg
)
398 fprintf(stderr
, "<< %s\n", __func__
);
401 si_async_handle_reply(msg
);
410 fprintf(stderr
, "-> %s %d\n", __func__
, gid
);
413 item
= si_group_bygid(si_search(), gid
);
414 LI_set_thread_item(CATEGORY_GROUP
+ 200, item
);
416 if (item
== NULL
) return NULL
;
417 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
421 getgrgid_async_call(gid_t gid
, si_group_async_callback callback
, void *context
)
426 fprintf(stderr
, ">> %s %d\n", __func__
, gid
);
429 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
430 if (sictx
== NULL
) return MACH_PORT_NULL
;
432 sictx
->orig_callback
= callback
;
433 sictx
->orig_context
= context
;
434 sictx
->cat
= CATEGORY_GROUP
;
435 sictx
->key_offset
= 200;
437 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
);
441 getgruid_async_handle_reply(mach_msg_header_t
*msg
)
444 fprintf(stderr
, "<< %s\n", __func__
);
447 si_async_handle_reply(msg
);
451 getgruuid(uuid_t uuid
)
456 uuid_string_t uuidstr
;
457 uuid_unparse_upper(uuid
, uuidstr
);
458 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
461 item
= si_group_byuuid(si_search(), uuid
);
462 LI_set_thread_item(CATEGORY_GROUP
+ 300, item
);
464 if (item
== NULL
) return NULL
;
465 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
472 fprintf(stderr
, "-- %s\n", __func__
);
475 LI_set_thread_list(CATEGORY_GROUP
, NULL
);
485 fprintf(stderr
, "-> %s\n", __func__
);
488 list
= LI_get_thread_list(CATEGORY_GROUP
);
491 list
= si_group_all(si_search());
492 LI_set_thread_list(CATEGORY_GROUP
, list
);
495 item
= si_list_next(list
);
496 if (item
== NULL
) return NULL
;
498 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
505 fprintf(stderr
, "-- %s\n", __func__
);
508 LI_set_thread_list(CATEGORY_GROUP
, NULL
);
512 setgroupent(int ignored
)
517 fprintf(stderr
, "-> %s\n", __func__
);
520 list
= LI_get_thread_list(CATEGORY_GROUP
);
523 if (list
== NULL
) return 0;
529 innetgr(const char *group
, const char *host
, const char *user
, const char *domain
)
533 fprintf(stderr
, "-> %s %s %s %s %s\n", __func__
, group
, host
, user
, domain
);
536 res
= si_in_netgroup(si_search(), group
, host
, user
, domain
);
539 fprintf(stderr
, "<- %s %d\n", __func__
, res
);
545 /* N.B. there is no async innetgr */
548 * setnetgrent is really more like a getXXXbyname routine than a
549 * setXXXent routine, since we are looking up a netgroup by name.
552 setnetgrent(const char *name
)
557 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
560 list
= si_netgroup_byname(si_search(), name
);
561 LI_set_thread_list(CATEGORY_NETGROUP
, list
);
564 /* N.B. there is no async getnetgrent */
567 getnetgrent(char **host
, char **user
, char **domain
)
571 struct netgrent_s
*ng
;
574 fprintf(stderr
, "-> %s\n", __func__
);
577 list
= LI_get_thread_list(CATEGORY_NETGROUP
);
578 item
= si_list_next(list
);
579 if (item
== NULL
) return 0;
581 ng
= (struct netgrent_s
*)((uintptr_t)item
+ sizeof(si_item_t
));
585 *domain
= ng
->ng_domain
;
594 fprintf(stderr
, "-- %s\n", __func__
);
597 LI_set_thread_list(CATEGORY_NETGROUP
, NULL
);
602 _check_groups(const char *function
, int32_t ngroups
)
604 static dispatch_once_t once
;
606 if (ngroups
> 0 && ngroups
< NGROUPS_MAX
) {
610 /* only log once per process */
611 dispatch_once(&once
, ^(void) {
612 const char *proc_name
= getprogname();
613 if (strcmp(proc_name
, "id") != 0 && strcmp(proc_name
, "smbd") != 0 && strcmp(proc_name
, "rpcsvchost") != 0) {
614 aslmsg msg
= asl_new(ASL_TYPE_MSG
);
617 snprintf(buffer
, sizeof(buffer
), "%d", (ngroups
== 0 ? INT_MAX
: ngroups
));
618 asl_set(msg
, "com.apple.message.value", buffer
);
620 asl_set(msg
, "com.apple.message.domain", "com.apple.system.libinfo");
621 asl_set(msg
, "com.apple.message.result", "noop");
622 asl_set(msg
, "com.apple.message.signature", function
);
624 asl_log(NULL
, msg
, ASL_LEVEL_NOTICE
, "%s called triggering group enumeration", function
);
635 getgrouplist_internal(const char *name
, int basegid
, gid_t
*groups
, uint32_t *ngroups
)
637 int i
, j
, x
, g
, add
, max
;
642 * On input, ngroups specifies the size of the groups array.
643 * On output, it is set to the number of groups that are being returned.
644 * Returns -1 if the size is too small to fit all the groups that were found.
648 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
651 if (name
== NULL
) return 0;
652 if (groups
== NULL
) return 0;
653 if (ngroups
== NULL
) return 0;
657 if (max
<= 0) return 0;
662 item
= si_grouplist(si_search(), name
, max
);
663 LI_set_thread_item(CATEGORY_GROUPLIST
, item
);
664 if (item
== NULL
) return 0;
666 gl
= (si_grouplist_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
670 for (i
= 0; i
< gl
->gl_count
; i
++)
674 for (j
= 0; j
< x
; j
++) {
675 if (groups
[j
] == g
) {
680 if (add
== 0) continue;
682 if (x
>= max
) return -1;
692 getgrouplist(const char *name
, int basegid
, int *groups
, int *ngroups
)
695 _check_groups("getgrouplist", *ngroups
);
698 return getgrouplist_internal(name
, basegid
, (gid_t
*)groups
, (uint32_t *)ngroups
);
702 merge_gid(gid_t
*list
, gid_t g
, int32_t *count
)
708 for (i
= 0; i
< cnt
; i
++) {
709 if (list
[i
] == g
) return;
717 _getgrouplist_2_internal(const char *name
, gid_t basegid
, gid_t
**groups
)
724 item
= si_grouplist(si_search(), name
, INT_MAX
);
725 LI_set_thread_item(CATEGORY_GROUPLIST
, item
);
726 if (item
== NULL
) return -1;
728 gl
= (si_grouplist_t
*) ((uintptr_t) item
+ sizeof(si_item_t
));
731 * we can allocate enough up-front, we'll only use what we need
732 * we add one to the count that was found in case the basegid is not there
734 gids
= calloc(gl
->gl_count
+ 1, sizeof(gid_t
));
735 if (gids
== NULL
) return -1;
738 merge_gid(gids
, basegid
, &count
);
739 if (gl
->gl_gid
!= NULL
) {
740 for (i
= 0; i
< gl
->gl_count
; i
++) {
741 merge_gid(gids
, gl
->gl_gid
[i
], &count
);
751 getgrouplist_2(const char *name
, gid_t basegid
, gid_t
**groups
)
754 * Passes back a gid_t list containing all the users groups (and basegid).
755 * Caller must free the list.
756 * Returns the number of gids in the list or -1 on failure.
760 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
763 if (name
== NULL
) return 0;
764 if (groups
== NULL
) return 0;
767 _check_groups("getgrouplist_2", INT_MAX
);
770 return _getgrouplist_2_internal(name
, basegid
, groups
);
774 getgroupcount(const char *name
, gid_t basegid
)
780 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
784 _check_groups("getgroupcount", INT_MAX
);
788 count
= _getgrouplist_2_internal(name
, basegid
, &groups
);
789 if (groups
!= NULL
) free(groups
);
794 /* XXX to do: async getgrouplist_2 */
797 initgroups(const char *name
, int basegid
)
801 gid_t groups
[NGROUPS
];
809 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
812 /* KAUTH_UID_NONE tells the kernel not to fetch supplementary groups from DirectoryService */
813 uid
= KAUTH_UID_NONE
;
816 /* get the UID for this user */
817 item
= si_user_byname(si_search(), name
);
820 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
822 si_item_release(item
);
830 * A failure either means that user belongs to more than NGROUPS groups
831 * or no groups at all.
834 (void) getgrouplist_internal(name
, basegid
, groups
, &ngroups
);
836 status
= __initgroups(ngroups
, groups
, uid
);
837 if (status
< 0) return -1;
845 alias_getbyname(const char *name
)
850 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
853 item
= si_alias_byname(si_search(), name
);
854 LI_set_thread_item(CATEGORY_ALIAS
+ 100, item
);
855 if (item
== NULL
) return NULL
;
857 return (struct aliasent
*)((uintptr_t)item
+ sizeof(si_item_t
));
861 alias_getbyname_async_call(const char *name
, si_alias_async_callback callback
, void *context
)
866 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
869 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
870 if (sictx
== NULL
) return MACH_PORT_NULL
;
872 sictx
->orig_callback
= callback
;
873 sictx
->orig_context
= context
;
874 sictx
->cat
= CATEGORY_ALIAS
;
875 sictx
->key_offset
= 100;
877 return si_async_call(si_search(), SI_CALL_ALIAS_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
881 alias_getbyname_async_handle_reply(mach_msg_header_t
*msg
)
884 fprintf(stderr
, "<< %s\n", __func__
);
887 si_async_handle_reply(msg
);
894 fprintf(stderr
, "-> %s\n", __func__
);
897 LI_set_thread_list(CATEGORY_ALIAS
, NULL
);
907 fprintf(stderr
, "-> %s\n", __func__
);
910 list
= LI_get_thread_list(CATEGORY_ALIAS
);
913 list
= si_alias_all(si_search());
914 LI_set_thread_list(CATEGORY_ALIAS
, list
);
917 item
= si_list_next(list
);
918 if (item
== NULL
) return NULL
;
920 return (struct aliasent
*)((uintptr_t)item
+ sizeof(si_item_t
));
927 fprintf(stderr
, "-- %s\n", __func__
);
930 LI_set_thread_list(CATEGORY_ALIAS
, NULL
);
936 freehostent(struct hostent
*h
)
938 if (h
== NULL
) return;
940 si_item_t
*item
= (si_item_t
*)((uintptr_t)h
- sizeof(si_item_t
));
941 si_item_release(item
);
945 gethostbynameerrno(const char *name
, int *err
)
949 struct in_addr addr4
;
952 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
955 memset(&addr4
, 0, sizeof(struct in_addr
));
956 status
= SI_STATUS_NO_ERROR
;
959 if (inet_aton(name
, &addr4
) == 1) item
= si_ipnode_byname(si_search(), name
, AF_INET
, 0, NULL
, &status
);
960 else item
= si_host_byname(si_search(), name
, AF_INET
, NULL
, &status
);
962 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
963 if (err
!= NULL
) *err
= status
;
965 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
966 if (item
== NULL
) return NULL
;
968 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
972 gethostbyname(const char *name
)
976 struct in_addr addr4
;
979 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
982 memset(&addr4
, 0, sizeof(struct in_addr
));
983 status
= SI_STATUS_NO_ERROR
;
986 if (inet_aton(name
, &addr4
) == 1) item
= si_ipnode_byname(si_search(), name
, AF_INET
, 0, NULL
, &status
);
987 else item
= si_host_byname(si_search(), name
, AF_INET
, NULL
, &status
);
989 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
992 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
993 if (item
== NULL
) return NULL
;
995 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
999 gethostbyname_async_call(const char *name
, si_host_async_callback callback
, void *context
)
1001 si_context_t
*sictx
;
1004 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1007 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1008 if (sictx
== NULL
) return MACH_PORT_NULL
;
1010 sictx
->orig_callback
= callback
;
1011 sictx
->orig_context
= context
;
1012 sictx
->cat
= CATEGORY_HOST
;
1013 sictx
->key_offset
= 100;
1015 return si_async_call(si_search(), SI_CALL_HOST_BYNAME
, name
, NULL
, NULL
, AF_INET
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1019 gethostbyname_async_start(const char *name
, si_host_async_callback callback
, void *context
)
1021 return gethostbyname_async_call(name
, callback
, context
);
1025 gethostbyname_async_cancel(mach_port_t p
)
1028 fprintf(stderr
, "-- %s\n", __func__
);
1036 gethostbyname_async_handle_reply(void *param
)
1038 mach_msg_header_t
*msg
;
1041 fprintf(stderr
, "<< %s\n", __func__
);
1044 msg
= (mach_msg_header_t
*)param
;
1045 si_async_handle_reply(msg
);
1050 gethostbyname_async_handleReply(void *param
)
1052 mach_msg_header_t
*msg
;
1055 fprintf(stderr
, "<< %s\n", __func__
);
1058 msg
= (mach_msg_header_t
*)param
;
1059 si_async_handle_reply(msg
);
1063 gethostbyname2(const char *name
, int af
)
1067 struct in_addr addr4
;
1068 struct in6_addr addr6
;
1069 si_mod_t
*search
= si_search();
1072 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, af
);
1075 memset(&addr4
, 0, sizeof(struct in_addr
));
1076 memset(&addr6
, 0, sizeof(struct in6_addr
));
1077 status
= SI_STATUS_NO_ERROR
;
1080 if (((af
== AF_INET
) && (inet_aton(name
, &addr4
) == 1)) || ((af
== AF_INET6
) && (inet_pton(af
, name
, &addr6
) == 1)))
1082 item
= si_ipnode_byname(search
, name
, (uint32_t)af
, 0, NULL
, &status
);
1086 item
= si_host_byname(search
, name
, (uint32_t)af
, NULL
, &status
);
1089 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1092 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
1093 if (item
== NULL
) return NULL
;
1095 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1099 gethostbyname2_async_call(const char *name
, int af
, si_group_async_callback callback
, void *context
)
1101 si_context_t
*sictx
;
1104 fprintf(stderr
, ">> %s %s %d\n", __func__
, name
, af
);
1107 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1108 if (sictx
== NULL
) return MACH_PORT_NULL
;
1110 sictx
->orig_callback
= callback
;
1111 sictx
->orig_context
= context
;
1112 sictx
->cat
= CATEGORY_HOST
;
1113 sictx
->key_offset
= 100;
1115 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
);
1119 gethostbyname2_async_cancel(mach_port_t p
)
1122 fprintf(stderr
, "-- %s\n", __func__
);
1129 gethostbyname2_async_handle_reply(mach_msg_header_t
*msg
)
1132 fprintf(stderr
, "<< %s\n", __func__
);
1135 si_async_handle_reply(msg
);
1139 gethostbyaddr(const void *addr
, socklen_t len
, int type
)
1145 fprintf(stderr
, "-> %s %s\n", __func__
, (type
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)addr
) : "-IPv6-");
1148 status
= SI_STATUS_NO_ERROR
;
1150 item
= si_host_byaddr(si_search(), addr
, (uint32_t)type
, NULL
, &status
);
1151 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1154 LI_set_thread_item(CATEGORY_HOST
+ 200, item
);
1155 if (item
== NULL
) return NULL
;
1157 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1161 gethostbyaddr_async_call(const void *addr
, socklen_t len
, int type
, si_host_async_callback callback
, void *context
)
1163 si_context_t
*sictx
;
1167 fprintf(stderr
, ">> %s %s\n", __func__
, (type
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)addr
) : "-IPv6-");
1170 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1171 if (sictx
== NULL
) return MACH_PORT_NULL
;
1173 sictx
->orig_callback
= callback
;
1174 sictx
->orig_context
= context
;
1175 sictx
->cat
= CATEGORY_HOST
;
1176 sictx
->key_offset
= 200;
1178 /* addr is not a C string - pass length in num3 */
1180 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
);
1184 gethostbyaddr_async_start(const char *addr
, int len
, int family
, si_host_async_callback callback
, void *context
)
1186 socklen_t slen
= len
;
1188 return gethostbyaddr_async_call(addr
, slen
, family
, callback
, context
);
1192 gethostbyaddr_async_cancel(mach_port_t p
)
1195 fprintf(stderr
, "-- %s\n", __func__
);
1203 gethostbyaddr_async_handle_reply(void *param
)
1206 mach_msg_header_t
*msg
;
1209 fprintf(stderr
, "<< %s\n", __func__
);
1212 msg
= (mach_msg_header_t
*)param
;
1213 si_async_handle_reply(msg
);
1218 gethostbyaddr_async_handleReply(void *param
)
1220 mach_msg_header_t
*msg
;
1223 fprintf(stderr
, "<< %s\n", __func__
);
1226 msg
= (mach_msg_header_t
*)param
;
1227 si_async_handle_reply(msg
);
1231 getipnodebyname(const char *name
, int family
, int flags
, int *err
)
1237 fprintf(stderr
, "-> %s %s %d 0x%08x\n", __func__
, name
, family
, flags
);
1240 status
= SI_STATUS_NO_ERROR
;
1242 item
= si_ipnode_byname(si_search(), name
, family
, flags
, NULL
, &status
);
1243 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1244 if (err
!= NULL
) *err
= status
;
1246 if (item
== NULL
) return NULL
;
1248 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1253 getipnodebyname_async_call(const char *name
, int family
, int flags
, int *err
, si_host_async_callback callback
, void *context
)
1255 si_context_t
*sictx
;
1258 fprintf(stderr
, ">> %s %s %d 0x%08x\n", __func__
, name
, family
, flags
);
1261 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1262 if (sictx
== NULL
) return MACH_PORT_NULL
;
1264 sictx
->orig_callback
= callback
;
1265 sictx
->orig_context
= context
;
1266 sictx
->cat
= CATEGORY_HOST
;
1267 sictx
->key_offset
= -1;
1269 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
);
1273 getipnodebyname_async_start(const char *name
, int family
, int flags
, int *err
, si_host_async_callback callback
, void *context
)
1275 return getipnodebyname_async_call(name
, family
, flags
, err
, callback
, context
);
1279 getipnodebyname_async_cancel(mach_port_t p
)
1282 fprintf(stderr
, "-- %s\n", __func__
);
1289 getipnodebyname_async_handle_reply(mach_msg_header_t
*msg
)
1292 fprintf(stderr
, "<< %s\n", __func__
);
1295 si_async_handle_reply(msg
);
1299 getipnodebyname_async_handleReply(mach_msg_header_t
*msg
)
1302 fprintf(stderr
, "<< %s\n", __func__
);
1305 si_async_handle_reply(msg
);
1310 is_a4_mapped(const char *s
)
1315 if (s
== NULL
) return 0;
1317 for (i
= 0; i
< 10; i
++)
1320 if (c
!= 0x0) return 0;
1323 for (i
= 10; i
< 12; i
++)
1326 if (c
!= 0xff) return 0;
1333 is_a4_compat(const char *s
)
1338 if (s
== NULL
) return 0;
1340 for (i
= 0; i
< 12; i
++)
1343 if (c
!= 0x0) return 0;
1346 /* Check for :: and ::1 */
1347 for (i
= 13; i
< 15; i
++)
1349 /* anything non-zero in these 3 bytes means it's a V4 address */
1351 if (c
!= 0x0) return 1;
1354 /* Leading 15 bytes are all zero */
1356 if (c
== 0x0) return 0;
1357 if (c
== 0x1) return 0;
1363 getipnodebyaddr(const void *src
, size_t len
, int family
, int *err
)
1368 fprintf(stderr
, "-> %s %s\n", __func__
, (family
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)src
) : "-IPv6-");
1371 if ((family
== AF_INET6
) && (len
== IPV6_ADDR_LEN
) && (is_a4_mapped((const char *)src
) || is_a4_compat((const char *)src
)))
1378 item
= si_host_byaddr(si_search(), src
, family
, NULL
, (uint32_t *)err
);
1379 if (item
== NULL
) return NULL
;
1381 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1386 si_libinfo_ipnode_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
1388 si_context_t
*sictx
;
1391 if (ctx
== NULL
) return;
1393 sictx
= (si_context_t
*)ctx
;
1395 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
1398 si_item_release(item
);
1402 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1406 ((si_ipnode_async_callback
)(sictx
->orig_callback
))(NULL
, status
, sictx
->orig_context
);
1410 h
= (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1411 ((si_ipnode_async_callback
)(sictx
->orig_callback
))(h
, status
, sictx
->orig_context
);
1417 getipnodebyaddr_async_call(const void *src
, socklen_t len
, int family
, int *err
, si_ipnode_async_callback callback
, void *context
)
1419 si_context_t
*sictx
;
1423 fprintf(stderr
, ">> %s %s\n", __func__
, (family
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)src
) : "-IPv6-");
1426 if ((family
== AF_INET6
) && (len
== IPV6_ADDR_LEN
) && (is_a4_mapped((const char *)src
) || is_a4_compat((const char *)src
)))
1433 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1434 if (sictx
== NULL
) return MACH_PORT_NULL
;
1436 sictx
->orig_callback
= callback
;
1437 sictx
->orig_context
= context
;
1438 sictx
->cat
= CATEGORY_HOST
;
1439 sictx
->key_offset
= -1;
1441 /* src is not a C string - pass length in num3 */
1443 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
);
1447 getipnodebyaddr_async_start(const void *addr
, size_t len
, int family
, int *error
, si_ipnode_async_callback callback
, void *context
)
1449 socklen_t slen
= len
;
1451 return getipnodebyaddr_async_call(addr
, slen
, family
, error
, callback
, context
);
1455 getipnodebyaddr_async_cancel(mach_port_t p
)
1458 fprintf(stderr
, "-- %s\n", __func__
);
1465 getipnodebyaddr_async_handle_reply(mach_msg_header_t
*msg
)
1468 fprintf(stderr
, "<< %s\n", __func__
);
1471 si_async_handle_reply(msg
);
1475 getipnodebyaddr_async_handleReply(mach_msg_header_t
*msg
)
1478 fprintf(stderr
, "<< %s\n", __func__
);
1481 si_async_handle_reply(msg
);
1486 sethostent(int ignored
)
1489 fprintf(stderr
, "-- %s\n", __func__
);
1492 LI_set_thread_list(CATEGORY_HOST
, NULL
);
1502 fprintf(stderr
, "-> %s\n", __func__
);
1505 list
= LI_get_thread_list(CATEGORY_HOST
);
1508 list
= si_host_all(si_search());
1509 LI_set_thread_list(CATEGORY_HOST
, list
);
1512 item
= si_list_next(list
);
1513 if (item
== NULL
) return NULL
;
1515 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1522 fprintf(stderr
, "-- %s\n", __func__
);
1525 LI_set_thread_list(CATEGORY_HOST
, NULL
);
1531 ether_hostton(const char *name
, struct ether_addr
*e
)
1539 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1542 if (name
== NULL
) return -1;
1543 if (e
== NULL
) return -1;
1545 item
= si_mac_byname(si_search(), name
);
1546 LI_set_thread_item(CATEGORY_MAC
+ 100, item
);
1547 if (item
== NULL
) return -1;
1549 mac
= (si_mac_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
1551 i
= sscanf(mac
->mac
, " %x:%x:%x:%x:%x:%x", &t
[0], &t
[1], &t
[2], &t
[3], &t
[4], &t
[5]);
1552 if (i
!= 6) return -1;
1554 for (i
= 0; i
< 6; i
++) e
->ether_addr_octet
[i
] = t
[i
];
1558 /* XXX to do? async ether_hostton */
1561 ether_ntohost(char *name
, const struct ether_addr
*e
)
1568 if (name
== NULL
) return -1;
1569 if (e
== NULL
) return -1;
1571 for (i
= 0; i
< 6; i
++) x
[i
] = e
->ether_addr_octet
[i
];
1572 snprintf(str
, sizeof(str
), "%x:%x:%x:%x:%x:%x", x
[0], x
[1], x
[2], x
[3], x
[4], x
[5]);
1575 fprintf(stderr
, "-> %s %s\n", __func__
, str
);
1578 item
= si_mac_bymac(si_search(), str
);
1579 LI_set_thread_item(CATEGORY_MAC
+ 200, item
);
1580 if (item
== NULL
) return -1;
1582 mac
= (si_mac_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
1584 memcpy(name
, mac
->host
, strlen(mac
->host
) + 1);
1588 /* XXX to do? async ether_ntohost */
1593 getnetbyname(const char *name
)
1598 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1601 item
= si_network_byname(si_search(), name
);
1602 LI_set_thread_item(CATEGORY_NETWORK
+ 100, item
);
1603 if (item
== NULL
) return NULL
;
1605 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1609 getnetbyname_async_call(const char *name
, si_network_async_callback callback
, void *context
)
1611 si_context_t
*sictx
;
1614 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1617 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1618 if (sictx
== NULL
) return MACH_PORT_NULL
;
1620 sictx
->orig_callback
= callback
;
1621 sictx
->orig_context
= context
;
1622 sictx
->cat
= CATEGORY_NETWORK
;
1623 sictx
->key_offset
= 100;
1625 return si_async_call(si_search(), SI_CALL_NETWORK_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1629 getnetbyname_async_handle_reply(mach_msg_header_t
*msg
)
1632 fprintf(stderr
, "<< %s\n", __func__
);
1635 si_async_handle_reply(msg
);
1639 getnetbyaddr(uint32_t net
, int type
)
1644 fprintf(stderr
, "-> %s 0x%08x\n", __func__
, net
);
1647 if (type
!= AF_INET
) return NULL
;
1649 item
= si_network_byaddr(si_search(), net
);
1650 LI_set_thread_item(CATEGORY_NETWORK
+ 200, item
);
1651 if (item
== NULL
) return NULL
;
1653 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1657 getnetbyaddr_async_call(uint32_t net
, int type
, si_group_async_callback callback
, void *context
)
1659 si_context_t
*sictx
;
1662 fprintf(stderr
, ">> %s 0x%08x\n", __func__
, net
);
1665 if (type
!= AF_INET
) return MACH_PORT_NULL
;
1667 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1668 if (sictx
== NULL
) return MACH_PORT_NULL
;
1670 sictx
->orig_callback
= callback
;
1671 sictx
->orig_context
= context
;
1672 sictx
->cat
= CATEGORY_NETWORK
;
1673 sictx
->key_offset
= 200;
1675 return si_async_call(si_search(), SI_CALL_NETWORK_BYADDR
, NULL
, NULL
, NULL
, net
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1679 getnetbyaddr_async_handle_reply(mach_msg_header_t
*msg
)
1682 fprintf(stderr
, "<< %s\n", __func__
);
1685 si_async_handle_reply(msg
);
1689 setnetent(int ignored
)
1692 fprintf(stderr
, "-- %s\n", __func__
);
1695 LI_set_thread_list(CATEGORY_NETWORK
, NULL
);
1705 fprintf(stderr
, "-> %s\n", __func__
);
1708 list
= LI_get_thread_list(CATEGORY_NETWORK
);
1711 list
= si_network_all(si_search());
1712 LI_set_thread_list(CATEGORY_NETWORK
, list
);
1715 item
= si_list_next(list
);
1716 if (item
== NULL
) return NULL
;
1718 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1725 fprintf(stderr
, "-- %s\n", __func__
);
1728 LI_set_thread_list(CATEGORY_NETWORK
, NULL
);
1734 getservbyname(const char *name
, const char *proto
)
1739 fprintf(stderr
, "-> %s %s %s\n", __func__
, name
, proto
);
1742 item
= si_service_byname(si_search(), name
, proto
);
1743 LI_set_thread_item(CATEGORY_SERVICE
+ 100, item
);
1744 if (item
== NULL
) return NULL
;
1746 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1750 getservbyname_async_call(const char *name
, const char *proto
, si_service_async_callback callback
, void *context
)
1752 si_context_t
*sictx
;
1755 fprintf(stderr
, ">> %s %s %s\n", __func__
, name
, proto
);
1758 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1759 if (sictx
== NULL
) return MACH_PORT_NULL
;
1761 sictx
->orig_callback
= callback
;
1762 sictx
->orig_context
= context
;
1763 sictx
->cat
= CATEGORY_SERVICE
;
1764 sictx
->key_offset
= 100;
1766 return si_async_call(si_search(), SI_CALL_SERVICE_BYNAME
, name
, proto
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1770 getservbyname_async_handle_reply(mach_msg_header_t
*msg
)
1773 fprintf(stderr
, "<< %s\n", __func__
);
1776 si_async_handle_reply(msg
);
1780 getservbyport(int port
, const char *proto
)
1785 fprintf(stderr
, "-> %s %d %s\n", __func__
, ntohs((uint16_t)port
), proto
);
1788 item
= si_service_byport(si_search(), port
, proto
);
1789 LI_set_thread_item(CATEGORY_SERVICE
+ 200, item
);
1790 if (item
== NULL
) return NULL
;
1792 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1796 getservbyport_async_call(int port
, const char *proto
, si_group_async_callback callback
, void *context
)
1798 si_context_t
*sictx
;
1801 fprintf(stderr
, ">> %s %d %s\n", __func__
, port
, proto
);
1804 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1805 if (sictx
== NULL
) return MACH_PORT_NULL
;
1807 sictx
->orig_callback
= callback
;
1808 sictx
->orig_context
= context
;
1809 sictx
->cat
= CATEGORY_SERVICE
;
1810 sictx
->key_offset
= 200;
1812 return si_async_call(si_search(), SI_CALL_SERVICE_BYPORT
, NULL
, proto
, NULL
, port
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1816 getservbyport_async_handle_reply(mach_msg_header_t
*msg
)
1819 fprintf(stderr
, "<< %s\n", __func__
);
1822 si_async_handle_reply(msg
);
1826 setservent(int ignored
)
1829 fprintf(stderr
, "-- %s\n", __func__
);
1832 LI_set_thread_list(CATEGORY_SERVICE
, NULL
);
1842 fprintf(stderr
, "-> %s\n", __func__
);
1845 list
= LI_get_thread_list(CATEGORY_SERVICE
);
1848 list
= si_service_all(si_search());
1849 LI_set_thread_list(CATEGORY_SERVICE
, list
);
1852 item
= si_list_next(list
);
1853 if (item
== NULL
) return NULL
;
1855 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1862 fprintf(stderr
, "-- %s\n", __func__
);
1865 LI_set_thread_list(CATEGORY_SERVICE
, NULL
);
1871 getprotobyname(const char *name
)
1876 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1879 item
= si_protocol_byname(si_search(), name
);
1880 LI_set_thread_item(CATEGORY_PROTOCOL
+ 100, item
);
1881 if (item
== NULL
) return NULL
;
1883 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1887 getprotobyname_async_call(const char *name
, si_protocol_async_callback callback
, void *context
)
1889 si_context_t
*sictx
;
1892 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1895 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1896 if (sictx
== NULL
) return MACH_PORT_NULL
;
1898 sictx
->orig_callback
= callback
;
1899 sictx
->orig_context
= context
;
1900 sictx
->cat
= CATEGORY_PROTOCOL
;
1901 sictx
->key_offset
= 100;
1903 return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1907 getprotobyname_async_handle_reply(mach_msg_header_t
*msg
)
1910 fprintf(stderr
, "<< %s\n", __func__
);
1913 si_async_handle_reply(msg
);
1917 getprotobynumber(int number
)
1922 fprintf(stderr
, "-> %s %d\n", __func__
, number
);
1925 item
= si_protocol_bynumber(si_search(), number
);
1926 LI_set_thread_item(CATEGORY_PROTOCOL
+ 200, item
);
1927 if (item
== NULL
) return NULL
;
1929 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1933 getprotobynumber_async_call(int number
, si_group_async_callback callback
, void *context
)
1935 si_context_t
*sictx
;
1938 fprintf(stderr
, ">> %s %d\n", __func__
, number
);
1941 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1942 if (sictx
== NULL
) return MACH_PORT_NULL
;
1944 sictx
->orig_callback
= callback
;
1945 sictx
->orig_context
= context
;
1946 sictx
->cat
= CATEGORY_PROTOCOL
;
1947 sictx
->key_offset
= 200;
1949 return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNUMBER
, NULL
, NULL
, NULL
, number
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1953 getprotobynumber_async_handle_reply(mach_msg_header_t
*msg
)
1956 fprintf(stderr
, "<< %s\n", __func__
);
1959 si_async_handle_reply(msg
);
1963 setprotoent(int ignored
)
1966 fprintf(stderr
, "-- %s\n", __func__
);
1969 LI_set_thread_list(CATEGORY_PROTOCOL
, NULL
);
1979 fprintf(stderr
, "-> %s\n", __func__
);
1982 list
= LI_get_thread_list(CATEGORY_PROTOCOL
);
1985 list
= si_protocol_all(si_search());
1986 LI_set_thread_list(CATEGORY_PROTOCOL
, list
);
1989 item
= si_list_next(list
);
1990 if (item
== NULL
) return NULL
;
1992 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1999 fprintf(stderr
, "-- %s\n", __func__
);
2002 LI_set_thread_list(CATEGORY_PROTOCOL
, NULL
);
2008 getrpcbyname(const char *name
)
2013 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
2016 item
= si_rpc_byname(si_search(), name
);
2017 LI_set_thread_item(CATEGORY_RPC
+ 100, item
);
2018 if (item
== NULL
) return NULL
;
2020 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2024 getrpcbyname_async_call(const char *name
, si_rpc_async_callback callback
, void *context
)
2026 si_context_t
*sictx
;
2029 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
2032 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2033 if (sictx
== NULL
) return MACH_PORT_NULL
;
2035 sictx
->orig_callback
= callback
;
2036 sictx
->orig_context
= context
;
2037 sictx
->cat
= CATEGORY_RPC
;
2038 sictx
->key_offset
= 100;
2040 return si_async_call(si_search(), SI_CALL_RPC_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2044 getrpcbyname_async_handle_reply(mach_msg_header_t
*msg
)
2047 fprintf(stderr
, "<< %s\n", __func__
);
2050 si_async_handle_reply(msg
);
2066 fprintf(stderr
, "-> %s %ld\n", __func__
, (long int)number
);
2069 item
= si_rpc_bynumber(si_search(), number
);
2070 LI_set_thread_item(CATEGORY_RPC
+ 200, item
);
2071 if (item
== NULL
) return NULL
;
2073 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2077 getrpcbynumber_async_call(int number
, si_group_async_callback callback
, void *context
)
2079 si_context_t
*sictx
;
2082 fprintf(stderr
, ">> %s %d\n", __func__
, number
);
2085 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2086 if (sictx
== NULL
) return MACH_PORT_NULL
;
2088 sictx
->orig_callback
= callback
;
2089 sictx
->orig_context
= context
;
2090 sictx
->cat
= CATEGORY_RPC
;
2091 sictx
->key_offset
= 200;
2093 return si_async_call(si_search(), SI_CALL_RPC_BYNUMBER
, NULL
, NULL
, NULL
, number
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2097 getrpcbynumber_async_handle_reply(mach_msg_header_t
*msg
)
2100 fprintf(stderr
, "<< %s\n", __func__
);
2103 si_async_handle_reply(msg
);
2107 setrpcent(int ignored
)
2110 fprintf(stderr
, "-- %s\n", __func__
);
2113 LI_set_thread_list(CATEGORY_RPC
, NULL
);
2123 fprintf(stderr
, "-> %s\n", __func__
);
2126 list
= LI_get_thread_list(CATEGORY_RPC
);
2129 list
= si_rpc_all(si_search());
2130 LI_set_thread_list(CATEGORY_RPC
, list
);
2133 item
= si_list_next(list
);
2134 if (item
== NULL
) return NULL
;
2136 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2143 fprintf(stderr
, "-- %s\n", __func__
);
2146 LI_set_thread_list(CATEGORY_RPC
, NULL
);
2152 getfsspec(const char *spec
)
2157 fprintf(stderr
, "-> %s %s\n", __func__
, spec
);
2160 item
= si_fs_byspec(si_search(), spec
);
2161 LI_set_thread_item(CATEGORY_FS
+ 100, item
);
2162 if (item
== NULL
) return NULL
;
2164 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2168 getfsbyname(const char *name
)
2171 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
2174 return getfsspec(name
);
2178 getfsspec_async_call(const char *spec
, si_fs_async_callback callback
, void *context
)
2180 si_context_t
*sictx
;
2183 fprintf(stderr
, ">> %s %s\n", __func__
, spec
);
2186 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2187 if (sictx
== NULL
) return MACH_PORT_NULL
;
2189 sictx
->orig_callback
= callback
;
2190 sictx
->orig_context
= context
;
2191 sictx
->cat
= CATEGORY_FS
;
2192 sictx
->key_offset
= 100;
2194 return si_async_call(si_search(), SI_CALL_FS_BYSPEC
, spec
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2198 getfsspec_async_handle_reply(mach_msg_header_t
*msg
)
2201 fprintf(stderr
, "<< %s\n", __func__
);
2204 si_async_handle_reply(msg
);
2208 getfsfile(const char *file
)
2213 fprintf(stderr
, "-> %s %s\n", __func__
, file
);
2216 item
= si_fs_byfile(si_search(), file
);
2217 LI_set_thread_item(CATEGORY_FS
+ 200, item
);
2218 if (item
== NULL
) return NULL
;
2220 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2224 getfsfile_async_call(const char *file
, si_fs_async_callback callback
, void *context
)
2226 si_context_t
*sictx
;
2229 fprintf(stderr
, ">> %s %s\n", __func__
, file
);
2232 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2233 if (sictx
== NULL
) return MACH_PORT_NULL
;
2235 sictx
->orig_callback
= callback
;
2236 sictx
->orig_context
= context
;
2237 sictx
->cat
= CATEGORY_FS
;
2238 sictx
->key_offset
= 200;
2240 return si_async_call(si_search(), SI_CALL_FS_BYFILE
, file
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2244 getfsfile_async_handle_reply(mach_msg_header_t
*msg
)
2247 fprintf(stderr
, "<< %s\n", __func__
);
2250 si_async_handle_reply(msg
);
2257 fprintf(stderr
, "-> %s\n", __func__
);
2260 LI_set_thread_list(CATEGORY_FS
, NULL
);
2271 fprintf(stderr
, "-> %s\n", __func__
);
2274 list
= LI_get_thread_list(CATEGORY_FS
);
2277 list
= si_fs_all(si_search());
2278 LI_set_thread_list(CATEGORY_FS
, list
);
2281 item
= si_list_next(list
);
2282 if (item
== NULL
) return NULL
;
2284 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2291 fprintf(stderr
, "-- %s\n", __func__
);
2294 LI_set_thread_list(CATEGORY_FS
, NULL
);
2300 _getaddrinfo_internal(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, const char *interface
, struct addrinfo
**res
)
2303 uint32_t family
, socktype
, protocol
, flags
, status
;
2304 struct addrinfo
*ai
;
2307 socktype
= SOCK_UNSPEC
;
2308 protocol
= IPPROTO_UNSPEC
;
2310 status
= SI_STATUS_NO_ERROR
;
2312 if (res
== NULL
) return 0;
2317 family
= hints
->ai_family
;
2318 socktype
= hints
->ai_socktype
;
2319 protocol
= hints
->ai_protocol
;
2320 flags
= hints
->ai_flags
;
2324 fprintf(stderr
, "-> %s %s %s %u %u %u 0x%08x %s\n", __func__
, nodename
, servname
, family
, socktype
, protocol
, flags
, (interface
== NULL
) ? "" : interface
);
2327 list
= si_addrinfo(si_search(), nodename
, servname
, family
, socktype
, protocol
, flags
, interface
, &status
);
2328 if ((status
!= SI_STATUS_NO_ERROR
) || (list
== NULL
) || (list
->count
== 0))
2330 si_list_release(list
);
2332 if (status
== SI_STATUS_NO_ERROR
) return EAI_NONAME
;
2333 else if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2334 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2335 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2339 *res
= si_list_to_addrinfo(list
);
2340 si_list_release(list
);
2341 if (*res
== NULL
) status
= EAI_MEMORY
;
2343 /* don't return the canonical name unless asked */
2344 if ((flags
& AI_CANONNAME
) == 0)
2346 for (ai
= *res
; ai
!= NULL
; ai
= ai
->ai_next
)
2348 free(ai
->ai_canonname
);
2349 ai
->ai_canonname
= NULL
;
2357 getaddrinfo(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, struct addrinfo
**res
)
2359 return _getaddrinfo_internal(nodename
, servname
, hints
, NULL
, res
);
2365 socket_name(int sock
)
2367 static char str
[16];
2371 case SOCK_UNSPEC
: return "SOCK_UNSPEC";
2372 case SOCK_STREAM
: return "SOCK_STREAM";
2373 case SOCK_DGRAM
: return "SOCK_DGRAM";
2376 sprintf(str
, "%d", sock
);
2383 static char str
[16];
2387 case PF_UNSPEC
: return "PF_UNSPEC";
2388 case PF_INET
: return "PF_INET";
2389 case PF_INET6
: return "PF_INET6";
2392 sprintf(str
, "%d", pf
);
2397 protocol_name(int p
)
2399 static char str
[16];
2403 case IPPROTO_UNSPEC
: return "IPPROTO_UNSPEC";
2404 case IPPROTO_TCP
: return "IPPROTO_TCP";
2405 case IPPROTO_UDP
: return "IPPROTO_UDP";
2408 sprintf(str
, "%d", p
);
2413 _gai_inet_ntop(struct in6_addr a
)
2415 static char buf
[128];
2421 memset(buf
, 0, 128);
2423 p
= (char *)&a
.__u6_addr
.__u6_addr32
;
2424 for (i
= 0; i
< 8; i
++, x
+= 1)
2428 sprintf(t
, "%hx", x
);
2430 if (i
< 7) strcat(buf
, ":");
2437 fprint_addrinfo(FILE *f
, struct addrinfo
*a
)
2441 struct sockaddr_in
*s4
;
2442 struct sockaddr_in6
*s6
;
2444 if (a
== NULL
) return;
2446 if (a
->ai_flags
!= 0)
2448 fprintf(f
, "flags =");
2449 if (a
->ai_flags
& AI_PASSIVE
) fprintf(f
, " AI_PASSIVE");
2450 if (a
->ai_flags
& AI_CANONNAME
) fprintf(f
, " AI_CANONNAME");
2451 if (a
->ai_flags
& AI_NUMERICHOST
) fprintf(f
, " AI_NUMERICHOST");
2452 if (a
->ai_flags
& AI_NUMERICSERV
) fprintf(f
, " AI_NUMERICSERV");
2456 fprintf(f
, "family = %s\n", family_name(a
->ai_family
));
2457 fprintf(f
, "socktype = %s\n", socket_name(a
->ai_socktype
));
2458 fprintf(f
, "protocol = %s\n", protocol_name(a
->ai_protocol
));
2460 fprintf(f
, "canonical name = ");
2461 if (a
->ai_canonname
== NULL
) fprintf(f
, "NULL\n");
2462 else fprintf(f
, "\"%s\"\n", a
->ai_canonname
);
2464 fprintf(f
, "addrlen = %ld\n", (long int)a
->ai_addrlen
);
2466 if (a
->ai_addr
== NULL
) fprintf(f
, "sockaddr = NULL\n");
2469 if (a
->ai_family
== PF_INET
)
2471 s4
= (struct sockaddr_in
*)a
->ai_addr
;
2473 fprintf(f
, "sockaddr_in len = %d\n", s4
->sin_len
);
2474 fprintf(f
, "sockaddr_in family = %s\n", family_name(s4
->sin_family
));
2475 fprintf(f
, "sockaddr_in port = %hu\n", ntohs(s4
->sin_port
));
2476 fprintf(f
, "sockaddr_in address = %s\n", inet_ntoa(s4
->sin_addr
));
2478 else if (a
->ai_family
== PF_INET6
)
2480 s6
= (struct sockaddr_in6
*)a
->ai_addr
;
2482 fprintf(f
, "sockaddr_in6 len = %d\n", s6
->sin6_len
);
2483 fprintf(f
, "sockaddr_in6 family = %s\n", family_name(s6
->sin6_family
));
2484 fprintf(f
, "sockaddr_in6 port = %hu\n", ntohs(s6
->sin6_port
));
2485 fprintf(f
, "sockaddr_in6 flowinfo = %d\n", s6
->sin6_flowinfo
);
2486 fprintf(f
, "sockaddr_in6 address = %s\n", _gai_inet_ntop(s6
->sin6_addr
));
2487 fprintf(f
, "sockaddr_in6 scope_id = %d\n", s6
->sin6_scope_id
);
2491 fprintf(f
, "sockaddr len = %d\n", a
->ai_addr
->sa_len
);
2492 fprintf(f
, "sockaddr family = %s\n", family_name(a
->ai_addr
->sa_family
));
2493 fprintf(f
, "sockaddr data = ");
2494 for (i
= 0; i
< a
->ai_addr
->sa_len
- 2; i
++)
2496 v
= a
->ai_addr
->sa_data
[i
];
2497 fprintf(f
, "%02x", v
);
2503 if (a
->ai_next
!= NULL
)
2505 fprintf(f
, "NEXT --->\n");
2506 fprint_addrinfo(f
, a
->ai_next
);
2513 si_libinfo_addrinfo_callback(si_list_t
*list
, uint32_t status
, void *ctx
)
2515 si_context_t
*sictx
;
2516 struct addrinfo
*out
;
2521 fprintf(stderr
, " %s error no context\n", __func__
);
2523 si_list_release(list
);
2527 sictx
= (si_context_t
*)ctx
;
2529 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
2532 fprintf(stderr
, " %s error no callback\n", __func__
);
2534 si_list_release(list
);
2539 if (status
!= SI_STATUS_NO_ERROR
)
2542 fprintf(stderr
, " %s original status %d\n", __func__
, status
);
2544 if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2545 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2546 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2552 fprintf(stderr
, " %s result NULL status %d (returning EAI_NONAME)\n", __func__
, status
);
2554 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(EAI_NONAME
, NULL
, sictx
->orig_context
);
2559 out
= si_list_to_addrinfo(list
);
2560 si_list_release(list
);
2564 fprintf(stderr
, " %s result conversion failed returning NULL status %d (returning EAI_MEMORY)\n", __func__
, status
);
2566 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(EAI_MEMORY
, NULL
, sictx
->orig_context
);
2572 fprintf(stderr
, " %s %d\n", __func__
, status
);
2573 fprint_addrinfo(stderr
, out
);
2575 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(status
, out
, sictx
->orig_context
);
2582 _getaddrinfo_interface_async_call(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, const char *interface
, si_addrinfo_async_callback callback
, void *context
)
2584 si_context_t
*sictx
;
2585 uint32_t family
, socktype
, protocol
, flags
;
2588 socktype
= SOCK_UNSPEC
;
2589 protocol
= IPPROTO_UNSPEC
;
2594 family
= hints
->ai_family
;
2595 socktype
= hints
->ai_socktype
;
2596 protocol
= hints
->ai_protocol
;
2597 flags
= hints
->ai_flags
;
2601 fprintf(stderr
, ">> %s %s %s %u %u %u 0x%08x\n", __func__
, nodename
, servname
, family
, socktype
, protocol
, flags
);
2604 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2605 if (sictx
== NULL
) return MACH_PORT_NULL
;
2607 sictx
->orig_callback
= callback
;
2608 sictx
->orig_context
= context
;
2609 sictx
->cat
= CATEGORY_ADDRINFO
;
2610 sictx
->key_offset
= 0;
2612 return si_async_call(si_search(), SI_CALL_ADDRINFO
, nodename
, servname
, interface
, family
, socktype
, protocol
, flags
, (void *)si_libinfo_addrinfo_callback
, sictx
);
2616 getaddrinfo_async_call(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, si_addrinfo_async_callback callback
, void *context
)
2618 return _getaddrinfo_interface_async_call(nodename
, servname
, hints
, NULL
, callback
, context
);
2622 getaddrinfo_async_start(mach_port_t
*p
, const char *nodename
, const char *servname
, const struct addrinfo
*hints
, si_addrinfo_async_callback callback
, void *context
)
2624 if (p
== NULL
) return EAI_SYSTEM
;
2626 *p
= getaddrinfo_async_call(nodename
, servname
, hints
, callback
, context
);
2628 if (*p
== MACH_PORT_NULL
) return EAI_SYSTEM
;
2633 getaddrinfo_async_send(mach_port_t
*p
, const char *nodename
, const char *servname
, const struct addrinfo
*hints
)
2635 return getaddrinfo_async_start(p
, nodename
, servname
, hints
, NULL
, NULL
);
2639 getaddrinfo_async_receive(mach_port_t p
, struct addrinfo
**res
)
2641 /* unsupported Leopard SPI */
2646 getaddrinfo_async_cancel(mach_port_t p
)
2649 fprintf(stderr
, "-- %s\n", __func__
);
2656 getaddrinfo_async_handle_reply(void *param
)
2658 mach_msg_header_t
*msg
;
2661 fprintf(stderr
, "<< %s\n", __func__
);
2664 msg
= (mach_msg_header_t
*)param
;
2665 si_async_handle_reply(msg
);
2673 _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
)
2677 uint32_t status
, len
, wantn
, wants
;
2680 fprintf(stderr
, "-> %s\n", __func__
);
2683 status
= SI_STATUS_NO_ERROR
;
2686 if ((node
!= NULL
) && (nodelen
> 0)) wantn
= 1;
2689 if ((service
!= NULL
) && (servicelen
> 0)) wants
= 1;
2691 if ((wantn
== 0) && (wants
== 0)) return status
;
2693 if (wantn
== 0) flags
|= NI_NUMERICHOST
;
2694 if (wants
== 0) flags
|= NI_NUMERICSERV
;
2696 item
= si_nameinfo(si_search(), sa
, flags
, interface
, &status
);
2697 if ((status
!= SI_STATUS_NO_ERROR
) || (item
== NULL
))
2699 si_item_release(item
);
2701 if (status
== SI_STATUS_NO_ERROR
) status
= EAI_NONAME
;
2702 else if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2703 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2704 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2708 ni
= (si_nameinfo_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
2711 if (ni
->ni_node
!= NULL
) len
= strlen(ni
->ni_node
) + 1;
2712 if ((wantn
== 1) && (len
> 0))
2716 si_item_release(item
);
2717 return EAI_OVERFLOW
;
2720 memset(node
, 0, nodelen
);
2721 memcpy(node
, ni
->ni_node
, len
);
2725 if (ni
->ni_serv
!= NULL
) len
= strlen(ni
->ni_serv
) + 1;
2726 if ((wants
== 1) && (len
> 0))
2728 if (len
> servicelen
)
2730 si_item_release(item
);
2731 return EAI_OVERFLOW
;
2734 memset(service
, 0, servicelen
);
2735 memcpy(service
, ni
->ni_serv
, len
);
2738 si_item_release(item
);
2743 getnameinfo(const struct sockaddr
*sa
, socklen_t salen
, char *node
, socklen_t nodelen
, char *service
, socklen_t servicelen
, int flags
)
2745 if (sa
== NULL
) return EAI_FAIL
;
2747 if (sa
->sa_family
== AF_LINK
) return getnameinfo_link(sa
, salen
, node
, nodelen
, service
, servicelen
, flags
);
2748 return _getnameinfo_interface_internal(sa
, salen
, node
, nodelen
, service
, servicelen
, flags
, NULL
);
2752 si_libinfo_nameinfo_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
2754 si_context_t
*sictx
;
2758 if (ctx
== NULL
) return;
2760 sictx
= (si_context_t
*)ctx
;
2762 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
2764 si_item_release(item
);
2769 if (status
!= SI_STATUS_NO_ERROR
)
2771 if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2772 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2773 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2778 ((si_nameinfo_async_callback
)(sictx
->orig_callback
))(status
, NULL
, NULL
, sictx
->orig_context
);
2783 LI_set_thread_item(CATEGORY_NAMEINFO
, item
);
2788 ni
= (si_nameinfo_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
2789 if (ni
->ni_node
!= NULL
) node
= strdup(ni
->ni_node
);
2790 if (ni
->ni_serv
!= NULL
) serv
= strdup(ni
->ni_serv
);
2792 ((si_nameinfo_async_callback
)(sictx
->orig_callback
))(status
, node
, serv
, sictx
->orig_context
);
2798 _getnameinfo_interface_async_call(const struct sockaddr
*sa
, size_t len
, int flags
, const char *interface
, si_nameinfo_async_callback callback
, void *context
)
2800 si_context_t
*sictx
;
2804 fprintf(stderr
, ">> %s\n", __func__
);
2807 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2808 if (sictx
== NULL
) return MACH_PORT_NULL
;
2810 sictx
->orig_callback
= callback
;
2811 sictx
->orig_context
= context
;
2812 sictx
->cat
= CATEGORY_ADDRINFO
;
2813 sictx
->key_offset
= 0;
2815 /* sa is not a C string - pass length in num3 */
2817 return si_async_call(si_search(), SI_CALL_NAMEINFO
, (const char *)sa
, NULL
, interface
, flags
, 0, salen
, 0, (void *)si_libinfo_nameinfo_callback
, sictx
);
2821 getnameinfo_async_call(const struct sockaddr
*sa
, size_t len
, int flags
, si_nameinfo_async_callback callback
, void *context
)
2823 return _getnameinfo_interface_async_call(sa
, len
, flags
, NULL
, callback
, context
);
2827 getnameinfo_async_start(mach_port_t
*p
, const struct sockaddr
*sa
, size_t salen
, int flags
, si_nameinfo_async_callback callback
, void *context
)
2829 if (p
== NULL
) return EAI_SYSTEM
;
2830 *p
= getnameinfo_async_call(sa
, salen
, flags
, callback
, context
);
2832 if (*p
== MACH_PORT_NULL
) return EAI_SYSTEM
;
2837 getnameinfo_async_send(mach_port_t
*p
, const struct sockaddr
*sa
, size_t salen
, int flags
)
2839 return getnameinfo_async_start(p
, sa
, salen
, flags
, NULL
, NULL
);
2843 getnameinfo_async_cancel(mach_port_t p
)
2846 fprintf(stderr
, "-- %s\n", __func__
);
2853 getnameinfo_async_handle_reply(void *param
)
2855 mach_msg_header_t
*msg
;
2858 fprintf(stderr
, "<< %s\n", __func__
);
2861 msg
= (mach_msg_header_t
*)param
;
2862 si_async_handle_reply(msg
);
2867 /* getpwXXX_r and getgrXXX_r */
2870 copy_user_r(struct passwd
*in
, struct passwd
*out
, char *buffer
, int buflen
)
2875 if (in
== NULL
) return -1;
2876 if (out
== NULL
) return -1;
2878 if (buffer
== NULL
) buflen
= 0;
2880 /* Calculate size of input */
2882 if (in
->pw_name
!= NULL
) hsize
+= (strlen(in
->pw_name
) + 1);
2883 if (in
->pw_passwd
!= NULL
) hsize
+= (strlen(in
->pw_passwd
) + 1);
2884 if (in
->pw_class
!= NULL
) hsize
+= (strlen(in
->pw_class
) + 1);
2885 if (in
->pw_gecos
!= NULL
) hsize
+= (strlen(in
->pw_gecos
) + 1);
2886 if (in
->pw_dir
!= NULL
) hsize
+= (strlen(in
->pw_dir
) + 1);
2887 if (in
->pw_shell
!= NULL
) hsize
+= (strlen(in
->pw_shell
) + 1);
2889 /* Check buffer space */
2890 if (hsize
> buflen
) return -1;
2892 /* Copy result into caller's struct passwd, using buffer for memory */
2895 out
->pw_name
= NULL
;
2896 if (in
->pw_name
!= NULL
)
2899 hsize
= strlen(in
->pw_name
) + 1;
2900 memmove(bp
, in
->pw_name
, hsize
);
2904 out
->pw_passwd
= NULL
;
2905 if (in
->pw_passwd
!= NULL
)
2907 out
->pw_passwd
= bp
;
2908 hsize
= strlen(in
->pw_passwd
) + 1;
2909 memmove(bp
, in
->pw_passwd
, hsize
);
2913 out
->pw_uid
= in
->pw_uid
;
2915 out
->pw_gid
= in
->pw_gid
;
2917 out
->pw_change
= in
->pw_change
;
2919 out
->pw_class
= NULL
;
2920 if (in
->pw_class
!= NULL
)
2923 hsize
= strlen(in
->pw_class
) + 1;
2924 memmove(bp
, in
->pw_class
, hsize
);
2928 out
->pw_gecos
= NULL
;
2929 if (in
->pw_gecos
!= NULL
)
2932 hsize
= strlen(in
->pw_gecos
) + 1;
2933 memmove(bp
, in
->pw_gecos
, hsize
);
2938 if (in
->pw_dir
!= NULL
)
2941 hsize
= strlen(in
->pw_dir
) + 1;
2942 memmove(bp
, in
->pw_dir
, hsize
);
2946 out
->pw_shell
= NULL
;
2947 if (in
->pw_shell
!= NULL
)
2950 hsize
= strlen(in
->pw_shell
) + 1;
2951 memmove(bp
, in
->pw_shell
, hsize
);
2955 out
->pw_expire
= in
->pw_expire
;
2961 copy_group_r(struct group
*in
, struct group
*out
, char *buffer
, int buflen
)
2967 if (in
== NULL
) return -1;
2968 if (out
== NULL
) return -1;
2970 if (buffer
== NULL
) buflen
= 0;
2972 /* Calculate size of input */
2974 if (in
->gr_name
!= NULL
) hsize
+= (strlen(in
->gr_name
) + 1);
2975 if (in
->gr_passwd
!= NULL
) hsize
+= (strlen(in
->gr_passwd
) + 1);
2977 /* NULL pointer at end of list */
2978 hsize
+= sizeof(char *);
2981 if (in
->gr_mem
!= NULL
)
2983 for (len
= 0; in
->gr_mem
[len
] != NULL
; len
++)
2985 hsize
+= sizeof(char *);
2986 hsize
+= (strlen(in
->gr_mem
[len
]) + 1);
2990 /* Check buffer space */
2991 if (hsize
> buflen
) return -1;
2993 /* Copy result into caller's struct group, using buffer for memory */
2996 out
->gr_name
= NULL
;
2997 if (in
->gr_name
!= NULL
)
3000 hsize
= strlen(in
->gr_name
) + 1;
3001 memmove(bp
, in
->gr_name
, hsize
);
3005 out
->gr_passwd
= NULL
;
3006 if (in
->gr_passwd
!= NULL
)
3008 out
->gr_passwd
= bp
;
3009 hsize
= strlen(in
->gr_passwd
) + 1;
3010 memmove(bp
, in
->gr_passwd
, hsize
);
3014 out
->gr_gid
= in
->gr_gid
;
3017 ap
= bp
+ ((len
+ 1) * sizeof(char *));
3019 if (in
->gr_mem
!= NULL
)
3021 out
->gr_mem
= (char **)bp
;
3022 for (i
= 0; i
< len
; i
++)
3024 addr
= (unsigned long)ap
;
3025 memmove(bp
, &addr
, sizeof(unsigned long));
3026 bp
+= sizeof(unsigned long);
3028 hsize
= strlen(in
->gr_mem
[i
]) + 1;
3029 memmove(ap
, in
->gr_mem
[i
], hsize
);
3034 memset(bp
, 0, sizeof(unsigned long));
3041 getgrnam_r(const char *name
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
3048 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
3051 if (result
!= NULL
) *result
= NULL
;
3053 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3055 item
= si_group_byname(si_search(), name
);
3056 if (item
== NULL
) return 0;
3058 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
3060 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
3061 si_item_release(item
);
3063 if (status
!= 0) return ERANGE
;
3070 getgrgid_r(gid_t gid
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
3077 fprintf(stderr
, "-> %s %d\n", __func__
, gid
);
3080 if (result
!= NULL
) *result
= NULL
;
3082 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3084 item
= si_group_bygid(si_search(), gid
);
3085 if (item
== NULL
) return 0;
3087 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
3089 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
3090 si_item_release(item
);
3092 if (status
!= 0) return ERANGE
;
3099 getgruuid_r(uuid_t uuid
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
3106 uuid_string_t uuidstr
;
3107 uuid_unparse_upper(uuid
, uuidstr
);
3108 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
3111 if (result
!= NULL
) *result
= NULL
;
3113 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3115 item
= si_group_byuuid(si_search(), uuid
);
3116 if (item
== NULL
) return 0;
3118 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
3120 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
3121 si_item_release(item
);
3123 if (status
!= 0) return ERANGE
;
3130 getpwnam_r(const char *name
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3137 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
3140 if (result
!= NULL
) *result
= NULL
;
3142 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3144 item
= si_user_byname(si_search(), name
);
3145 if (item
== NULL
) return 0;
3147 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3149 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3150 si_item_release(item
);
3152 if (status
!= 0) return ERANGE
;
3159 getpwuid_r(uid_t uid
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3164 uid_t localuid
= uid
;
3167 fprintf(stderr
, "-> %s %d\n", __func__
, uid
);
3170 if (result
!= NULL
) *result
= NULL
;
3172 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3174 item
= si_user_byuid(si_search(), localuid
);
3175 if (item
== NULL
) return 0;
3177 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3179 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3180 si_item_release(item
);
3182 if (status
!= 0) return ERANGE
;
3189 getpwuuid_r(uuid_t uuid
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3196 uuid_string_t uuidstr
;
3197 uuid_unparse_upper(uuid
, uuidstr
);
3198 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
3201 if (result
!= NULL
) *result
= NULL
;
3203 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3205 item
= si_user_byuuid(si_search(), uuid
);
3206 if (item
== NULL
) return 0;
3208 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3210 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3211 si_item_release(item
);
3213 if (status
!= 0) return ERANGE
;
3222 user_from_uid(uid_t uid
, int nouser
)
3225 static char buf
[16];
3228 if (pw
!= NULL
) return pw
->pw_name
;
3230 if (nouser
) return NULL
;
3232 snprintf(buf
, sizeof(buf
), "%u", uid
);
3237 group_from_gid(gid_t gid
, int nogroup
)
3240 static char buf
[16];
3243 if (gr
!= NULL
) return gr
->gr_name
;
3245 if (nogroup
) return NULL
;
3247 snprintf(buf
, sizeof(buf
), "%u", gid
);
3251 /* no longer supported */
3254 prdb_getbyname(const char *name
)
3257 fprintf(stderr
, "~~ %s\n", __func__
);
3266 fprintf(stderr
, "~~ %s\n", __func__
);
3272 prdb_set(const char *name
)
3275 fprintf(stderr
, "~~ %s\n", __func__
);
3283 fprintf(stderr
, "~~ %s\n", __func__
);
3287 struct bootparamsent
*
3288 bootparams_getbyname(const char *name
)
3291 fprintf(stderr
, "~~ %s\n", __func__
);
3296 struct bootparamsent
*
3297 bootparams_getent(void)
3300 fprintf(stderr
, "~~ %s\n", __func__
);
3306 bootparams_setent(void)
3309 fprintf(stderr
, "~~ %s\n", __func__
);
3314 bootparams_endent(void)
3317 fprintf(stderr
, "~~ %s\n", __func__
);
3322 bootp_getbyether(struct ether_addr
*enaddr
, char **name
,struct in_addr
*ipaddr
, char **bootfile
)
3325 fprintf(stderr
, "~~ %s\n", __func__
);
3331 bootp_getbyip(struct ether_addr
*enaddr
, char **name
, struct in_addr
*ipaddr
, char **bootfile
)
3334 fprintf(stderr
, "~~ %s\n", __func__
);