2 * Copyright (c) 2008 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@
30 #include <printerdb.h>
31 #include <sys/param.h>
32 #include <sys/syscall.h>
34 #include <arpa/inet.h>
35 #include <netinet/if_ether.h>
36 #include "si_module.h"
38 #include <thread_data.h>
39 #include <sys/kauth.h>
40 #include "netdb_async.h"
43 #define IPPROTO_UNSPEC 0
44 #define IPV6_ADDR_LEN 16
45 #define IPV4_ADDR_LEN 4
47 /* The kernel's initgroups call */
48 extern int __initgroups(u_int gidsetsize
, gid_t
*gidset
, int gmuid
);
50 /* SPI from long ago */
53 extern struct addrinfo
*si_list_to_addrinfo(si_list_t
*list
);
54 extern int getnameinfo_link(const struct sockaddr
*sa
, socklen_t salen
, char *host
, size_t hostlen
, char *serv
, size_t servlen
, int flags
);
55 __private_extern__
void search_set_flags(si_mod_t
*si
, const char *name
, uint32_t flag
);
58 * Impedence matching for async calls.
60 * This layer holds on to the caller's callback and context in this
61 * structure, which gets passed to the si_module async routines along
62 * with a callbac in this layer. When this layer gets a callback,
63 * it can save the item or list in thread-specific memory and then
64 * invoke the caller's callback with the appropriate data type.
78 static si_mod_t
*search
= NULL
;
80 if (search
== NULL
) search
= si_module_with_name("search");
86 si_search_module_set_flags(const char *name
, uint32_t flag
)
88 search_set_flags(si_search(), name
, flag
);
92 si_libinfo_general_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
100 struct grouplist_s
*l
;
109 if (ctx
== NULL
) return;
111 sictx
= (si_context_t
*)ctx
;
113 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
116 si_item_release(item
);
120 if (sictx
->key_offset
>= 0)
122 LI_set_thread_item(sictx
->cat
+ sictx
->key_offset
, item
);
126 if (item
!= NULL
) res
.x
= (char*)((uintptr_t)item
+ sizeof(si_item_t
));
132 ((si_user_async_callback
)(sictx
->orig_callback
))(res
.u
, sictx
->orig_context
);
137 ((si_group_async_callback
)(sictx
->orig_callback
))(res
.g
, sictx
->orig_context
);
140 case CATEGORY_GROUPLIST
:
142 ((si_grouplist_async_callback
)(sictx
->orig_callback
))(res
.l
, sictx
->orig_context
);
145 case CATEGORY_HOST_IPV4
:
146 case CATEGORY_HOST_IPV6
:
148 ((si_host_async_callback
)(sictx
->orig_callback
))(res
.h
, sictx
->orig_context
);
151 case CATEGORY_NETWORK
:
153 ((si_network_async_callback
)(sictx
->orig_callback
))(res
.n
, sictx
->orig_context
);
156 case CATEGORY_SERVICE
:
158 ((si_service_async_callback
)(sictx
->orig_callback
))(res
.s
, sictx
->orig_context
);
161 case CATEGORY_PROTOCOL
:
163 ((si_protocol_async_callback
)(sictx
->orig_callback
))(res
.p
, sictx
->orig_context
);
168 ((si_rpc_async_callback
)(sictx
->orig_callback
))(res
.r
, sictx
->orig_context
);
173 ((si_fs_async_callback
)(sictx
->orig_callback
))(res
.f
, sictx
->orig_context
);
184 getpwnam(const char *name
)
189 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
192 item
= si_user_byname(si_search(), name
);
193 LI_set_thread_item(CATEGORY_USER
+ 100, item
);
195 if (item
== NULL
) return NULL
;
196 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
200 getpwnam_async_call(const char *name
, si_user_async_callback callback
, void *context
)
205 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
208 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
209 if (sictx
== NULL
) return MACH_PORT_NULL
;
211 sictx
->orig_callback
= callback
;
212 sictx
->orig_context
= context
;
213 sictx
->cat
= CATEGORY_USER
;
214 sictx
->key_offset
= 100;
216 return si_async_call(si_search(), SI_CALL_USER_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
220 getpwnam_async_handle_reply(mach_msg_header_t
*msg
)
223 fprintf(stderr
, "<< %s\n", __func__
);
226 si_async_handle_reply(msg
);
235 fprintf(stderr
, "-> %s %d\n", __func__
, uid
);
238 item
= si_user_byuid(si_search(), uid
);
239 LI_set_thread_item(CATEGORY_USER
+ 200, item
);
241 if (item
== NULL
) return NULL
;
242 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
246 getpwuid_async_call(uid_t uid
, si_user_async_callback callback
, void *context
)
251 fprintf(stderr
, ">> %s %d\n", __func__
, uid
);
254 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
255 if (sictx
== NULL
) return MACH_PORT_NULL
;
257 sictx
->orig_callback
= callback
;
258 sictx
->orig_context
= context
;
259 sictx
->cat
= CATEGORY_USER
;
260 sictx
->key_offset
= 200;
262 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
);
266 getpwuid_async_handle_reply(mach_msg_header_t
*msg
)
269 fprintf(stderr
, "<< %s\n", __func__
);
272 si_async_handle_reply(msg
);
279 fprintf(stderr
, "-- %s\n", __func__
);
282 LI_set_thread_list(CATEGORY_USER
, NULL
);
292 fprintf(stderr
, "-> %s\n", __func__
);
295 list
= LI_get_thread_list(CATEGORY_USER
);
298 list
= si_user_all(si_search());
299 LI_set_thread_list(CATEGORY_USER
, list
);
302 item
= si_list_next(list
);
303 if (item
== NULL
) return NULL
;
305 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
312 fprintf(stderr
, "-- %s\n", __func__
);
315 LI_set_thread_list(CATEGORY_USER
, NULL
);
319 setpassent(int ignored
)
324 fprintf(stderr
, "-> %s\n", __func__
);
327 list
= LI_get_thread_list(CATEGORY_USER
);
330 if (list
== NULL
) return 0;
337 getgrnam(const char *name
)
342 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
345 item
= si_group_byname(si_search(), name
);
346 LI_set_thread_item(CATEGORY_GROUP
+ 100, item
);
348 if (item
== NULL
) return NULL
;
349 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
353 getgrnam_async_call(const char *name
, si_group_async_callback callback
, void *context
)
358 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
361 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
362 if (sictx
== NULL
) return MACH_PORT_NULL
;
364 sictx
->orig_callback
= callback
;
365 sictx
->orig_context
= context
;
366 sictx
->cat
= CATEGORY_GROUP
;
367 sictx
->key_offset
= 100;
369 return si_async_call(si_search(), SI_CALL_GROUP_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
373 getgrnam_async_handle_reply(mach_msg_header_t
*msg
)
376 fprintf(stderr
, "<< %s\n", __func__
);
379 si_async_handle_reply(msg
);
388 fprintf(stderr
, "-> %s %d\n", __func__
, gid
);
391 item
= si_group_bygid(si_search(), gid
);
392 LI_set_thread_item(CATEGORY_GROUP
+ 200, item
);
394 if (item
== NULL
) return NULL
;
395 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
399 getgrgid_async_call(gid_t gid
, si_group_async_callback callback
, void *context
)
404 fprintf(stderr
, ">> %s %d\n", __func__
, gid
);
407 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
408 if (sictx
== NULL
) return MACH_PORT_NULL
;
410 sictx
->orig_callback
= callback
;
411 sictx
->orig_context
= context
;
412 sictx
->cat
= CATEGORY_GROUP
;
413 sictx
->key_offset
= 200;
415 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
);
419 getgruid_async_handle_reply(mach_msg_header_t
*msg
)
422 fprintf(stderr
, "<< %s\n", __func__
);
425 si_async_handle_reply(msg
);
432 fprintf(stderr
, "-- %s\n", __func__
);
435 LI_set_thread_list(CATEGORY_GROUP
, NULL
);
445 fprintf(stderr
, "-> %s\n", __func__
);
448 list
= LI_get_thread_list(CATEGORY_GROUP
);
451 list
= si_group_all(si_search());
452 LI_set_thread_list(CATEGORY_GROUP
, list
);
455 item
= si_list_next(list
);
456 if (item
== NULL
) return NULL
;
458 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
465 fprintf(stderr
, "-- %s\n", __func__
);
468 LI_set_thread_list(CATEGORY_GROUP
, NULL
);
472 setgroupent(int ignored
)
477 fprintf(stderr
, "-> %s\n", __func__
);
480 list
= LI_get_thread_list(CATEGORY_GROUP
);
483 if (list
== NULL
) return 0;
489 innetgr(const char *group
, const char *host
, const char *user
, const char *domain
)
493 fprintf(stderr
, "-> %s %s %s %s %s\n", __func__
, group
, host
, user
, domain
);
496 res
= si_in_netgroup(si_search(), group
, host
, user
, domain
);
499 fprintf(stderr
, "<- %s %d\n", __func__
, res
);
505 /* N.B. there is no async innetgr */
508 * setnetgrent is really more like a getXXXbyname routine than a
509 * setXXXent routine, since we are looking up a netgroup by name.
512 setnetgrent(const char *name
)
517 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
520 list
= si_netgroup_byname(si_search(), name
);
521 LI_set_thread_list(CATEGORY_NETGROUP
, list
);
524 /* N.B. there is no async getnetgrent */
527 getnetgrent(char **host
, char **user
, char **domain
)
531 struct netgrent_s
*ng
;
534 fprintf(stderr
, "-> %s\n", __func__
);
537 list
= LI_get_thread_list(CATEGORY_NETGROUP
);
538 item
= si_list_next(list
);
539 if (item
== NULL
) return 0;
541 ng
= (struct netgrent_s
*)((uintptr_t)item
+ sizeof(si_item_t
));
545 *domain
= ng
->ng_domain
;
554 fprintf(stderr
, "-- %s\n", __func__
);
557 LI_set_thread_list(CATEGORY_NETGROUP
, NULL
);
563 getgrouplist_internal(const char *name
, int basegid
, gid_t
*groups
, uint32_t *ngroups
, int set_thread_data
)
565 int i
, j
, x
, g
, add
, max
;
570 * On input, ngroups specifies the size of the groups array.
571 * On output, it is set to the number of groups that are being returned.
572 * Returns -1 if the size is too small to fit all the groups that were found.
576 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
579 if (name
== NULL
) return 0;
580 if (groups
== NULL
) return 0;
581 if (ngroups
== NULL
) return 0;
585 if (max
<= 0) return 0;
590 item
= si_grouplist(si_search(), name
);
591 if (set_thread_data
!= 0) LI_set_thread_item(CATEGORY_GROUPLIST
, item
);
592 if (item
== NULL
) return 0;
594 gl
= (si_grouplist_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
598 if (gl
->gl_basegid
!= basegid
)
600 if (x
>= max
) return -1;
601 groups
[x
] = gl
->gl_basegid
;
606 for (i
= 0; i
< gl
->gl_count
; i
++)
608 g
= (int)*(gl
->gl_gid
[i
]);
610 for (j
= 0; (j
< x
) && (add
== 1); j
++) if (groups
[j
] == g
) add
= 0;
611 if (add
== 0) continue;
613 if (x
>= max
) return -1;
623 getgrouplist(const char *name
, int basegid
, int *groups
, int *ngroups
)
625 return getgrouplist_internal(name
, basegid
, (gid_t
*)groups
, (uint32_t *)ngroups
, 1);
628 /* XXX to do: async getgrouplist */
631 merge_gid(gid_t
**list
, gid_t g
, int32_t *count
)
635 if (list
== NULL
) return -1;
639 *list
= (gid_t
*)calloc(1, sizeof(gid_t
));
646 (*list
)[(*count
)++] = g
;
650 for (i
= 0; i
< *count
; i
++) if ((*list
)[i
] == g
) return 0;
652 *list
= (gid_t
*)reallocf(*list
, (*count
+ 1) * sizeof(gid_t
));
653 (*list
)[(*count
)++] = g
;
658 getgrouplist_2(const char *name
, gid_t basegid
, gid_t
**groups
)
660 int32_t i
, status
, count
;
666 * Passes back a gid_t list containing all the users groups (and basegid).
667 * Caller must free the list.
668 * Returns the number of gids in the list or -1 on failure.
672 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
675 if (name
== NULL
) return 0;
676 if (groups
== NULL
) return 0;
678 item
= si_grouplist(si_search(), name
);
679 LI_set_thread_item(CATEGORY_GROUPLIST
, item
);
680 if (item
== NULL
) return -1;
682 gl
= (si_grouplist_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
687 status
= merge_gid(groups
, basegid
, &count
);
688 if (status
!= 0) return status
;
690 status
= merge_gid(groups
, gl
->gl_basegid
, &count
);
691 if (status
!= 0) return status
;
693 for (i
= 0; i
< gl
->gl_count
; i
++)
695 g
= (gid_t
)*(gl
->gl_gid
[i
]);
696 status
= merge_gid(groups
, g
, &count
);
697 if (status
!= 0) return status
;
704 getgroupcount(const char *name
, gid_t basegid
)
706 int32_t i
, status
, count
;
713 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
716 if (name
== NULL
) return 0;
718 item
= si_grouplist(si_search(), name
);
719 LI_set_thread_item(CATEGORY_GROUPLIST
, item
);
720 if (item
== NULL
) return -1;
722 gl
= (si_grouplist_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
727 status
= merge_gid(&groups
, basegid
, &count
);
728 if (status
!= 0) return status
;
730 status
= merge_gid(&groups
, gl
->gl_basegid
, &count
);
731 if (status
!= 0) return status
;
733 for (i
= 0; i
< gl
->gl_count
; i
++)
735 g
= (gid_t
)*(gl
->gl_gid
[i
]);
736 status
= merge_gid(&groups
, g
, &count
);
737 if (status
!= 0) return status
;
740 if (groups
!= NULL
) free(groups
);
745 /* XXX to do: async getgrouplist_2 */
748 initgroups(const char *name
, int basegid
)
752 gid_t groups
[NGROUPS
];
760 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
763 /* KAUTH_UID_NONE tells the kernel not to fetch supplementary groups from DirectoryService */
764 uid
= KAUTH_UID_NONE
;
767 /* get the UID for this user */
768 item
= si_user_byname(si_search(), name
);
771 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
774 si_item_release(item
);
780 status
= getgrouplist_internal(name
, basegid
, groups
, &ngroups
, 0);
783 * A failure either means that user belongs to more than NGROUPS groups
784 * or no groups at all.
787 status
= __initgroups(ngroups
, groups
, uid
);
788 if (status
< 0) return -1;
796 alias_getbyname(const char *name
)
801 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
804 item
= si_alias_byname(si_search(), name
);
805 LI_set_thread_item(CATEGORY_ALIAS
+ 100, item
);
806 if (item
== NULL
) return NULL
;
808 return (struct aliasent
*)((uintptr_t)item
+ sizeof(si_item_t
));
812 alias_getbyname_async_call(const char *name
, si_alias_async_callback callback
, void *context
)
817 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
820 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
821 if (sictx
== NULL
) return MACH_PORT_NULL
;
823 sictx
->orig_callback
= callback
;
824 sictx
->orig_context
= context
;
825 sictx
->cat
= CATEGORY_ALIAS
;
826 sictx
->key_offset
= 100;
828 return si_async_call(si_search(), SI_CALL_ALIAS_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
832 alias_getbyname_async_handle_reply(mach_msg_header_t
*msg
)
835 fprintf(stderr
, "<< %s\n", __func__
);
838 si_async_handle_reply(msg
);
845 fprintf(stderr
, "-> %s\n", __func__
);
848 LI_set_thread_list(CATEGORY_ALIAS
, NULL
);
858 fprintf(stderr
, "-> %s\n", __func__
);
861 list
= LI_get_thread_list(CATEGORY_ALIAS
);
864 list
= si_alias_all(si_search());
865 LI_set_thread_list(CATEGORY_ALIAS
, list
);
868 item
= si_list_next(list
);
869 if (item
== NULL
) return NULL
;
871 return (struct aliasent
*)((uintptr_t)item
+ sizeof(si_item_t
));
878 fprintf(stderr
, "-- %s\n", __func__
);
881 LI_set_thread_list(CATEGORY_ALIAS
, NULL
);
887 freehostent(struct hostent
*h
)
889 if (h
== NULL
) return;
891 si_item_t
*item
= (si_item_t
*)((uintptr_t)h
- sizeof(si_item_t
));
892 si_item_release(item
);
896 gethostbynameerrno(const char *name
, int *err
)
900 struct in_addr addr4
;
903 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
906 memset(&addr4
, 0, sizeof(struct in_addr
));
907 status
= SI_STATUS_NO_ERROR
;
910 if (inet_aton(name
, &addr4
) == 1) item
= si_ipnode_byname(si_search(), name
, AF_INET
, 0, NULL
, &status
);
911 else item
= si_host_byname(si_search(), name
, AF_INET
, NULL
, &status
);
913 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
914 if (err
!= NULL
) *err
= status
;
916 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
917 if (item
== NULL
) return NULL
;
919 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
923 gethostbyname(const char *name
)
927 struct in_addr addr4
;
930 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
933 memset(&addr4
, 0, sizeof(struct in_addr
));
934 status
= SI_STATUS_NO_ERROR
;
937 if (inet_aton(name
, &addr4
) == 1) item
= si_ipnode_byname(si_search(), name
, AF_INET
, 0, NULL
, &status
);
938 else item
= si_host_byname(si_search(), name
, AF_INET
, NULL
, &status
);
940 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
943 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
944 if (item
== NULL
) return NULL
;
946 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
950 gethostbyname_async_call(const char *name
, si_host_async_callback callback
, void *context
)
955 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
958 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
959 if (sictx
== NULL
) return MACH_PORT_NULL
;
961 sictx
->orig_callback
= callback
;
962 sictx
->orig_context
= context
;
963 sictx
->cat
= CATEGORY_HOST
;
964 sictx
->key_offset
= 100;
966 return si_async_call(si_search(), SI_CALL_HOST_BYNAME
, name
, NULL
, NULL
, AF_INET
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
970 gethostbyname_async_start(const char *name
, si_host_async_callback callback
, void *context
)
972 return gethostbyname_async_call(name
, callback
, context
);
976 gethostbyname_async_cancel(mach_port_t p
)
979 fprintf(stderr
, "-- %s\n", __func__
);
987 gethostbyname_async_handle_reply(void *param
)
989 mach_msg_header_t
*msg
;
992 fprintf(stderr
, "<< %s\n", __func__
);
995 msg
= (mach_msg_header_t
*)param
;
996 si_async_handle_reply(msg
);
1001 gethostbyname_async_handleReply(void *param
)
1003 mach_msg_header_t
*msg
;
1006 fprintf(stderr
, "<< %s\n", __func__
);
1009 msg
= (mach_msg_header_t
*)param
;
1010 si_async_handle_reply(msg
);
1014 gethostbyname2(const char *name
, int af
)
1018 struct in_addr addr4
;
1019 struct in6_addr addr6
;
1020 si_mod_t
*search
= si_search();
1023 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, af
);
1026 memset(&addr4
, 0, sizeof(struct in_addr
));
1027 memset(&addr6
, 0, sizeof(struct in6_addr
));
1028 status
= SI_STATUS_NO_ERROR
;
1031 if (((af
== AF_INET
) && (inet_aton(name
, &addr4
) == 1)) || ((af
== AF_INET6
) && (inet_pton(af
, name
, &addr6
) == 1)))
1033 item
= si_ipnode_byname(search
, name
, (uint32_t)af
, 0, NULL
, &status
);
1037 item
= si_host_byname(search
, name
, (uint32_t)af
, NULL
, &status
);
1040 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1043 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
1044 if (item
== NULL
) return NULL
;
1046 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1050 gethostbyname2_async_call(const char *name
, int af
, si_group_async_callback callback
, void *context
)
1052 si_context_t
*sictx
;
1055 fprintf(stderr
, ">> %s %s %d\n", __func__
, name
, af
);
1058 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1059 if (sictx
== NULL
) return MACH_PORT_NULL
;
1061 sictx
->orig_callback
= callback
;
1062 sictx
->orig_context
= context
;
1063 sictx
->cat
= CATEGORY_HOST
;
1064 sictx
->key_offset
= 100;
1066 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
);
1070 gethostbyname2_async_cancel(mach_port_t p
)
1073 fprintf(stderr
, "-- %s\n", __func__
);
1080 gethostbyname2_async_handle_reply(mach_msg_header_t
*msg
)
1083 fprintf(stderr
, "<< %s\n", __func__
);
1086 si_async_handle_reply(msg
);
1090 gethostbyaddr(const void *addr
, socklen_t len
, int type
)
1096 fprintf(stderr
, "-> %s %s\n", __func__
, (type
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)addr
) : "-IPv6-");
1099 status
= SI_STATUS_NO_ERROR
;
1101 item
= si_host_byaddr(si_search(), addr
, (uint32_t)type
, NULL
, &status
);
1102 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1105 LI_set_thread_item(CATEGORY_HOST
+ 200, item
);
1106 if (item
== NULL
) return NULL
;
1108 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1112 gethostbyaddr_async_call(const void *addr
, socklen_t len
, int type
, si_host_async_callback callback
, void *context
)
1114 si_context_t
*sictx
;
1118 fprintf(stderr
, ">> %s %s\n", __func__
, (type
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)addr
) : "-IPv6-");
1121 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1122 if (sictx
== NULL
) return MACH_PORT_NULL
;
1124 sictx
->orig_callback
= callback
;
1125 sictx
->orig_context
= context
;
1126 sictx
->cat
= CATEGORY_HOST
;
1127 sictx
->key_offset
= 200;
1129 /* addr is not a C string - pass length in num3 */
1131 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
);
1135 gethostbyaddr_async_start(const char *addr
, int len
, int family
, si_host_async_callback callback
, void *context
)
1137 socklen_t slen
= len
;
1139 return gethostbyaddr_async_call(addr
, slen
, family
, callback
, context
);
1143 gethostbyaddr_async_cancel(mach_port_t p
)
1146 fprintf(stderr
, "-- %s\n", __func__
);
1154 gethostbyaddr_async_handle_reply(void *param
)
1157 mach_msg_header_t
*msg
;
1160 fprintf(stderr
, "<< %s\n", __func__
);
1163 msg
= (mach_msg_header_t
*)param
;
1164 si_async_handle_reply(msg
);
1169 gethostbyaddr_async_handleReply(void *param
)
1171 mach_msg_header_t
*msg
;
1174 fprintf(stderr
, "<< %s\n", __func__
);
1177 msg
= (mach_msg_header_t
*)param
;
1178 si_async_handle_reply(msg
);
1182 getipnodebyname(const char *name
, int family
, int flags
, int *err
)
1188 fprintf(stderr
, "-> %s %s %d 0x%08x\n", __func__
, name
, family
, flags
);
1191 status
= SI_STATUS_NO_ERROR
;
1193 item
= si_ipnode_byname(si_search(), name
, family
, flags
, NULL
, &status
);
1194 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1195 if (err
!= NULL
) *err
= status
;
1197 if (item
== NULL
) return NULL
;
1199 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1204 getipnodebyname_async_call(const char *name
, int family
, int flags
, int *err
, si_host_async_callback callback
, void *context
)
1206 si_context_t
*sictx
;
1209 fprintf(stderr
, ">> %s %s %d 0x%08x\n", __func__
, name
, family
, flags
);
1212 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1213 if (sictx
== NULL
) return MACH_PORT_NULL
;
1215 sictx
->orig_callback
= callback
;
1216 sictx
->orig_context
= context
;
1217 sictx
->cat
= CATEGORY_HOST
;
1218 sictx
->key_offset
= -1;
1220 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
);
1224 getipnodebyname_async_start(const char *name
, int family
, int flags
, int *err
, si_host_async_callback callback
, void *context
)
1226 return getipnodebyname_async_call(name
, family
, flags
, err
, callback
, context
);
1230 getipnodebyname_async_cancel(mach_port_t p
)
1233 fprintf(stderr
, "-- %s\n", __func__
);
1240 getipnodebyname_async_handle_reply(mach_msg_header_t
*msg
)
1243 fprintf(stderr
, "<< %s\n", __func__
);
1246 si_async_handle_reply(msg
);
1250 getipnodebyname_async_handleReply(mach_msg_header_t
*msg
)
1253 fprintf(stderr
, "<< %s\n", __func__
);
1256 si_async_handle_reply(msg
);
1261 is_a4_mapped(const char *s
)
1266 if (s
== NULL
) return 0;
1268 for (i
= 0; i
< 10; i
++)
1271 if (c
!= 0x0) return 0;
1274 for (i
= 10; i
< 12; i
++)
1277 if (c
!= 0xff) return 0;
1284 is_a4_compat(const char *s
)
1289 if (s
== NULL
) return 0;
1291 for (i
= 0; i
< 12; i
++)
1294 if (c
!= 0x0) return 0;
1297 /* Check for :: and ::1 */
1298 for (i
= 13; i
< 15; i
++)
1300 /* anything non-zero in these 3 bytes means it's a V4 address */
1302 if (c
!= 0x0) return 1;
1305 /* Leading 15 bytes are all zero */
1307 if (c
== 0x0) return 0;
1308 if (c
== 0x1) return 0;
1314 getipnodebyaddr(const void *src
, size_t len
, int family
, int *err
)
1319 fprintf(stderr
, "-> %s %s\n", __func__
, (family
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)src
) : "-IPv6-");
1322 if ((family
== AF_INET6
) && (len
== IPV6_ADDR_LEN
) && (is_a4_mapped((const char *)src
) || is_a4_compat((const char *)src
)))
1329 item
= si_host_byaddr(si_search(), src
, family
, NULL
, (uint32_t *)err
);
1330 if (item
== NULL
) return NULL
;
1332 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1337 si_libinfo_ipnode_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
1339 si_context_t
*sictx
;
1342 if (ctx
== NULL
) return;
1344 sictx
= (si_context_t
*)ctx
;
1346 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
1349 si_item_release(item
);
1353 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1357 ((si_ipnode_async_callback
)(sictx
->orig_callback
))(NULL
, status
, sictx
->orig_context
);
1361 h
= (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1362 ((si_ipnode_async_callback
)(sictx
->orig_callback
))(h
, status
, sictx
->orig_context
);
1368 getipnodebyaddr_async_call(const void *src
, socklen_t len
, int family
, int *err
, si_ipnode_async_callback callback
, void *context
)
1370 si_context_t
*sictx
;
1374 fprintf(stderr
, ">> %s %s\n", __func__
, (family
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)src
) : "-IPv6-");
1377 if ((family
== AF_INET6
) && (len
== IPV6_ADDR_LEN
) && (is_a4_mapped((const char *)src
) || is_a4_compat((const char *)src
)))
1384 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1385 if (sictx
== NULL
) return MACH_PORT_NULL
;
1387 sictx
->orig_callback
= callback
;
1388 sictx
->orig_context
= context
;
1389 sictx
->cat
= CATEGORY_HOST
;
1390 sictx
->key_offset
= -1;
1392 /* src is not a C string - pass length in num3 */
1394 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
);
1398 getipnodebyaddr_async_start(const void *addr
, size_t len
, int family
, int *error
, si_ipnode_async_callback callback
, void *context
)
1400 socklen_t slen
= len
;
1402 return getipnodebyaddr_async_call(addr
, slen
, family
, error
, callback
, context
);
1406 getipnodebyaddr_async_cancel(mach_port_t p
)
1409 fprintf(stderr
, "-- %s\n", __func__
);
1416 getipnodebyaddr_async_handle_reply(mach_msg_header_t
*msg
)
1419 fprintf(stderr
, "<< %s\n", __func__
);
1422 si_async_handle_reply(msg
);
1426 getipnodebyaddr_async_handleReply(mach_msg_header_t
*msg
)
1429 fprintf(stderr
, "<< %s\n", __func__
);
1432 si_async_handle_reply(msg
);
1437 sethostent(int ignored
)
1440 fprintf(stderr
, "-- %s\n", __func__
);
1443 LI_set_thread_list(CATEGORY_HOST
, NULL
);
1453 fprintf(stderr
, "-> %s\n", __func__
);
1456 list
= LI_get_thread_list(CATEGORY_HOST
);
1459 list
= si_host_all(si_search());
1460 LI_set_thread_list(CATEGORY_HOST
, list
);
1463 item
= si_list_next(list
);
1464 if (item
== NULL
) return NULL
;
1466 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1473 fprintf(stderr
, "-- %s\n", __func__
);
1476 LI_set_thread_list(CATEGORY_HOST
, NULL
);
1482 ether_hostton(const char *name
, struct ether_addr
*e
)
1490 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1493 if (name
== NULL
) return -1;
1494 if (e
== NULL
) return -1;
1496 item
= si_mac_byname(si_search(), name
);
1497 LI_set_thread_item(CATEGORY_MAC
+ 100, item
);
1498 if (item
== NULL
) return -1;
1500 mac
= (si_mac_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
1502 i
= sscanf(mac
->mac
, " %x:%x:%x:%x:%x:%x", &t
[0], &t
[1], &t
[2], &t
[3], &t
[4], &t
[5]);
1503 if (i
!= 6) return -1;
1505 for (i
= 0; i
< 6; i
++) e
->ether_addr_octet
[i
] = t
[i
];
1509 /* XXX to do? async ether_hostton */
1512 ether_ntohost(char *name
, const struct ether_addr
*e
)
1519 if (name
== NULL
) return -1;
1520 if (e
== NULL
) return -1;
1522 for (i
= 0; i
< 6; i
++) x
[i
] = e
->ether_addr_octet
[i
];
1523 snprintf(str
, sizeof(str
), "%x:%x:%x:%x:%x:%x", x
[0], x
[1], x
[2], x
[3], x
[4], x
[5]);
1526 fprintf(stderr
, "-> %s %s\n", __func__
, str
);
1529 item
= si_mac_bymac(si_search(), str
);
1530 LI_set_thread_item(CATEGORY_MAC
+ 200, item
);
1531 if (item
== NULL
) return -1;
1533 mac
= (si_mac_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
1535 memcpy(name
, mac
->host
, strlen(mac
->host
) + 1);
1539 /* XXX to do? async ether_ntohost */
1544 getnetbyname(const char *name
)
1549 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1552 item
= si_network_byname(si_search(), name
);
1553 LI_set_thread_item(CATEGORY_NETWORK
+ 100, item
);
1554 if (item
== NULL
) return NULL
;
1556 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1560 getnetbyname_async_call(const char *name
, si_network_async_callback callback
, void *context
)
1562 si_context_t
*sictx
;
1565 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1568 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1569 if (sictx
== NULL
) return MACH_PORT_NULL
;
1571 sictx
->orig_callback
= callback
;
1572 sictx
->orig_context
= context
;
1573 sictx
->cat
= CATEGORY_NETWORK
;
1574 sictx
->key_offset
= 100;
1576 return si_async_call(si_search(), SI_CALL_NETWORK_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1580 getnetbyname_async_handle_reply(mach_msg_header_t
*msg
)
1583 fprintf(stderr
, "<< %s\n", __func__
);
1586 si_async_handle_reply(msg
);
1590 getnetbyaddr(uint32_t net
, int type
)
1595 fprintf(stderr
, "-> %s 0x%08x\n", __func__
, net
);
1598 if (type
!= AF_INET
) return NULL
;
1600 item
= si_network_byaddr(si_search(), net
);
1601 LI_set_thread_item(CATEGORY_NETWORK
+ 200, item
);
1602 if (item
== NULL
) return NULL
;
1604 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1608 getnetbyaddr_async_call(uint32_t net
, int type
, si_group_async_callback callback
, void *context
)
1610 si_context_t
*sictx
;
1613 fprintf(stderr
, ">> %s 0x%08x\n", __func__
, net
);
1616 if (type
!= AF_INET
) return MACH_PORT_NULL
;
1618 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1619 if (sictx
== NULL
) return MACH_PORT_NULL
;
1621 sictx
->orig_callback
= callback
;
1622 sictx
->orig_context
= context
;
1623 sictx
->cat
= CATEGORY_NETWORK
;
1624 sictx
->key_offset
= 200;
1626 return si_async_call(si_search(), SI_CALL_NETWORK_BYADDR
, NULL
, NULL
, NULL
, net
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1630 getnetbyaddr_async_handle_reply(mach_msg_header_t
*msg
)
1633 fprintf(stderr
, "<< %s\n", __func__
);
1636 si_async_handle_reply(msg
);
1640 setnetent(int ignored
)
1643 fprintf(stderr
, "-- %s\n", __func__
);
1646 LI_set_thread_list(CATEGORY_NETWORK
, NULL
);
1656 fprintf(stderr
, "-> %s\n", __func__
);
1659 list
= LI_get_thread_list(CATEGORY_NETWORK
);
1662 list
= si_network_all(si_search());
1663 LI_set_thread_list(CATEGORY_NETWORK
, list
);
1666 item
= si_list_next(list
);
1667 if (item
== NULL
) return NULL
;
1669 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1676 fprintf(stderr
, "-- %s\n", __func__
);
1679 LI_set_thread_list(CATEGORY_NETWORK
, NULL
);
1685 getservbyname(const char *name
, const char *proto
)
1690 fprintf(stderr
, "-> %s %s %s\n", __func__
, name
, proto
);
1693 item
= si_service_byname(si_search(), name
, proto
);
1694 LI_set_thread_item(CATEGORY_SERVICE
+ 100, item
);
1695 if (item
== NULL
) return NULL
;
1697 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1701 getservbyname_async_call(const char *name
, const char *proto
, si_service_async_callback callback
, void *context
)
1703 si_context_t
*sictx
;
1706 fprintf(stderr
, ">> %s %s %s\n", __func__
, name
, proto
);
1709 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1710 if (sictx
== NULL
) return MACH_PORT_NULL
;
1712 sictx
->orig_callback
= callback
;
1713 sictx
->orig_context
= context
;
1714 sictx
->cat
= CATEGORY_SERVICE
;
1715 sictx
->key_offset
= 100;
1717 return si_async_call(si_search(), SI_CALL_SERVICE_BYNAME
, name
, proto
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1721 getservbyname_async_handle_reply(mach_msg_header_t
*msg
)
1724 fprintf(stderr
, "<< %s\n", __func__
);
1727 si_async_handle_reply(msg
);
1731 getservbyport(int port
, const char *proto
)
1736 fprintf(stderr
, "-> %s %d %s\n", __func__
, ntohs((uint16_t)port
), proto
);
1739 item
= si_service_byport(si_search(), port
, proto
);
1740 LI_set_thread_item(CATEGORY_SERVICE
+ 200, item
);
1741 if (item
== NULL
) return NULL
;
1743 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1747 getservbyport_async_call(int port
, const char *proto
, si_group_async_callback callback
, void *context
)
1749 si_context_t
*sictx
;
1752 fprintf(stderr
, ">> %s %d %s\n", __func__
, port
, proto
);
1755 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1756 if (sictx
== NULL
) return MACH_PORT_NULL
;
1758 sictx
->orig_callback
= callback
;
1759 sictx
->orig_context
= context
;
1760 sictx
->cat
= CATEGORY_SERVICE
;
1761 sictx
->key_offset
= 200;
1763 return si_async_call(si_search(), SI_CALL_SERVICE_BYPORT
, NULL
, proto
, NULL
, port
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1767 getservbyport_async_handle_reply(mach_msg_header_t
*msg
)
1770 fprintf(stderr
, "<< %s\n", __func__
);
1773 si_async_handle_reply(msg
);
1777 setservent(int ignored
)
1780 fprintf(stderr
, "-- %s\n", __func__
);
1783 LI_set_thread_list(CATEGORY_SERVICE
, NULL
);
1793 fprintf(stderr
, "-> %s\n", __func__
);
1796 list
= LI_get_thread_list(CATEGORY_SERVICE
);
1799 list
= si_service_all(si_search());
1800 LI_set_thread_list(CATEGORY_SERVICE
, list
);
1803 item
= si_list_next(list
);
1804 if (item
== NULL
) return NULL
;
1806 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1813 fprintf(stderr
, "-- %s\n", __func__
);
1816 LI_set_thread_list(CATEGORY_SERVICE
, NULL
);
1822 getprotobyname(const char *name
)
1827 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1830 item
= si_protocol_byname(si_search(), name
);
1831 LI_set_thread_item(CATEGORY_PROTOCOL
+ 100, item
);
1832 if (item
== NULL
) return NULL
;
1834 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1838 getprotobyname_async_call(const char *name
, si_protocol_async_callback callback
, void *context
)
1840 si_context_t
*sictx
;
1843 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1846 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1847 if (sictx
== NULL
) return MACH_PORT_NULL
;
1849 sictx
->orig_callback
= callback
;
1850 sictx
->orig_context
= context
;
1851 sictx
->cat
= CATEGORY_PROTOCOL
;
1852 sictx
->key_offset
= 100;
1854 return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1858 getprotobyname_async_handle_reply(mach_msg_header_t
*msg
)
1861 fprintf(stderr
, "<< %s\n", __func__
);
1864 si_async_handle_reply(msg
);
1868 getprotobynumber(int number
)
1873 fprintf(stderr
, "-> %s %d\n", __func__
, number
);
1876 item
= si_protocol_bynumber(si_search(), number
);
1877 LI_set_thread_item(CATEGORY_PROTOCOL
+ 200, item
);
1878 if (item
== NULL
) return NULL
;
1880 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1884 getprotobynumber_async_call(int number
, si_group_async_callback callback
, void *context
)
1886 si_context_t
*sictx
;
1889 fprintf(stderr
, ">> %s %d\n", __func__
, number
);
1892 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1893 if (sictx
== NULL
) return MACH_PORT_NULL
;
1895 sictx
->orig_callback
= callback
;
1896 sictx
->orig_context
= context
;
1897 sictx
->cat
= CATEGORY_PROTOCOL
;
1898 sictx
->key_offset
= 200;
1900 return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNUMBER
, NULL
, NULL
, NULL
, number
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1904 getprotobynumber_async_handle_reply(mach_msg_header_t
*msg
)
1907 fprintf(stderr
, "<< %s\n", __func__
);
1910 si_async_handle_reply(msg
);
1914 setprotoent(int ignored
)
1917 fprintf(stderr
, "-- %s\n", __func__
);
1920 LI_set_thread_list(CATEGORY_PROTOCOL
, NULL
);
1930 fprintf(stderr
, "-> %s\n", __func__
);
1933 list
= LI_get_thread_list(CATEGORY_PROTOCOL
);
1936 list
= si_protocol_all(si_search());
1937 LI_set_thread_list(CATEGORY_PROTOCOL
, list
);
1940 item
= si_list_next(list
);
1941 if (item
== NULL
) return NULL
;
1943 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1950 fprintf(stderr
, "-- %s\n", __func__
);
1953 LI_set_thread_list(CATEGORY_PROTOCOL
, NULL
);
1959 getrpcbyname(const char *name
)
1964 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1967 item
= si_rpc_byname(si_search(), name
);
1968 LI_set_thread_item(CATEGORY_RPC
+ 100, item
);
1969 if (item
== NULL
) return NULL
;
1971 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1975 getrpcbyname_async_call(const char *name
, si_rpc_async_callback callback
, void *context
)
1977 si_context_t
*sictx
;
1980 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1983 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1984 if (sictx
== NULL
) return MACH_PORT_NULL
;
1986 sictx
->orig_callback
= callback
;
1987 sictx
->orig_context
= context
;
1988 sictx
->cat
= CATEGORY_RPC
;
1989 sictx
->key_offset
= 100;
1991 return si_async_call(si_search(), SI_CALL_RPC_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1995 getrpcbyname_async_handle_reply(mach_msg_header_t
*msg
)
1998 fprintf(stderr
, "<< %s\n", __func__
);
2001 si_async_handle_reply(msg
);
2017 fprintf(stderr
, "-> %s %ld\n", __func__
, (long int)number
);
2020 item
= si_rpc_bynumber(si_search(), number
);
2021 LI_set_thread_item(CATEGORY_RPC
+ 200, item
);
2022 if (item
== NULL
) return NULL
;
2024 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2028 getrpcbynumber_async_call(int number
, si_group_async_callback callback
, void *context
)
2030 si_context_t
*sictx
;
2033 fprintf(stderr
, ">> %s %d\n", __func__
, number
);
2036 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2037 if (sictx
== NULL
) return MACH_PORT_NULL
;
2039 sictx
->orig_callback
= callback
;
2040 sictx
->orig_context
= context
;
2041 sictx
->cat
= CATEGORY_RPC
;
2042 sictx
->key_offset
= 200;
2044 return si_async_call(si_search(), SI_CALL_RPC_BYNUMBER
, NULL
, NULL
, NULL
, number
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2048 getrpcbynumber_async_handle_reply(mach_msg_header_t
*msg
)
2051 fprintf(stderr
, "<< %s\n", __func__
);
2054 si_async_handle_reply(msg
);
2058 setrpcent(int ignored
)
2061 fprintf(stderr
, "-- %s\n", __func__
);
2064 LI_set_thread_list(CATEGORY_RPC
, NULL
);
2074 fprintf(stderr
, "-> %s\n", __func__
);
2077 list
= LI_get_thread_list(CATEGORY_RPC
);
2080 list
= si_rpc_all(si_search());
2081 LI_set_thread_list(CATEGORY_RPC
, list
);
2084 item
= si_list_next(list
);
2085 if (item
== NULL
) return NULL
;
2087 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2094 fprintf(stderr
, "-- %s\n", __func__
);
2097 LI_set_thread_list(CATEGORY_RPC
, NULL
);
2103 getfsspec(const char *spec
)
2108 fprintf(stderr
, "-> %s %s\n", __func__
, spec
);
2111 item
= si_fs_byspec(si_search(), spec
);
2112 LI_set_thread_item(CATEGORY_FS
+ 100, item
);
2113 if (item
== NULL
) return NULL
;
2115 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2119 getfsbyname(const char *name
)
2122 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
2125 return getfsspec(name
);
2129 getfsspec_async_call(const char *spec
, si_fs_async_callback callback
, void *context
)
2131 si_context_t
*sictx
;
2134 fprintf(stderr
, ">> %s %s\n", __func__
, spec
);
2137 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2138 if (sictx
== NULL
) return MACH_PORT_NULL
;
2140 sictx
->orig_callback
= callback
;
2141 sictx
->orig_context
= context
;
2142 sictx
->cat
= CATEGORY_FS
;
2143 sictx
->key_offset
= 100;
2145 return si_async_call(si_search(), SI_CALL_FS_BYSPEC
, spec
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2149 getfsspec_async_handle_reply(mach_msg_header_t
*msg
)
2152 fprintf(stderr
, "<< %s\n", __func__
);
2155 si_async_handle_reply(msg
);
2159 getfsfile(const char *file
)
2164 fprintf(stderr
, "-> %s %s\n", __func__
, file
);
2167 item
= si_fs_byfile(si_search(), file
);
2168 LI_set_thread_item(CATEGORY_FS
+ 200, item
);
2169 if (item
== NULL
) return NULL
;
2171 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2175 getfsfile_async_call(const char *file
, si_fs_async_callback callback
, void *context
)
2177 si_context_t
*sictx
;
2180 fprintf(stderr
, ">> %s %s\n", __func__
, file
);
2183 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2184 if (sictx
== NULL
) return MACH_PORT_NULL
;
2186 sictx
->orig_callback
= callback
;
2187 sictx
->orig_context
= context
;
2188 sictx
->cat
= CATEGORY_FS
;
2189 sictx
->key_offset
= 200;
2191 return si_async_call(si_search(), SI_CALL_FS_BYFILE
, file
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2195 getfsfile_async_handle_reply(mach_msg_header_t
*msg
)
2198 fprintf(stderr
, "<< %s\n", __func__
);
2201 si_async_handle_reply(msg
);
2208 fprintf(stderr
, "-> %s\n", __func__
);
2211 LI_set_thread_list(CATEGORY_FS
, NULL
);
2222 fprintf(stderr
, "-> %s\n", __func__
);
2225 list
= LI_get_thread_list(CATEGORY_FS
);
2228 list
= si_fs_all(si_search());
2229 LI_set_thread_list(CATEGORY_FS
, list
);
2232 item
= si_list_next(list
);
2233 if (item
== NULL
) return NULL
;
2235 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2242 fprintf(stderr
, "-- %s\n", __func__
);
2245 LI_set_thread_list(CATEGORY_FS
, NULL
);
2251 _getaddrinfo_internal(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, const char *interface
, struct addrinfo
**res
)
2254 uint32_t family
, socktype
, protocol
, flags
, status
;
2255 struct addrinfo
*ai
;
2258 socktype
= SOCK_UNSPEC
;
2259 protocol
= IPPROTO_UNSPEC
;
2261 status
= SI_STATUS_NO_ERROR
;
2263 if (res
== NULL
) return 0;
2268 family
= hints
->ai_family
;
2269 socktype
= hints
->ai_socktype
;
2270 protocol
= hints
->ai_protocol
;
2271 flags
= hints
->ai_flags
;
2275 fprintf(stderr
, "-> %s %s %s %u %u %u 0x%08x %s\n", __func__
, nodename
, servname
, family
, socktype
, protocol
, flags
, (interface
== NULL
) ? "" : interface
);
2278 list
= si_addrinfo(si_search(), nodename
, servname
, family
, socktype
, protocol
, flags
, interface
, &status
);
2279 if ((status
!= SI_STATUS_NO_ERROR
) || (list
== NULL
) || (list
->count
== 0))
2281 si_list_release(list
);
2283 if (status
== SI_STATUS_NO_ERROR
) return EAI_NONAME
;
2284 else if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2285 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2286 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2290 *res
= si_list_to_addrinfo(list
);
2291 si_list_release(list
);
2292 if (*res
== NULL
) status
= EAI_MEMORY
;
2294 /* don't return the canonical name unless asked */
2295 if ((flags
& AI_CANONNAME
) == 0)
2297 for (ai
= *res
; ai
!= NULL
; ai
= ai
->ai_next
)
2299 free(ai
->ai_canonname
);
2300 ai
->ai_canonname
= NULL
;
2308 getaddrinfo(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, struct addrinfo
**res
)
2310 return _getaddrinfo_internal(nodename
, servname
, hints
, NULL
, res
);
2316 socket_name(int sock
)
2318 static char str
[16];
2322 case SOCK_UNSPEC
: return "SOCK_UNSPEC";
2323 case SOCK_STREAM
: return "SOCK_STREAM";
2324 case SOCK_DGRAM
: return "SOCK_DGRAM";
2327 sprintf(str
, "%d", sock
);
2334 static char str
[16];
2338 case PF_UNSPEC
: return "PF_UNSPEC";
2339 case PF_INET
: return "PF_INET";
2340 case PF_INET6
: return "PF_INET6";
2343 sprintf(str
, "%d", pf
);
2348 protocol_name(int p
)
2350 static char str
[16];
2354 case IPPROTO_UNSPEC
: return "IPPROTO_UNSPEC";
2355 case IPPROTO_TCP
: return "IPPROTO_TCP";
2356 case IPPROTO_UDP
: return "IPPROTO_UDP";
2359 sprintf(str
, "%d", p
);
2364 _gai_inet_ntop(struct in6_addr a
)
2366 static char buf
[128];
2372 memset(buf
, 0, 128);
2374 p
= (char *)&a
.__u6_addr
.__u6_addr32
;
2375 for (i
= 0; i
< 8; i
++, x
+= 1)
2379 sprintf(t
, "%hx", x
);
2381 if (i
< 7) strcat(buf
, ":");
2388 fprint_addrinfo(FILE *f
, struct addrinfo
*a
)
2392 struct sockaddr_in
*s4
;
2393 struct sockaddr_in6
*s6
;
2395 if (a
== NULL
) return;
2397 if (a
->ai_flags
!= 0)
2399 fprintf(f
, "flags =");
2400 if (a
->ai_flags
& AI_PASSIVE
) fprintf(f
, " AI_PASSIVE");
2401 if (a
->ai_flags
& AI_CANONNAME
) fprintf(f
, " AI_CANONNAME");
2402 if (a
->ai_flags
& AI_NUMERICHOST
) fprintf(f
, " AI_NUMERICHOST");
2403 if (a
->ai_flags
& AI_NUMERICSERV
) fprintf(f
, " AI_NUMERICSERV");
2407 fprintf(f
, "family = %s\n", family_name(a
->ai_family
));
2408 fprintf(f
, "socktype = %s\n", socket_name(a
->ai_socktype
));
2409 fprintf(f
, "protocol = %s\n", protocol_name(a
->ai_protocol
));
2411 fprintf(f
, "canonical name = ");
2412 if (a
->ai_canonname
== NULL
) fprintf(f
, "NULL\n");
2413 else fprintf(f
, "\"%s\"\n", a
->ai_canonname
);
2415 fprintf(f
, "addrlen = %ld\n", (long int)a
->ai_addrlen
);
2417 if (a
->ai_addr
== NULL
) fprintf(f
, "sockaddr = NULL\n");
2420 if (a
->ai_family
== PF_INET
)
2422 s4
= (struct sockaddr_in
*)a
->ai_addr
;
2424 fprintf(f
, "sockaddr_in len = %d\n", s4
->sin_len
);
2425 fprintf(f
, "sockaddr_in family = %s\n", family_name(s4
->sin_family
));
2426 fprintf(f
, "sockaddr_in port = %hu\n", ntohs(s4
->sin_port
));
2427 fprintf(f
, "sockaddr_in address = %s\n", inet_ntoa(s4
->sin_addr
));
2429 else if (a
->ai_family
== PF_INET6
)
2431 s6
= (struct sockaddr_in6
*)a
->ai_addr
;
2433 fprintf(f
, "sockaddr_in6 len = %d\n", s6
->sin6_len
);
2434 fprintf(f
, "sockaddr_in6 family = %s\n", family_name(s6
->sin6_family
));
2435 fprintf(f
, "sockaddr_in6 port = %hu\n", ntohs(s6
->sin6_port
));
2436 fprintf(f
, "sockaddr_in6 flowinfo = %d\n", s6
->sin6_flowinfo
);
2437 fprintf(f
, "sockaddr_in6 address = %s\n", _gai_inet_ntop(s6
->sin6_addr
));
2438 fprintf(f
, "sockaddr_in6 scope_id = %d\n", s6
->sin6_scope_id
);
2442 fprintf(f
, "sockaddr len = %d\n", a
->ai_addr
->sa_len
);
2443 fprintf(f
, "sockaddr family = %s\n", family_name(a
->ai_addr
->sa_family
));
2444 fprintf(f
, "sockaddr data = ");
2445 for (i
= 0; i
< a
->ai_addr
->sa_len
- 2; i
++)
2447 v
= a
->ai_addr
->sa_data
[i
];
2448 fprintf(f
, "%02x", v
);
2454 if (a
->ai_next
!= NULL
)
2456 fprintf(f
, "NEXT --->\n");
2457 fprint_addrinfo(f
, a
->ai_next
);
2464 si_libinfo_addrinfo_callback(si_list_t
*list
, uint32_t status
, void *ctx
)
2466 si_context_t
*sictx
;
2467 struct addrinfo
*out
;
2472 fprintf(stderr
, " %s error no context\n", __func__
);
2474 si_list_release(list
);
2478 sictx
= (si_context_t
*)ctx
;
2480 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
2483 fprintf(stderr
, " %s error no callback\n", __func__
);
2485 si_list_release(list
);
2490 if (status
!= SI_STATUS_NO_ERROR
)
2493 fprintf(stderr
, " %s original status %d\n", __func__
, status
);
2495 if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2496 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2497 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2503 fprintf(stderr
, " %s result NULL status %d (returning EAI_NONAME)\n", __func__
, status
);
2505 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(EAI_NONAME
, NULL
, sictx
->orig_context
);
2510 out
= si_list_to_addrinfo(list
);
2511 si_list_release(list
);
2515 fprintf(stderr
, " %s result conversion failed returning NULL status %d (returning EAI_MEMORY)\n", __func__
, status
);
2517 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(EAI_MEMORY
, NULL
, sictx
->orig_context
);
2523 fprintf(stderr
, " %s %d\n", __func__
, status
);
2524 fprint_addrinfo(stderr
, out
);
2526 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(status
, out
, sictx
->orig_context
);
2533 _getaddrinfo_interface_async_call(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, const char *interface
, si_addrinfo_async_callback callback
, void *context
)
2535 si_context_t
*sictx
;
2536 uint32_t family
, socktype
, protocol
, flags
;
2539 socktype
= SOCK_UNSPEC
;
2540 protocol
= IPPROTO_UNSPEC
;
2545 family
= hints
->ai_family
;
2546 socktype
= hints
->ai_socktype
;
2547 protocol
= hints
->ai_protocol
;
2548 flags
= hints
->ai_flags
;
2552 fprintf(stderr
, ">> %s %s %s %u %u %u 0x%08x\n", __func__
, nodename
, servname
, family
, socktype
, protocol
, flags
);
2555 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2556 if (sictx
== NULL
) return MACH_PORT_NULL
;
2558 sictx
->orig_callback
= callback
;
2559 sictx
->orig_context
= context
;
2560 sictx
->cat
= CATEGORY_ADDRINFO
;
2561 sictx
->key_offset
= 0;
2563 return si_async_call(si_search(), SI_CALL_ADDRINFO
, nodename
, servname
, interface
, family
, socktype
, protocol
, flags
, (void *)si_libinfo_addrinfo_callback
, sictx
);
2567 getaddrinfo_async_call(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, si_addrinfo_async_callback callback
, void *context
)
2569 return _getaddrinfo_interface_async_call(nodename
, servname
, hints
, NULL
, callback
, context
);
2573 getaddrinfo_async_start(mach_port_t
*p
, const char *nodename
, const char *servname
, const struct addrinfo
*hints
, si_addrinfo_async_callback callback
, void *context
)
2575 if (p
== NULL
) return EAI_SYSTEM
;
2577 *p
= getaddrinfo_async_call(nodename
, servname
, hints
, callback
, context
);
2579 if (*p
== MACH_PORT_NULL
) return EAI_SYSTEM
;
2584 getaddrinfo_async_send(mach_port_t
*p
, const char *nodename
, const char *servname
, const struct addrinfo
*hints
)
2586 return getaddrinfo_async_start(p
, nodename
, servname
, hints
, NULL
, NULL
);
2590 getaddrinfo_async_receive(mach_port_t p
, struct addrinfo
**res
)
2592 /* unsupported Leopard SPI */
2597 getaddrinfo_async_cancel(mach_port_t p
)
2600 fprintf(stderr
, "-- %s\n", __func__
);
2607 getaddrinfo_async_handle_reply(void *param
)
2609 mach_msg_header_t
*msg
;
2612 fprintf(stderr
, "<< %s\n", __func__
);
2615 msg
= (mach_msg_header_t
*)param
;
2616 si_async_handle_reply(msg
);
2624 _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
)
2628 uint32_t status
, len
, wantn
, wants
;
2631 fprintf(stderr
, "-> %s\n", __func__
);
2634 status
= SI_STATUS_NO_ERROR
;
2637 if ((node
!= NULL
) && (nodelen
> 0)) wantn
= 1;
2640 if ((service
!= NULL
) && (servicelen
> 0)) wants
= 1;
2642 if ((wantn
== 0) && (wants
== 0)) return status
;
2644 if (wantn
== 0) flags
|= NI_NUMERICHOST
;
2645 if (wants
== 0) flags
|= NI_NUMERICSERV
;
2647 item
= si_nameinfo(si_search(), sa
, flags
, interface
, &status
);
2648 if ((status
!= SI_STATUS_NO_ERROR
) || (item
== NULL
))
2650 si_item_release(item
);
2652 if (status
== SI_STATUS_NO_ERROR
) status
= EAI_NONAME
;
2653 else if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2654 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2655 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2659 ni
= (si_nameinfo_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
2662 if (ni
->ni_node
!= NULL
) len
= strlen(ni
->ni_node
) + 1;
2663 if ((wantn
== 1) && (len
> 0))
2667 si_item_release(item
);
2668 return EAI_OVERFLOW
;
2671 memset(node
, 0, nodelen
);
2672 memcpy(node
, ni
->ni_node
, len
);
2676 if (ni
->ni_serv
!= NULL
) len
= strlen(ni
->ni_serv
) + 1;
2677 if ((wants
== 1) && (len
> 0))
2679 if (len
> servicelen
)
2681 si_item_release(item
);
2682 return EAI_OVERFLOW
;
2685 memset(service
, 0, servicelen
);
2686 memcpy(service
, ni
->ni_serv
, len
);
2689 si_item_release(item
);
2694 getnameinfo(const struct sockaddr
*sa
, socklen_t salen
, char *node
, socklen_t nodelen
, char *service
, socklen_t servicelen
, int flags
)
2696 if (sa
== NULL
) return EAI_FAIL
;
2698 if (sa
->sa_family
== AF_LINK
) return getnameinfo_link(sa
, salen
, node
, nodelen
, service
, servicelen
, flags
);
2699 return _getnameinfo_interface_internal(sa
, salen
, node
, nodelen
, service
, servicelen
, flags
, NULL
);
2703 si_libinfo_nameinfo_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
2705 si_context_t
*sictx
;
2709 if (ctx
== NULL
) return;
2711 sictx
= (si_context_t
*)ctx
;
2713 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
2715 si_item_release(item
);
2720 if (status
!= SI_STATUS_NO_ERROR
)
2722 if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2723 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2724 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2729 ((si_nameinfo_async_callback
)(sictx
->orig_callback
))(status
, NULL
, NULL
, sictx
->orig_context
);
2734 LI_set_thread_item(CATEGORY_NAMEINFO
, item
);
2739 ni
= (si_nameinfo_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
2740 if (ni
->ni_node
!= NULL
) node
= strdup(ni
->ni_node
);
2741 if (ni
->ni_serv
!= NULL
) serv
= strdup(ni
->ni_serv
);
2743 ((si_nameinfo_async_callback
)(sictx
->orig_callback
))(status
, node
, serv
, sictx
->orig_context
);
2749 _getnameinfo_interface_async_call(const struct sockaddr
*sa
, size_t len
, int flags
, const char *interface
, si_nameinfo_async_callback callback
, void *context
)
2751 si_context_t
*sictx
;
2755 fprintf(stderr
, ">> %s\n", __func__
);
2758 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2759 if (sictx
== NULL
) return MACH_PORT_NULL
;
2761 sictx
->orig_callback
= callback
;
2762 sictx
->orig_context
= context
;
2763 sictx
->cat
= CATEGORY_ADDRINFO
;
2764 sictx
->key_offset
= 0;
2766 /* sa is not a C string - pass length in num3 */
2768 return si_async_call(si_search(), SI_CALL_NAMEINFO
, (const char *)sa
, NULL
, interface
, flags
, 0, salen
, 0, (void *)si_libinfo_nameinfo_callback
, sictx
);
2772 getnameinfo_async_call(const struct sockaddr
*sa
, size_t len
, int flags
, si_nameinfo_async_callback callback
, void *context
)
2774 return _getnameinfo_interface_async_call(sa
, len
, flags
, NULL
, callback
, context
);
2778 getnameinfo_async_start(mach_port_t
*p
, const struct sockaddr
*sa
, size_t salen
, int flags
, si_nameinfo_async_callback callback
, void *context
)
2780 if (p
== NULL
) return EAI_SYSTEM
;
2781 *p
= getnameinfo_async_call(sa
, salen
, flags
, callback
, context
);
2783 if (*p
== MACH_PORT_NULL
) return EAI_SYSTEM
;
2788 getnameinfo_async_send(mach_port_t
*p
, const struct sockaddr
*sa
, size_t salen
, int flags
)
2790 return getnameinfo_async_start(p
, sa
, salen
, flags
, NULL
, NULL
);
2794 getnameinfo_async_cancel(mach_port_t p
)
2797 fprintf(stderr
, "-- %s\n", __func__
);
2804 getnameinfo_async_handle_reply(void *param
)
2806 mach_msg_header_t
*msg
;
2809 fprintf(stderr
, "<< %s\n", __func__
);
2812 msg
= (mach_msg_header_t
*)param
;
2813 si_async_handle_reply(msg
);
2818 /* getpwXXX_r and getgrXXX_r */
2821 copy_user_r(struct passwd
*in
, struct passwd
*out
, char *buffer
, int buflen
)
2826 if (in
== NULL
) return -1;
2827 if (out
== NULL
) return -1;
2829 if (buffer
== NULL
) buflen
= 0;
2831 /* Calculate size of input */
2833 if (in
->pw_name
!= NULL
) hsize
+= (strlen(in
->pw_name
) + 1);
2834 if (in
->pw_passwd
!= NULL
) hsize
+= (strlen(in
->pw_passwd
) + 1);
2835 if (in
->pw_class
!= NULL
) hsize
+= (strlen(in
->pw_class
) + 1);
2836 if (in
->pw_gecos
!= NULL
) hsize
+= (strlen(in
->pw_gecos
) + 1);
2837 if (in
->pw_dir
!= NULL
) hsize
+= (strlen(in
->pw_dir
) + 1);
2838 if (in
->pw_shell
!= NULL
) hsize
+= (strlen(in
->pw_shell
) + 1);
2840 /* Check buffer space */
2841 if (hsize
> buflen
) return -1;
2843 /* Copy result into caller's struct passwd, using buffer for memory */
2846 out
->pw_name
= NULL
;
2847 if (in
->pw_name
!= NULL
)
2850 hsize
= strlen(in
->pw_name
) + 1;
2851 memmove(bp
, in
->pw_name
, hsize
);
2855 out
->pw_passwd
= NULL
;
2856 if (in
->pw_passwd
!= NULL
)
2858 out
->pw_passwd
= bp
;
2859 hsize
= strlen(in
->pw_passwd
) + 1;
2860 memmove(bp
, in
->pw_passwd
, hsize
);
2864 out
->pw_uid
= in
->pw_uid
;
2866 out
->pw_gid
= in
->pw_gid
;
2868 out
->pw_change
= in
->pw_change
;
2870 out
->pw_class
= NULL
;
2871 if (in
->pw_class
!= NULL
)
2874 hsize
= strlen(in
->pw_class
) + 1;
2875 memmove(bp
, in
->pw_class
, hsize
);
2879 out
->pw_gecos
= NULL
;
2880 if (in
->pw_gecos
!= NULL
)
2883 hsize
= strlen(in
->pw_gecos
) + 1;
2884 memmove(bp
, in
->pw_gecos
, hsize
);
2889 if (in
->pw_dir
!= NULL
)
2892 hsize
= strlen(in
->pw_dir
) + 1;
2893 memmove(bp
, in
->pw_dir
, hsize
);
2897 out
->pw_shell
= NULL
;
2898 if (in
->pw_shell
!= NULL
)
2901 hsize
= strlen(in
->pw_shell
) + 1;
2902 memmove(bp
, in
->pw_shell
, hsize
);
2906 out
->pw_expire
= in
->pw_expire
;
2912 copy_group_r(struct group
*in
, struct group
*out
, char *buffer
, int buflen
)
2918 if (in
== NULL
) return -1;
2919 if (out
== NULL
) return -1;
2921 if (buffer
== NULL
) buflen
= 0;
2923 /* Calculate size of input */
2925 if (in
->gr_name
!= NULL
) hsize
+= (strlen(in
->gr_name
) + 1);
2926 if (in
->gr_passwd
!= NULL
) hsize
+= (strlen(in
->gr_passwd
) + 1);
2928 /* NULL pointer at end of list */
2929 hsize
+= sizeof(char *);
2932 if (in
->gr_mem
!= NULL
)
2934 for (len
= 0; in
->gr_mem
[len
] != NULL
; len
++)
2936 hsize
+= sizeof(char *);
2937 hsize
+= (strlen(in
->gr_mem
[len
]) + 1);
2941 /* Check buffer space */
2942 if (hsize
> buflen
) return -1;
2944 /* Copy result into caller's struct group, using buffer for memory */
2947 out
->gr_name
= NULL
;
2948 if (in
->gr_name
!= NULL
)
2951 hsize
= strlen(in
->gr_name
) + 1;
2952 memmove(bp
, in
->gr_name
, hsize
);
2956 out
->gr_passwd
= NULL
;
2957 if (in
->gr_passwd
!= NULL
)
2959 out
->gr_passwd
= bp
;
2960 hsize
= strlen(in
->gr_passwd
) + 1;
2961 memmove(bp
, in
->gr_passwd
, hsize
);
2965 out
->gr_gid
= in
->gr_gid
;
2968 ap
= bp
+ ((len
+ 1) * sizeof(char *));
2970 if (in
->gr_mem
!= NULL
)
2972 out
->gr_mem
= (char **)bp
;
2973 for (i
= 0; i
< len
; i
++)
2975 addr
= (unsigned long)ap
;
2976 memmove(bp
, &addr
, sizeof(unsigned long));
2977 bp
+= sizeof(unsigned long);
2979 hsize
= strlen(in
->gr_mem
[i
]) + 1;
2980 memmove(ap
, in
->gr_mem
[i
], hsize
);
2985 memset(bp
, 0, sizeof(unsigned long));
2992 getgrnam_r(const char *name
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
2999 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
3002 if (result
!= NULL
) *result
= NULL
;
3004 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3006 item
= si_group_byname(si_search(), name
);
3007 if (item
== NULL
) return 0;
3009 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
3011 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
3012 si_item_release(item
);
3014 if (status
!= 0) return ERANGE
;
3021 getgrgid_r(gid_t gid
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
3028 fprintf(stderr
, "-> %s %d\n", __func__
, gid
);
3031 if (result
!= NULL
) *result
= NULL
;
3033 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3035 item
= si_group_bygid(si_search(), gid
);
3036 if (item
== NULL
) return 0;
3038 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
3040 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
3041 si_item_release(item
);
3043 if (status
!= 0) return ERANGE
;
3050 getpwnam_r(const char *name
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3057 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
3060 if (result
!= NULL
) *result
= NULL
;
3062 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3064 item
= si_user_byname(si_search(), name
);
3065 if (item
== NULL
) return 0;
3067 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3069 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3070 si_item_release(item
);
3072 if (status
!= 0) return ERANGE
;
3079 getpwuid_r(uid_t uid
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3086 fprintf(stderr
, "-> %s %d\n", __func__
, uid
);
3089 if (result
!= NULL
) *result
= NULL
;
3091 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3093 item
= si_user_byuid(si_search(), uid
);
3094 if (item
== NULL
) return 0;
3096 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3098 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3099 si_item_release(item
);
3101 if (status
!= 0) return ERANGE
;
3110 user_from_uid(uid_t uid
, int nouser
)
3113 static char buf
[16];
3116 if (pw
!= NULL
) return pw
->pw_name
;
3118 if (nouser
) return NULL
;
3120 snprintf(buf
, sizeof(buf
), "%u", uid
);
3125 group_from_gid(gid_t gid
, int nogroup
)
3128 static char buf
[16];
3131 if (gr
!= NULL
) return gr
->gr_name
;
3133 if (nogroup
) return NULL
;
3135 snprintf(buf
, sizeof(buf
), "%u", gid
);
3139 /* no longer supported */
3142 prdb_getbyname(const char *name
)
3145 fprintf(stderr
, "~~ %s\n", __func__
);
3154 fprintf(stderr
, "~~ %s\n", __func__
);
3160 prdb_set(const char *name
)
3163 fprintf(stderr
, "~~ %s\n", __func__
);
3171 fprintf(stderr
, "~~ %s\n", __func__
);
3175 struct bootparamsent
*
3176 bootparams_getbyname(const char *name
)
3179 fprintf(stderr
, "~~ %s\n", __func__
);
3184 struct bootparamsent
*
3185 bootparams_getent(void)
3188 fprintf(stderr
, "~~ %s\n", __func__
);
3194 bootparams_setent(void)
3197 fprintf(stderr
, "~~ %s\n", __func__
);
3202 bootparams_endent(void)
3205 fprintf(stderr
, "~~ %s\n", __func__
);
3210 bootp_getbyether(struct ether_addr
*enaddr
, char **name
,struct in_addr
*ipaddr
, char **bootfile
)
3213 fprintf(stderr
, "~~ %s\n", __func__
);
3219 bootp_getbyip(struct ether_addr
*enaddr
, char **name
, struct in_addr
*ipaddr
, char **bootfile
)
3222 fprintf(stderr
, "~~ %s\n", __func__
);