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>
46 #define IPPROTO_UNSPEC 0
47 #define IPV6_ADDR_LEN 16
48 #define IPV4_ADDR_LEN 4
51 extern int __initgroups(u_int gidsetsize
, gid_t
*gidset
, int gmuid
);
53 /* SPI from long ago */
56 extern struct addrinfo
*si_list_to_addrinfo(si_list_t
*list
);
57 extern int getnameinfo_link(const struct sockaddr
*sa
, socklen_t salen
, char *host
, size_t hostlen
, char *serv
, size_t servlen
, int flags
);
58 __private_extern__
void search_set_flags(si_mod_t
*si
, const char *name
, uint32_t flag
);
61 * Impedence matching for async calls.
63 * This layer holds on to the caller's callback and context in this
64 * structure, which gets passed to the si_module async routines along
65 * with a callbac in this layer. When this layer gets a callback,
66 * it can save the item or list in thread-specific memory and then
67 * invoke the caller's callback with the appropriate data type.
81 static si_mod_t
*search
= NULL
;
83 if (search
== NULL
) search
= si_module_with_name("search");
89 si_search_module_set_flags(const char *name
, uint32_t flag
)
91 search_set_flags(si_search(), name
, flag
);
95 si_libinfo_general_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
103 struct grouplist_s
*l
;
112 if (ctx
== NULL
) return;
114 sictx
= (si_context_t
*)ctx
;
116 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
119 si_item_release(item
);
123 if (sictx
->key_offset
>= 0)
125 LI_set_thread_item(sictx
->cat
+ sictx
->key_offset
, item
);
129 if (item
!= NULL
) res
.x
= (char*)((uintptr_t)item
+ sizeof(si_item_t
));
135 ((si_user_async_callback
)(sictx
->orig_callback
))(res
.u
, sictx
->orig_context
);
140 ((si_group_async_callback
)(sictx
->orig_callback
))(res
.g
, sictx
->orig_context
);
143 case CATEGORY_GROUPLIST
:
145 ((si_grouplist_async_callback
)(sictx
->orig_callback
))(res
.l
, sictx
->orig_context
);
148 case CATEGORY_HOST_IPV4
:
149 case CATEGORY_HOST_IPV6
:
151 ((si_host_async_callback
)(sictx
->orig_callback
))(res
.h
, sictx
->orig_context
);
154 case CATEGORY_NETWORK
:
156 ((si_network_async_callback
)(sictx
->orig_callback
))(res
.n
, sictx
->orig_context
);
159 case CATEGORY_SERVICE
:
161 ((si_service_async_callback
)(sictx
->orig_callback
))(res
.s
, sictx
->orig_context
);
164 case CATEGORY_PROTOCOL
:
166 ((si_protocol_async_callback
)(sictx
->orig_callback
))(res
.p
, sictx
->orig_context
);
171 ((si_rpc_async_callback
)(sictx
->orig_callback
))(res
.r
, sictx
->orig_context
);
176 ((si_fs_async_callback
)(sictx
->orig_callback
))(res
.f
, sictx
->orig_context
);
187 getpwnam(const char *name
)
192 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
);
241 item
= si_user_byuid(si_search(), uid
);
242 LI_set_thread_item(CATEGORY_USER
+ 200, item
);
244 if (item
== NULL
) return NULL
;
245 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
249 getpwuid_async_call(uid_t uid
, si_user_async_callback callback
, void *context
)
254 fprintf(stderr
, ">> %s %d\n", __func__
, uid
);
257 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
258 if (sictx
== NULL
) return MACH_PORT_NULL
;
260 sictx
->orig_callback
= callback
;
261 sictx
->orig_context
= context
;
262 sictx
->cat
= CATEGORY_USER
;
263 sictx
->key_offset
= 200;
265 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
);
269 getpwuid_async_handle_reply(mach_msg_header_t
*msg
)
272 fprintf(stderr
, "<< %s\n", __func__
);
275 si_async_handle_reply(msg
);
279 getpwuuid(uuid_t uuid
)
284 uuid_string_t uuidstr
;
285 uuid_unparse_upper(uuid
, uuidstr
);
286 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
289 item
= si_user_byuuid(si_search(), uuid
);
290 LI_set_thread_item(CATEGORY_USER
+ 300, item
);
292 if (item
== NULL
) return NULL
;
293 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
300 fprintf(stderr
, "-- %s\n", __func__
);
303 LI_set_thread_list(CATEGORY_USER
, NULL
);
313 fprintf(stderr
, "-> %s\n", __func__
);
316 list
= LI_get_thread_list(CATEGORY_USER
);
319 list
= si_user_all(si_search());
320 LI_set_thread_list(CATEGORY_USER
, list
);
323 item
= si_list_next(list
);
324 if (item
== NULL
) return NULL
;
326 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
333 fprintf(stderr
, "-- %s\n", __func__
);
336 LI_set_thread_list(CATEGORY_USER
, NULL
);
340 setpassent(int ignored
)
345 fprintf(stderr
, "-> %s\n", __func__
);
348 list
= LI_get_thread_list(CATEGORY_USER
);
351 if (list
== NULL
) return 0;
358 getgrnam(const char *name
)
363 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
366 item
= si_group_byname(si_search(), name
);
367 LI_set_thread_item(CATEGORY_GROUP
+ 100, item
);
369 if (item
== NULL
) return NULL
;
370 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
374 getgrnam_async_call(const char *name
, si_group_async_callback callback
, void *context
)
379 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
382 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
383 if (sictx
== NULL
) return MACH_PORT_NULL
;
385 sictx
->orig_callback
= callback
;
386 sictx
->orig_context
= context
;
387 sictx
->cat
= CATEGORY_GROUP
;
388 sictx
->key_offset
= 100;
390 return si_async_call(si_search(), SI_CALL_GROUP_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
394 getgrnam_async_handle_reply(mach_msg_header_t
*msg
)
397 fprintf(stderr
, "<< %s\n", __func__
);
400 si_async_handle_reply(msg
);
409 fprintf(stderr
, "-> %s %d\n", __func__
, gid
);
412 item
= si_group_bygid(si_search(), gid
);
413 LI_set_thread_item(CATEGORY_GROUP
+ 200, item
);
415 if (item
== NULL
) return NULL
;
416 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
420 getgrgid_async_call(gid_t gid
, si_group_async_callback callback
, void *context
)
425 fprintf(stderr
, ">> %s %d\n", __func__
, gid
);
428 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
429 if (sictx
== NULL
) return MACH_PORT_NULL
;
431 sictx
->orig_callback
= callback
;
432 sictx
->orig_context
= context
;
433 sictx
->cat
= CATEGORY_GROUP
;
434 sictx
->key_offset
= 200;
436 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
);
440 getgruid_async_handle_reply(mach_msg_header_t
*msg
)
443 fprintf(stderr
, "<< %s\n", __func__
);
446 si_async_handle_reply(msg
);
450 getgruuid(uuid_t uuid
)
455 uuid_string_t uuidstr
;
456 uuid_unparse_upper(uuid
, uuidstr
);
457 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
460 item
= si_group_byuuid(si_search(), uuid
);
461 LI_set_thread_item(CATEGORY_GROUP
+ 300, item
);
463 if (item
== NULL
) return NULL
;
464 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
471 fprintf(stderr
, "-- %s\n", __func__
);
474 LI_set_thread_list(CATEGORY_GROUP
, NULL
);
484 fprintf(stderr
, "-> %s\n", __func__
);
487 list
= LI_get_thread_list(CATEGORY_GROUP
);
490 list
= si_group_all(si_search());
491 LI_set_thread_list(CATEGORY_GROUP
, list
);
494 item
= si_list_next(list
);
495 if (item
== NULL
) return NULL
;
497 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
504 fprintf(stderr
, "-- %s\n", __func__
);
507 LI_set_thread_list(CATEGORY_GROUP
, NULL
);
511 setgroupent(int ignored
)
516 fprintf(stderr
, "-> %s\n", __func__
);
519 list
= LI_get_thread_list(CATEGORY_GROUP
);
522 if (list
== NULL
) return 0;
528 innetgr(const char *group
, const char *host
, const char *user
, const char *domain
)
532 fprintf(stderr
, "-> %s %s %s %s %s\n", __func__
, group
, host
, user
, domain
);
535 res
= si_in_netgroup(si_search(), group
, host
, user
, domain
);
538 fprintf(stderr
, "<- %s %d\n", __func__
, res
);
544 /* N.B. there is no async innetgr */
547 * setnetgrent is really more like a getXXXbyname routine than a
548 * setXXXent routine, since we are looking up a netgroup by name.
551 setnetgrent(const char *name
)
556 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
559 list
= si_netgroup_byname(si_search(), name
);
560 LI_set_thread_list(CATEGORY_NETGROUP
, list
);
563 /* N.B. there is no async getnetgrent */
566 getnetgrent(char **host
, char **user
, char **domain
)
570 struct netgrent_s
*ng
;
573 fprintf(stderr
, "-> %s\n", __func__
);
576 list
= LI_get_thread_list(CATEGORY_NETGROUP
);
577 item
= si_list_next(list
);
578 if (item
== NULL
) return 0;
580 ng
= (struct netgrent_s
*)((uintptr_t)item
+ sizeof(si_item_t
));
584 *domain
= ng
->ng_domain
;
593 fprintf(stderr
, "-- %s\n", __func__
);
596 LI_set_thread_list(CATEGORY_NETGROUP
, NULL
);
601 _check_groups(const char *function
, int32_t ngroups
)
603 static dispatch_once_t once
;
605 if (ngroups
> 0 && ngroups
< NGROUPS_MAX
) {
609 /* only log once per process */
610 dispatch_once(&once
, ^(void) {
611 const char *proc_name
= getprogname();
612 if (strcmp(proc_name
, "id") != 0 && strcmp(proc_name
, "smbd") != 0 && strcmp(proc_name
, "rpcsvchost") != 0) {
613 aslmsg msg
= asl_new(ASL_TYPE_MSG
);
616 snprintf(buffer
, sizeof(buffer
), "%d", (ngroups
== 0 ? INT_MAX
: ngroups
));
617 asl_set(msg
, "com.apple.message.value", buffer
);
619 asl_set(msg
, "com.apple.message.domain", "com.apple.system.libinfo");
620 asl_set(msg
, "com.apple.message.result", "noop");
621 asl_set(msg
, "com.apple.message.signature", function
);
623 asl_log(NULL
, msg
, ASL_LEVEL_NOTICE
, "%s called triggering group enumeration", function
);
634 getgrouplist_internal(const char *name
, int basegid
, gid_t
*groups
, uint32_t *ngroups
)
636 int i
, j
, x
, g
, add
, max
;
641 * On input, ngroups specifies the size of the groups array.
642 * On output, it is set to the number of groups that are being returned.
643 * Returns -1 if the size is too small to fit all the groups that were found.
647 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
650 if (name
== NULL
) return 0;
651 if (groups
== NULL
) return 0;
652 if (ngroups
== NULL
) return 0;
656 if (max
<= 0) return 0;
661 item
= si_grouplist(si_search(), name
, max
);
662 LI_set_thread_item(CATEGORY_GROUPLIST
, item
);
663 if (item
== NULL
) return 0;
665 gl
= (si_grouplist_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
669 for (i
= 0; i
< gl
->gl_count
; i
++)
673 for (j
= 0; j
< x
; j
++) {
674 if (groups
[j
] == g
) {
679 if (add
== 0) continue;
681 if (x
>= max
) return -1;
691 getgrouplist(const char *name
, int basegid
, int *groups
, int *ngroups
)
694 _check_groups("getgrouplist", *ngroups
);
697 return getgrouplist_internal(name
, basegid
, (gid_t
*)groups
, (uint32_t *)ngroups
);
701 merge_gid(gid_t
*list
, gid_t g
, int32_t *count
)
707 for (i
= 0; i
< cnt
; i
++) {
708 if (list
[i
] == g
) return;
716 _getgrouplist_2_internal(const char *name
, gid_t basegid
, gid_t
**groups
)
723 item
= si_grouplist(si_search(), name
, INT_MAX
);
724 LI_set_thread_item(CATEGORY_GROUPLIST
, item
);
725 if (item
== NULL
) return -1;
727 gl
= (si_grouplist_t
*) ((uintptr_t) item
+ sizeof(si_item_t
));
730 * we can allocate enough up-front, we'll only use what we need
731 * we add one to the count that was found in case the basegid is not there
733 gids
= calloc(gl
->gl_count
+ 1, sizeof(gid_t
));
734 if (gids
== NULL
) return -1;
737 merge_gid(gids
, basegid
, &count
);
738 if (gl
->gl_gid
!= NULL
) {
739 for (i
= 0; i
< gl
->gl_count
; i
++) {
740 merge_gid(gids
, gl
->gl_gid
[i
], &count
);
750 getgrouplist_2(const char *name
, gid_t basegid
, gid_t
**groups
)
753 * Passes back a gid_t list containing all the users groups (and basegid).
754 * Caller must free the list.
755 * Returns the number of gids in the list or -1 on failure.
759 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
762 if (name
== NULL
) return 0;
763 if (groups
== NULL
) return 0;
766 _check_groups("getgrouplist_2", INT_MAX
);
769 return _getgrouplist_2_internal(name
, basegid
, groups
);
773 getgroupcount(const char *name
, gid_t basegid
)
779 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
783 _check_groups("getgroupcount", INT_MAX
);
787 count
= _getgrouplist_2_internal(name
, basegid
, &groups
);
788 if (groups
!= NULL
) free(groups
);
793 /* XXX to do: async getgrouplist_2 */
796 initgroups(const char *name
, int basegid
)
800 gid_t groups
[NGROUPS
];
808 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
811 /* KAUTH_UID_NONE tells the kernel not to fetch supplementary groups from DirectoryService */
812 uid
= KAUTH_UID_NONE
;
815 /* get the UID for this user */
816 item
= si_user_byname(si_search(), name
);
819 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
821 si_item_release(item
);
829 * A failure either means that user belongs to more than NGROUPS groups
830 * or no groups at all.
833 (void) getgrouplist_internal(name
, basegid
, groups
, &ngroups
);
835 status
= __initgroups(ngroups
, groups
, uid
);
836 if (status
< 0) return -1;
844 alias_getbyname(const char *name
)
849 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
852 item
= si_alias_byname(si_search(), name
);
853 LI_set_thread_item(CATEGORY_ALIAS
+ 100, item
);
854 if (item
== NULL
) return NULL
;
856 return (struct aliasent
*)((uintptr_t)item
+ sizeof(si_item_t
));
860 alias_getbyname_async_call(const char *name
, si_alias_async_callback callback
, void *context
)
865 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
868 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
869 if (sictx
== NULL
) return MACH_PORT_NULL
;
871 sictx
->orig_callback
= callback
;
872 sictx
->orig_context
= context
;
873 sictx
->cat
= CATEGORY_ALIAS
;
874 sictx
->key_offset
= 100;
876 return si_async_call(si_search(), SI_CALL_ALIAS_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
880 alias_getbyname_async_handle_reply(mach_msg_header_t
*msg
)
883 fprintf(stderr
, "<< %s\n", __func__
);
886 si_async_handle_reply(msg
);
893 fprintf(stderr
, "-> %s\n", __func__
);
896 LI_set_thread_list(CATEGORY_ALIAS
, NULL
);
906 fprintf(stderr
, "-> %s\n", __func__
);
909 list
= LI_get_thread_list(CATEGORY_ALIAS
);
912 list
= si_alias_all(si_search());
913 LI_set_thread_list(CATEGORY_ALIAS
, list
);
916 item
= si_list_next(list
);
917 if (item
== NULL
) return NULL
;
919 return (struct aliasent
*)((uintptr_t)item
+ sizeof(si_item_t
));
926 fprintf(stderr
, "-- %s\n", __func__
);
929 LI_set_thread_list(CATEGORY_ALIAS
, NULL
);
935 freehostent(struct hostent
*h
)
937 if (h
== NULL
) return;
939 si_item_t
*item
= (si_item_t
*)((uintptr_t)h
- sizeof(si_item_t
));
940 si_item_release(item
);
944 gethostbynameerrno(const char *name
, int *err
)
948 struct in_addr addr4
;
951 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
954 memset(&addr4
, 0, sizeof(struct in_addr
));
955 status
= SI_STATUS_NO_ERROR
;
958 if (inet_aton(name
, &addr4
) == 1) item
= si_ipnode_byname(si_search(), name
, AF_INET
, 0, NULL
, &status
);
959 else item
= si_host_byname(si_search(), name
, AF_INET
, NULL
, &status
);
961 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
962 if (err
!= NULL
) *err
= status
;
964 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
965 if (item
== NULL
) return NULL
;
967 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
971 gethostbyname(const char *name
)
975 struct in_addr addr4
;
978 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
981 memset(&addr4
, 0, sizeof(struct in_addr
));
982 status
= SI_STATUS_NO_ERROR
;
985 if (inet_aton(name
, &addr4
) == 1) item
= si_ipnode_byname(si_search(), name
, AF_INET
, 0, NULL
, &status
);
986 else item
= si_host_byname(si_search(), name
, AF_INET
, NULL
, &status
);
988 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
991 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
992 if (item
== NULL
) return NULL
;
994 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
998 gethostbyname_async_call(const char *name
, si_host_async_callback callback
, void *context
)
1000 si_context_t
*sictx
;
1003 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1006 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1007 if (sictx
== NULL
) return MACH_PORT_NULL
;
1009 sictx
->orig_callback
= callback
;
1010 sictx
->orig_context
= context
;
1011 sictx
->cat
= CATEGORY_HOST
;
1012 sictx
->key_offset
= 100;
1014 return si_async_call(si_search(), SI_CALL_HOST_BYNAME
, name
, NULL
, NULL
, AF_INET
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1018 gethostbyname_async_start(const char *name
, si_host_async_callback callback
, void *context
)
1020 return gethostbyname_async_call(name
, callback
, context
);
1024 gethostbyname_async_cancel(mach_port_t p
)
1027 fprintf(stderr
, "-- %s\n", __func__
);
1035 gethostbyname_async_handle_reply(void *param
)
1037 mach_msg_header_t
*msg
;
1040 fprintf(stderr
, "<< %s\n", __func__
);
1043 msg
= (mach_msg_header_t
*)param
;
1044 si_async_handle_reply(msg
);
1049 gethostbyname_async_handleReply(void *param
)
1051 mach_msg_header_t
*msg
;
1054 fprintf(stderr
, "<< %s\n", __func__
);
1057 msg
= (mach_msg_header_t
*)param
;
1058 si_async_handle_reply(msg
);
1062 gethostbyname2(const char *name
, int af
)
1066 struct in_addr addr4
;
1067 struct in6_addr addr6
;
1068 si_mod_t
*search
= si_search();
1071 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, af
);
1074 memset(&addr4
, 0, sizeof(struct in_addr
));
1075 memset(&addr6
, 0, sizeof(struct in6_addr
));
1076 status
= SI_STATUS_NO_ERROR
;
1079 if (((af
== AF_INET
) && (inet_aton(name
, &addr4
) == 1)) || ((af
== AF_INET6
) && (inet_pton(af
, name
, &addr6
) == 1)))
1081 item
= si_ipnode_byname(search
, name
, (uint32_t)af
, 0, NULL
, &status
);
1085 item
= si_host_byname(search
, name
, (uint32_t)af
, NULL
, &status
);
1088 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1091 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
1092 if (item
== NULL
) return NULL
;
1094 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1098 gethostbyname2_async_call(const char *name
, int af
, si_group_async_callback callback
, void *context
)
1100 si_context_t
*sictx
;
1103 fprintf(stderr
, ">> %s %s %d\n", __func__
, name
, af
);
1106 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1107 if (sictx
== NULL
) return MACH_PORT_NULL
;
1109 sictx
->orig_callback
= callback
;
1110 sictx
->orig_context
= context
;
1111 sictx
->cat
= CATEGORY_HOST
;
1112 sictx
->key_offset
= 100;
1114 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
);
1118 gethostbyname2_async_cancel(mach_port_t p
)
1121 fprintf(stderr
, "-- %s\n", __func__
);
1128 gethostbyname2_async_handle_reply(mach_msg_header_t
*msg
)
1131 fprintf(stderr
, "<< %s\n", __func__
);
1134 si_async_handle_reply(msg
);
1138 gethostbyaddr(const void *addr
, socklen_t len
, int type
)
1144 fprintf(stderr
, "-> %s %s\n", __func__
, (type
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)addr
) : "-IPv6-");
1147 status
= SI_STATUS_NO_ERROR
;
1149 item
= si_host_byaddr(si_search(), addr
, (uint32_t)type
, NULL
, &status
);
1150 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1153 LI_set_thread_item(CATEGORY_HOST
+ 200, item
);
1154 if (item
== NULL
) return NULL
;
1156 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1160 gethostbyaddr_async_call(const void *addr
, socklen_t len
, int type
, si_host_async_callback callback
, void *context
)
1162 si_context_t
*sictx
;
1166 fprintf(stderr
, ">> %s %s\n", __func__
, (type
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)addr
) : "-IPv6-");
1169 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1170 if (sictx
== NULL
) return MACH_PORT_NULL
;
1172 sictx
->orig_callback
= callback
;
1173 sictx
->orig_context
= context
;
1174 sictx
->cat
= CATEGORY_HOST
;
1175 sictx
->key_offset
= 200;
1177 /* addr is not a C string - pass length in num3 */
1179 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
);
1183 gethostbyaddr_async_start(const char *addr
, int len
, int family
, si_host_async_callback callback
, void *context
)
1185 socklen_t slen
= len
;
1187 return gethostbyaddr_async_call(addr
, slen
, family
, callback
, context
);
1191 gethostbyaddr_async_cancel(mach_port_t p
)
1194 fprintf(stderr
, "-- %s\n", __func__
);
1202 gethostbyaddr_async_handle_reply(void *param
)
1205 mach_msg_header_t
*msg
;
1208 fprintf(stderr
, "<< %s\n", __func__
);
1211 msg
= (mach_msg_header_t
*)param
;
1212 si_async_handle_reply(msg
);
1217 gethostbyaddr_async_handleReply(void *param
)
1219 mach_msg_header_t
*msg
;
1222 fprintf(stderr
, "<< %s\n", __func__
);
1225 msg
= (mach_msg_header_t
*)param
;
1226 si_async_handle_reply(msg
);
1230 getipnodebyname(const char *name
, int family
, int flags
, int *err
)
1236 fprintf(stderr
, "-> %s %s %d 0x%08x\n", __func__
, name
, family
, flags
);
1239 status
= SI_STATUS_NO_ERROR
;
1241 item
= si_ipnode_byname(si_search(), name
, family
, flags
, NULL
, &status
);
1242 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1243 if (err
!= NULL
) *err
= status
;
1245 if (item
== NULL
) return NULL
;
1247 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1252 getipnodebyname_async_call(const char *name
, int family
, int flags
, int *err
, si_host_async_callback callback
, void *context
)
1254 si_context_t
*sictx
;
1257 fprintf(stderr
, ">> %s %s %d 0x%08x\n", __func__
, name
, family
, flags
);
1260 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1261 if (sictx
== NULL
) return MACH_PORT_NULL
;
1263 sictx
->orig_callback
= callback
;
1264 sictx
->orig_context
= context
;
1265 sictx
->cat
= CATEGORY_HOST
;
1266 sictx
->key_offset
= -1;
1268 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
);
1272 getipnodebyname_async_start(const char *name
, int family
, int flags
, int *err
, si_host_async_callback callback
, void *context
)
1274 return getipnodebyname_async_call(name
, family
, flags
, err
, callback
, context
);
1278 getipnodebyname_async_cancel(mach_port_t p
)
1281 fprintf(stderr
, "-- %s\n", __func__
);
1288 getipnodebyname_async_handle_reply(mach_msg_header_t
*msg
)
1291 fprintf(stderr
, "<< %s\n", __func__
);
1294 si_async_handle_reply(msg
);
1298 getipnodebyname_async_handleReply(mach_msg_header_t
*msg
)
1301 fprintf(stderr
, "<< %s\n", __func__
);
1304 si_async_handle_reply(msg
);
1309 is_a4_mapped(const char *s
)
1314 if (s
== NULL
) return 0;
1316 for (i
= 0; i
< 10; i
++)
1319 if (c
!= 0x0) return 0;
1322 for (i
= 10; i
< 12; i
++)
1325 if (c
!= 0xff) return 0;
1332 is_a4_compat(const char *s
)
1337 if (s
== NULL
) return 0;
1339 for (i
= 0; i
< 12; i
++)
1342 if (c
!= 0x0) return 0;
1345 /* Check for :: and ::1 */
1346 for (i
= 13; i
< 15; i
++)
1348 /* anything non-zero in these 3 bytes means it's a V4 address */
1350 if (c
!= 0x0) return 1;
1353 /* Leading 15 bytes are all zero */
1355 if (c
== 0x0) return 0;
1356 if (c
== 0x1) return 0;
1362 getipnodebyaddr(const void *src
, size_t len
, int family
, int *err
)
1367 fprintf(stderr
, "-> %s %s\n", __func__
, (family
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)src
) : "-IPv6-");
1370 if ((family
== AF_INET6
) && (len
== IPV6_ADDR_LEN
) && (is_a4_mapped((const char *)src
) || is_a4_compat((const char *)src
)))
1377 item
= si_host_byaddr(si_search(), src
, family
, NULL
, (uint32_t *)err
);
1378 if (item
== NULL
) return NULL
;
1380 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1385 si_libinfo_ipnode_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
1387 si_context_t
*sictx
;
1390 if (ctx
== NULL
) return;
1392 sictx
= (si_context_t
*)ctx
;
1394 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
1397 si_item_release(item
);
1401 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1405 ((si_ipnode_async_callback
)(sictx
->orig_callback
))(NULL
, status
, sictx
->orig_context
);
1409 h
= (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1410 ((si_ipnode_async_callback
)(sictx
->orig_callback
))(h
, status
, sictx
->orig_context
);
1416 getipnodebyaddr_async_call(const void *src
, socklen_t len
, int family
, int *err
, si_ipnode_async_callback callback
, void *context
)
1418 si_context_t
*sictx
;
1422 fprintf(stderr
, ">> %s %s\n", __func__
, (family
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)src
) : "-IPv6-");
1425 if ((family
== AF_INET6
) && (len
== IPV6_ADDR_LEN
) && (is_a4_mapped((const char *)src
) || is_a4_compat((const char *)src
)))
1432 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1433 if (sictx
== NULL
) return MACH_PORT_NULL
;
1435 sictx
->orig_callback
= callback
;
1436 sictx
->orig_context
= context
;
1437 sictx
->cat
= CATEGORY_HOST
;
1438 sictx
->key_offset
= -1;
1440 /* src is not a C string - pass length in num3 */
1442 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
);
1446 getipnodebyaddr_async_start(const void *addr
, size_t len
, int family
, int *error
, si_ipnode_async_callback callback
, void *context
)
1448 socklen_t slen
= len
;
1450 return getipnodebyaddr_async_call(addr
, slen
, family
, error
, callback
, context
);
1454 getipnodebyaddr_async_cancel(mach_port_t p
)
1457 fprintf(stderr
, "-- %s\n", __func__
);
1464 getipnodebyaddr_async_handle_reply(mach_msg_header_t
*msg
)
1467 fprintf(stderr
, "<< %s\n", __func__
);
1470 si_async_handle_reply(msg
);
1474 getipnodebyaddr_async_handleReply(mach_msg_header_t
*msg
)
1477 fprintf(stderr
, "<< %s\n", __func__
);
1480 si_async_handle_reply(msg
);
1485 sethostent(int ignored
)
1488 fprintf(stderr
, "-- %s\n", __func__
);
1491 LI_set_thread_list(CATEGORY_HOST
, NULL
);
1501 fprintf(stderr
, "-> %s\n", __func__
);
1504 list
= LI_get_thread_list(CATEGORY_HOST
);
1507 list
= si_host_all(si_search());
1508 LI_set_thread_list(CATEGORY_HOST
, list
);
1511 item
= si_list_next(list
);
1512 if (item
== NULL
) return NULL
;
1514 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1521 fprintf(stderr
, "-- %s\n", __func__
);
1524 LI_set_thread_list(CATEGORY_HOST
, NULL
);
1530 ether_hostton(const char *name
, struct ether_addr
*e
)
1538 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1541 if (name
== NULL
) return -1;
1542 if (e
== NULL
) return -1;
1544 item
= si_mac_byname(si_search(), name
);
1545 LI_set_thread_item(CATEGORY_MAC
+ 100, item
);
1546 if (item
== NULL
) return -1;
1548 mac
= (si_mac_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
1550 i
= sscanf(mac
->mac
, " %x:%x:%x:%x:%x:%x", &t
[0], &t
[1], &t
[2], &t
[3], &t
[4], &t
[5]);
1551 if (i
!= 6) return -1;
1553 for (i
= 0; i
< 6; i
++) e
->ether_addr_octet
[i
] = t
[i
];
1557 /* XXX to do? async ether_hostton */
1560 ether_ntohost(char *name
, const struct ether_addr
*e
)
1567 if (name
== NULL
) return -1;
1568 if (e
== NULL
) return -1;
1570 for (i
= 0; i
< 6; i
++) x
[i
] = e
->ether_addr_octet
[i
];
1571 snprintf(str
, sizeof(str
), "%x:%x:%x:%x:%x:%x", x
[0], x
[1], x
[2], x
[3], x
[4], x
[5]);
1574 fprintf(stderr
, "-> %s %s\n", __func__
, str
);
1577 item
= si_mac_bymac(si_search(), str
);
1578 LI_set_thread_item(CATEGORY_MAC
+ 200, item
);
1579 if (item
== NULL
) return -1;
1581 mac
= (si_mac_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
1583 memcpy(name
, mac
->host
, strlen(mac
->host
) + 1);
1587 /* XXX to do? async ether_ntohost */
1592 getnetbyname(const char *name
)
1597 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1600 item
= si_network_byname(si_search(), name
);
1601 LI_set_thread_item(CATEGORY_NETWORK
+ 100, item
);
1602 if (item
== NULL
) return NULL
;
1604 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1608 getnetbyname_async_call(const char *name
, si_network_async_callback callback
, void *context
)
1610 si_context_t
*sictx
;
1613 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1616 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1617 if (sictx
== NULL
) return MACH_PORT_NULL
;
1619 sictx
->orig_callback
= callback
;
1620 sictx
->orig_context
= context
;
1621 sictx
->cat
= CATEGORY_NETWORK
;
1622 sictx
->key_offset
= 100;
1624 return si_async_call(si_search(), SI_CALL_NETWORK_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1628 getnetbyname_async_handle_reply(mach_msg_header_t
*msg
)
1631 fprintf(stderr
, "<< %s\n", __func__
);
1634 si_async_handle_reply(msg
);
1638 getnetbyaddr(uint32_t net
, int type
)
1643 fprintf(stderr
, "-> %s 0x%08x\n", __func__
, net
);
1646 if (type
!= AF_INET
) return NULL
;
1648 item
= si_network_byaddr(si_search(), net
);
1649 LI_set_thread_item(CATEGORY_NETWORK
+ 200, item
);
1650 if (item
== NULL
) return NULL
;
1652 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1656 getnetbyaddr_async_call(uint32_t net
, int type
, si_group_async_callback callback
, void *context
)
1658 si_context_t
*sictx
;
1661 fprintf(stderr
, ">> %s 0x%08x\n", __func__
, net
);
1664 if (type
!= AF_INET
) return MACH_PORT_NULL
;
1666 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1667 if (sictx
== NULL
) return MACH_PORT_NULL
;
1669 sictx
->orig_callback
= callback
;
1670 sictx
->orig_context
= context
;
1671 sictx
->cat
= CATEGORY_NETWORK
;
1672 sictx
->key_offset
= 200;
1674 return si_async_call(si_search(), SI_CALL_NETWORK_BYADDR
, NULL
, NULL
, NULL
, net
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1678 getnetbyaddr_async_handle_reply(mach_msg_header_t
*msg
)
1681 fprintf(stderr
, "<< %s\n", __func__
);
1684 si_async_handle_reply(msg
);
1688 setnetent(int ignored
)
1691 fprintf(stderr
, "-- %s\n", __func__
);
1694 LI_set_thread_list(CATEGORY_NETWORK
, NULL
);
1704 fprintf(stderr
, "-> %s\n", __func__
);
1707 list
= LI_get_thread_list(CATEGORY_NETWORK
);
1710 list
= si_network_all(si_search());
1711 LI_set_thread_list(CATEGORY_NETWORK
, list
);
1714 item
= si_list_next(list
);
1715 if (item
== NULL
) return NULL
;
1717 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1724 fprintf(stderr
, "-- %s\n", __func__
);
1727 LI_set_thread_list(CATEGORY_NETWORK
, NULL
);
1733 getservbyname(const char *name
, const char *proto
)
1738 fprintf(stderr
, "-> %s %s %s\n", __func__
, name
, proto
);
1741 item
= si_service_byname(si_search(), name
, proto
);
1742 LI_set_thread_item(CATEGORY_SERVICE
+ 100, item
);
1743 if (item
== NULL
) return NULL
;
1745 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1749 getservbyname_async_call(const char *name
, const char *proto
, si_service_async_callback callback
, void *context
)
1751 si_context_t
*sictx
;
1754 fprintf(stderr
, ">> %s %s %s\n", __func__
, name
, proto
);
1757 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1758 if (sictx
== NULL
) return MACH_PORT_NULL
;
1760 sictx
->orig_callback
= callback
;
1761 sictx
->orig_context
= context
;
1762 sictx
->cat
= CATEGORY_SERVICE
;
1763 sictx
->key_offset
= 100;
1765 return si_async_call(si_search(), SI_CALL_SERVICE_BYNAME
, name
, proto
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1769 getservbyname_async_handle_reply(mach_msg_header_t
*msg
)
1772 fprintf(stderr
, "<< %s\n", __func__
);
1775 si_async_handle_reply(msg
);
1779 getservbyport(int port
, const char *proto
)
1784 fprintf(stderr
, "-> %s %d %s\n", __func__
, ntohs((uint16_t)port
), proto
);
1787 item
= si_service_byport(si_search(), port
, proto
);
1788 LI_set_thread_item(CATEGORY_SERVICE
+ 200, item
);
1789 if (item
== NULL
) return NULL
;
1791 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1795 getservbyport_async_call(int port
, const char *proto
, si_group_async_callback callback
, void *context
)
1797 si_context_t
*sictx
;
1800 fprintf(stderr
, ">> %s %d %s\n", __func__
, port
, proto
);
1803 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1804 if (sictx
== NULL
) return MACH_PORT_NULL
;
1806 sictx
->orig_callback
= callback
;
1807 sictx
->orig_context
= context
;
1808 sictx
->cat
= CATEGORY_SERVICE
;
1809 sictx
->key_offset
= 200;
1811 return si_async_call(si_search(), SI_CALL_SERVICE_BYPORT
, NULL
, proto
, NULL
, port
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1815 getservbyport_async_handle_reply(mach_msg_header_t
*msg
)
1818 fprintf(stderr
, "<< %s\n", __func__
);
1821 si_async_handle_reply(msg
);
1825 setservent(int ignored
)
1828 fprintf(stderr
, "-- %s\n", __func__
);
1831 LI_set_thread_list(CATEGORY_SERVICE
, NULL
);
1841 fprintf(stderr
, "-> %s\n", __func__
);
1844 list
= LI_get_thread_list(CATEGORY_SERVICE
);
1847 list
= si_service_all(si_search());
1848 LI_set_thread_list(CATEGORY_SERVICE
, list
);
1851 item
= si_list_next(list
);
1852 if (item
== NULL
) return NULL
;
1854 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1861 fprintf(stderr
, "-- %s\n", __func__
);
1864 LI_set_thread_list(CATEGORY_SERVICE
, NULL
);
1870 getprotobyname(const char *name
)
1875 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1878 item
= si_protocol_byname(si_search(), name
);
1879 LI_set_thread_item(CATEGORY_PROTOCOL
+ 100, item
);
1880 if (item
== NULL
) return NULL
;
1882 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1886 getprotobyname_async_call(const char *name
, si_protocol_async_callback callback
, void *context
)
1888 si_context_t
*sictx
;
1891 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1894 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1895 if (sictx
== NULL
) return MACH_PORT_NULL
;
1897 sictx
->orig_callback
= callback
;
1898 sictx
->orig_context
= context
;
1899 sictx
->cat
= CATEGORY_PROTOCOL
;
1900 sictx
->key_offset
= 100;
1902 return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1906 getprotobyname_async_handle_reply(mach_msg_header_t
*msg
)
1909 fprintf(stderr
, "<< %s\n", __func__
);
1912 si_async_handle_reply(msg
);
1916 getprotobynumber(int number
)
1921 fprintf(stderr
, "-> %s %d\n", __func__
, number
);
1924 item
= si_protocol_bynumber(si_search(), number
);
1925 LI_set_thread_item(CATEGORY_PROTOCOL
+ 200, item
);
1926 if (item
== NULL
) return NULL
;
1928 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1932 getprotobynumber_async_call(int number
, si_group_async_callback callback
, void *context
)
1934 si_context_t
*sictx
;
1937 fprintf(stderr
, ">> %s %d\n", __func__
, number
);
1940 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1941 if (sictx
== NULL
) return MACH_PORT_NULL
;
1943 sictx
->orig_callback
= callback
;
1944 sictx
->orig_context
= context
;
1945 sictx
->cat
= CATEGORY_PROTOCOL
;
1946 sictx
->key_offset
= 200;
1948 return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNUMBER
, NULL
, NULL
, NULL
, number
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1952 getprotobynumber_async_handle_reply(mach_msg_header_t
*msg
)
1955 fprintf(stderr
, "<< %s\n", __func__
);
1958 si_async_handle_reply(msg
);
1962 setprotoent(int ignored
)
1965 fprintf(stderr
, "-- %s\n", __func__
);
1968 LI_set_thread_list(CATEGORY_PROTOCOL
, NULL
);
1978 fprintf(stderr
, "-> %s\n", __func__
);
1981 list
= LI_get_thread_list(CATEGORY_PROTOCOL
);
1984 list
= si_protocol_all(si_search());
1985 LI_set_thread_list(CATEGORY_PROTOCOL
, list
);
1988 item
= si_list_next(list
);
1989 if (item
== NULL
) return NULL
;
1991 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1998 fprintf(stderr
, "-- %s\n", __func__
);
2001 LI_set_thread_list(CATEGORY_PROTOCOL
, NULL
);
2007 getrpcbyname(const char *name
)
2012 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
2015 item
= si_rpc_byname(si_search(), name
);
2016 LI_set_thread_item(CATEGORY_RPC
+ 100, item
);
2017 if (item
== NULL
) return NULL
;
2019 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2023 getrpcbyname_async_call(const char *name
, si_rpc_async_callback callback
, void *context
)
2025 si_context_t
*sictx
;
2028 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
2031 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2032 if (sictx
== NULL
) return MACH_PORT_NULL
;
2034 sictx
->orig_callback
= callback
;
2035 sictx
->orig_context
= context
;
2036 sictx
->cat
= CATEGORY_RPC
;
2037 sictx
->key_offset
= 100;
2039 return si_async_call(si_search(), SI_CALL_RPC_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2043 getrpcbyname_async_handle_reply(mach_msg_header_t
*msg
)
2046 fprintf(stderr
, "<< %s\n", __func__
);
2049 si_async_handle_reply(msg
);
2065 fprintf(stderr
, "-> %s %ld\n", __func__
, (long int)number
);
2068 item
= si_rpc_bynumber(si_search(), number
);
2069 LI_set_thread_item(CATEGORY_RPC
+ 200, item
);
2070 if (item
== NULL
) return NULL
;
2072 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2076 getrpcbynumber_async_call(int number
, si_group_async_callback callback
, void *context
)
2078 si_context_t
*sictx
;
2081 fprintf(stderr
, ">> %s %d\n", __func__
, number
);
2084 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2085 if (sictx
== NULL
) return MACH_PORT_NULL
;
2087 sictx
->orig_callback
= callback
;
2088 sictx
->orig_context
= context
;
2089 sictx
->cat
= CATEGORY_RPC
;
2090 sictx
->key_offset
= 200;
2092 return si_async_call(si_search(), SI_CALL_RPC_BYNUMBER
, NULL
, NULL
, NULL
, number
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2096 getrpcbynumber_async_handle_reply(mach_msg_header_t
*msg
)
2099 fprintf(stderr
, "<< %s\n", __func__
);
2102 si_async_handle_reply(msg
);
2106 setrpcent(int ignored
)
2109 fprintf(stderr
, "-- %s\n", __func__
);
2112 LI_set_thread_list(CATEGORY_RPC
, NULL
);
2122 fprintf(stderr
, "-> %s\n", __func__
);
2125 list
= LI_get_thread_list(CATEGORY_RPC
);
2128 list
= si_rpc_all(si_search());
2129 LI_set_thread_list(CATEGORY_RPC
, list
);
2132 item
= si_list_next(list
);
2133 if (item
== NULL
) return NULL
;
2135 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2142 fprintf(stderr
, "-- %s\n", __func__
);
2145 LI_set_thread_list(CATEGORY_RPC
, NULL
);
2151 getfsspec(const char *spec
)
2156 fprintf(stderr
, "-> %s %s\n", __func__
, spec
);
2159 item
= si_fs_byspec(si_search(), spec
);
2160 LI_set_thread_item(CATEGORY_FS
+ 100, item
);
2161 if (item
== NULL
) return NULL
;
2163 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2167 getfsbyname(const char *name
)
2170 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
2173 return getfsspec(name
);
2177 getfsspec_async_call(const char *spec
, si_fs_async_callback callback
, void *context
)
2179 si_context_t
*sictx
;
2182 fprintf(stderr
, ">> %s %s\n", __func__
, spec
);
2185 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2186 if (sictx
== NULL
) return MACH_PORT_NULL
;
2188 sictx
->orig_callback
= callback
;
2189 sictx
->orig_context
= context
;
2190 sictx
->cat
= CATEGORY_FS
;
2191 sictx
->key_offset
= 100;
2193 return si_async_call(si_search(), SI_CALL_FS_BYSPEC
, spec
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2197 getfsspec_async_handle_reply(mach_msg_header_t
*msg
)
2200 fprintf(stderr
, "<< %s\n", __func__
);
2203 si_async_handle_reply(msg
);
2207 getfsfile(const char *file
)
2212 fprintf(stderr
, "-> %s %s\n", __func__
, file
);
2215 item
= si_fs_byfile(si_search(), file
);
2216 LI_set_thread_item(CATEGORY_FS
+ 200, item
);
2217 if (item
== NULL
) return NULL
;
2219 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2223 getfsfile_async_call(const char *file
, si_fs_async_callback callback
, void *context
)
2225 si_context_t
*sictx
;
2228 fprintf(stderr
, ">> %s %s\n", __func__
, file
);
2231 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2232 if (sictx
== NULL
) return MACH_PORT_NULL
;
2234 sictx
->orig_callback
= callback
;
2235 sictx
->orig_context
= context
;
2236 sictx
->cat
= CATEGORY_FS
;
2237 sictx
->key_offset
= 200;
2239 return si_async_call(si_search(), SI_CALL_FS_BYFILE
, file
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2243 getfsfile_async_handle_reply(mach_msg_header_t
*msg
)
2246 fprintf(stderr
, "<< %s\n", __func__
);
2249 si_async_handle_reply(msg
);
2256 fprintf(stderr
, "-> %s\n", __func__
);
2259 LI_set_thread_list(CATEGORY_FS
, NULL
);
2270 fprintf(stderr
, "-> %s\n", __func__
);
2273 list
= LI_get_thread_list(CATEGORY_FS
);
2276 list
= si_fs_all(si_search());
2277 LI_set_thread_list(CATEGORY_FS
, list
);
2280 item
= si_list_next(list
);
2281 if (item
== NULL
) return NULL
;
2283 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2290 fprintf(stderr
, "-- %s\n", __func__
);
2293 LI_set_thread_list(CATEGORY_FS
, NULL
);
2299 _getaddrinfo_internal(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, const char *interface
, struct addrinfo
**res
)
2302 uint32_t family
, socktype
, protocol
, flags
, status
;
2303 struct addrinfo
*ai
;
2306 socktype
= SOCK_UNSPEC
;
2307 protocol
= IPPROTO_UNSPEC
;
2309 status
= SI_STATUS_NO_ERROR
;
2311 if (res
== NULL
) return 0;
2316 family
= hints
->ai_family
;
2317 socktype
= hints
->ai_socktype
;
2318 protocol
= hints
->ai_protocol
;
2319 flags
= hints
->ai_flags
;
2323 fprintf(stderr
, "-> %s %s %s %u %u %u 0x%08x %s\n", __func__
, nodename
, servname
, family
, socktype
, protocol
, flags
, (interface
== NULL
) ? "" : interface
);
2326 list
= si_addrinfo(si_search(), nodename
, servname
, family
, socktype
, protocol
, flags
, interface
, &status
);
2327 if ((status
!= SI_STATUS_NO_ERROR
) || (list
== NULL
) || (list
->count
== 0))
2329 si_list_release(list
);
2331 if (status
== SI_STATUS_NO_ERROR
) return EAI_NONAME
;
2332 else if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2333 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2334 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2338 *res
= si_list_to_addrinfo(list
);
2339 si_list_release(list
);
2340 if (*res
== NULL
) status
= EAI_MEMORY
;
2342 /* don't return the canonical name unless asked */
2343 if ((flags
& AI_CANONNAME
) == 0)
2345 for (ai
= *res
; ai
!= NULL
; ai
= ai
->ai_next
)
2347 free(ai
->ai_canonname
);
2348 ai
->ai_canonname
= NULL
;
2356 getaddrinfo(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, struct addrinfo
**res
)
2358 return _getaddrinfo_internal(nodename
, servname
, hints
, NULL
, res
);
2364 socket_name(int sock
)
2366 static char str
[16];
2370 case SOCK_UNSPEC
: return "SOCK_UNSPEC";
2371 case SOCK_STREAM
: return "SOCK_STREAM";
2372 case SOCK_DGRAM
: return "SOCK_DGRAM";
2375 sprintf(str
, "%d", sock
);
2382 static char str
[16];
2386 case PF_UNSPEC
: return "PF_UNSPEC";
2387 case PF_INET
: return "PF_INET";
2388 case PF_INET6
: return "PF_INET6";
2391 sprintf(str
, "%d", pf
);
2396 protocol_name(int p
)
2398 static char str
[16];
2402 case IPPROTO_UNSPEC
: return "IPPROTO_UNSPEC";
2403 case IPPROTO_TCP
: return "IPPROTO_TCP";
2404 case IPPROTO_UDP
: return "IPPROTO_UDP";
2407 sprintf(str
, "%d", p
);
2412 _gai_inet_ntop(struct in6_addr a
)
2414 static char buf
[128];
2420 memset(buf
, 0, 128);
2422 p
= (char *)&a
.__u6_addr
.__u6_addr32
;
2423 for (i
= 0; i
< 8; i
++, x
+= 1)
2427 sprintf(t
, "%hx", x
);
2429 if (i
< 7) strcat(buf
, ":");
2436 fprint_addrinfo(FILE *f
, struct addrinfo
*a
)
2440 struct sockaddr_in
*s4
;
2441 struct sockaddr_in6
*s6
;
2443 if (a
== NULL
) return;
2445 if (a
->ai_flags
!= 0)
2447 fprintf(f
, "flags =");
2448 if (a
->ai_flags
& AI_PASSIVE
) fprintf(f
, " AI_PASSIVE");
2449 if (a
->ai_flags
& AI_CANONNAME
) fprintf(f
, " AI_CANONNAME");
2450 if (a
->ai_flags
& AI_NUMERICHOST
) fprintf(f
, " AI_NUMERICHOST");
2451 if (a
->ai_flags
& AI_NUMERICSERV
) fprintf(f
, " AI_NUMERICSERV");
2455 fprintf(f
, "family = %s\n", family_name(a
->ai_family
));
2456 fprintf(f
, "socktype = %s\n", socket_name(a
->ai_socktype
));
2457 fprintf(f
, "protocol = %s\n", protocol_name(a
->ai_protocol
));
2459 fprintf(f
, "canonical name = ");
2460 if (a
->ai_canonname
== NULL
) fprintf(f
, "NULL\n");
2461 else fprintf(f
, "\"%s\"\n", a
->ai_canonname
);
2463 fprintf(f
, "addrlen = %ld\n", (long int)a
->ai_addrlen
);
2465 if (a
->ai_addr
== NULL
) fprintf(f
, "sockaddr = NULL\n");
2468 if (a
->ai_family
== PF_INET
)
2470 s4
= (struct sockaddr_in
*)a
->ai_addr
;
2472 fprintf(f
, "sockaddr_in len = %d\n", s4
->sin_len
);
2473 fprintf(f
, "sockaddr_in family = %s\n", family_name(s4
->sin_family
));
2474 fprintf(f
, "sockaddr_in port = %hu\n", ntohs(s4
->sin_port
));
2475 fprintf(f
, "sockaddr_in address = %s\n", inet_ntoa(s4
->sin_addr
));
2477 else if (a
->ai_family
== PF_INET6
)
2479 s6
= (struct sockaddr_in6
*)a
->ai_addr
;
2481 fprintf(f
, "sockaddr_in6 len = %d\n", s6
->sin6_len
);
2482 fprintf(f
, "sockaddr_in6 family = %s\n", family_name(s6
->sin6_family
));
2483 fprintf(f
, "sockaddr_in6 port = %hu\n", ntohs(s6
->sin6_port
));
2484 fprintf(f
, "sockaddr_in6 flowinfo = %d\n", s6
->sin6_flowinfo
);
2485 fprintf(f
, "sockaddr_in6 address = %s\n", _gai_inet_ntop(s6
->sin6_addr
));
2486 fprintf(f
, "sockaddr_in6 scope_id = %d\n", s6
->sin6_scope_id
);
2490 fprintf(f
, "sockaddr len = %d\n", a
->ai_addr
->sa_len
);
2491 fprintf(f
, "sockaddr family = %s\n", family_name(a
->ai_addr
->sa_family
));
2492 fprintf(f
, "sockaddr data = ");
2493 for (i
= 0; i
< a
->ai_addr
->sa_len
- 2; i
++)
2495 v
= a
->ai_addr
->sa_data
[i
];
2496 fprintf(f
, "%02x", v
);
2502 if (a
->ai_next
!= NULL
)
2504 fprintf(f
, "NEXT --->\n");
2505 fprint_addrinfo(f
, a
->ai_next
);
2512 si_libinfo_addrinfo_callback(si_list_t
*list
, uint32_t status
, void *ctx
)
2514 si_context_t
*sictx
;
2515 struct addrinfo
*out
;
2520 fprintf(stderr
, " %s error no context\n", __func__
);
2522 si_list_release(list
);
2526 sictx
= (si_context_t
*)ctx
;
2528 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
2531 fprintf(stderr
, " %s error no callback\n", __func__
);
2533 si_list_release(list
);
2538 if (status
!= SI_STATUS_NO_ERROR
)
2541 fprintf(stderr
, " %s original status %d\n", __func__
, status
);
2543 if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2544 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2545 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2551 fprintf(stderr
, " %s result NULL status %d (returning EAI_NONAME)\n", __func__
, status
);
2553 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(EAI_NONAME
, NULL
, sictx
->orig_context
);
2558 out
= si_list_to_addrinfo(list
);
2559 si_list_release(list
);
2563 fprintf(stderr
, " %s result conversion failed returning NULL status %d (returning EAI_MEMORY)\n", __func__
, status
);
2565 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(EAI_MEMORY
, NULL
, sictx
->orig_context
);
2571 fprintf(stderr
, " %s %d\n", __func__
, status
);
2572 fprint_addrinfo(stderr
, out
);
2574 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(status
, out
, sictx
->orig_context
);
2581 _getaddrinfo_interface_async_call(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, const char *interface
, si_addrinfo_async_callback callback
, void *context
)
2583 si_context_t
*sictx
;
2584 uint32_t family
, socktype
, protocol
, flags
;
2587 socktype
= SOCK_UNSPEC
;
2588 protocol
= IPPROTO_UNSPEC
;
2593 family
= hints
->ai_family
;
2594 socktype
= hints
->ai_socktype
;
2595 protocol
= hints
->ai_protocol
;
2596 flags
= hints
->ai_flags
;
2600 fprintf(stderr
, ">> %s %s %s %u %u %u 0x%08x\n", __func__
, nodename
, servname
, family
, socktype
, protocol
, flags
);
2603 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2604 if (sictx
== NULL
) return MACH_PORT_NULL
;
2606 sictx
->orig_callback
= callback
;
2607 sictx
->orig_context
= context
;
2608 sictx
->cat
= CATEGORY_ADDRINFO
;
2609 sictx
->key_offset
= 0;
2611 return si_async_call(si_search(), SI_CALL_ADDRINFO
, nodename
, servname
, interface
, family
, socktype
, protocol
, flags
, (void *)si_libinfo_addrinfo_callback
, sictx
);
2615 getaddrinfo_async_call(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, si_addrinfo_async_callback callback
, void *context
)
2617 return _getaddrinfo_interface_async_call(nodename
, servname
, hints
, NULL
, callback
, context
);
2621 getaddrinfo_async_start(mach_port_t
*p
, const char *nodename
, const char *servname
, const struct addrinfo
*hints
, si_addrinfo_async_callback callback
, void *context
)
2623 if (p
== NULL
) return EAI_SYSTEM
;
2625 *p
= getaddrinfo_async_call(nodename
, servname
, hints
, callback
, context
);
2627 if (*p
== MACH_PORT_NULL
) return EAI_SYSTEM
;
2632 getaddrinfo_async_send(mach_port_t
*p
, const char *nodename
, const char *servname
, const struct addrinfo
*hints
)
2634 return getaddrinfo_async_start(p
, nodename
, servname
, hints
, NULL
, NULL
);
2638 getaddrinfo_async_receive(mach_port_t p
, struct addrinfo
**res
)
2640 /* unsupported Leopard SPI */
2645 getaddrinfo_async_cancel(mach_port_t p
)
2648 fprintf(stderr
, "-- %s\n", __func__
);
2655 getaddrinfo_async_handle_reply(void *param
)
2657 mach_msg_header_t
*msg
;
2660 fprintf(stderr
, "<< %s\n", __func__
);
2663 msg
= (mach_msg_header_t
*)param
;
2664 si_async_handle_reply(msg
);
2672 _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
)
2676 uint32_t status
, len
, wantn
, wants
;
2679 fprintf(stderr
, "-> %s\n", __func__
);
2682 status
= SI_STATUS_NO_ERROR
;
2685 if ((node
!= NULL
) && (nodelen
> 0)) wantn
= 1;
2688 if ((service
!= NULL
) && (servicelen
> 0)) wants
= 1;
2690 if ((wantn
== 0) && (wants
== 0)) return status
;
2692 if (wantn
== 0) flags
|= NI_NUMERICHOST
;
2693 if (wants
== 0) flags
|= NI_NUMERICSERV
;
2695 item
= si_nameinfo(si_search(), sa
, flags
, interface
, &status
);
2696 if ((status
!= SI_STATUS_NO_ERROR
) || (item
== NULL
))
2698 si_item_release(item
);
2700 if (status
== SI_STATUS_NO_ERROR
) status
= EAI_NONAME
;
2701 else if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2702 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2703 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2707 ni
= (si_nameinfo_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
2710 if (ni
->ni_node
!= NULL
) len
= strlen(ni
->ni_node
) + 1;
2711 if ((wantn
== 1) && (len
> 0))
2715 si_item_release(item
);
2716 return EAI_OVERFLOW
;
2719 memset(node
, 0, nodelen
);
2720 memcpy(node
, ni
->ni_node
, len
);
2724 if (ni
->ni_serv
!= NULL
) len
= strlen(ni
->ni_serv
) + 1;
2725 if ((wants
== 1) && (len
> 0))
2727 if (len
> servicelen
)
2729 si_item_release(item
);
2730 return EAI_OVERFLOW
;
2733 memset(service
, 0, servicelen
);
2734 memcpy(service
, ni
->ni_serv
, len
);
2737 si_item_release(item
);
2742 getnameinfo(const struct sockaddr
*sa
, socklen_t salen
, char *node
, socklen_t nodelen
, char *service
, socklen_t servicelen
, int flags
)
2744 if (sa
== NULL
) return EAI_FAIL
;
2746 if (sa
->sa_family
== AF_LINK
) return getnameinfo_link(sa
, salen
, node
, nodelen
, service
, servicelen
, flags
);
2747 return _getnameinfo_interface_internal(sa
, salen
, node
, nodelen
, service
, servicelen
, flags
, NULL
);
2751 si_libinfo_nameinfo_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
2753 si_context_t
*sictx
;
2757 if (ctx
== NULL
) return;
2759 sictx
= (si_context_t
*)ctx
;
2761 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
2763 si_item_release(item
);
2768 if (status
!= SI_STATUS_NO_ERROR
)
2770 if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2771 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2772 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2777 ((si_nameinfo_async_callback
)(sictx
->orig_callback
))(status
, NULL
, NULL
, sictx
->orig_context
);
2782 LI_set_thread_item(CATEGORY_NAMEINFO
, item
);
2787 ni
= (si_nameinfo_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
2788 if (ni
->ni_node
!= NULL
) node
= strdup(ni
->ni_node
);
2789 if (ni
->ni_serv
!= NULL
) serv
= strdup(ni
->ni_serv
);
2791 ((si_nameinfo_async_callback
)(sictx
->orig_callback
))(status
, node
, serv
, sictx
->orig_context
);
2797 _getnameinfo_interface_async_call(const struct sockaddr
*sa
, size_t len
, int flags
, const char *interface
, si_nameinfo_async_callback callback
, void *context
)
2799 si_context_t
*sictx
;
2803 fprintf(stderr
, ">> %s\n", __func__
);
2806 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2807 if (sictx
== NULL
) return MACH_PORT_NULL
;
2809 sictx
->orig_callback
= callback
;
2810 sictx
->orig_context
= context
;
2811 sictx
->cat
= CATEGORY_ADDRINFO
;
2812 sictx
->key_offset
= 0;
2814 /* sa is not a C string - pass length in num3 */
2816 return si_async_call(si_search(), SI_CALL_NAMEINFO
, (const char *)sa
, NULL
, interface
, flags
, 0, salen
, 0, (void *)si_libinfo_nameinfo_callback
, sictx
);
2820 getnameinfo_async_call(const struct sockaddr
*sa
, size_t len
, int flags
, si_nameinfo_async_callback callback
, void *context
)
2822 return _getnameinfo_interface_async_call(sa
, len
, flags
, NULL
, callback
, context
);
2826 getnameinfo_async_start(mach_port_t
*p
, const struct sockaddr
*sa
, size_t salen
, int flags
, si_nameinfo_async_callback callback
, void *context
)
2828 if (p
== NULL
) return EAI_SYSTEM
;
2829 *p
= getnameinfo_async_call(sa
, salen
, flags
, callback
, context
);
2831 if (*p
== MACH_PORT_NULL
) return EAI_SYSTEM
;
2836 getnameinfo_async_send(mach_port_t
*p
, const struct sockaddr
*sa
, size_t salen
, int flags
)
2838 return getnameinfo_async_start(p
, sa
, salen
, flags
, NULL
, NULL
);
2842 getnameinfo_async_cancel(mach_port_t p
)
2845 fprintf(stderr
, "-- %s\n", __func__
);
2852 getnameinfo_async_handle_reply(void *param
)
2854 mach_msg_header_t
*msg
;
2857 fprintf(stderr
, "<< %s\n", __func__
);
2860 msg
= (mach_msg_header_t
*)param
;
2861 si_async_handle_reply(msg
);
2866 /* getpwXXX_r and getgrXXX_r */
2869 copy_user_r(struct passwd
*in
, struct passwd
*out
, char *buffer
, int buflen
)
2874 if (in
== NULL
) return -1;
2875 if (out
== NULL
) return -1;
2877 if (buffer
== NULL
) buflen
= 0;
2879 /* Calculate size of input */
2881 if (in
->pw_name
!= NULL
) hsize
+= (strlen(in
->pw_name
) + 1);
2882 if (in
->pw_passwd
!= NULL
) hsize
+= (strlen(in
->pw_passwd
) + 1);
2883 if (in
->pw_class
!= NULL
) hsize
+= (strlen(in
->pw_class
) + 1);
2884 if (in
->pw_gecos
!= NULL
) hsize
+= (strlen(in
->pw_gecos
) + 1);
2885 if (in
->pw_dir
!= NULL
) hsize
+= (strlen(in
->pw_dir
) + 1);
2886 if (in
->pw_shell
!= NULL
) hsize
+= (strlen(in
->pw_shell
) + 1);
2888 /* Check buffer space */
2889 if (hsize
> buflen
) return -1;
2891 /* Copy result into caller's struct passwd, using buffer for memory */
2894 out
->pw_name
= NULL
;
2895 if (in
->pw_name
!= NULL
)
2898 hsize
= strlen(in
->pw_name
) + 1;
2899 memmove(bp
, in
->pw_name
, hsize
);
2903 out
->pw_passwd
= NULL
;
2904 if (in
->pw_passwd
!= NULL
)
2906 out
->pw_passwd
= bp
;
2907 hsize
= strlen(in
->pw_passwd
) + 1;
2908 memmove(bp
, in
->pw_passwd
, hsize
);
2912 out
->pw_uid
= in
->pw_uid
;
2914 out
->pw_gid
= in
->pw_gid
;
2916 out
->pw_change
= in
->pw_change
;
2918 out
->pw_class
= NULL
;
2919 if (in
->pw_class
!= NULL
)
2922 hsize
= strlen(in
->pw_class
) + 1;
2923 memmove(bp
, in
->pw_class
, hsize
);
2927 out
->pw_gecos
= NULL
;
2928 if (in
->pw_gecos
!= NULL
)
2931 hsize
= strlen(in
->pw_gecos
) + 1;
2932 memmove(bp
, in
->pw_gecos
, hsize
);
2937 if (in
->pw_dir
!= NULL
)
2940 hsize
= strlen(in
->pw_dir
) + 1;
2941 memmove(bp
, in
->pw_dir
, hsize
);
2945 out
->pw_shell
= NULL
;
2946 if (in
->pw_shell
!= NULL
)
2949 hsize
= strlen(in
->pw_shell
) + 1;
2950 memmove(bp
, in
->pw_shell
, hsize
);
2954 out
->pw_expire
= in
->pw_expire
;
2960 copy_group_r(struct group
*in
, struct group
*out
, char *buffer
, int buflen
)
2966 if (in
== NULL
) return -1;
2967 if (out
== NULL
) return -1;
2969 if (buffer
== NULL
) buflen
= 0;
2971 /* Calculate size of input */
2973 if (in
->gr_name
!= NULL
) hsize
+= (strlen(in
->gr_name
) + 1);
2974 if (in
->gr_passwd
!= NULL
) hsize
+= (strlen(in
->gr_passwd
) + 1);
2976 /* NULL pointer at end of list */
2977 hsize
+= sizeof(char *);
2980 if (in
->gr_mem
!= NULL
)
2982 for (len
= 0; in
->gr_mem
[len
] != NULL
; len
++)
2984 hsize
+= sizeof(char *);
2985 hsize
+= (strlen(in
->gr_mem
[len
]) + 1);
2989 /* Check buffer space */
2990 if (hsize
> buflen
) return -1;
2992 /* Copy result into caller's struct group, using buffer for memory */
2995 out
->gr_name
= NULL
;
2996 if (in
->gr_name
!= NULL
)
2999 hsize
= strlen(in
->gr_name
) + 1;
3000 memmove(bp
, in
->gr_name
, hsize
);
3004 out
->gr_passwd
= NULL
;
3005 if (in
->gr_passwd
!= NULL
)
3007 out
->gr_passwd
= bp
;
3008 hsize
= strlen(in
->gr_passwd
) + 1;
3009 memmove(bp
, in
->gr_passwd
, hsize
);
3013 out
->gr_gid
= in
->gr_gid
;
3016 ap
= bp
+ ((len
+ 1) * sizeof(char *));
3018 if (in
->gr_mem
!= NULL
)
3020 out
->gr_mem
= (char **)bp
;
3021 for (i
= 0; i
< len
; i
++)
3023 addr
= (unsigned long)ap
;
3024 memmove(bp
, &addr
, sizeof(unsigned long));
3025 bp
+= sizeof(unsigned long);
3027 hsize
= strlen(in
->gr_mem
[i
]) + 1;
3028 memmove(ap
, in
->gr_mem
[i
], hsize
);
3033 memset(bp
, 0, sizeof(unsigned long));
3040 getgrnam_r(const char *name
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
3047 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
3050 if (result
!= NULL
) *result
= NULL
;
3052 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3054 item
= si_group_byname(si_search(), name
);
3055 if (item
== NULL
) return 0;
3057 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
3059 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
3060 si_item_release(item
);
3062 if (status
!= 0) return ERANGE
;
3069 getgrgid_r(gid_t gid
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
3076 fprintf(stderr
, "-> %s %d\n", __func__
, gid
);
3079 if (result
!= NULL
) *result
= NULL
;
3081 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3083 item
= si_group_bygid(si_search(), gid
);
3084 if (item
== NULL
) return 0;
3086 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
3088 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
3089 si_item_release(item
);
3091 if (status
!= 0) return ERANGE
;
3098 getgruuid_r(uuid_t uuid
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
3105 uuid_string_t uuidstr
;
3106 uuid_unparse_upper(uuid
, uuidstr
);
3107 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
3110 if (result
!= NULL
) *result
= NULL
;
3112 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3114 item
= si_group_byuuid(si_search(), uuid
);
3115 if (item
== NULL
) return 0;
3117 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
3119 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
3120 si_item_release(item
);
3122 if (status
!= 0) return ERANGE
;
3129 getpwnam_r(const char *name
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3136 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
3139 if (result
!= NULL
) *result
= NULL
;
3141 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3143 item
= si_user_byname(si_search(), name
);
3144 if (item
== NULL
) return 0;
3146 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3148 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3149 si_item_release(item
);
3151 if (status
!= 0) return ERANGE
;
3158 getpwuid_r(uid_t uid
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3165 fprintf(stderr
, "-> %s %d\n", __func__
, uid
);
3168 if (result
!= NULL
) *result
= NULL
;
3170 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3172 item
= si_user_byuid(si_search(), uid
);
3173 if (item
== NULL
) return 0;
3175 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3177 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3178 si_item_release(item
);
3180 if (status
!= 0) return ERANGE
;
3187 getpwuuid_r(uuid_t uuid
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3194 uuid_string_t uuidstr
;
3195 uuid_unparse_upper(uuid
, uuidstr
);
3196 fprintf(stderr
, "-> %s %s\n", __func__
, uuidstr
);
3199 if (result
!= NULL
) *result
= NULL
;
3201 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3203 item
= si_user_byuuid(si_search(), uuid
);
3204 if (item
== NULL
) return 0;
3206 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3208 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3209 si_item_release(item
);
3211 if (status
!= 0) return ERANGE
;
3220 user_from_uid(uid_t uid
, int nouser
)
3223 static char buf
[16];
3226 if (pw
!= NULL
) return pw
->pw_name
;
3228 if (nouser
) return NULL
;
3230 snprintf(buf
, sizeof(buf
), "%u", uid
);
3235 group_from_gid(gid_t gid
, int nogroup
)
3238 static char buf
[16];
3241 if (gr
!= NULL
) return gr
->gr_name
;
3243 if (nogroup
) return NULL
;
3245 snprintf(buf
, sizeof(buf
), "%u", gid
);
3249 /* no longer supported */
3252 prdb_getbyname(const char *name
)
3255 fprintf(stderr
, "~~ %s\n", __func__
);
3264 fprintf(stderr
, "~~ %s\n", __func__
);
3270 prdb_set(const char *name
)
3273 fprintf(stderr
, "~~ %s\n", __func__
);
3281 fprintf(stderr
, "~~ %s\n", __func__
);
3285 struct bootparamsent
*
3286 bootparams_getbyname(const char *name
)
3289 fprintf(stderr
, "~~ %s\n", __func__
);
3294 struct bootparamsent
*
3295 bootparams_getent(void)
3298 fprintf(stderr
, "~~ %s\n", __func__
);
3304 bootparams_setent(void)
3307 fprintf(stderr
, "~~ %s\n", __func__
);
3312 bootparams_endent(void)
3315 fprintf(stderr
, "~~ %s\n", __func__
);
3320 bootp_getbyether(struct ether_addr
*enaddr
, char **name
,struct in_addr
*ipaddr
, char **bootfile
)
3323 fprintf(stderr
, "~~ %s\n", __func__
);
3329 bootp_getbyip(struct ether_addr
*enaddr
, char **name
, struct in_addr
*ipaddr
, char **bootfile
)
3332 fprintf(stderr
, "~~ %s\n", __func__
);