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
51 #define SYSTEM_UID_LIMIT 500
54 extern int __initgroups(u_int gidsetsize
, gid_t
*gidset
, int gmuid
);
56 /* SPI from long ago */
59 extern struct addrinfo
*si_list_to_addrinfo(si_list_t
*list
);
60 extern int getnameinfo_link(const struct sockaddr
*sa
, socklen_t salen
, char *host
, size_t hostlen
, char *serv
, size_t servlen
, int flags
);
61 __private_extern__
void search_set_flags(si_mod_t
*si
, const char *name
, uint32_t flag
);
64 * Impedence matching for async calls.
66 * This layer holds on to the caller's callback and context in this
67 * structure, which gets passed to the si_module async routines along
68 * with a callbac in this layer. When this layer gets a callback,
69 * it can save the item or list in thread-specific memory and then
70 * invoke the caller's callback with the appropriate data type.
84 static si_mod_t
*search
= NULL
;
86 if (search
== NULL
) search
= si_module_with_name("file");
94 static si_mod_t
*search
= NULL
;
96 if (search
== NULL
) search
= si_module_with_name("search");
102 si_search_module_set_flags(const char *name
, uint32_t flag
)
104 search_set_flags(si_search(), name
, flag
);
108 si_libinfo_general_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
116 struct grouplist_s
*l
;
125 if (ctx
== NULL
) return;
127 sictx
= (si_context_t
*)ctx
;
129 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
132 si_item_release(item
);
136 if (sictx
->key_offset
>= 0)
138 LI_set_thread_item(sictx
->cat
+ sictx
->key_offset
, item
);
142 if (item
!= NULL
) res
.x
= (char*)((uintptr_t)item
+ sizeof(si_item_t
));
148 ((si_user_async_callback
)(sictx
->orig_callback
))(res
.u
, sictx
->orig_context
);
153 ((si_group_async_callback
)(sictx
->orig_callback
))(res
.g
, sictx
->orig_context
);
156 case CATEGORY_GROUPLIST
:
158 ((si_grouplist_async_callback
)(sictx
->orig_callback
))(res
.l
, sictx
->orig_context
);
161 case CATEGORY_HOST_IPV4
:
162 case CATEGORY_HOST_IPV6
:
164 ((si_host_async_callback
)(sictx
->orig_callback
))(res
.h
, sictx
->orig_context
);
167 case CATEGORY_NETWORK
:
169 ((si_network_async_callback
)(sictx
->orig_callback
))(res
.n
, sictx
->orig_context
);
172 case CATEGORY_SERVICE
:
174 ((si_service_async_callback
)(sictx
->orig_callback
))(res
.s
, sictx
->orig_context
);
177 case CATEGORY_PROTOCOL
:
179 ((si_protocol_async_callback
)(sictx
->orig_callback
))(res
.p
, sictx
->orig_context
);
184 ((si_rpc_async_callback
)(sictx
->orig_callback
))(res
.r
, sictx
->orig_context
);
189 ((si_fs_async_callback
)(sictx
->orig_callback
))(res
.f
, sictx
->orig_context
);
200 getpwnam(const char *name
)
205 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
207 item
= si_user_byname(si_search(), name
);
208 LI_set_thread_item(CATEGORY_USER
+ 100, item
);
210 if (item
== NULL
) return NULL
;
211 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
215 getpwnam_async_call(const char *name
, si_user_async_callback callback
, void *context
)
220 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
223 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
224 if (sictx
== NULL
) return MACH_PORT_NULL
;
226 sictx
->orig_callback
= callback
;
227 sictx
->orig_context
= context
;
228 sictx
->cat
= CATEGORY_USER
;
229 sictx
->key_offset
= 100;
231 return si_async_call(si_search(), SI_CALL_USER_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
235 getpwnam_async_handle_reply(mach_msg_header_t
*msg
)
238 fprintf(stderr
, "<< %s\n", __func__
);
241 si_async_handle_reply(msg
);
247 si_item_t
*item
= NULL
;
250 fprintf(stderr
, "-> %s %d\n", __func__
, uid
);
253 // Search the file module first for all system uids
254 // (ie, uid value < 500) since they should all be
255 // in the /etc/*passwd file.
256 if (uid
< SYSTEM_UID_LIMIT
)
257 item
= si_user_byuid(si_search_file(), uid
);
260 item
= si_user_byuid(si_search(), uid
);
261 LI_set_thread_item(CATEGORY_USER
+ 200, item
);
263 if (item
== NULL
) return NULL
;
264 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
268 getpwuid_async_call(uid_t uid
, si_user_async_callback callback
, void *context
)
273 fprintf(stderr
, ">> %s %d\n", __func__
, uid
);
276 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
277 if (sictx
== NULL
) return MACH_PORT_NULL
;
279 sictx
->orig_callback
= callback
;
280 sictx
->orig_context
= context
;
281 sictx
->cat
= CATEGORY_USER
;
282 sictx
->key_offset
= 200;
284 // Search the file module first for all system uids
285 // (ie, uid value < 500) since they should all be
286 // in the /etc/*passwd file.
287 if (uid
< SYSTEM_UID_LIMIT
)
289 si_item_t
*item
= si_user_byuid(si_search_file(), uid
);
292 si_item_release(item
);
293 return si_async_call(si_search_file(), SI_CALL_USER_BYUID
, NULL
, NULL
, NULL
, (uint32_t)uid
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
297 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
);
301 getpwuid_async_handle_reply(mach_msg_header_t
*msg
)
304 fprintf(stderr
, "<< %s\n", __func__
);
307 si_async_handle_reply(msg
);
311 getpwuuid(uuid_t uuid
)
316 uuid_string_t uuidstr
;
317 uuid_unparse_upper(uuid
, uuidstr
);
318 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
321 item
= si_user_byuuid(si_search(), uuid
);
322 LI_set_thread_item(CATEGORY_USER
+ 300, item
);
324 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
);
345 fprintf(stderr
, "-> %s\n", __func__
);
348 list
= LI_get_thread_list(CATEGORY_USER
);
351 list
= si_user_all(si_search());
352 LI_set_thread_list(CATEGORY_USER
, list
);
355 item
= si_list_next(list
);
356 if (item
== NULL
) return NULL
;
358 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
365 fprintf(stderr
, "-- %s\n", __func__
);
368 LI_set_thread_list(CATEGORY_USER
, NULL
);
372 setpassent(int ignored
)
377 fprintf(stderr
, "-> %s\n", __func__
);
380 list
= LI_get_thread_list(CATEGORY_USER
);
383 if (list
== NULL
) return 0;
390 getgrnam(const char *name
)
395 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
398 item
= si_group_byname(si_search(), name
);
399 LI_set_thread_item(CATEGORY_GROUP
+ 100, item
);
401 if (item
== NULL
) return NULL
;
402 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
406 getgrnam_async_call(const char *name
, si_group_async_callback callback
, void *context
)
411 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
414 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
415 if (sictx
== NULL
) return MACH_PORT_NULL
;
417 sictx
->orig_callback
= callback
;
418 sictx
->orig_context
= context
;
419 sictx
->cat
= CATEGORY_GROUP
;
420 sictx
->key_offset
= 100;
422 return si_async_call(si_search(), SI_CALL_GROUP_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
426 getgrnam_async_handle_reply(mach_msg_header_t
*msg
)
429 fprintf(stderr
, "<< %s\n", __func__
);
432 si_async_handle_reply(msg
);
441 fprintf(stderr
, "-> %s %d\n", __func__
, gid
);
444 item
= si_group_bygid(si_search(), gid
);
445 LI_set_thread_item(CATEGORY_GROUP
+ 200, item
);
447 if (item
== NULL
) return NULL
;
448 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
452 getgrgid_async_call(gid_t gid
, si_group_async_callback callback
, void *context
)
457 fprintf(stderr
, ">> %s %d\n", __func__
, gid
);
460 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
461 if (sictx
== NULL
) return MACH_PORT_NULL
;
463 sictx
->orig_callback
= callback
;
464 sictx
->orig_context
= context
;
465 sictx
->cat
= CATEGORY_GROUP
;
466 sictx
->key_offset
= 200;
468 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
);
472 getgruid_async_handle_reply(mach_msg_header_t
*msg
)
475 fprintf(stderr
, "<< %s\n", __func__
);
478 si_async_handle_reply(msg
);
482 getgruuid(uuid_t uuid
)
487 uuid_string_t uuidstr
;
488 uuid_unparse_upper(uuid
, uuidstr
);
489 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
492 item
= si_group_byuuid(si_search(), uuid
);
493 LI_set_thread_item(CATEGORY_GROUP
+ 300, item
);
495 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
);
516 fprintf(stderr
, "-> %s\n", __func__
);
519 list
= LI_get_thread_list(CATEGORY_GROUP
);
522 list
= si_group_all(si_search());
523 LI_set_thread_list(CATEGORY_GROUP
, list
);
526 item
= si_list_next(list
);
527 if (item
== NULL
) return NULL
;
529 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
536 fprintf(stderr
, "-- %s\n", __func__
);
539 LI_set_thread_list(CATEGORY_GROUP
, NULL
);
543 setgroupent(int ignored
)
548 fprintf(stderr
, "-> %s\n", __func__
);
551 list
= LI_get_thread_list(CATEGORY_GROUP
);
554 if (list
== NULL
) return 0;
560 innetgr(const char *group
, const char *host
, const char *user
, const char *domain
)
564 fprintf(stderr
, "-> %s %s %s %s %s\n", __func__
, group
, host
, user
, domain
);
567 res
= si_in_netgroup(si_search(), group
, host
, user
, domain
);
570 fprintf(stderr
, "<- %s %d\n", __func__
, res
);
576 /* N.B. there is no async innetgr */
579 * setnetgrent is really more like a getXXXbyname routine than a
580 * setXXXent routine, since we are looking up a netgroup by name.
583 setnetgrent(const char *name
)
588 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
591 list
= si_netgroup_byname(si_search(), name
);
592 LI_set_thread_list(CATEGORY_NETGROUP
, list
);
595 /* N.B. there is no async getnetgrent */
598 getnetgrent(char **host
, char **user
, char **domain
)
602 struct netgrent_s
*ng
;
605 fprintf(stderr
, "-> %s\n", __func__
);
608 list
= LI_get_thread_list(CATEGORY_NETGROUP
);
609 item
= si_list_next(list
);
610 if (item
== NULL
) return 0;
612 ng
= (struct netgrent_s
*)((uintptr_t)item
+ sizeof(si_item_t
));
616 *domain
= ng
->ng_domain
;
625 fprintf(stderr
, "-- %s\n", __func__
);
628 LI_set_thread_list(CATEGORY_NETGROUP
, NULL
);
633 _check_groups(const char *function
, int32_t ngroups
)
635 static dispatch_once_t once
;
637 if (ngroups
> 0 && ngroups
< NGROUPS_MAX
) {
641 /* only log once per process */
642 dispatch_once(&once
, ^(void) {
643 const char *proc_name
= getprogname();
644 if (strcmp(proc_name
, "id") != 0 && strcmp(proc_name
, "smbd") != 0 && strcmp(proc_name
, "rpcsvchost") != 0) {
645 #pragma clang diagnostic push
646 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
647 aslmsg msg
= asl_new(ASL_TYPE_MSG
);
650 snprintf(buffer
, sizeof(buffer
), "%d", (ngroups
== 0 ? INT_MAX
: ngroups
));
651 asl_set(msg
, "com.apple.message.value", buffer
);
653 asl_set(msg
, "com.apple.message.domain", "com.apple.system.libinfo");
654 asl_set(msg
, "com.apple.message.result", "noop");
655 asl_set(msg
, "com.apple.message.signature", function
);
657 asl_log(NULL
, msg
, ASL_LEVEL_NOTICE
, "%s called triggering group enumeration", function
);
661 #pragma clang diagnostic pop
669 getgrouplist_internal(const char *name
, int basegid
, gid_t
*groups
, uint32_t *ngroups
)
671 int i
, j
, x
, g
, add
, max
;
676 * On input, ngroups specifies the size of the groups array.
677 * On output, it is set to the number of groups that are being returned.
678 * Returns -1 if the size is too small to fit all the groups that were found.
682 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
685 if (name
== NULL
) return 0;
686 if (groups
== NULL
) return 0;
687 if (ngroups
== NULL
) return 0;
691 if (max
<= 0) return 0;
696 item
= si_grouplist(si_search(), name
, max
+1);
697 LI_set_thread_item(CATEGORY_GROUPLIST
, item
);
698 if (item
== NULL
) return 0;
700 gl
= (si_grouplist_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
704 for (i
= 0; i
< gl
->gl_count
; i
++)
708 for (j
= 0; j
< x
; j
++) {
709 if (groups
[j
] == g
) {
714 if (add
== 0) continue;
716 if (x
>= max
) return -1;
726 getgrouplist(const char *name
, int basegid
, int *groups
, int *ngroups
)
729 _check_groups("getgrouplist", *ngroups
);
732 return getgrouplist_internal(name
, basegid
, (gid_t
*)groups
, (uint32_t *)ngroups
);
736 merge_gid(gid_t
*list
, gid_t g
, int32_t *count
)
742 for (i
= 0; i
< cnt
; i
++) {
743 if (list
[i
] == g
) return;
751 _getgrouplist_2_internal(const char *name
, gid_t basegid
, gid_t
**groups
)
758 item
= si_grouplist(si_search(), name
, INT_MAX
);
759 LI_set_thread_item(CATEGORY_GROUPLIST
, item
);
760 if (item
== NULL
) return -1;
762 gl
= (si_grouplist_t
*) ((uintptr_t) item
+ sizeof(si_item_t
));
765 * we can allocate enough up-front, we'll only use what we need
766 * we add one to the count that was found in case the basegid is not there
768 gids
= calloc(gl
->gl_count
+ 1, sizeof(gid_t
));
769 if (gids
== NULL
) return -1;
772 merge_gid(gids
, basegid
, &count
);
773 if (gl
->gl_gid
!= NULL
) {
774 for (i
= 0; i
< gl
->gl_count
; i
++) {
775 merge_gid(gids
, gl
->gl_gid
[i
], &count
);
785 getgrouplist_2(const char *name
, gid_t basegid
, gid_t
**groups
)
788 * Passes back a gid_t list containing all the users groups (and basegid).
789 * Caller must free the list.
790 * Returns the number of gids in the list or -1 on failure.
794 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
797 if (name
== NULL
) return 0;
798 if (groups
== NULL
) return 0;
801 _check_groups("getgrouplist_2", INT_MAX
);
804 return _getgrouplist_2_internal(name
, basegid
, groups
);
808 getgroupcount(const char *name
, gid_t basegid
)
814 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
818 _check_groups("getgroupcount", INT_MAX
);
822 count
= _getgrouplist_2_internal(name
, basegid
, &groups
);
823 if (groups
!= NULL
) free(groups
);
828 /* XXX to do: async getgrouplist_2 */
831 initgroups(const char *name
, int basegid
)
835 gid_t groups
[NGROUPS
];
843 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
846 /* KAUTH_UID_NONE tells the kernel not to fetch supplementary groups from DirectoryService */
847 uid
= KAUTH_UID_NONE
;
850 /* get the UID for this user */
851 item
= si_user_byname(si_search(), name
);
854 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
856 si_item_release(item
);
864 * A failure either means that user belongs to more than NGROUPS groups
865 * or no groups at all.
868 (void) getgrouplist_internal(name
, basegid
, groups
, &ngroups
);
870 status
= __initgroups(ngroups
, groups
, uid
);
871 if (status
< 0) return -1;
879 alias_getbyname(const char *name
)
884 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
887 item
= si_alias_byname(si_search(), name
);
888 LI_set_thread_item(CATEGORY_ALIAS
+ 100, item
);
889 if (item
== NULL
) return NULL
;
891 return (struct aliasent
*)((uintptr_t)item
+ sizeof(si_item_t
));
895 alias_getbyname_async_call(const char *name
, si_alias_async_callback callback
, void *context
)
900 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
903 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
904 if (sictx
== NULL
) return MACH_PORT_NULL
;
906 sictx
->orig_callback
= callback
;
907 sictx
->orig_context
= context
;
908 sictx
->cat
= CATEGORY_ALIAS
;
909 sictx
->key_offset
= 100;
911 return si_async_call(si_search(), SI_CALL_ALIAS_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
915 alias_getbyname_async_handle_reply(mach_msg_header_t
*msg
)
918 fprintf(stderr
, "<< %s\n", __func__
);
921 si_async_handle_reply(msg
);
928 fprintf(stderr
, "-> %s\n", __func__
);
931 LI_set_thread_list(CATEGORY_ALIAS
, NULL
);
941 fprintf(stderr
, "-> %s\n", __func__
);
944 list
= LI_get_thread_list(CATEGORY_ALIAS
);
947 list
= si_alias_all(si_search());
948 LI_set_thread_list(CATEGORY_ALIAS
, list
);
951 item
= si_list_next(list
);
952 if (item
== NULL
) return NULL
;
954 return (struct aliasent
*)((uintptr_t)item
+ sizeof(si_item_t
));
961 fprintf(stderr
, "-- %s\n", __func__
);
964 LI_set_thread_list(CATEGORY_ALIAS
, NULL
);
970 freehostent(struct hostent
*h
)
972 if (h
== NULL
) return;
974 si_item_t
*item
= (si_item_t
*)((uintptr_t)h
- sizeof(si_item_t
));
975 si_item_release(item
);
979 gethostbynameerrno(const char *name
, int *err
)
983 struct in_addr addr4
;
986 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
989 memset(&addr4
, 0, sizeof(struct in_addr
));
990 status
= SI_STATUS_NO_ERROR
;
993 if (inet_aton(name
, &addr4
) == 1) item
= si_ipnode_byname(si_search(), name
, AF_INET
, 0, NULL
, &status
);
994 else item
= si_host_byname(si_search(), name
, AF_INET
, NULL
, &status
);
996 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
997 if (err
!= NULL
) *err
= status
;
999 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
1000 if (item
== NULL
) return NULL
;
1002 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1006 gethostbyname(const char *name
)
1010 struct in_addr addr4
;
1013 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1016 memset(&addr4
, 0, sizeof(struct in_addr
));
1017 status
= SI_STATUS_NO_ERROR
;
1020 if (inet_aton(name
, &addr4
) == 1) item
= si_ipnode_byname(si_search(), name
, AF_INET
, 0, NULL
, &status
);
1021 else item
= si_host_byname(si_search(), name
, AF_INET
, NULL
, &status
);
1023 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1026 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
1027 if (item
== NULL
) return NULL
;
1029 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1033 gethostbyname_async_call(const char *name
, si_host_async_callback callback
, void *context
)
1035 si_context_t
*sictx
;
1038 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1041 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1042 if (sictx
== NULL
) return MACH_PORT_NULL
;
1044 sictx
->orig_callback
= callback
;
1045 sictx
->orig_context
= context
;
1046 sictx
->cat
= CATEGORY_HOST
;
1047 sictx
->key_offset
= 100;
1049 return si_async_call(si_search(), SI_CALL_HOST_BYNAME
, name
, NULL
, NULL
, AF_INET
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1053 gethostbyname_async_start(const char *name
, si_host_async_callback callback
, void *context
)
1055 return gethostbyname_async_call(name
, callback
, context
);
1059 gethostbyname_async_cancel(mach_port_t p
)
1062 fprintf(stderr
, "-- %s\n", __func__
);
1070 gethostbyname_async_handle_reply(void *param
)
1072 mach_msg_header_t
*msg
;
1075 fprintf(stderr
, "<< %s\n", __func__
);
1078 msg
= (mach_msg_header_t
*)param
;
1079 si_async_handle_reply(msg
);
1084 gethostbyname_async_handleReply(void *param
)
1086 mach_msg_header_t
*msg
;
1089 fprintf(stderr
, "<< %s\n", __func__
);
1092 msg
= (mach_msg_header_t
*)param
;
1093 si_async_handle_reply(msg
);
1097 gethostbyname2(const char *name
, int af
)
1101 struct in_addr addr4
;
1102 struct in6_addr addr6
;
1103 si_mod_t
*search
= si_search();
1106 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, af
);
1109 memset(&addr4
, 0, sizeof(struct in_addr
));
1110 memset(&addr6
, 0, sizeof(struct in6_addr
));
1111 status
= SI_STATUS_NO_ERROR
;
1114 if (((af
== AF_INET
) && (inet_aton(name
, &addr4
) == 1)) || ((af
== AF_INET6
) && (inet_pton(af
, name
, &addr6
) == 1)))
1116 item
= si_ipnode_byname(search
, name
, (uint32_t)af
, 0, NULL
, &status
);
1120 item
= si_host_byname(search
, name
, (uint32_t)af
, NULL
, &status
);
1123 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1126 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
1127 if (item
== NULL
) return NULL
;
1129 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1133 gethostbyname2_async_call(const char *name
, int af
, si_group_async_callback callback
, void *context
)
1135 si_context_t
*sictx
;
1138 fprintf(stderr
, ">> %s %s %d\n", __func__
, name
, af
);
1141 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1142 if (sictx
== NULL
) return MACH_PORT_NULL
;
1144 sictx
->orig_callback
= callback
;
1145 sictx
->orig_context
= context
;
1146 sictx
->cat
= CATEGORY_HOST
;
1147 sictx
->key_offset
= 100;
1149 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
);
1153 gethostbyname2_async_cancel(mach_port_t p
)
1156 fprintf(stderr
, "-- %s\n", __func__
);
1163 gethostbyname2_async_handle_reply(mach_msg_header_t
*msg
)
1166 fprintf(stderr
, "<< %s\n", __func__
);
1169 si_async_handle_reply(msg
);
1173 gethostbyaddr(const void *addr
, socklen_t len
, int type
)
1179 fprintf(stderr
, "-> %s %s\n", __func__
, (type
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)addr
) : "-IPv6-");
1182 status
= SI_STATUS_NO_ERROR
;
1184 item
= si_host_byaddr(si_search(), addr
, (uint32_t)type
, NULL
, &status
);
1185 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1188 LI_set_thread_item(CATEGORY_HOST
+ 200, item
);
1189 if (item
== NULL
) return NULL
;
1191 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1195 gethostbyaddr_async_call(const void *addr
, socklen_t len
, int type
, si_host_async_callback callback
, void *context
)
1197 si_context_t
*sictx
;
1201 fprintf(stderr
, ">> %s %s\n", __func__
, (type
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)addr
) : "-IPv6-");
1204 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1205 if (sictx
== NULL
) return MACH_PORT_NULL
;
1207 sictx
->orig_callback
= callback
;
1208 sictx
->orig_context
= context
;
1209 sictx
->cat
= CATEGORY_HOST
;
1210 sictx
->key_offset
= 200;
1212 /* addr is not a C string - pass length in num3 */
1214 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
);
1218 gethostbyaddr_async_start(const char *addr
, int len
, int family
, si_host_async_callback callback
, void *context
)
1220 socklen_t slen
= len
;
1222 return gethostbyaddr_async_call(addr
, slen
, family
, callback
, context
);
1226 gethostbyaddr_async_cancel(mach_port_t p
)
1229 fprintf(stderr
, "-- %s\n", __func__
);
1237 gethostbyaddr_async_handle_reply(void *param
)
1240 mach_msg_header_t
*msg
;
1243 fprintf(stderr
, "<< %s\n", __func__
);
1246 msg
= (mach_msg_header_t
*)param
;
1247 si_async_handle_reply(msg
);
1252 gethostbyaddr_async_handleReply(void *param
)
1254 mach_msg_header_t
*msg
;
1257 fprintf(stderr
, "<< %s\n", __func__
);
1260 msg
= (mach_msg_header_t
*)param
;
1261 si_async_handle_reply(msg
);
1265 getipnodebyname(const char *name
, int family
, int flags
, int *err
)
1271 fprintf(stderr
, "-> %s %s %d 0x%08x\n", __func__
, name
, family
, flags
);
1274 status
= SI_STATUS_NO_ERROR
;
1276 item
= si_ipnode_byname(si_search(), name
, family
, flags
, NULL
, &status
);
1277 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1278 if (err
!= NULL
) *err
= status
;
1280 if (item
== NULL
) return NULL
;
1282 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1287 getipnodebyname_async_call(const char *name
, int family
, int flags
, int *err
, si_host_async_callback callback
, void *context
)
1289 si_context_t
*sictx
;
1292 fprintf(stderr
, ">> %s %s %d 0x%08x\n", __func__
, name
, family
, flags
);
1295 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1296 if (sictx
== NULL
) return MACH_PORT_NULL
;
1298 sictx
->orig_callback
= callback
;
1299 sictx
->orig_context
= context
;
1300 sictx
->cat
= CATEGORY_HOST
;
1301 sictx
->key_offset
= -1;
1303 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
);
1307 getipnodebyname_async_start(const char *name
, int family
, int flags
, int *err
, si_host_async_callback callback
, void *context
)
1309 return getipnodebyname_async_call(name
, family
, flags
, err
, callback
, context
);
1313 getipnodebyname_async_cancel(mach_port_t p
)
1316 fprintf(stderr
, "-- %s\n", __func__
);
1323 getipnodebyname_async_handle_reply(mach_msg_header_t
*msg
)
1326 fprintf(stderr
, "<< %s\n", __func__
);
1329 si_async_handle_reply(msg
);
1333 getipnodebyname_async_handleReply(mach_msg_header_t
*msg
)
1336 fprintf(stderr
, "<< %s\n", __func__
);
1339 si_async_handle_reply(msg
);
1344 is_a4_mapped(const char *s
)
1349 if (s
== NULL
) return 0;
1351 for (i
= 0; i
< 10; i
++)
1354 if (c
!= 0x0) return 0;
1357 for (i
= 10; i
< 12; i
++)
1360 if (c
!= 0xff) return 0;
1367 is_a4_compat(const char *s
)
1372 if (s
== NULL
) return 0;
1374 for (i
= 0; i
< 12; i
++)
1377 if (c
!= 0x0) return 0;
1380 /* Check for :: and ::1 */
1381 for (i
= 13; i
< 15; i
++)
1383 /* anything non-zero in these 3 bytes means it's a V4 address */
1385 if (c
!= 0x0) return 1;
1388 /* Leading 15 bytes are all zero */
1390 if (c
== 0x0) return 0;
1391 if (c
== 0x1) return 0;
1397 getipnodebyaddr(const void *src
, size_t len
, int family
, int *err
)
1402 fprintf(stderr
, "-> %s %s\n", __func__
, (family
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)src
) : "-IPv6-");
1405 if ((family
== AF_INET6
) && (len
== IPV6_ADDR_LEN
) && (is_a4_mapped((const char *)src
) || is_a4_compat((const char *)src
)))
1412 item
= si_host_byaddr(si_search(), src
, family
, NULL
, (uint32_t *)err
);
1413 if (item
== NULL
) return NULL
;
1415 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1420 si_libinfo_ipnode_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
1422 si_context_t
*sictx
;
1425 if (ctx
== NULL
) return;
1427 sictx
= (si_context_t
*)ctx
;
1429 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
1432 si_item_release(item
);
1436 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1440 ((si_ipnode_async_callback
)(sictx
->orig_callback
))(NULL
, status
, sictx
->orig_context
);
1444 h
= (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1445 ((si_ipnode_async_callback
)(sictx
->orig_callback
))(h
, status
, sictx
->orig_context
);
1451 getipnodebyaddr_async_call(const void *src
, socklen_t len
, int family
, int *err
, si_ipnode_async_callback callback
, void *context
)
1453 si_context_t
*sictx
;
1457 fprintf(stderr
, ">> %s %s\n", __func__
, (family
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)src
) : "-IPv6-");
1460 if ((family
== AF_INET6
) && (len
== IPV6_ADDR_LEN
) && (is_a4_mapped((const char *)src
) || is_a4_compat((const char *)src
)))
1467 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1468 if (sictx
== NULL
) return MACH_PORT_NULL
;
1470 sictx
->orig_callback
= callback
;
1471 sictx
->orig_context
= context
;
1472 sictx
->cat
= CATEGORY_HOST
;
1473 sictx
->key_offset
= -1;
1475 /* src is not a C string - pass length in num3 */
1477 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
);
1481 getipnodebyaddr_async_start(const void *addr
, size_t len
, int family
, int *error
, si_ipnode_async_callback callback
, void *context
)
1483 socklen_t slen
= len
;
1485 return getipnodebyaddr_async_call(addr
, slen
, family
, error
, callback
, context
);
1489 getipnodebyaddr_async_cancel(mach_port_t p
)
1492 fprintf(stderr
, "-- %s\n", __func__
);
1499 getipnodebyaddr_async_handle_reply(mach_msg_header_t
*msg
)
1502 fprintf(stderr
, "<< %s\n", __func__
);
1505 si_async_handle_reply(msg
);
1509 getipnodebyaddr_async_handleReply(mach_msg_header_t
*msg
)
1512 fprintf(stderr
, "<< %s\n", __func__
);
1515 si_async_handle_reply(msg
);
1520 sethostent(int ignored
)
1523 fprintf(stderr
, "-- %s\n", __func__
);
1526 LI_set_thread_list(CATEGORY_HOST
, NULL
);
1536 fprintf(stderr
, "-> %s\n", __func__
);
1539 list
= LI_get_thread_list(CATEGORY_HOST
);
1542 list
= si_host_all(si_search());
1543 LI_set_thread_list(CATEGORY_HOST
, list
);
1546 item
= si_list_next(list
);
1547 if (item
== NULL
) return NULL
;
1549 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1556 fprintf(stderr
, "-- %s\n", __func__
);
1559 LI_set_thread_list(CATEGORY_HOST
, NULL
);
1565 ether_hostton(const char *name
, struct ether_addr
*e
)
1573 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1576 if (name
== NULL
) return -1;
1577 if (e
== NULL
) return -1;
1579 item
= si_mac_byname(si_search(), name
);
1580 LI_set_thread_item(CATEGORY_MAC
+ 100, item
);
1581 if (item
== NULL
) return -1;
1583 mac
= (si_mac_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
1585 i
= sscanf(mac
->mac
, " %x:%x:%x:%x:%x:%x", &t
[0], &t
[1], &t
[2], &t
[3], &t
[4], &t
[5]);
1586 if (i
!= 6) return -1;
1588 for (i
= 0; i
< 6; i
++) e
->ether_addr_octet
[i
] = t
[i
];
1592 /* XXX to do? async ether_hostton */
1595 ether_ntohost(char *name
, const struct ether_addr
*e
)
1602 if (name
== NULL
) return -1;
1603 if (e
== NULL
) return -1;
1605 for (i
= 0; i
< 6; i
++) x
[i
] = e
->ether_addr_octet
[i
];
1606 snprintf(str
, sizeof(str
), "%x:%x:%x:%x:%x:%x", x
[0], x
[1], x
[2], x
[3], x
[4], x
[5]);
1609 fprintf(stderr
, "-> %s %s\n", __func__
, str
);
1612 item
= si_mac_bymac(si_search(), str
);
1613 LI_set_thread_item(CATEGORY_MAC
+ 200, item
);
1614 if (item
== NULL
) return -1;
1616 mac
= (si_mac_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
1618 memcpy(name
, mac
->host
, strlen(mac
->host
) + 1);
1622 /* XXX to do? async ether_ntohost */
1627 getnetbyname(const char *name
)
1632 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1635 item
= si_network_byname(si_search(), name
);
1636 LI_set_thread_item(CATEGORY_NETWORK
+ 100, item
);
1637 if (item
== NULL
) return NULL
;
1639 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1643 getnetbyname_async_call(const char *name
, si_network_async_callback callback
, void *context
)
1645 si_context_t
*sictx
;
1648 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1651 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1652 if (sictx
== NULL
) return MACH_PORT_NULL
;
1654 sictx
->orig_callback
= callback
;
1655 sictx
->orig_context
= context
;
1656 sictx
->cat
= CATEGORY_NETWORK
;
1657 sictx
->key_offset
= 100;
1659 return si_async_call(si_search(), SI_CALL_NETWORK_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1663 getnetbyname_async_handle_reply(mach_msg_header_t
*msg
)
1666 fprintf(stderr
, "<< %s\n", __func__
);
1669 si_async_handle_reply(msg
);
1673 getnetbyaddr(uint32_t net
, int type
)
1678 fprintf(stderr
, "-> %s 0x%08x\n", __func__
, net
);
1681 if (type
!= AF_INET
) return NULL
;
1683 item
= si_network_byaddr(si_search(), net
);
1684 LI_set_thread_item(CATEGORY_NETWORK
+ 200, item
);
1685 if (item
== NULL
) return NULL
;
1687 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1691 getnetbyaddr_async_call(uint32_t net
, int type
, si_group_async_callback callback
, void *context
)
1693 si_context_t
*sictx
;
1696 fprintf(stderr
, ">> %s 0x%08x\n", __func__
, net
);
1699 if (type
!= AF_INET
) return MACH_PORT_NULL
;
1701 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1702 if (sictx
== NULL
) return MACH_PORT_NULL
;
1704 sictx
->orig_callback
= callback
;
1705 sictx
->orig_context
= context
;
1706 sictx
->cat
= CATEGORY_NETWORK
;
1707 sictx
->key_offset
= 200;
1709 return si_async_call(si_search(), SI_CALL_NETWORK_BYADDR
, NULL
, NULL
, NULL
, net
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1713 getnetbyaddr_async_handle_reply(mach_msg_header_t
*msg
)
1716 fprintf(stderr
, "<< %s\n", __func__
);
1719 si_async_handle_reply(msg
);
1723 setnetent(int ignored
)
1726 fprintf(stderr
, "-- %s\n", __func__
);
1729 LI_set_thread_list(CATEGORY_NETWORK
, NULL
);
1739 fprintf(stderr
, "-> %s\n", __func__
);
1742 list
= LI_get_thread_list(CATEGORY_NETWORK
);
1745 list
= si_network_all(si_search());
1746 LI_set_thread_list(CATEGORY_NETWORK
, list
);
1749 item
= si_list_next(list
);
1750 if (item
== NULL
) return NULL
;
1752 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1759 fprintf(stderr
, "-- %s\n", __func__
);
1762 LI_set_thread_list(CATEGORY_NETWORK
, NULL
);
1768 getservbyname(const char *name
, const char *proto
)
1773 fprintf(stderr
, "-> %s %s %s\n", __func__
, name
, proto
);
1776 item
= si_service_byname(si_search(), name
, proto
);
1777 LI_set_thread_item(CATEGORY_SERVICE
+ 100, item
);
1778 if (item
== NULL
) return NULL
;
1780 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1784 getservbyname_async_call(const char *name
, const char *proto
, si_service_async_callback callback
, void *context
)
1786 si_context_t
*sictx
;
1789 fprintf(stderr
, ">> %s %s %s\n", __func__
, name
, proto
);
1792 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1793 if (sictx
== NULL
) return MACH_PORT_NULL
;
1795 sictx
->orig_callback
= callback
;
1796 sictx
->orig_context
= context
;
1797 sictx
->cat
= CATEGORY_SERVICE
;
1798 sictx
->key_offset
= 100;
1800 return si_async_call(si_search(), SI_CALL_SERVICE_BYNAME
, name
, proto
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1804 getservbyname_async_handle_reply(mach_msg_header_t
*msg
)
1807 fprintf(stderr
, "<< %s\n", __func__
);
1810 si_async_handle_reply(msg
);
1814 getservbyport(int port
, const char *proto
)
1819 fprintf(stderr
, "-> %s %d %s\n", __func__
, ntohs((uint16_t)port
), proto
);
1822 item
= si_service_byport(si_search(), port
, proto
);
1823 LI_set_thread_item(CATEGORY_SERVICE
+ 200, item
);
1824 if (item
== NULL
) return NULL
;
1826 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1830 getservbyport_async_call(int port
, const char *proto
, si_group_async_callback callback
, void *context
)
1832 si_context_t
*sictx
;
1835 fprintf(stderr
, ">> %s %d %s\n", __func__
, port
, proto
);
1838 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1839 if (sictx
== NULL
) return MACH_PORT_NULL
;
1841 sictx
->orig_callback
= callback
;
1842 sictx
->orig_context
= context
;
1843 sictx
->cat
= CATEGORY_SERVICE
;
1844 sictx
->key_offset
= 200;
1846 return si_async_call(si_search(), SI_CALL_SERVICE_BYPORT
, NULL
, proto
, NULL
, port
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1850 getservbyport_async_handle_reply(mach_msg_header_t
*msg
)
1853 fprintf(stderr
, "<< %s\n", __func__
);
1856 si_async_handle_reply(msg
);
1860 setservent(int ignored
)
1863 fprintf(stderr
, "-- %s\n", __func__
);
1866 LI_set_thread_list(CATEGORY_SERVICE
, NULL
);
1876 fprintf(stderr
, "-> %s\n", __func__
);
1879 list
= LI_get_thread_list(CATEGORY_SERVICE
);
1882 list
= si_service_all(si_search());
1883 LI_set_thread_list(CATEGORY_SERVICE
, list
);
1886 item
= si_list_next(list
);
1887 if (item
== NULL
) return NULL
;
1889 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1896 fprintf(stderr
, "-- %s\n", __func__
);
1899 LI_set_thread_list(CATEGORY_SERVICE
, NULL
);
1905 getprotobyname(const char *name
)
1910 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1913 item
= si_protocol_byname(si_search(), name
);
1914 LI_set_thread_item(CATEGORY_PROTOCOL
+ 100, item
);
1915 if (item
== NULL
) return NULL
;
1917 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1921 getprotobyname_async_call(const char *name
, si_protocol_async_callback callback
, void *context
)
1923 si_context_t
*sictx
;
1926 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1929 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1930 if (sictx
== NULL
) return MACH_PORT_NULL
;
1932 sictx
->orig_callback
= callback
;
1933 sictx
->orig_context
= context
;
1934 sictx
->cat
= CATEGORY_PROTOCOL
;
1935 sictx
->key_offset
= 100;
1937 return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1941 getprotobyname_async_handle_reply(mach_msg_header_t
*msg
)
1944 fprintf(stderr
, "<< %s\n", __func__
);
1947 si_async_handle_reply(msg
);
1951 getprotobynumber(int number
)
1956 fprintf(stderr
, "-> %s %d\n", __func__
, number
);
1959 item
= si_protocol_bynumber(si_search(), number
);
1960 LI_set_thread_item(CATEGORY_PROTOCOL
+ 200, item
);
1961 if (item
== NULL
) return NULL
;
1963 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1967 getprotobynumber_async_call(int number
, si_group_async_callback callback
, void *context
)
1969 si_context_t
*sictx
;
1972 fprintf(stderr
, ">> %s %d\n", __func__
, number
);
1975 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1976 if (sictx
== NULL
) return MACH_PORT_NULL
;
1978 sictx
->orig_callback
= callback
;
1979 sictx
->orig_context
= context
;
1980 sictx
->cat
= CATEGORY_PROTOCOL
;
1981 sictx
->key_offset
= 200;
1983 return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNUMBER
, NULL
, NULL
, NULL
, number
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1987 getprotobynumber_async_handle_reply(mach_msg_header_t
*msg
)
1990 fprintf(stderr
, "<< %s\n", __func__
);
1993 si_async_handle_reply(msg
);
1997 setprotoent(int ignored
)
2000 fprintf(stderr
, "-- %s\n", __func__
);
2003 LI_set_thread_list(CATEGORY_PROTOCOL
, NULL
);
2013 fprintf(stderr
, "-> %s\n", __func__
);
2016 list
= LI_get_thread_list(CATEGORY_PROTOCOL
);
2019 list
= si_protocol_all(si_search());
2020 LI_set_thread_list(CATEGORY_PROTOCOL
, list
);
2023 item
= si_list_next(list
);
2024 if (item
== NULL
) return NULL
;
2026 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2033 fprintf(stderr
, "-- %s\n", __func__
);
2036 LI_set_thread_list(CATEGORY_PROTOCOL
, NULL
);
2042 getrpcbyname(const char *name
)
2047 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
2050 item
= si_rpc_byname(si_search(), name
);
2051 LI_set_thread_item(CATEGORY_RPC
+ 100, item
);
2052 if (item
== NULL
) return NULL
;
2054 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2058 getrpcbyname_async_call(const char *name
, si_rpc_async_callback callback
, void *context
)
2060 si_context_t
*sictx
;
2063 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
2066 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2067 if (sictx
== NULL
) return MACH_PORT_NULL
;
2069 sictx
->orig_callback
= callback
;
2070 sictx
->orig_context
= context
;
2071 sictx
->cat
= CATEGORY_RPC
;
2072 sictx
->key_offset
= 100;
2074 return si_async_call(si_search(), SI_CALL_RPC_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2078 getrpcbyname_async_handle_reply(mach_msg_header_t
*msg
)
2081 fprintf(stderr
, "<< %s\n", __func__
);
2084 si_async_handle_reply(msg
);
2100 fprintf(stderr
, "-> %s %ld\n", __func__
, (long int)number
);
2103 item
= si_rpc_bynumber(si_search(), number
);
2104 LI_set_thread_item(CATEGORY_RPC
+ 200, item
);
2105 if (item
== NULL
) return NULL
;
2107 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2111 getrpcbynumber_async_call(int number
, si_group_async_callback callback
, void *context
)
2113 si_context_t
*sictx
;
2116 fprintf(stderr
, ">> %s %d\n", __func__
, number
);
2119 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2120 if (sictx
== NULL
) return MACH_PORT_NULL
;
2122 sictx
->orig_callback
= callback
;
2123 sictx
->orig_context
= context
;
2124 sictx
->cat
= CATEGORY_RPC
;
2125 sictx
->key_offset
= 200;
2127 return si_async_call(si_search(), SI_CALL_RPC_BYNUMBER
, NULL
, NULL
, NULL
, number
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2131 getrpcbynumber_async_handle_reply(mach_msg_header_t
*msg
)
2134 fprintf(stderr
, "<< %s\n", __func__
);
2137 si_async_handle_reply(msg
);
2141 setrpcent(int ignored
)
2144 fprintf(stderr
, "-- %s\n", __func__
);
2147 LI_set_thread_list(CATEGORY_RPC
, NULL
);
2157 fprintf(stderr
, "-> %s\n", __func__
);
2160 list
= LI_get_thread_list(CATEGORY_RPC
);
2163 list
= si_rpc_all(si_search());
2164 LI_set_thread_list(CATEGORY_RPC
, list
);
2167 item
= si_list_next(list
);
2168 if (item
== NULL
) return NULL
;
2170 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2177 fprintf(stderr
, "-- %s\n", __func__
);
2180 LI_set_thread_list(CATEGORY_RPC
, NULL
);
2186 getfsspec(const char *spec
)
2191 fprintf(stderr
, "-> %s %s\n", __func__
, spec
);
2194 item
= si_fs_byspec(si_search(), spec
);
2195 LI_set_thread_item(CATEGORY_FS
+ 100, item
);
2196 if (item
== NULL
) return NULL
;
2198 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2202 getfsbyname(const char *name
)
2205 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
2208 return getfsspec(name
);
2212 getfsspec_async_call(const char *spec
, si_fs_async_callback callback
, void *context
)
2214 si_context_t
*sictx
;
2217 fprintf(stderr
, ">> %s %s\n", __func__
, spec
);
2220 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2221 if (sictx
== NULL
) return MACH_PORT_NULL
;
2223 sictx
->orig_callback
= callback
;
2224 sictx
->orig_context
= context
;
2225 sictx
->cat
= CATEGORY_FS
;
2226 sictx
->key_offset
= 100;
2228 return si_async_call(si_search(), SI_CALL_FS_BYSPEC
, spec
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2232 getfsspec_async_handle_reply(mach_msg_header_t
*msg
)
2235 fprintf(stderr
, "<< %s\n", __func__
);
2238 si_async_handle_reply(msg
);
2242 getfsfile(const char *file
)
2247 fprintf(stderr
, "-> %s %s\n", __func__
, file
);
2250 item
= si_fs_byfile(si_search(), file
);
2251 LI_set_thread_item(CATEGORY_FS
+ 200, item
);
2252 if (item
== NULL
) return NULL
;
2254 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2258 getfsfile_async_call(const char *file
, si_fs_async_callback callback
, void *context
)
2260 si_context_t
*sictx
;
2263 fprintf(stderr
, ">> %s %s\n", __func__
, file
);
2266 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2267 if (sictx
== NULL
) return MACH_PORT_NULL
;
2269 sictx
->orig_callback
= callback
;
2270 sictx
->orig_context
= context
;
2271 sictx
->cat
= CATEGORY_FS
;
2272 sictx
->key_offset
= 200;
2274 return si_async_call(si_search(), SI_CALL_FS_BYFILE
, file
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2278 getfsfile_async_handle_reply(mach_msg_header_t
*msg
)
2281 fprintf(stderr
, "<< %s\n", __func__
);
2284 si_async_handle_reply(msg
);
2291 fprintf(stderr
, "-> %s\n", __func__
);
2294 LI_set_thread_list(CATEGORY_FS
, NULL
);
2305 fprintf(stderr
, "-> %s\n", __func__
);
2308 list
= LI_get_thread_list(CATEGORY_FS
);
2311 list
= si_fs_all(si_search());
2312 LI_set_thread_list(CATEGORY_FS
, list
);
2315 item
= si_list_next(list
);
2316 if (item
== NULL
) return NULL
;
2318 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2325 fprintf(stderr
, "-- %s\n", __func__
);
2328 LI_set_thread_list(CATEGORY_FS
, NULL
);
2334 _getaddrinfo_internal(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, const char *interface
, struct addrinfo
**res
)
2337 uint32_t family
, socktype
, protocol
, flags
, status
;
2338 struct addrinfo
*ai
;
2341 socktype
= SOCK_UNSPEC
;
2342 protocol
= IPPROTO_UNSPEC
;
2344 status
= SI_STATUS_NO_ERROR
;
2346 if (res
== NULL
) return 0;
2351 family
= hints
->ai_family
;
2352 socktype
= hints
->ai_socktype
;
2353 protocol
= hints
->ai_protocol
;
2354 flags
= hints
->ai_flags
;
2357 if (flags
== 0) flags
= AI_DEFAULT
;
2360 fprintf(stderr
, "-> %s %s %s %u %u %u 0x%08x %s\n", __func__
, nodename
, servname
, family
, socktype
, protocol
, flags
, (interface
== NULL
) ? "" : interface
);
2363 list
= si_addrinfo(si_search(), nodename
, servname
, family
, socktype
, protocol
, flags
, interface
, &status
);
2364 if ((status
!= SI_STATUS_NO_ERROR
) || (list
== NULL
) || (list
->count
== 0))
2366 si_list_release(list
);
2368 if (status
== SI_STATUS_NO_ERROR
) return EAI_NONAME
;
2369 else if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2370 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2371 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2375 *res
= si_list_to_addrinfo(list
);
2376 si_list_release(list
);
2377 if (*res
== NULL
) status
= EAI_MEMORY
;
2379 /* don't return the canonical name unless asked */
2380 if ((flags
& AI_CANONNAME
) == 0)
2382 for (ai
= *res
; ai
!= NULL
; ai
= ai
->ai_next
)
2384 free(ai
->ai_canonname
);
2385 ai
->ai_canonname
= NULL
;
2393 getaddrinfo(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, struct addrinfo
**res
)
2395 return _getaddrinfo_internal(nodename
, servname
, hints
, NULL
, res
);
2401 socket_name(int sock
)
2403 static char str
[16];
2407 case SOCK_UNSPEC
: return "SOCK_UNSPEC";
2408 case SOCK_STREAM
: return "SOCK_STREAM";
2409 case SOCK_DGRAM
: return "SOCK_DGRAM";
2412 sprintf(str
, "%d", sock
);
2419 static char str
[16];
2423 case PF_UNSPEC
: return "PF_UNSPEC";
2424 case PF_INET
: return "PF_INET";
2425 case PF_INET6
: return "PF_INET6";
2428 sprintf(str
, "%d", pf
);
2433 protocol_name(int p
)
2435 static char str
[16];
2439 case IPPROTO_UNSPEC
: return "IPPROTO_UNSPEC";
2440 case IPPROTO_TCP
: return "IPPROTO_TCP";
2441 case IPPROTO_UDP
: return "IPPROTO_UDP";
2444 sprintf(str
, "%d", p
);
2449 _gai_inet_ntop(struct in6_addr a
)
2451 static char buf
[128];
2457 memset(buf
, 0, 128);
2459 p
= (char *)&a
.__u6_addr
.__u6_addr32
;
2460 for (i
= 0; i
< 8; i
++, x
+= 1)
2464 sprintf(t
, "%hx", x
);
2466 if (i
< 7) strcat(buf
, ":");
2473 fprint_addrinfo(FILE *f
, struct addrinfo
*a
)
2477 struct sockaddr_in
*s4
;
2478 struct sockaddr_in6
*s6
;
2480 if (a
== NULL
) return;
2482 if (a
->ai_flags
!= 0)
2484 fprintf(f
, "flags =");
2485 if (a
->ai_flags
& AI_PASSIVE
) fprintf(f
, " AI_PASSIVE");
2486 if (a
->ai_flags
& AI_CANONNAME
) fprintf(f
, " AI_CANONNAME");
2487 if (a
->ai_flags
& AI_NUMERICHOST
) fprintf(f
, " AI_NUMERICHOST");
2488 if (a
->ai_flags
& AI_NUMERICSERV
) fprintf(f
, " AI_NUMERICSERV");
2492 fprintf(f
, "family = %s\n", family_name(a
->ai_family
));
2493 fprintf(f
, "socktype = %s\n", socket_name(a
->ai_socktype
));
2494 fprintf(f
, "protocol = %s\n", protocol_name(a
->ai_protocol
));
2496 fprintf(f
, "canonical name = ");
2497 if (a
->ai_canonname
== NULL
) fprintf(f
, "NULL\n");
2498 else fprintf(f
, "\"%s\"\n", a
->ai_canonname
);
2500 fprintf(f
, "addrlen = %ld\n", (long int)a
->ai_addrlen
);
2502 if (a
->ai_addr
== NULL
) fprintf(f
, "sockaddr = NULL\n");
2505 if (a
->ai_family
== PF_INET
)
2507 s4
= (struct sockaddr_in
*)a
->ai_addr
;
2509 fprintf(f
, "sockaddr_in len = %d\n", s4
->sin_len
);
2510 fprintf(f
, "sockaddr_in family = %s\n", family_name(s4
->sin_family
));
2511 fprintf(f
, "sockaddr_in port = %hu\n", ntohs(s4
->sin_port
));
2512 fprintf(f
, "sockaddr_in address = %s\n", inet_ntoa(s4
->sin_addr
));
2514 else if (a
->ai_family
== PF_INET6
)
2516 s6
= (struct sockaddr_in6
*)a
->ai_addr
;
2518 fprintf(f
, "sockaddr_in6 len = %d\n", s6
->sin6_len
);
2519 fprintf(f
, "sockaddr_in6 family = %s\n", family_name(s6
->sin6_family
));
2520 fprintf(f
, "sockaddr_in6 port = %hu\n", ntohs(s6
->sin6_port
));
2521 fprintf(f
, "sockaddr_in6 flowinfo = %d\n", s6
->sin6_flowinfo
);
2522 fprintf(f
, "sockaddr_in6 address = %s\n", _gai_inet_ntop(s6
->sin6_addr
));
2523 fprintf(f
, "sockaddr_in6 scope_id = %d\n", s6
->sin6_scope_id
);
2527 fprintf(f
, "sockaddr len = %d\n", a
->ai_addr
->sa_len
);
2528 fprintf(f
, "sockaddr family = %s\n", family_name(a
->ai_addr
->sa_family
));
2529 fprintf(f
, "sockaddr data = ");
2530 for (i
= 0; i
< a
->ai_addr
->sa_len
- 2; i
++)
2532 v
= a
->ai_addr
->sa_data
[i
];
2533 fprintf(f
, "%02x", v
);
2539 if (a
->ai_next
!= NULL
)
2541 fprintf(f
, "NEXT --->\n");
2542 fprint_addrinfo(f
, a
->ai_next
);
2549 si_libinfo_addrinfo_callback(si_list_t
*list
, uint32_t status
, void *ctx
)
2551 si_context_t
*sictx
;
2552 struct addrinfo
*out
;
2557 fprintf(stderr
, " %s error no context\n", __func__
);
2559 si_list_release(list
);
2563 sictx
= (si_context_t
*)ctx
;
2565 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
2568 fprintf(stderr
, " %s error no callback\n", __func__
);
2570 si_list_release(list
);
2575 if (status
!= SI_STATUS_NO_ERROR
)
2578 fprintf(stderr
, " %s original status %d\n", __func__
, status
);
2580 if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2581 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2582 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2588 fprintf(stderr
, " %s result NULL status %d (returning EAI_NONAME)\n", __func__
, status
);
2590 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(EAI_NONAME
, NULL
, sictx
->orig_context
);
2595 out
= si_list_to_addrinfo(list
);
2596 si_list_release(list
);
2600 fprintf(stderr
, " %s result conversion failed returning NULL status %d (returning EAI_MEMORY)\n", __func__
, status
);
2602 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(EAI_MEMORY
, NULL
, sictx
->orig_context
);
2608 fprintf(stderr
, " %s %d\n", __func__
, status
);
2609 fprint_addrinfo(stderr
, out
);
2611 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(status
, out
, sictx
->orig_context
);
2618 _getaddrinfo_interface_async_call(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, const char *interface
, si_addrinfo_async_callback callback
, void *context
)
2620 si_context_t
*sictx
;
2621 uint32_t family
, socktype
, protocol
, flags
;
2624 socktype
= SOCK_UNSPEC
;
2625 protocol
= IPPROTO_UNSPEC
;
2630 family
= hints
->ai_family
;
2631 socktype
= hints
->ai_socktype
;
2632 protocol
= hints
->ai_protocol
;
2633 flags
= hints
->ai_flags
;
2636 if (flags
== 0) flags
= AI_DEFAULT
;
2639 fprintf(stderr
, ">> %s %s %s %u %u %u 0x%08x\n", __func__
, nodename
, servname
, family
, socktype
, protocol
, flags
);
2642 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2643 if (sictx
== NULL
) return MACH_PORT_NULL
;
2645 sictx
->orig_callback
= callback
;
2646 sictx
->orig_context
= context
;
2647 sictx
->cat
= CATEGORY_ADDRINFO
;
2648 sictx
->key_offset
= 0;
2650 return si_async_call(si_search(), SI_CALL_ADDRINFO
, nodename
, servname
, interface
, family
, socktype
, protocol
, flags
, (void *)si_libinfo_addrinfo_callback
, sictx
);
2654 getaddrinfo_async_call(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, si_addrinfo_async_callback callback
, void *context
)
2656 return _getaddrinfo_interface_async_call(nodename
, servname
, hints
, NULL
, callback
, context
);
2660 getaddrinfo_async_start(mach_port_t
*p
, const char *nodename
, const char *servname
, const struct addrinfo
*hints
, si_addrinfo_async_callback callback
, void *context
)
2662 if (p
== NULL
) return EAI_SYSTEM
;
2664 *p
= getaddrinfo_async_call(nodename
, servname
, hints
, callback
, context
);
2666 if (*p
== MACH_PORT_NULL
) return EAI_SYSTEM
;
2671 getaddrinfo_async_send(mach_port_t
*p
, const char *nodename
, const char *servname
, const struct addrinfo
*hints
)
2673 return getaddrinfo_async_start(p
, nodename
, servname
, hints
, NULL
, NULL
);
2677 getaddrinfo_async_receive(mach_port_t p
, struct addrinfo
**res
)
2679 /* unsupported Leopard SPI */
2684 getaddrinfo_async_cancel(mach_port_t p
)
2687 fprintf(stderr
, "-- %s\n", __func__
);
2694 getaddrinfo_async_handle_reply(void *param
)
2696 mach_msg_header_t
*msg
;
2699 fprintf(stderr
, "<< %s\n", __func__
);
2702 msg
= (mach_msg_header_t
*)param
;
2703 si_async_handle_reply(msg
);
2711 _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
)
2715 uint32_t status
, len
, wantn
, wants
;
2718 fprintf(stderr
, "-> %s\n", __func__
);
2721 status
= SI_STATUS_NO_ERROR
;
2724 if ((node
!= NULL
) && (nodelen
> 0)) wantn
= 1;
2727 if ((service
!= NULL
) && (servicelen
> 0)) wants
= 1;
2729 if ((wantn
== 0) && (wants
== 0)) return status
;
2731 if (wantn
== 0) flags
|= NI_NUMERICHOST
;
2732 if (wants
== 0) flags
|= NI_NUMERICSERV
;
2734 item
= si_nameinfo(si_search(), sa
, flags
, interface
, &status
);
2735 if ((status
!= SI_STATUS_NO_ERROR
) || (item
== NULL
))
2737 si_item_release(item
);
2739 if (status
== SI_STATUS_NO_ERROR
) status
= EAI_NONAME
;
2740 else if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2741 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2742 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2746 ni
= (si_nameinfo_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
2749 if (ni
->ni_node
!= NULL
) len
= strlen(ni
->ni_node
) + 1;
2750 if ((wantn
== 1) && (len
> 0))
2754 si_item_release(item
);
2755 return EAI_OVERFLOW
;
2758 memset(node
, 0, nodelen
);
2759 memcpy(node
, ni
->ni_node
, len
);
2763 if (ni
->ni_serv
!= NULL
) len
= strlen(ni
->ni_serv
) + 1;
2764 if ((wants
== 1) && (len
> 0))
2766 if (len
> servicelen
)
2768 si_item_release(item
);
2769 return EAI_OVERFLOW
;
2772 memset(service
, 0, servicelen
);
2773 memcpy(service
, ni
->ni_serv
, len
);
2776 si_item_release(item
);
2781 getnameinfo(const struct sockaddr
*sa
, socklen_t salen
, char *node
, socklen_t nodelen
, char *service
, socklen_t servicelen
, int flags
)
2783 if (sa
== NULL
) return EAI_FAIL
;
2785 if (sa
->sa_family
== AF_LINK
) return getnameinfo_link(sa
, salen
, node
, nodelen
, service
, servicelen
, flags
);
2786 return _getnameinfo_interface_internal(sa
, salen
, node
, nodelen
, service
, servicelen
, flags
, NULL
);
2790 si_libinfo_nameinfo_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
2792 si_context_t
*sictx
;
2796 if (ctx
== NULL
) return;
2798 sictx
= (si_context_t
*)ctx
;
2800 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
2802 si_item_release(item
);
2807 if (status
!= SI_STATUS_NO_ERROR
)
2809 if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2810 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2811 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2816 ((si_nameinfo_async_callback
)(sictx
->orig_callback
))(status
, NULL
, NULL
, sictx
->orig_context
);
2821 LI_set_thread_item(CATEGORY_NAMEINFO
, item
);
2826 ni
= (si_nameinfo_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
2827 if (ni
->ni_node
!= NULL
) node
= strdup(ni
->ni_node
);
2828 if (ni
->ni_serv
!= NULL
) serv
= strdup(ni
->ni_serv
);
2830 ((si_nameinfo_async_callback
)(sictx
->orig_callback
))(status
, node
, serv
, sictx
->orig_context
);
2836 _getnameinfo_interface_async_call(const struct sockaddr
*sa
, size_t len
, int flags
, const char *interface
, si_nameinfo_async_callback callback
, void *context
)
2838 si_context_t
*sictx
;
2842 fprintf(stderr
, ">> %s\n", __func__
);
2845 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2846 if (sictx
== NULL
) return MACH_PORT_NULL
;
2848 sictx
->orig_callback
= callback
;
2849 sictx
->orig_context
= context
;
2850 sictx
->cat
= CATEGORY_ADDRINFO
;
2851 sictx
->key_offset
= 0;
2853 /* sa is not a C string - pass length in num3 */
2855 return si_async_call(si_search(), SI_CALL_NAMEINFO
, (const char *)sa
, NULL
, interface
, flags
, 0, salen
, 0, (void *)si_libinfo_nameinfo_callback
, sictx
);
2859 getnameinfo_async_call(const struct sockaddr
*sa
, size_t len
, int flags
, si_nameinfo_async_callback callback
, void *context
)
2861 return _getnameinfo_interface_async_call(sa
, len
, flags
, NULL
, callback
, context
);
2865 getnameinfo_async_start(mach_port_t
*p
, const struct sockaddr
*sa
, size_t salen
, int flags
, si_nameinfo_async_callback callback
, void *context
)
2867 if (p
== NULL
) return EAI_SYSTEM
;
2868 *p
= getnameinfo_async_call(sa
, salen
, flags
, callback
, context
);
2870 if (*p
== MACH_PORT_NULL
) return EAI_SYSTEM
;
2875 getnameinfo_async_send(mach_port_t
*p
, const struct sockaddr
*sa
, size_t salen
, int flags
)
2877 return getnameinfo_async_start(p
, sa
, salen
, flags
, NULL
, NULL
);
2881 getnameinfo_async_cancel(mach_port_t p
)
2884 fprintf(stderr
, "-- %s\n", __func__
);
2891 getnameinfo_async_handle_reply(void *param
)
2893 mach_msg_header_t
*msg
;
2896 fprintf(stderr
, "<< %s\n", __func__
);
2899 msg
= (mach_msg_header_t
*)param
;
2900 si_async_handle_reply(msg
);
2905 /* getpwXXX_r and getgrXXX_r */
2908 copy_user_r(struct passwd
*in
, struct passwd
*out
, char *buffer
, int buflen
)
2913 if (in
== NULL
) return -1;
2914 if (out
== NULL
) return -1;
2916 if (buffer
== NULL
) buflen
= 0;
2918 /* Calculate size of input */
2920 if (in
->pw_name
!= NULL
) hsize
+= (strlen(in
->pw_name
) + 1);
2921 if (in
->pw_passwd
!= NULL
) hsize
+= (strlen(in
->pw_passwd
) + 1);
2922 if (in
->pw_class
!= NULL
) hsize
+= (strlen(in
->pw_class
) + 1);
2923 if (in
->pw_gecos
!= NULL
) hsize
+= (strlen(in
->pw_gecos
) + 1);
2924 if (in
->pw_dir
!= NULL
) hsize
+= (strlen(in
->pw_dir
) + 1);
2925 if (in
->pw_shell
!= NULL
) hsize
+= (strlen(in
->pw_shell
) + 1);
2927 /* Check buffer space */
2928 if (hsize
> buflen
) return -1;
2930 /* Copy result into caller's struct passwd, using buffer for memory */
2933 out
->pw_name
= NULL
;
2934 if (in
->pw_name
!= NULL
)
2937 hsize
= strlen(in
->pw_name
) + 1;
2938 memmove(bp
, in
->pw_name
, hsize
);
2942 out
->pw_passwd
= NULL
;
2943 if (in
->pw_passwd
!= NULL
)
2945 out
->pw_passwd
= bp
;
2946 hsize
= strlen(in
->pw_passwd
) + 1;
2947 memmove(bp
, in
->pw_passwd
, hsize
);
2951 out
->pw_uid
= in
->pw_uid
;
2953 out
->pw_gid
= in
->pw_gid
;
2955 out
->pw_change
= in
->pw_change
;
2957 out
->pw_class
= NULL
;
2958 if (in
->pw_class
!= NULL
)
2961 hsize
= strlen(in
->pw_class
) + 1;
2962 memmove(bp
, in
->pw_class
, hsize
);
2966 out
->pw_gecos
= NULL
;
2967 if (in
->pw_gecos
!= NULL
)
2970 hsize
= strlen(in
->pw_gecos
) + 1;
2971 memmove(bp
, in
->pw_gecos
, hsize
);
2976 if (in
->pw_dir
!= NULL
)
2979 hsize
= strlen(in
->pw_dir
) + 1;
2980 memmove(bp
, in
->pw_dir
, hsize
);
2984 out
->pw_shell
= NULL
;
2985 if (in
->pw_shell
!= NULL
)
2988 hsize
= strlen(in
->pw_shell
) + 1;
2989 memmove(bp
, in
->pw_shell
, hsize
);
2993 out
->pw_expire
= in
->pw_expire
;
2999 copy_group_r(struct group
*in
, struct group
*out
, char *buffer
, int buflen
)
3005 if (in
== NULL
) return -1;
3006 if (out
== NULL
) return -1;
3008 if (buffer
== NULL
) buflen
= 0;
3010 /* Calculate size of input */
3012 if (in
->gr_name
!= NULL
) hsize
+= (strlen(in
->gr_name
) + 1);
3013 if (in
->gr_passwd
!= NULL
) hsize
+= (strlen(in
->gr_passwd
) + 1);
3015 /* NULL pointer at end of list */
3016 hsize
+= sizeof(char *);
3019 if (in
->gr_mem
!= NULL
)
3021 for (len
= 0; in
->gr_mem
[len
] != NULL
; len
++)
3023 hsize
+= sizeof(char *);
3024 hsize
+= (strlen(in
->gr_mem
[len
]) + 1);
3028 /* Check buffer space */
3029 if (hsize
> buflen
) return -1;
3031 /* Copy result into caller's struct group, using buffer for memory */
3034 out
->gr_name
= NULL
;
3035 if (in
->gr_name
!= NULL
)
3038 hsize
= strlen(in
->gr_name
) + 1;
3039 memmove(bp
, in
->gr_name
, hsize
);
3043 out
->gr_passwd
= NULL
;
3044 if (in
->gr_passwd
!= NULL
)
3046 out
->gr_passwd
= bp
;
3047 hsize
= strlen(in
->gr_passwd
) + 1;
3048 memmove(bp
, in
->gr_passwd
, hsize
);
3052 out
->gr_gid
= in
->gr_gid
;
3055 ap
= bp
+ ((len
+ 1) * sizeof(char *));
3057 if (in
->gr_mem
!= NULL
)
3059 out
->gr_mem
= (char **)bp
;
3060 for (i
= 0; i
< len
; i
++)
3062 addr
= (unsigned long)ap
;
3063 memmove(bp
, &addr
, sizeof(unsigned long));
3064 bp
+= sizeof(unsigned long);
3066 hsize
= strlen(in
->gr_mem
[i
]) + 1;
3067 memmove(ap
, in
->gr_mem
[i
], hsize
);
3072 memset(bp
, 0, sizeof(unsigned long));
3079 getgrnam_r(const char *name
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
3086 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
3089 if (result
!= NULL
) *result
= NULL
;
3091 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3093 item
= si_group_byname(si_search(), name
);
3094 if (item
== NULL
) return 0;
3096 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
3098 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
3099 si_item_release(item
);
3101 if (status
!= 0) return ERANGE
;
3108 getgrgid_r(gid_t gid
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
3115 fprintf(stderr
, "-> %s %d\n", __func__
, gid
);
3118 if (result
!= NULL
) *result
= NULL
;
3120 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3122 item
= si_group_bygid(si_search(), gid
);
3123 if (item
== NULL
) return 0;
3125 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
3127 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
3128 si_item_release(item
);
3130 if (status
!= 0) return ERANGE
;
3137 getgruuid_r(uuid_t uuid
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
3144 uuid_string_t uuidstr
;
3145 uuid_unparse_upper(uuid
, uuidstr
);
3146 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
3149 if (result
!= NULL
) *result
= NULL
;
3151 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3153 item
= si_group_byuuid(si_search(), uuid
);
3154 if (item
== NULL
) return 0;
3156 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
3158 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
3159 si_item_release(item
);
3161 if (status
!= 0) return ERANGE
;
3168 getpwnam_r(const char *name
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3175 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
3178 if (result
!= NULL
) *result
= NULL
;
3180 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3182 item
= si_user_byname(si_search(), name
);
3183 if (item
== NULL
) return 0;
3185 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3187 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3188 si_item_release(item
);
3190 if (status
!= 0) return ERANGE
;
3197 getpwuid_r(uid_t uid
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3199 si_item_t
*item
= NULL
;
3204 fprintf(stderr
, "-> %s %d\n", __func__
, uid
);
3207 if (result
!= NULL
) *result
= NULL
;
3209 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3211 // Search the file module first for all system uids
3212 // (ie, uid value < 500) since they should all be
3213 // in the /etc/*passwd file.
3214 if (uid
< SYSTEM_UID_LIMIT
)
3215 item
= si_user_byuid(si_search_file(), uid
);
3218 item
= si_user_byuid(si_search(), uid
);
3219 if (item
== NULL
) return 0;
3221 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3223 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3224 si_item_release(item
);
3226 if (status
!= 0) return ERANGE
;
3233 getpwuuid_r(uuid_t uuid
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3240 uuid_string_t uuidstr
;
3241 uuid_unparse_upper(uuid
, uuidstr
);
3242 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
3245 if (result
!= NULL
) *result
= NULL
;
3247 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3249 item
= si_user_byuuid(si_search(), uuid
);
3250 if (item
== NULL
) return 0;
3252 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3254 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3255 si_item_release(item
);
3257 if (status
!= 0) return ERANGE
;
3266 user_from_uid(uid_t uid
, int nouser
)
3269 static char buf
[16];
3272 if (pw
!= NULL
) return pw
->pw_name
;
3274 if (nouser
) return NULL
;
3276 snprintf(buf
, sizeof(buf
), "%u", uid
);
3281 group_from_gid(gid_t gid
, int nogroup
)
3284 static char buf
[16];
3287 if (gr
!= NULL
) return gr
->gr_name
;
3289 if (nogroup
) return NULL
;
3291 snprintf(buf
, sizeof(buf
), "%u", gid
);
3295 /* no longer supported */
3298 prdb_getbyname(const char *name
)
3301 fprintf(stderr
, "~~ %s\n", __func__
);
3310 fprintf(stderr
, "~~ %s\n", __func__
);
3316 prdb_set(const char *name
)
3319 fprintf(stderr
, "~~ %s\n", __func__
);
3327 fprintf(stderr
, "~~ %s\n", __func__
);
3331 struct bootparamsent
*
3332 bootparams_getbyname(const char *name
)
3335 fprintf(stderr
, "~~ %s\n", __func__
);
3340 struct bootparamsent
*
3341 bootparams_getent(void)
3344 fprintf(stderr
, "~~ %s\n", __func__
);
3350 bootparams_setent(void)
3353 fprintf(stderr
, "~~ %s\n", __func__
);
3358 bootparams_endent(void)
3361 fprintf(stderr
, "~~ %s\n", __func__
);
3366 bootp_getbyether(struct ether_addr
*enaddr
, char **name
,struct in_addr
*ipaddr
, char **bootfile
)
3369 fprintf(stderr
, "~~ %s\n", __func__
);
3375 bootp_getbyip(struct ether_addr
*enaddr
, char **name
, struct in_addr
*ipaddr
, char **bootfile
)
3378 fprintf(stderr
, "~~ %s\n", __func__
);