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 <libkern/OSAtomic.h>
37 #include "si_module.h"
39 #include <thread_data.h>
40 #include <sys/kauth.h>
41 #include "netdb_async.h"
44 #define IPPROTO_UNSPEC 0
45 #define IPV6_ADDR_LEN 16
46 #define IPV4_ADDR_LEN 4
48 /* SPI from long ago */
51 __private_extern__
struct addrinfo
*si_list_to_addrinfo(si_list_t
*list
);
54 * Impedence matching for async calls.
56 * This layer holds on to the caller's callback and context in this
57 * structure, which gets passed to the si_module async routines along
58 * with a callbac in this layer. When this layer gets a callback,
59 * it can save the item or list in thread-specific memory and then
60 * invoke the caller's callback with the appropriate data type.
71 __private_extern__ si_mod_t
*
74 static si_mod_t
*search
= NULL
;
75 static OSSpinLock spin
= OS_SPINLOCK_INIT
;
79 OSSpinLockLock(&spin
);
80 if (search
== NULL
) search
= si_module_with_name("search");
81 OSSpinLockUnlock(&spin
);
88 si_libinfo_general_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
96 struct grouplist_s
*l
;
105 if (ctx
== NULL
) return;
107 sictx
= (si_context_t
*)ctx
;
109 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
112 si_item_release(item
);
116 if (sictx
->key_offset
>= 0)
118 LI_set_thread_item(sictx
->cat
+ sictx
->key_offset
, item
);
122 if (item
!= NULL
) res
.x
= (char*)((uintptr_t)item
+ sizeof(si_item_t
));
128 ((si_user_async_callback
)(sictx
->orig_callback
))(res
.u
, sictx
->orig_context
);
133 ((si_group_async_callback
)(sictx
->orig_callback
))(res
.g
, sictx
->orig_context
);
136 case CATEGORY_GROUPLIST
:
138 ((si_grouplist_async_callback
)(sictx
->orig_callback
))(res
.l
, sictx
->orig_context
);
141 case CATEGORY_HOST_IPV4
:
142 case CATEGORY_HOST_IPV6
:
144 ((si_host_async_callback
)(sictx
->orig_callback
))(res
.h
, sictx
->orig_context
);
147 case CATEGORY_NETWORK
:
149 ((si_network_async_callback
)(sictx
->orig_callback
))(res
.n
, sictx
->orig_context
);
152 case CATEGORY_SERVICE
:
154 ((si_service_async_callback
)(sictx
->orig_callback
))(res
.s
, sictx
->orig_context
);
157 case CATEGORY_PROTOCOL
:
159 ((si_protocol_async_callback
)(sictx
->orig_callback
))(res
.p
, sictx
->orig_context
);
164 ((si_rpc_async_callback
)(sictx
->orig_callback
))(res
.r
, sictx
->orig_context
);
169 ((si_fs_async_callback
)(sictx
->orig_callback
))(res
.f
, sictx
->orig_context
);
180 getpwnam(const char *name
)
185 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
188 item
= si_user_byname(si_search(), name
);
189 LI_set_thread_item(CATEGORY_USER
+ 100, item
);
191 if (item
== NULL
) return NULL
;
192 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
196 getpwnam_async_call(const char *name
, si_user_async_callback callback
, void *context
)
201 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
204 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
205 if (sictx
== NULL
) return MACH_PORT_NULL
;
207 sictx
->orig_callback
= callback
;
208 sictx
->orig_context
= context
;
209 sictx
->cat
= CATEGORY_USER
;
210 sictx
->key_offset
= 100;
212 return si_async_call(si_search(), SI_CALL_USER_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
216 getpwnam_async_handle_reply(mach_msg_header_t
*msg
)
219 fprintf(stderr
, "<< %s\n", __func__
);
222 si_async_handle_reply(msg
);
231 fprintf(stderr
, "-> %s %d\n", __func__
, uid
);
234 item
= si_user_byuid(si_search(), uid
);
235 LI_set_thread_item(CATEGORY_USER
+ 200, item
);
237 if (item
== NULL
) return NULL
;
238 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
242 getpwuid_async_call(uid_t uid
, si_user_async_callback callback
, void *context
)
247 fprintf(stderr
, ">> %s %d\n", __func__
, uid
);
250 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
251 if (sictx
== NULL
) return MACH_PORT_NULL
;
253 sictx
->orig_callback
= callback
;
254 sictx
->orig_context
= context
;
255 sictx
->cat
= CATEGORY_USER
;
256 sictx
->key_offset
= 200;
258 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
);
262 getpwuid_async_handle_reply(mach_msg_header_t
*msg
)
265 fprintf(stderr
, "<< %s\n", __func__
);
268 si_async_handle_reply(msg
);
275 fprintf(stderr
, "-- %s\n", __func__
);
278 LI_set_thread_list(CATEGORY_USER
, NULL
);
288 fprintf(stderr
, "-> %s\n", __func__
);
291 list
= LI_get_thread_list(CATEGORY_USER
);
294 list
= si_user_all(si_search());
295 LI_set_thread_list(CATEGORY_USER
, list
);
298 item
= si_list_next(list
);
299 if (item
== NULL
) return NULL
;
301 return (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
308 fprintf(stderr
, "-- %s\n", __func__
);
311 LI_set_thread_list(CATEGORY_USER
, NULL
);
315 setpassent(int ignored
)
320 fprintf(stderr
, "-> %s\n", __func__
);
323 list
= LI_get_thread_list(CATEGORY_USER
);
326 if (list
== NULL
) return 0;
333 getgrnam(const char *name
)
338 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
341 item
= si_group_byname(si_search(), name
);
342 LI_set_thread_item(CATEGORY_GROUP
+ 100, item
);
344 if (item
== NULL
) return NULL
;
345 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
349 getgrnam_async_call(const char *name
, si_group_async_callback callback
, void *context
)
354 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
357 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
358 if (sictx
== NULL
) return MACH_PORT_NULL
;
360 sictx
->orig_callback
= callback
;
361 sictx
->orig_context
= context
;
362 sictx
->cat
= CATEGORY_GROUP
;
363 sictx
->key_offset
= 100;
365 return si_async_call(si_search(), SI_CALL_GROUP_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
369 getgrnam_async_handle_reply(mach_msg_header_t
*msg
)
372 fprintf(stderr
, "<< %s\n", __func__
);
375 si_async_handle_reply(msg
);
384 fprintf(stderr
, "-> %s %d\n", __func__
, gid
);
387 item
= si_group_bygid(si_search(), gid
);
388 LI_set_thread_item(CATEGORY_GROUP
+ 200, item
);
390 if (item
== NULL
) return NULL
;
391 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
395 getgrgid_async_call(gid_t gid
, si_group_async_callback callback
, void *context
)
400 fprintf(stderr
, ">> %s %d\n", __func__
, gid
);
403 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
404 if (sictx
== NULL
) return MACH_PORT_NULL
;
406 sictx
->orig_callback
= callback
;
407 sictx
->orig_context
= context
;
408 sictx
->cat
= CATEGORY_GROUP
;
409 sictx
->key_offset
= 200;
411 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
);
415 getgruid_async_handle_reply(mach_msg_header_t
*msg
)
418 fprintf(stderr
, "<< %s\n", __func__
);
421 si_async_handle_reply(msg
);
428 fprintf(stderr
, "-- %s\n", __func__
);
431 LI_set_thread_list(CATEGORY_GROUP
, NULL
);
441 fprintf(stderr
, "-> %s\n", __func__
);
444 list
= LI_get_thread_list(CATEGORY_GROUP
);
447 list
= si_group_all(si_search());
448 LI_set_thread_list(CATEGORY_GROUP
, list
);
451 item
= si_list_next(list
);
452 if (item
== NULL
) return NULL
;
454 return (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
461 fprintf(stderr
, "-- %s\n", __func__
);
464 LI_set_thread_list(CATEGORY_GROUP
, NULL
);
468 setgroupent(int ignored
)
473 fprintf(stderr
, "-> %s\n", __func__
);
476 list
= LI_get_thread_list(CATEGORY_GROUP
);
479 if (list
== NULL
) return 0;
485 innetgr(const char *group
, const char *host
, const char *user
, const char *domain
)
489 fprintf(stderr
, "-> %s %s %s %s %s\n", __func__
, group
, host
, user
, domain
);
492 res
= si_in_netgroup(si_search(), group
, host
, user
, domain
);
495 fprintf(stderr
, "<- %s %d\n", __func__
, res
);
501 /* N.B. there is no async innetgr */
504 * setnetgrent is really more like a getXXXbyname routine than a
505 * setXXXent routine, since we are looking up a netgroup by name.
508 setnetgrent(const char *name
)
513 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
516 list
= si_netgroup_byname(si_search(), name
);
517 LI_set_thread_list(CATEGORY_NETGROUP
, list
);
520 /* N.B. there is no async getnetgrent */
523 getnetgrent(char **host
, char **user
, char **domain
)
527 struct netgrent_s
*ng
;
530 fprintf(stderr
, "-> %s\n", __func__
);
533 list
= LI_get_thread_list(CATEGORY_NETGROUP
);
534 item
= si_list_next(list
);
535 if (item
== NULL
) return 0;
537 ng
= (struct netgrent_s
*)((uintptr_t)item
+ sizeof(si_item_t
));
541 *domain
= ng
->ng_domain
;
550 fprintf(stderr
, "-- %s\n", __func__
);
553 LI_set_thread_list(CATEGORY_NETGROUP
, NULL
);
559 getgrouplist(const char *name
, int basegid
, int *groups
, int *ngroups
)
561 int i
, j
, x
, g
, add
, max
;
566 * On input, ngroups specifies the size of the groups array.
567 * On output, it is set to the number of groups that are being returned.
568 * Returns -1 if the size is too small to fit all the groups that were found.
572 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
575 if (name
== NULL
) return 0;
576 if (groups
== NULL
) return 0;
577 if (ngroups
== NULL
) return 0;
581 if (max
<= 0) return 0;
586 item
= si_grouplist(si_search(), name
);
587 LI_set_thread_item(CATEGORY_GROUPLIST
, item
);
588 if (item
== NULL
) return 0;
590 gl
= (si_grouplist_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
594 if (gl
->gl_basegid
!= basegid
)
596 if (x
>= max
) return -1;
597 groups
[x
] = gl
->gl_basegid
;
602 for (i
= 0; i
< gl
->gl_count
; i
++)
604 g
= (int)*(gl
->gl_gid
[i
]);
606 for (j
= 0; (j
< x
) && (add
== 1); j
++) if (groups
[j
] == g
) add
= 0;
607 if (add
== 0) continue;
609 if (x
>= max
) return -1;
618 /* XXX to do: async getgrouplist */
621 merge_gid(gid_t
**list
, gid_t g
, int32_t *count
)
625 if (list
== NULL
) return -1;
629 *list
= (gid_t
*)calloc(1, sizeof(gid_t
));
636 (*list
)[(*count
)++] = g
;
640 for (i
= 0; i
< *count
; i
++) if ((*list
)[i
] == g
) return 0;
642 *list
= (gid_t
*)reallocf(*list
, (*count
+ 1) * sizeof(gid_t
));
643 (*list
)[(*count
)++] = g
;
648 getgrouplist_2(const char *name
, gid_t basegid
, gid_t
**groups
)
650 int32_t i
, status
, count
;
656 * Passes back a gid_t list containing all the users groups (and basegid).
657 * Caller must free the list.
658 * Returns the number of gids in the list or -1 on failure.
662 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
665 if (name
== NULL
) return 0;
666 if (groups
== NULL
) return 0;
668 item
= si_grouplist(si_search(), name
);
669 LI_set_thread_item(CATEGORY_GROUPLIST
, item
);
670 if (item
== NULL
) return -1;
672 gl
= (si_grouplist_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
677 status
= merge_gid(groups
, basegid
, &count
);
678 if (status
!= 0) return status
;
680 status
= merge_gid(groups
, gl
->gl_basegid
, &count
);
681 if (status
!= 0) return status
;
683 for (i
= 0; i
< gl
->gl_count
; i
++)
685 g
= (gid_t
)*(gl
->gl_gid
[i
]);
686 status
= merge_gid(groups
, g
, &count
);
687 if (status
!= 0) return status
;
694 getgroupcount(const char *name
, gid_t basegid
)
696 int32_t i
, status
, count
;
703 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
706 if (name
== NULL
) return 0;
708 item
= si_grouplist(si_search(), name
);
709 LI_set_thread_item(CATEGORY_GROUPLIST
, item
);
710 if (item
== NULL
) return -1;
712 gl
= (si_grouplist_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
717 status
= merge_gid(&groups
, basegid
, &count
);
718 if (status
!= 0) return status
;
720 status
= merge_gid(&groups
, gl
->gl_basegid
, &count
);
721 if (status
!= 0) return status
;
723 for (i
= 0; i
< gl
->gl_count
; i
++)
725 g
= (gid_t
)*(gl
->gl_gid
[i
]);
726 status
= merge_gid(&groups
, g
, &count
);
727 if (status
!= 0) return status
;
730 if (groups
!= NULL
) free(groups
);
735 /* XXX to do: async getgrouplist_2 */
738 initgroups(const char *name
, int basegid
)
740 int status
, ngroups
, groups
[NGROUPS
];
748 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, basegid
);
751 /* KAUTH_UID_NONE tells the kernel not to fetch supplementary groups from DirectoryService */
752 uid
= KAUTH_UID_NONE
;
755 /* get the UID for this user */
756 item
= si_user_byname(si_search(), name
);
759 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
762 si_item_release(item
);
768 status
= getgrouplist(name
, basegid
, groups
, &ngroups
);
771 * A failure either means that user belongs to more than NGROUPS groups
772 * or no groups at all.
775 status
= syscall(SYS_initgroups
, ngroups
, groups
, uid
);
776 if (status
< 0) return -1;
784 alias_getbyname(const char *name
)
789 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
792 item
= si_alias_byname(si_search(), name
);
793 LI_set_thread_item(CATEGORY_ALIAS
+ 100, item
);
794 if (item
== NULL
) return NULL
;
796 return (struct aliasent
*)((uintptr_t)item
+ sizeof(si_item_t
));
800 alias_getbyname_async_call(const char *name
, si_alias_async_callback callback
, void *context
)
805 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
808 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
809 if (sictx
== NULL
) return MACH_PORT_NULL
;
811 sictx
->orig_callback
= callback
;
812 sictx
->orig_context
= context
;
813 sictx
->cat
= CATEGORY_ALIAS
;
814 sictx
->key_offset
= 100;
816 return si_async_call(si_search(), SI_CALL_ALIAS_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
820 alias_getbyname_async_handle_reply(mach_msg_header_t
*msg
)
823 fprintf(stderr
, "<< %s\n", __func__
);
826 si_async_handle_reply(msg
);
833 fprintf(stderr
, "-> %s\n", __func__
);
836 LI_set_thread_list(CATEGORY_ALIAS
, NULL
);
846 fprintf(stderr
, "-> %s\n", __func__
);
849 list
= LI_get_thread_list(CATEGORY_ALIAS
);
852 list
= si_alias_all(si_search());
853 LI_set_thread_list(CATEGORY_ALIAS
, list
);
856 item
= si_list_next(list
);
857 if (item
== NULL
) return NULL
;
859 return (struct aliasent
*)((uintptr_t)item
+ sizeof(si_item_t
));
866 fprintf(stderr
, "-- %s\n", __func__
);
869 LI_set_thread_list(CATEGORY_ALIAS
, NULL
);
875 freehostent(struct hostent
*h
)
877 if (h
== NULL
) return;
879 si_item_t
*item
= (si_item_t
*)((uintptr_t)h
- sizeof(si_item_t
));
880 si_item_release(item
);
884 gethostbynameerrno(const char *name
, int *err
)
888 struct in_addr addr4
;
891 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
894 memset(&addr4
, 0, sizeof(struct in_addr
));
895 status
= SI_STATUS_NO_ERROR
;
898 if (inet_aton(name
, &addr4
) == 1) item
= si_ipnode_byname(si_search(), name
, AF_INET
, 0, NULL
, &status
);
899 else item
= si_host_byname(si_search(), name
, AF_INET
, NULL
, &status
);
901 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
902 if (err
!= NULL
) *err
= status
;
904 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
905 if (item
== NULL
) return NULL
;
907 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
911 gethostbyname(const char *name
)
915 struct in_addr addr4
;
918 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
921 memset(&addr4
, 0, sizeof(struct in_addr
));
922 status
= SI_STATUS_NO_ERROR
;
925 if (inet_aton(name
, &addr4
) == 1) item
= si_ipnode_byname(si_search(), name
, AF_INET
, 0, NULL
, &status
);
926 else item
= si_host_byname(si_search(), name
, AF_INET
, NULL
, &status
);
928 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
931 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
932 if (item
== NULL
) return NULL
;
934 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
938 gethostbyname_async_call(const char *name
, si_host_async_callback callback
, void *context
)
943 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
946 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
947 if (sictx
== NULL
) return MACH_PORT_NULL
;
949 sictx
->orig_callback
= callback
;
950 sictx
->orig_context
= context
;
951 sictx
->cat
= CATEGORY_HOST
;
952 sictx
->key_offset
= 100;
954 return si_async_call(si_search(), SI_CALL_HOST_BYNAME
, name
, NULL
, NULL
, AF_INET
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
958 gethostbyname_async_start(const char *name
, si_host_async_callback callback
, void *context
)
960 return gethostbyname_async_call(name
, callback
, context
);
964 gethostbyname_async_cancel(mach_port_t p
)
967 fprintf(stderr
, "-- %s\n", __func__
);
975 gethostbyname_async_handle_reply(void *param
)
977 mach_msg_header_t
*msg
;
980 fprintf(stderr
, "<< %s\n", __func__
);
983 msg
= (mach_msg_header_t
*)param
;
984 si_async_handle_reply(msg
);
989 gethostbyname_async_handleReply(void *param
)
991 mach_msg_header_t
*msg
;
994 fprintf(stderr
, "<< %s\n", __func__
);
997 msg
= (mach_msg_header_t
*)param
;
998 si_async_handle_reply(msg
);
1002 gethostbyname2(const char *name
, int af
)
1006 struct in_addr addr4
;
1007 struct in6_addr addr6
;
1008 si_mod_t
*search
= si_search();
1011 fprintf(stderr
, "-> %s %s %d\n", __func__
, name
, af
);
1014 memset(&addr4
, 0, sizeof(struct in_addr
));
1015 memset(&addr6
, 0, sizeof(struct in6_addr
));
1016 status
= SI_STATUS_NO_ERROR
;
1019 if (((af
== AF_INET
) && (inet_aton(name
, &addr4
) == 1)) || ((af
== AF_INET6
) && (inet_pton(af
, name
, &addr6
) == 1)))
1021 item
= si_ipnode_byname(search
, name
, (uint32_t)af
, 0, NULL
, &status
);
1025 item
= si_host_byname(search
, name
, (uint32_t)af
, NULL
, &status
);
1028 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1031 LI_set_thread_item(CATEGORY_HOST
+ 100, item
);
1032 if (item
== NULL
) return NULL
;
1034 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1038 gethostbyname2_async_call(const char *name
, int af
, si_group_async_callback callback
, void *context
)
1040 si_context_t
*sictx
;
1043 fprintf(stderr
, ">> %s %s %d\n", __func__
, name
, af
);
1046 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1047 if (sictx
== NULL
) return MACH_PORT_NULL
;
1049 sictx
->orig_callback
= callback
;
1050 sictx
->orig_context
= context
;
1051 sictx
->cat
= CATEGORY_HOST
;
1052 sictx
->key_offset
= 100;
1054 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
);
1058 gethostbyname2_async_cancel(mach_port_t p
)
1061 fprintf(stderr
, "-- %s\n", __func__
);
1068 gethostbyname2_async_handle_reply(mach_msg_header_t
*msg
)
1071 fprintf(stderr
, "<< %s\n", __func__
);
1074 si_async_handle_reply(msg
);
1078 gethostbyaddr(const void *addr
, socklen_t len
, int type
)
1084 fprintf(stderr
, "-> %s %s\n", __func__
, (type
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)addr
) : "-IPv6-");
1087 status
= SI_STATUS_NO_ERROR
;
1089 item
= si_host_byaddr(si_search(), addr
, (uint32_t)type
, NULL
, &status
);
1090 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1093 LI_set_thread_item(CATEGORY_HOST
+ 200, item
);
1094 if (item
== NULL
) return NULL
;
1096 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1100 gethostbyaddr_async_call(const void *addr
, socklen_t len
, int type
, si_host_async_callback callback
, void *context
)
1102 si_context_t
*sictx
;
1106 fprintf(stderr
, ">> %s %s\n", __func__
, (type
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)addr
) : "-IPv6-");
1109 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1110 if (sictx
== NULL
) return MACH_PORT_NULL
;
1112 sictx
->orig_callback
= callback
;
1113 sictx
->orig_context
= context
;
1114 sictx
->cat
= CATEGORY_HOST
;
1115 sictx
->key_offset
= 200;
1117 /* addr is not a C string - pass length in num3 */
1119 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
);
1123 gethostbyaddr_async_start(const char *addr
, int len
, int family
, si_host_async_callback callback
, void *context
)
1125 socklen_t slen
= len
;
1127 return gethostbyaddr_async_call(addr
, slen
, family
, callback
, context
);
1131 gethostbyaddr_async_cancel(mach_port_t p
)
1134 fprintf(stderr
, "-- %s\n", __func__
);
1142 gethostbyaddr_async_handle_reply(void *param
)
1145 mach_msg_header_t
*msg
;
1148 fprintf(stderr
, "<< %s\n", __func__
);
1151 msg
= (mach_msg_header_t
*)param
;
1152 si_async_handle_reply(msg
);
1157 gethostbyaddr_async_handleReply(void *param
)
1159 mach_msg_header_t
*msg
;
1162 fprintf(stderr
, "<< %s\n", __func__
);
1165 msg
= (mach_msg_header_t
*)param
;
1166 si_async_handle_reply(msg
);
1170 getipnodebyname(const char *name
, int family
, int flags
, int *err
)
1176 fprintf(stderr
, "-> %s %s %d 0x%08x\n", __func__
, name
, family
, flags
);
1179 status
= SI_STATUS_NO_ERROR
;
1181 item
= si_ipnode_byname(si_search(), name
, family
, flags
, NULL
, &status
);
1182 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1183 if (err
!= NULL
) *err
= status
;
1185 if (item
== NULL
) return NULL
;
1187 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1192 getipnodebyname_async_call(const char *name
, int family
, int flags
, int *err
, si_host_async_callback callback
, void *context
)
1194 si_context_t
*sictx
;
1197 fprintf(stderr
, ">> %s %s %d 0x%08x\n", __func__
, name
, family
, flags
);
1200 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1201 if (sictx
== NULL
) return MACH_PORT_NULL
;
1203 sictx
->orig_callback
= callback
;
1204 sictx
->orig_context
= context
;
1205 sictx
->cat
= CATEGORY_HOST
;
1206 sictx
->key_offset
= -1;
1208 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
);
1212 getipnodebyname_async_start(const char *name
, int family
, int flags
, int *err
, si_host_async_callback callback
, void *context
)
1214 return getipnodebyname_async_call(name
, family
, flags
, err
, callback
, context
);
1218 getipnodebyname_async_cancel(mach_port_t p
)
1221 fprintf(stderr
, "-- %s\n", __func__
);
1228 getipnodebyname_async_handle_reply(mach_msg_header_t
*msg
)
1231 fprintf(stderr
, "<< %s\n", __func__
);
1234 si_async_handle_reply(msg
);
1238 getipnodebyname_async_handleReply(mach_msg_header_t
*msg
)
1241 fprintf(stderr
, "<< %s\n", __func__
);
1244 si_async_handle_reply(msg
);
1249 is_a4_mapped(const char *s
)
1254 if (s
== NULL
) return 0;
1256 for (i
= 0; i
< 10; i
++)
1259 if (c
!= 0x0) return 0;
1262 for (i
= 10; i
< 12; i
++)
1265 if (c
!= 0xff) return 0;
1272 is_a4_compat(const char *s
)
1277 if (s
== NULL
) return 0;
1279 for (i
= 0; i
< 12; i
++)
1282 if (c
!= 0x0) return 0;
1285 /* Check for :: and ::1 */
1286 for (i
= 13; i
< 15; i
++)
1288 /* anything non-zero in these 3 bytes means it's a V4 address */
1290 if (c
!= 0x0) return 1;
1293 /* Leading 15 bytes are all zero */
1295 if (c
== 0x0) return 0;
1296 if (c
== 0x1) return 0;
1302 getipnodebyaddr(const void *src
, size_t len
, int family
, int *err
)
1307 fprintf(stderr
, "-> %s %s\n", __func__
, (family
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)src
) : "-IPv6-");
1310 if ((family
== AF_INET6
) && (len
== IPV6_ADDR_LEN
) && (is_a4_mapped((const char *)src
) || is_a4_compat((const char *)src
)))
1317 item
= si_host_byaddr(si_search(), src
, family
, NULL
, (uint32_t *)err
);
1318 if (item
== NULL
) return NULL
;
1320 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1325 si_libinfo_ipnode_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
1327 si_context_t
*sictx
;
1330 if (ctx
== NULL
) return;
1332 sictx
= (si_context_t
*)ctx
;
1334 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
1337 si_item_release(item
);
1341 if (status
>= SI_STATUS_INTERNAL
) status
= NO_RECOVERY
;
1345 ((si_ipnode_async_callback
)(sictx
->orig_callback
))(NULL
, status
, sictx
->orig_context
);
1349 h
= (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1350 ((si_ipnode_async_callback
)(sictx
->orig_callback
))(h
, status
, sictx
->orig_context
);
1356 getipnodebyaddr_async_call(const void *src
, socklen_t len
, int family
, int *err
, si_ipnode_async_callback callback
, void *context
)
1358 si_context_t
*sictx
;
1362 fprintf(stderr
, ">> %s %s\n", __func__
, (family
== AF_INET
) ? inet_ntoa(*(struct in_addr
*)src
) : "-IPv6-");
1365 if ((family
== AF_INET6
) && (len
== IPV6_ADDR_LEN
) && (is_a4_mapped((const char *)src
) || is_a4_compat((const char *)src
)))
1372 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1373 if (sictx
== NULL
) return MACH_PORT_NULL
;
1375 sictx
->orig_callback
= callback
;
1376 sictx
->orig_context
= context
;
1377 sictx
->cat
= CATEGORY_HOST
;
1378 sictx
->key_offset
= -1;
1380 /* src is not a C string - pass length in num3 */
1382 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
);
1386 getipnodebyaddr_async_start(const void *addr
, size_t len
, int family
, int *error
, si_ipnode_async_callback callback
, void *context
)
1388 socklen_t slen
= len
;
1390 return getipnodebyaddr_async_call(addr
, slen
, family
, error
, callback
, context
);
1394 getipnodebyaddr_async_cancel(mach_port_t p
)
1397 fprintf(stderr
, "-- %s\n", __func__
);
1404 getipnodebyaddr_async_handle_reply(mach_msg_header_t
*msg
)
1407 fprintf(stderr
, "<< %s\n", __func__
);
1410 si_async_handle_reply(msg
);
1414 getipnodebyaddr_async_handleReply(mach_msg_header_t
*msg
)
1417 fprintf(stderr
, "<< %s\n", __func__
);
1420 si_async_handle_reply(msg
);
1425 sethostent(int ignored
)
1428 fprintf(stderr
, "-- %s\n", __func__
);
1431 LI_set_thread_list(CATEGORY_HOST
, NULL
);
1441 fprintf(stderr
, "-> %s\n", __func__
);
1444 list
= LI_get_thread_list(CATEGORY_HOST
);
1447 list
= si_host_all(si_search());
1448 LI_set_thread_list(CATEGORY_HOST
, list
);
1451 item
= si_list_next(list
);
1452 if (item
== NULL
) return NULL
;
1454 return (struct hostent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1461 fprintf(stderr
, "-- %s\n", __func__
);
1464 LI_set_thread_list(CATEGORY_HOST
, NULL
);
1470 ether_hostton(const char *name
, struct ether_addr
*e
)
1478 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1481 if (name
== NULL
) return -1;
1482 if (e
== NULL
) return -1;
1484 item
= si_mac_byname(si_search(), name
);
1485 LI_set_thread_item(CATEGORY_MAC
+ 100, item
);
1486 if (item
== NULL
) return -1;
1488 cmac
= (char *)((uintptr_t)item
+ sizeof(si_item_t
));
1490 i
= sscanf(cmac
, " %x:%x:%x:%x:%x:%x", &t
[0], &t
[1], &t
[2], &t
[3], &t
[4], &t
[5]);
1491 if (i
!= 6) return -1;
1493 for (i
= 0; i
< 6; i
++) e
->ether_addr_octet
[i
] = t
[i
];
1497 /* XXX to do? async ether_hostton */
1500 ether_ntohost(char *name
, const struct ether_addr
*e
)
1507 if (name
== NULL
) return -1;
1508 if (e
== NULL
) return -1;
1510 for (i
= 0; i
< 6; i
++) x
[i
] = e
->ether_addr_octet
[i
];
1511 snprintf(str
, sizeof(str
), "%x:%x:%x:%x:%x:%x", x
[0], x
[1], x
[2], x
[3], x
[4], x
[5]);
1514 fprintf(stderr
, "-> %s %s\n", __func__
, str
);
1517 item
= si_mac_bymac(si_search(), str
);
1518 LI_set_thread_item(CATEGORY_MAC
+ 200, item
);
1519 if (item
== NULL
) return -1;
1521 cname
= (char *)((uintptr_t)item
+ sizeof(si_item_t
));
1523 memcpy(name
, cname
, strlen(cname
) + 1);
1527 /* XXX to do? async ether_ntohost */
1532 getnetbyname(const char *name
)
1537 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1540 item
= si_network_byname(si_search(), name
);
1541 LI_set_thread_item(CATEGORY_NETWORK
+ 100, item
);
1542 if (item
== NULL
) return NULL
;
1544 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1548 getnetbyname_async_call(const char *name
, si_network_async_callback callback
, void *context
)
1550 si_context_t
*sictx
;
1553 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1556 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1557 if (sictx
== NULL
) return MACH_PORT_NULL
;
1559 sictx
->orig_callback
= callback
;
1560 sictx
->orig_context
= context
;
1561 sictx
->cat
= CATEGORY_NETWORK
;
1562 sictx
->key_offset
= 100;
1564 return si_async_call(si_search(), SI_CALL_NETWORK_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1568 getnetbyname_async_handle_reply(mach_msg_header_t
*msg
)
1571 fprintf(stderr
, "<< %s\n", __func__
);
1574 si_async_handle_reply(msg
);
1578 getnetbyaddr(uint32_t net
, int type
)
1583 fprintf(stderr
, "-> %s 0x%08x\n", __func__
, net
);
1586 if (type
!= AF_INET
) return NULL
;
1588 item
= si_network_byaddr(si_search(), net
);
1589 LI_set_thread_item(CATEGORY_NETWORK
+ 200, item
);
1590 if (item
== NULL
) return NULL
;
1592 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1596 getnetbyaddr_async_call(uint32_t net
, int type
, si_group_async_callback callback
, void *context
)
1598 si_context_t
*sictx
;
1601 fprintf(stderr
, ">> %s 0x%08x\n", __func__
, net
);
1604 if (type
!= AF_INET
) return MACH_PORT_NULL
;
1606 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1607 if (sictx
== NULL
) return MACH_PORT_NULL
;
1609 sictx
->orig_callback
= callback
;
1610 sictx
->orig_context
= context
;
1611 sictx
->cat
= CATEGORY_NETWORK
;
1612 sictx
->key_offset
= 200;
1614 return si_async_call(si_search(), SI_CALL_NETWORK_BYADDR
, NULL
, NULL
, NULL
, net
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1618 getnetbyaddr_async_handle_reply(mach_msg_header_t
*msg
)
1621 fprintf(stderr
, "<< %s\n", __func__
);
1624 si_async_handle_reply(msg
);
1628 setnetent(int ignored
)
1631 fprintf(stderr
, "-- %s\n", __func__
);
1634 LI_set_thread_list(CATEGORY_NETWORK
, NULL
);
1644 fprintf(stderr
, "-> %s\n", __func__
);
1647 list
= LI_get_thread_list(CATEGORY_NETWORK
);
1650 list
= si_network_all(si_search());
1651 LI_set_thread_list(CATEGORY_NETWORK
, list
);
1654 item
= si_list_next(list
);
1655 if (item
== NULL
) return NULL
;
1657 return (struct netent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1664 fprintf(stderr
, "-- %s\n", __func__
);
1667 LI_set_thread_list(CATEGORY_NETWORK
, NULL
);
1673 getservbyname(const char *name
, const char *proto
)
1678 fprintf(stderr
, "-> %s %s %s\n", __func__
, name
, proto
);
1681 item
= si_service_byname(si_search(), name
, proto
);
1682 LI_set_thread_item(CATEGORY_SERVICE
+ 100, item
);
1683 if (item
== NULL
) return NULL
;
1685 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1689 getservbyname_async_call(const char *name
, const char *proto
, si_service_async_callback callback
, void *context
)
1691 si_context_t
*sictx
;
1694 fprintf(stderr
, ">> %s %s %s\n", __func__
, name
, proto
);
1697 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1698 if (sictx
== NULL
) return MACH_PORT_NULL
;
1700 sictx
->orig_callback
= callback
;
1701 sictx
->orig_context
= context
;
1702 sictx
->cat
= CATEGORY_SERVICE
;
1703 sictx
->key_offset
= 100;
1705 return si_async_call(si_search(), SI_CALL_SERVICE_BYNAME
, name
, proto
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1709 getservbyname_async_handle_reply(mach_msg_header_t
*msg
)
1712 fprintf(stderr
, "<< %s\n", __func__
);
1715 si_async_handle_reply(msg
);
1719 getservbyport(int port
, const char *proto
)
1724 fprintf(stderr
, "-> %s %d %s\n", __func__
, ntohs((uint16_t)port
), proto
);
1727 item
= si_service_byport(si_search(), port
, proto
);
1728 LI_set_thread_item(CATEGORY_SERVICE
+ 200, item
);
1729 if (item
== NULL
) return NULL
;
1731 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1735 getservbyport_async_call(int port
, const char *proto
, si_group_async_callback callback
, void *context
)
1737 si_context_t
*sictx
;
1740 fprintf(stderr
, ">> %s %d %s\n", __func__
, port
, proto
);
1743 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1744 if (sictx
== NULL
) return MACH_PORT_NULL
;
1746 sictx
->orig_callback
= callback
;
1747 sictx
->orig_context
= context
;
1748 sictx
->cat
= CATEGORY_SERVICE
;
1749 sictx
->key_offset
= 200;
1751 return si_async_call(si_search(), SI_CALL_SERVICE_BYPORT
, NULL
, proto
, NULL
, port
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1755 getservbyport_async_handle_reply(mach_msg_header_t
*msg
)
1758 fprintf(stderr
, "<< %s\n", __func__
);
1761 si_async_handle_reply(msg
);
1765 setservent(int ignored
)
1768 fprintf(stderr
, "-- %s\n", __func__
);
1771 LI_set_thread_list(CATEGORY_SERVICE
, NULL
);
1781 fprintf(stderr
, "-> %s\n", __func__
);
1784 list
= LI_get_thread_list(CATEGORY_SERVICE
);
1787 list
= si_service_all(si_search());
1788 LI_set_thread_list(CATEGORY_SERVICE
, list
);
1791 item
= si_list_next(list
);
1792 if (item
== NULL
) return NULL
;
1794 return (struct servent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1801 fprintf(stderr
, "-- %s\n", __func__
);
1804 LI_set_thread_list(CATEGORY_SERVICE
, NULL
);
1810 getprotobyname(const char *name
)
1815 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1818 item
= si_protocol_byname(si_search(), name
);
1819 LI_set_thread_item(CATEGORY_PROTOCOL
+ 100, item
);
1820 if (item
== NULL
) return NULL
;
1822 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1826 getprotobyname_async_call(const char *name
, si_protocol_async_callback callback
, void *context
)
1828 si_context_t
*sictx
;
1831 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1834 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1835 if (sictx
== NULL
) return MACH_PORT_NULL
;
1837 sictx
->orig_callback
= callback
;
1838 sictx
->orig_context
= context
;
1839 sictx
->cat
= CATEGORY_PROTOCOL
;
1840 sictx
->key_offset
= 100;
1842 return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1846 getprotobyname_async_handle_reply(mach_msg_header_t
*msg
)
1849 fprintf(stderr
, "<< %s\n", __func__
);
1852 si_async_handle_reply(msg
);
1856 getprotobynumber(int number
)
1861 fprintf(stderr
, "-> %s %d\n", __func__
, number
);
1864 item
= si_protocol_bynumber(si_search(), number
);
1865 LI_set_thread_item(CATEGORY_PROTOCOL
+ 200, item
);
1866 if (item
== NULL
) return NULL
;
1868 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1872 getprotobynumber_async_call(int number
, si_group_async_callback callback
, void *context
)
1874 si_context_t
*sictx
;
1877 fprintf(stderr
, ">> %s %d\n", __func__
, number
);
1880 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1881 if (sictx
== NULL
) return MACH_PORT_NULL
;
1883 sictx
->orig_callback
= callback
;
1884 sictx
->orig_context
= context
;
1885 sictx
->cat
= CATEGORY_PROTOCOL
;
1886 sictx
->key_offset
= 200;
1888 return si_async_call(si_search(), SI_CALL_PROTOCOL_BYNUMBER
, NULL
, NULL
, NULL
, number
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1892 getprotobynumber_async_handle_reply(mach_msg_header_t
*msg
)
1895 fprintf(stderr
, "<< %s\n", __func__
);
1898 si_async_handle_reply(msg
);
1902 setprotoent(int ignored
)
1905 fprintf(stderr
, "-- %s\n", __func__
);
1908 LI_set_thread_list(CATEGORY_PROTOCOL
, NULL
);
1918 fprintf(stderr
, "-> %s\n", __func__
);
1921 list
= LI_get_thread_list(CATEGORY_PROTOCOL
);
1924 list
= si_protocol_all(si_search());
1925 LI_set_thread_list(CATEGORY_PROTOCOL
, list
);
1928 item
= si_list_next(list
);
1929 if (item
== NULL
) return NULL
;
1931 return (struct protoent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1938 fprintf(stderr
, "-- %s\n", __func__
);
1941 LI_set_thread_list(CATEGORY_PROTOCOL
, NULL
);
1947 getrpcbyname(const char *name
)
1952 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
1955 item
= si_rpc_byname(si_search(), name
);
1956 LI_set_thread_item(CATEGORY_RPC
+ 100, item
);
1957 if (item
== NULL
) return NULL
;
1959 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
1963 getrpcbyname_async_call(const char *name
, si_rpc_async_callback callback
, void *context
)
1965 si_context_t
*sictx
;
1968 fprintf(stderr
, ">> %s %s\n", __func__
, name
);
1971 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
1972 if (sictx
== NULL
) return MACH_PORT_NULL
;
1974 sictx
->orig_callback
= callback
;
1975 sictx
->orig_context
= context
;
1976 sictx
->cat
= CATEGORY_RPC
;
1977 sictx
->key_offset
= 100;
1979 return si_async_call(si_search(), SI_CALL_RPC_BYNAME
, name
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
1983 getrpcbyname_async_handle_reply(mach_msg_header_t
*msg
)
1986 fprintf(stderr
, "<< %s\n", __func__
);
1989 si_async_handle_reply(msg
);
2005 fprintf(stderr
, "-> %s %ld\n", __func__
, (long int)number
);
2008 item
= si_rpc_bynumber(si_search(), number
);
2009 LI_set_thread_item(CATEGORY_RPC
+ 200, item
);
2010 if (item
== NULL
) return NULL
;
2012 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2016 getrpcbynumber_async_call(int number
, si_group_async_callback callback
, void *context
)
2018 si_context_t
*sictx
;
2021 fprintf(stderr
, ">> %s %d\n", __func__
, number
);
2024 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2025 if (sictx
== NULL
) return MACH_PORT_NULL
;
2027 sictx
->orig_callback
= callback
;
2028 sictx
->orig_context
= context
;
2029 sictx
->cat
= CATEGORY_RPC
;
2030 sictx
->key_offset
= 200;
2032 return si_async_call(si_search(), SI_CALL_RPC_BYNUMBER
, NULL
, NULL
, NULL
, number
, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2036 getrpcbynumber_async_handle_reply(mach_msg_header_t
*msg
)
2039 fprintf(stderr
, "<< %s\n", __func__
);
2042 si_async_handle_reply(msg
);
2046 setrpcent(int ignored
)
2049 fprintf(stderr
, "-- %s\n", __func__
);
2052 LI_set_thread_list(CATEGORY_RPC
, NULL
);
2062 fprintf(stderr
, "-> %s\n", __func__
);
2065 list
= LI_get_thread_list(CATEGORY_RPC
);
2068 list
= si_rpc_all(si_search());
2069 LI_set_thread_list(CATEGORY_RPC
, list
);
2072 item
= si_list_next(list
);
2073 if (item
== NULL
) return NULL
;
2075 return (struct rpcent
*)((uintptr_t)item
+ sizeof(si_item_t
));
2082 fprintf(stderr
, "-- %s\n", __func__
);
2085 LI_set_thread_list(CATEGORY_RPC
, NULL
);
2091 getfsspec(const char *spec
)
2096 fprintf(stderr
, "-> %s %s\n", __func__
, spec
);
2099 item
= si_fs_byspec(si_search(), spec
);
2100 LI_set_thread_item(CATEGORY_FS
+ 100, item
);
2101 if (item
== NULL
) return NULL
;
2103 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2107 getfsbyname(const char *name
)
2110 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
2113 return getfsspec(name
);
2117 getfsspec_async_call(const char *spec
, si_fs_async_callback callback
, void *context
)
2119 si_context_t
*sictx
;
2122 fprintf(stderr
, ">> %s %s\n", __func__
, spec
);
2125 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2126 if (sictx
== NULL
) return MACH_PORT_NULL
;
2128 sictx
->orig_callback
= callback
;
2129 sictx
->orig_context
= context
;
2130 sictx
->cat
= CATEGORY_FS
;
2131 sictx
->key_offset
= 100;
2133 return si_async_call(si_search(), SI_CALL_FS_BYSPEC
, spec
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2137 getfsspec_async_handle_reply(mach_msg_header_t
*msg
)
2140 fprintf(stderr
, "<< %s\n", __func__
);
2143 si_async_handle_reply(msg
);
2147 getfsfile(const char *file
)
2152 fprintf(stderr
, "-> %s %s\n", __func__
, file
);
2155 item
= si_fs_byfile(si_search(), file
);
2156 LI_set_thread_item(CATEGORY_FS
+ 200, item
);
2157 if (item
== NULL
) return NULL
;
2159 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2163 getfsfile_async_call(const char *file
, si_fs_async_callback callback
, void *context
)
2165 si_context_t
*sictx
;
2168 fprintf(stderr
, ">> %s %s\n", __func__
, file
);
2171 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2172 if (sictx
== NULL
) return MACH_PORT_NULL
;
2174 sictx
->orig_callback
= callback
;
2175 sictx
->orig_context
= context
;
2176 sictx
->cat
= CATEGORY_FS
;
2177 sictx
->key_offset
= 200;
2179 return si_async_call(si_search(), SI_CALL_FS_BYFILE
, file
, NULL
, NULL
, 0, 0, 0, 0, (void *)si_libinfo_general_callback
, sictx
);
2183 getfsfile_async_handle_reply(mach_msg_header_t
*msg
)
2186 fprintf(stderr
, "<< %s\n", __func__
);
2189 si_async_handle_reply(msg
);
2196 fprintf(stderr
, "-> %s\n", __func__
);
2199 LI_set_thread_list(CATEGORY_FS
, NULL
);
2210 fprintf(stderr
, "-> %s\n", __func__
);
2213 list
= LI_get_thread_list(CATEGORY_FS
);
2216 list
= si_fs_all(si_search());
2217 LI_set_thread_list(CATEGORY_FS
, list
);
2220 item
= si_list_next(list
);
2221 if (item
== NULL
) return NULL
;
2223 return (struct fstab
*)((uintptr_t)item
+ sizeof(si_item_t
));
2230 fprintf(stderr
, "-- %s\n", __func__
);
2233 LI_set_thread_list(CATEGORY_FS
, NULL
);
2239 _getaddrinfo_internal(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, const char *interface
, struct addrinfo
**res
)
2242 uint32_t family
, socktype
, protocol
, flags
, status
;
2243 struct addrinfo
*ai
;
2246 socktype
= SOCK_UNSPEC
;
2247 protocol
= IPPROTO_UNSPEC
;
2249 status
= SI_STATUS_NO_ERROR
;
2251 if (res
== NULL
) return 0;
2256 family
= hints
->ai_family
;
2257 socktype
= hints
->ai_socktype
;
2258 protocol
= hints
->ai_protocol
;
2259 flags
= hints
->ai_flags
;
2263 fprintf(stderr
, "-> %s %s %s %u %u %u 0x%08x %s\n", __func__
, nodename
, servname
, family
, socktype
, protocol
, flags
, (interface
== NULL
) ? "" : interface
);
2266 list
= si_addrinfo(si_search(), nodename
, servname
, family
, socktype
, protocol
, flags
, interface
, &status
);
2267 if ((status
!= SI_STATUS_NO_ERROR
) || (list
== NULL
))
2269 si_list_release(list
);
2271 if (status
== SI_STATUS_NO_ERROR
) return EAI_NONAME
;
2272 else if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2273 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2274 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2278 *res
= si_list_to_addrinfo(list
);
2279 si_list_release(list
);
2280 if (*res
== NULL
) status
= EAI_MEMORY
;
2282 /* don't return the canonical name unless asked */
2283 if ((flags
& AI_CANONNAME
) == 0)
2285 for (ai
= *res
; ai
!= NULL
; ai
= ai
->ai_next
)
2287 free(ai
->ai_canonname
);
2288 ai
->ai_canonname
= NULL
;
2296 getaddrinfo(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, struct addrinfo
**res
)
2298 return _getaddrinfo_internal(nodename
, servname
, hints
, NULL
, res
);
2304 socket_name(int sock
)
2306 static char str
[16];
2310 case SOCK_UNSPEC
: return "SOCK_UNSPEC";
2311 case SOCK_STREAM
: return "SOCK_STREAM";
2312 case SOCK_DGRAM
: return "SOCK_DGRAM";
2315 sprintf(str
, "%d", sock
);
2322 static char str
[16];
2326 case PF_UNSPEC
: return "PF_UNSPEC";
2327 case PF_INET
: return "PF_INET";
2328 case PF_INET6
: return "PF_INET6";
2331 sprintf(str
, "%d", pf
);
2336 protocol_name(int p
)
2338 static char str
[16];
2342 case IPPROTO_UNSPEC
: return "IPPROTO_UNSPEC";
2343 case IPPROTO_TCP
: return "IPPROTO_TCP";
2344 case IPPROTO_UDP
: return "IPPROTO_UDP";
2347 sprintf(str
, "%d", p
);
2352 _gai_inet_ntop(struct in6_addr a
)
2354 static char buf
[128];
2360 memset(buf
, 0, 128);
2362 p
= (char *)&a
.__u6_addr
.__u6_addr32
;
2363 for (i
= 0; i
< 8; i
++, x
+= 1)
2367 sprintf(t
, "%hx", x
);
2369 if (i
< 7) strcat(buf
, ":");
2376 fprint_addrinfo(FILE *f
, struct addrinfo
*a
)
2380 struct sockaddr_in
*s4
;
2381 struct sockaddr_in6
*s6
;
2383 if (a
== NULL
) return;
2385 if (a
->ai_flags
!= 0)
2387 fprintf(f
, "flags =");
2388 if (a
->ai_flags
& AI_PASSIVE
) fprintf(f
, " AI_PASSIVE");
2389 if (a
->ai_flags
& AI_CANONNAME
) fprintf(f
, " AI_CANONNAME");
2390 if (a
->ai_flags
& AI_NUMERICHOST
) fprintf(f
, " AI_NUMERICHOST");
2391 if (a
->ai_flags
& AI_NUMERICSERV
) fprintf(f
, " AI_NUMERICSERV");
2395 fprintf(f
, "family = %s\n", family_name(a
->ai_family
));
2396 fprintf(f
, "socktype = %s\n", socket_name(a
->ai_socktype
));
2397 fprintf(f
, "protocol = %s\n", protocol_name(a
->ai_protocol
));
2399 fprintf(f
, "canonical name = ");
2400 if (a
->ai_canonname
== NULL
) fprintf(f
, "NULL\n");
2401 else fprintf(f
, "\"%s\"\n", a
->ai_canonname
);
2403 fprintf(f
, "addrlen = %ld\n", (long int)a
->ai_addrlen
);
2405 if (a
->ai_addr
== NULL
) fprintf(f
, "sockaddr = NULL\n");
2408 if (a
->ai_family
== PF_INET
)
2410 s4
= (struct sockaddr_in
*)a
->ai_addr
;
2412 fprintf(f
, "sockaddr_in len = %d\n", s4
->sin_len
);
2413 fprintf(f
, "sockaddr_in family = %s\n", family_name(s4
->sin_family
));
2414 fprintf(f
, "sockaddr_in port = %hu\n", ntohs(s4
->sin_port
));
2415 fprintf(f
, "sockaddr_in address = %s\n", inet_ntoa(s4
->sin_addr
));
2417 else if (a
->ai_family
== PF_INET6
)
2419 s6
= (struct sockaddr_in6
*)a
->ai_addr
;
2421 fprintf(f
, "sockaddr_in6 len = %d\n", s6
->sin6_len
);
2422 fprintf(f
, "sockaddr_in6 family = %s\n", family_name(s6
->sin6_family
));
2423 fprintf(f
, "sockaddr_in6 port = %hu\n", ntohs(s6
->sin6_port
));
2424 fprintf(f
, "sockaddr_in6 flowinfo = %d\n", s6
->sin6_flowinfo
);
2425 fprintf(f
, "sockaddr_in6 address = %s\n", _gai_inet_ntop(s6
->sin6_addr
));
2426 fprintf(f
, "sockaddr_in6 scope_id = %d\n", s6
->sin6_scope_id
);
2430 fprintf(f
, "sockaddr len = %d\n", a
->ai_addr
->sa_len
);
2431 fprintf(f
, "sockaddr family = %s\n", family_name(a
->ai_addr
->sa_family
));
2432 fprintf(f
, "sockaddr data = ");
2433 for (i
= 0; i
< a
->ai_addr
->sa_len
- 2; i
++)
2435 v
= a
->ai_addr
->sa_data
[i
];
2436 fprintf(f
, "%02x", v
);
2442 if (a
->ai_next
!= NULL
)
2444 fprintf(f
, "NEXT --->\n");
2445 fprint_addrinfo(f
, a
->ai_next
);
2452 si_libinfo_addrinfo_callback(si_list_t
*list
, uint32_t status
, void *ctx
)
2454 si_context_t
*sictx
;
2455 struct addrinfo
*out
;
2460 fprintf(stderr
, " %s error no context\n", __func__
);
2462 si_list_release(list
);
2466 sictx
= (si_context_t
*)ctx
;
2468 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
2471 fprintf(stderr
, " %s error no callback\n", __func__
);
2473 si_list_release(list
);
2478 if (status
!= SI_STATUS_NO_ERROR
)
2481 fprintf(stderr
, " %s original status %d\n", __func__
, status
);
2483 if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2484 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2485 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2491 fprintf(stderr
, " %s result NULL status %d (returning EAI_NONAME)\n", __func__
, status
);
2493 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(EAI_NONAME
, NULL
, sictx
->orig_context
);
2498 out
= si_list_to_addrinfo(list
);
2499 si_list_release(list
);
2503 fprintf(stderr
, " %s result conversion failed returning NULL status %d (returning EAI_MEMORY)\n", __func__
, status
);
2505 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(EAI_MEMORY
, NULL
, sictx
->orig_context
);
2511 fprintf(stderr
, " %s %d\n", __func__
, status
);
2512 fprint_addrinfo(stderr
, out
);
2514 ((si_addrinfo_async_callback
)(sictx
->orig_callback
))(status
, out
, sictx
->orig_context
);
2521 _getaddrinfo_interface_async_call(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, const char *interface
, si_addrinfo_async_callback callback
, void *context
)
2523 si_context_t
*sictx
;
2524 uint32_t family
, socktype
, protocol
, flags
;
2527 socktype
= SOCK_UNSPEC
;
2528 protocol
= IPPROTO_UNSPEC
;
2533 family
= hints
->ai_family
;
2534 socktype
= hints
->ai_socktype
;
2535 protocol
= hints
->ai_protocol
;
2536 flags
= hints
->ai_flags
;
2540 fprintf(stderr
, ">> %s %s %s %u %u %u 0x%08x\n", __func__
, nodename
, servname
, family
, socktype
, protocol
, flags
);
2543 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2544 if (sictx
== NULL
) return MACH_PORT_NULL
;
2546 sictx
->orig_callback
= callback
;
2547 sictx
->orig_context
= context
;
2548 sictx
->cat
= CATEGORY_ADDRINFO
;
2549 sictx
->key_offset
= 0;
2551 return si_async_call(si_search(), SI_CALL_ADDRINFO
, nodename
, servname
, interface
, family
, socktype
, protocol
, flags
, (void *)si_libinfo_addrinfo_callback
, sictx
);
2555 getaddrinfo_async_call(const char *nodename
, const char *servname
, const struct addrinfo
*hints
, si_addrinfo_async_callback callback
, void *context
)
2557 return _getaddrinfo_interface_async_call(nodename
, servname
, hints
, NULL
, callback
, context
);
2561 getaddrinfo_async_start(mach_port_t
*p
, const char *nodename
, const char *servname
, const struct addrinfo
*hints
, si_addrinfo_async_callback callback
, void *context
)
2563 if (p
== NULL
) return EAI_SYSTEM
;
2565 *p
= getaddrinfo_async_call(nodename
, servname
, hints
, callback
, context
);
2567 if (*p
== MACH_PORT_NULL
) return EAI_SYSTEM
;
2572 getaddrinfo_async_send(mach_port_t
*p
, const char *nodename
, const char *servname
, const struct addrinfo
*hints
)
2574 return getaddrinfo_async_start(p
, nodename
, servname
, hints
, NULL
, NULL
);
2578 getaddrinfo_async_receive(mach_port_t p
, struct addrinfo
**res
)
2580 /* unsupported Leopard SPI */
2585 getaddrinfo_async_cancel(mach_port_t p
)
2588 fprintf(stderr
, "-- %s\n", __func__
);
2595 getaddrinfo_async_handle_reply(void *param
)
2597 mach_msg_header_t
*msg
;
2600 fprintf(stderr
, "<< %s\n", __func__
);
2603 msg
= (mach_msg_header_t
*)param
;
2604 si_async_handle_reply(msg
);
2612 _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
)
2616 uint32_t status
, len
, wantn
, wants
;
2619 fprintf(stderr
, "-> %s\n", __func__
);
2622 status
= SI_STATUS_NO_ERROR
;
2625 if ((node
!= NULL
) && (nodelen
> 0)) wantn
= 1;
2628 if ((service
!= NULL
) && (servicelen
> 0)) wants
= 1;
2630 if ((wantn
== 0) && (wants
== 0)) return status
;
2632 if (wantn
== 0) flags
|= NI_NUMERICHOST
;
2633 if (wants
== 0) flags
|= NI_NUMERICSERV
;
2635 item
= si_nameinfo(si_search(), sa
, flags
, interface
, &status
);
2636 if ((status
!= SI_STATUS_NO_ERROR
) || (item
== NULL
))
2638 si_item_release(item
);
2640 if (status
== SI_STATUS_NO_ERROR
) status
= EAI_NONAME
;
2641 else if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2642 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2643 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2647 ni
= (si_nameinfo_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
2650 if (ni
->ni_node
!= NULL
) len
= strlen(ni
->ni_node
) + 1;
2651 if ((wantn
== 1) && (len
> 0))
2655 si_item_release(item
);
2656 return EAI_OVERFLOW
;
2659 memset(node
, 0, nodelen
);
2660 memcpy(node
, ni
->ni_node
, len
);
2664 if (ni
->ni_serv
!= NULL
) len
= strlen(ni
->ni_serv
) + 1;
2665 if ((wants
== 1) && (len
> 0))
2667 if (len
> servicelen
)
2669 si_item_release(item
);
2670 return EAI_OVERFLOW
;
2673 memset(service
, 0, servicelen
);
2674 memcpy(service
, ni
->ni_serv
, len
);
2677 si_item_release(item
);
2682 getnameinfo(const struct sockaddr
*sa
, socklen_t salen
, char *node
, socklen_t nodelen
, char *service
, socklen_t servicelen
, int flags
)
2684 return _getnameinfo_interface_internal(sa
, salen
, node
, nodelen
, service
, servicelen
, flags
, NULL
);
2688 si_libinfo_nameinfo_callback(si_item_t
*item
, uint32_t status
, void *ctx
)
2690 si_context_t
*sictx
;
2694 if (ctx
== NULL
) return;
2696 sictx
= (si_context_t
*)ctx
;
2698 if ((sictx
->orig_callback
== NULL
) || (status
== SI_STATUS_CALL_CANCELLED
))
2700 si_item_release(item
);
2705 if (status
!= SI_STATUS_NO_ERROR
)
2707 if (status
<= SI_STATUS_EAI_PLUS_100
) status
= EAI_FAIL
;
2708 else if (status
>= SI_STATUS_ERRNO_PLUS_200
) status
= EAI_FAIL
;
2709 else status
= status
- SI_STATUS_EAI_PLUS_100
;
2714 ((si_nameinfo_async_callback
)(sictx
->orig_callback
))(status
, NULL
, NULL
, sictx
->orig_context
);
2719 LI_set_thread_item(CATEGORY_NAMEINFO
, item
);
2724 ni
= (si_nameinfo_t
*)((uintptr_t)item
+ sizeof(si_item_t
));
2725 if (ni
->ni_node
!= NULL
) node
= strdup(ni
->ni_node
);
2726 if (ni
->ni_serv
!= NULL
) serv
= strdup(ni
->ni_serv
);
2728 ((si_nameinfo_async_callback
)(sictx
->orig_callback
))(status
, node
, serv
, sictx
->orig_context
);
2734 _getnameinfo_interface_async_call(const struct sockaddr
*sa
, size_t len
, int flags
, const char *interface
, si_nameinfo_async_callback callback
, void *context
)
2736 si_context_t
*sictx
;
2740 fprintf(stderr
, ">> %s\n", __func__
);
2743 sictx
= (si_context_t
*)calloc(1, sizeof(si_context_t
));
2744 if (sictx
== NULL
) return MACH_PORT_NULL
;
2746 sictx
->orig_callback
= callback
;
2747 sictx
->orig_context
= context
;
2748 sictx
->cat
= CATEGORY_ADDRINFO
;
2749 sictx
->key_offset
= 0;
2751 /* sa is not a C string - pass length in num3 */
2753 return si_async_call(si_search(), SI_CALL_NAMEINFO
, (const char *)sa
, NULL
, interface
, flags
, 0, salen
, 0, (void *)si_libinfo_nameinfo_callback
, sictx
);
2757 getnameinfo_async_call(const struct sockaddr
*sa
, size_t len
, int flags
, si_nameinfo_async_callback callback
, void *context
)
2759 return _getnameinfo_interface_async_call(sa
, len
, flags
, NULL
, callback
, context
);
2763 getnameinfo_async_start(mach_port_t
*p
, const struct sockaddr
*sa
, size_t salen
, int flags
, si_nameinfo_async_callback callback
, void *context
)
2765 if (p
== NULL
) return EAI_SYSTEM
;
2766 *p
= getnameinfo_async_call(sa
, salen
, flags
, callback
, context
);
2768 if (*p
== MACH_PORT_NULL
) return EAI_SYSTEM
;
2773 getnameinfo_async_send(mach_port_t
*p
, const struct sockaddr
*sa
, size_t salen
, int flags
)
2775 return getnameinfo_async_start(p
, sa
, salen
, flags
, NULL
, NULL
);
2779 getnameinfo_async_cancel(mach_port_t p
)
2782 fprintf(stderr
, "-- %s\n", __func__
);
2789 getnameinfo_async_handle_reply(void *param
)
2791 mach_msg_header_t
*msg
;
2794 fprintf(stderr
, "<< %s\n", __func__
);
2797 msg
= (mach_msg_header_t
*)param
;
2798 si_async_handle_reply(msg
);
2803 /* getpwXXX_r and getgrXXX_r */
2806 copy_user_r(struct passwd
*in
, struct passwd
*out
, char *buffer
, int buflen
)
2811 if (in
== NULL
) return -1;
2812 if (out
== NULL
) return -1;
2814 if (buffer
== NULL
) buflen
= 0;
2816 /* Calculate size of input */
2818 if (in
->pw_name
!= NULL
) hsize
+= (strlen(in
->pw_name
) + 1);
2819 if (in
->pw_passwd
!= NULL
) hsize
+= (strlen(in
->pw_passwd
) + 1);
2820 if (in
->pw_class
!= NULL
) hsize
+= (strlen(in
->pw_class
) + 1);
2821 if (in
->pw_gecos
!= NULL
) hsize
+= (strlen(in
->pw_gecos
) + 1);
2822 if (in
->pw_dir
!= NULL
) hsize
+= (strlen(in
->pw_dir
) + 1);
2823 if (in
->pw_shell
!= NULL
) hsize
+= (strlen(in
->pw_shell
) + 1);
2825 /* Check buffer space */
2826 if (hsize
> buflen
) return -1;
2828 /* Copy result into caller's struct passwd, using buffer for memory */
2831 out
->pw_name
= NULL
;
2832 if (in
->pw_name
!= NULL
)
2835 hsize
= strlen(in
->pw_name
) + 1;
2836 memmove(bp
, in
->pw_name
, hsize
);
2840 out
->pw_passwd
= NULL
;
2841 if (in
->pw_passwd
!= NULL
)
2843 out
->pw_passwd
= bp
;
2844 hsize
= strlen(in
->pw_passwd
) + 1;
2845 memmove(bp
, in
->pw_passwd
, hsize
);
2849 out
->pw_uid
= in
->pw_uid
;
2851 out
->pw_gid
= in
->pw_gid
;
2853 out
->pw_change
= in
->pw_change
;
2855 out
->pw_class
= NULL
;
2856 if (in
->pw_class
!= NULL
)
2859 hsize
= strlen(in
->pw_class
) + 1;
2860 memmove(bp
, in
->pw_class
, hsize
);
2864 out
->pw_gecos
= NULL
;
2865 if (in
->pw_gecos
!= NULL
)
2868 hsize
= strlen(in
->pw_gecos
) + 1;
2869 memmove(bp
, in
->pw_gecos
, hsize
);
2874 if (in
->pw_dir
!= NULL
)
2877 hsize
= strlen(in
->pw_dir
) + 1;
2878 memmove(bp
, in
->pw_dir
, hsize
);
2882 out
->pw_shell
= NULL
;
2883 if (in
->pw_shell
!= NULL
)
2886 hsize
= strlen(in
->pw_shell
) + 1;
2887 memmove(bp
, in
->pw_shell
, hsize
);
2891 out
->pw_expire
= in
->pw_expire
;
2897 copy_group_r(struct group
*in
, struct group
*out
, char *buffer
, int buflen
)
2903 if (in
== NULL
) return -1;
2904 if (out
== NULL
) return -1;
2906 if (buffer
== NULL
) buflen
= 0;
2908 /* Calculate size of input */
2910 if (in
->gr_name
!= NULL
) hsize
+= (strlen(in
->gr_name
) + 1);
2911 if (in
->gr_passwd
!= NULL
) hsize
+= (strlen(in
->gr_passwd
) + 1);
2913 /* NULL pointer at end of list */
2914 hsize
+= sizeof(char *);
2917 if (in
->gr_mem
!= NULL
)
2919 for (len
= 0; in
->gr_mem
[len
] != NULL
; len
++)
2921 hsize
+= sizeof(char *);
2922 hsize
+= (strlen(in
->gr_mem
[len
]) + 1);
2926 /* Check buffer space */
2927 if (hsize
> buflen
) return -1;
2929 /* Copy result into caller's struct group, using buffer for memory */
2932 out
->gr_name
= NULL
;
2933 if (in
->gr_name
!= NULL
)
2936 hsize
= strlen(in
->gr_name
) + 1;
2937 memmove(bp
, in
->gr_name
, hsize
);
2941 out
->gr_passwd
= NULL
;
2942 if (in
->gr_passwd
!= NULL
)
2944 out
->gr_passwd
= bp
;
2945 hsize
= strlen(in
->gr_passwd
) + 1;
2946 memmove(bp
, in
->gr_passwd
, hsize
);
2950 out
->gr_gid
= in
->gr_gid
;
2953 ap
= bp
+ ((len
+ 1) * sizeof(char *));
2955 if (in
->gr_mem
!= NULL
)
2957 out
->gr_mem
= (char **)bp
;
2958 for (i
= 0; i
< len
; i
++)
2960 addr
= (unsigned long)ap
;
2961 memmove(bp
, &addr
, sizeof(unsigned long));
2962 bp
+= sizeof(unsigned long);
2964 hsize
= strlen(in
->gr_mem
[i
]) + 1;
2965 memmove(ap
, in
->gr_mem
[i
], hsize
);
2970 memset(bp
, 0, sizeof(unsigned long));
2977 getgrnam_r(const char *name
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
2984 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
2987 if (result
!= NULL
) *result
= NULL
;
2989 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
2991 item
= si_group_byname(si_search(), name
);
2992 if (item
== NULL
) return 0;
2994 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
2996 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
2997 si_item_release(item
);
2999 if (status
!= 0) return ERANGE
;
3006 getgrgid_r(gid_t gid
, struct group
*grp
, char *buffer
, size_t bufsize
, struct group
**result
)
3013 fprintf(stderr
, "-> %s %d\n", __func__
, gid
);
3016 if (result
!= NULL
) *result
= NULL
;
3018 if ((grp
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3020 item
= si_group_bygid(si_search(), gid
);
3021 if (item
== NULL
) return 0;
3023 g
= (struct group
*)((uintptr_t)item
+ sizeof(si_item_t
));
3025 status
= copy_group_r(g
, grp
, buffer
, bufsize
);
3026 si_item_release(item
);
3028 if (status
!= 0) return ERANGE
;
3035 getpwnam_r(const char *name
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3042 fprintf(stderr
, "-> %s %s\n", __func__
, name
);
3045 if (result
!= NULL
) *result
= NULL
;
3047 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3049 item
= si_user_byname(si_search(), name
);
3050 if (item
== NULL
) return 0;
3052 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3054 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3055 si_item_release(item
);
3057 if (status
!= 0) return ERANGE
;
3064 getpwuid_r(uid_t uid
, struct passwd
*pw
, char *buffer
, size_t bufsize
, struct passwd
**result
)
3071 fprintf(stderr
, "-> %s %d\n", __func__
, uid
);
3074 if (result
!= NULL
) *result
= NULL
;
3076 if ((pw
== NULL
) || (buffer
== NULL
) || (result
== NULL
) || (bufsize
== 0)) return ERANGE
;
3078 item
= si_user_byuid(si_search(), uid
);
3079 if (item
== NULL
) return 0;
3081 p
= (struct passwd
*)((uintptr_t)item
+ sizeof(si_item_t
));
3083 status
= copy_user_r(p
, pw
, buffer
, bufsize
);
3084 si_item_release(item
);
3086 if (status
!= 0) return ERANGE
;
3095 user_from_uid(uid_t uid
, int nouser
)
3098 static char buf
[16];
3101 if (pw
!= NULL
) return pw
->pw_name
;
3103 if (nouser
) return NULL
;
3105 snprintf(buf
, sizeof(buf
), "%u", uid
);
3110 group_from_gid(gid_t gid
, int nogroup
)
3113 static char buf
[16];
3116 if (gr
!= NULL
) return gr
->gr_name
;
3118 if (nogroup
) return NULL
;
3120 snprintf(buf
, sizeof(buf
), "%u", gid
);
3124 /* no longer supported */
3127 prdb_getbyname(const char *name
)
3130 fprintf(stderr
, "~~ %s\n", __func__
);
3139 fprintf(stderr
, "~~ %s\n", __func__
);
3145 prdb_set(const char *name
)
3148 fprintf(stderr
, "~~ %s\n", __func__
);
3156 fprintf(stderr
, "~~ %s\n", __func__
);
3160 struct bootparamsent
*
3161 bootparams_getbyname(const char *name
)
3164 fprintf(stderr
, "~~ %s\n", __func__
);
3169 struct bootparamsent
*
3170 bootparams_getent(void)
3173 fprintf(stderr
, "~~ %s\n", __func__
);
3179 bootparams_setent(void)
3182 fprintf(stderr
, "~~ %s\n", __func__
);
3187 bootparams_endent(void)
3190 fprintf(stderr
, "~~ %s\n", __func__
);
3195 bootp_getbyether(struct ether_addr
*enaddr
, char **name
,struct in_addr
*ipaddr
, char **bootfile
)
3198 fprintf(stderr
, "~~ %s\n", __func__
);
3204 bootp_getbyip(struct ether_addr
*enaddr
, char **name
, struct in_addr
*ipaddr
, char **bootfile
)
3207 fprintf(stderr
, "~~ %s\n", __func__
);