]> git.saurik.com Git - apple/libinfo.git/commitdiff
Libinfo-391.tar.gz mac-os-x-107 mac-os-x-1071 v391
authorApple <opensource@apple.com>
Tue, 14 Jun 2011 23:26:46 +0000 (23:26 +0000)
committerApple <opensource@apple.com>
Tue, 14 Jun 2011 23:26:46 +0000 (23:26 +0000)
48 files changed:
Libinfo.xcodeproj/project.pbxproj [new file with mode: 0644]
Makefile [deleted file]
dns.subproj/Makefile [deleted file]
dns.subproj/Makefile.dist [deleted file]
gen.subproj/Makefile [deleted file]
gen.subproj/getifmaddrs.3 [new file with mode: 0644]
gen.subproj/getifmaddrs.c [new file with mode: 0644]
gen.subproj/ifaddrs.h
gen.subproj/inet6_opt_init.3 [new file with mode: 0644]
gen.subproj/inet6_rth_space.3 [new file with mode: 0644]
gen.subproj/ip6opt.c
gen.subproj/rthdr.c
lookup.subproj/Makefile [deleted file]
lookup.subproj/cache_module.c
lookup.subproj/ds_module.c
lookup.subproj/file_module.c
lookup.subproj/getgrent.3
lookup.subproj/getnameinfo.3
lookup.subproj/getnameinfo_link.c [new file with mode: 0644]
lookup.subproj/ils.c
lookup.subproj/kvbuf.c
lookup.subproj/libinfo.c
lookup.subproj/libinfo.h
lookup.subproj/mdns_module.c
lookup.subproj/search_module.c
lookup.subproj/si_getaddrinfo.c
lookup.subproj/si_module.c
lookup.subproj/si_module.h
lookup.subproj/thread_data.c
lookup.subproj/thread_data.h
membership.subproj/Makefile [deleted file]
membership.subproj/mbr_uid_to_uuid.3
membership.subproj/membership.c
membership.subproj/membership.h
membership.subproj/membershipPriv.h
membership.subproj/ntsid.h
netinfo.subproj/Makefile [deleted file]
nis.subproj/Makefile [deleted file]
nis.subproj/yp_prot.h
rpc.subproj/Makefile [deleted file]
rpc.subproj/clnt_simple.c
rpc.subproj/clnt_tcp.c
rpc.subproj/clnt_udp.c
rpc.subproj/getrpcport.c
rpc.subproj/pmap_clnt.c
rpc.subproj/pmap_getport.c
util.subproj/Makefile [deleted file]
xcodescripts/install_files.sh [new file with mode: 0755]

diff --git a/Libinfo.xcodeproj/project.pbxproj b/Libinfo.xcodeproj/project.pbxproj
new file mode 100644 (file)
index 0000000..d633498
--- /dev/null
@@ -0,0 +1,1166 @@
+// !$*UTF8*$!
+{
+       archiveVersion = 1;
+       classes = {
+       };
+       objectVersion = 45;
+       objects = {
+
+/* Begin PBXBuildFile section */
+               2D31A0FC128074E700D5A84C /* getifmaddrs.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D31A0FB128074E700D5A84C /* getifmaddrs.c */; };
+               2D31A0FD128074E700D5A84C /* getifmaddrs.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D31A0FB128074E700D5A84C /* getifmaddrs.c */; };
+               2D4070B1129354A700FE81ED /* getnameinfo_link.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D4070B0129354A700FE81ED /* getnameinfo_link.c */; };
+               2D4070B2129354A700FE81ED /* getnameinfo_link.c in Sources */ = {isa = PBXBuildFile; fileRef = 2D4070B0129354A700FE81ED /* getnameinfo_link.c */; };
+               3FCF60EC1257C272008D8BB1 /* herror.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5283EE11478C200058CCB0 /* herror.c */; };
+               3FCF60ED1257C272008D8BB1 /* res_comp.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5283F711478C200058CCB0 /* res_comp.c */; };
+               3FCF60EE1257C272008D8BB1 /* res_data.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5283F811478C200058CCB0 /* res_data.c */; };
+               3FCF60EF1257C272008D8BB1 /* res_debug.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5283F911478C200058CCB0 /* res_debug.c */; };
+               3FCF60F01257C272008D8BB1 /* res_init.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5283FA11478C200058CCB0 /* res_init.c */; };
+               3FCF60F11257C272008D8BB1 /* res_mkquery.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5283FB11478C200058CCB0 /* res_mkquery.c */; };
+               3FCF60F21257C272008D8BB1 /* res_query.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5283FC11478C200058CCB0 /* res_query.c */; };
+               3FCF60F31257C272008D8BB1 /* res_send.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5283FE11478C200058CCB0 /* res_send.c */; };
+               3FCF60F41257C272008D8BB1 /* getifaddrs.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52840411478C200058CCB0 /* getifaddrs.c */; };
+               3FCF60F51257C272008D8BB1 /* if_indextoname.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52840A11478C200058CCB0 /* if_indextoname.c */; };
+               3FCF60F61257C272008D8BB1 /* if_nameindex.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52840B11478C200058CCB0 /* if_nameindex.c */; };
+               3FCF60F71257C272008D8BB1 /* if_nametoindex.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52840C11478C200058CCB0 /* if_nametoindex.c */; };
+               3FCF60F81257C272008D8BB1 /* inet_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52841011478C200058CCB0 /* inet_ntop.c */; };
+               3FCF60F91257C272008D8BB1 /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52841111478C200058CCB0 /* inet_pton.c */; };
+               3FCF60FA1257C272008D8BB1 /* ip6opt.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52841211478C200058CCB0 /* ip6opt.c */; };
+               3FCF60FB1257C272008D8BB1 /* map_v4v6.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52841411478C200058CCB0 /* map_v4v6.c */; };
+               3FCF60FC1257C272008D8BB1 /* rthdr.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52841511478C200058CCB0 /* rthdr.c */; };
+               3FCF60FD1257C272008D8BB1 /* vars.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52841611478C200058CCB0 /* vars.c */; };
+               3FCF610A1257C272008D8BB1 /* membership.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52843E11478C200058CCB0 /* membership.c */; };
+               3FCF610B1257C272008D8BB1 /* ni_stub.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52844411478C200058CCB0 /* ni_stub.c */; };
+               3FCF610C1257C272008D8BB1 /* getdomainname.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52844611478C200058CCB0 /* getdomainname.c */; };
+               3FCF610D1257C272008D8BB1 /* getnetgrent.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52844711478C200058CCB0 /* getnetgrent.c */; };
+               3FCF610E1257C272008D8BB1 /* innetgr.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52844811478C200058CCB0 /* innetgr.c */; };
+               3FCF610F1257C272008D8BB1 /* setdomainname.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52844A11478C200058CCB0 /* setdomainname.c */; };
+               3FCF61101257C272008D8BB1 /* xdr_domainname.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52844B11478C200058CCB0 /* xdr_domainname.c */; };
+               3FCF61111257C272008D8BB1 /* xdr_keydat.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52844C11478C200058CCB0 /* xdr_keydat.c */; };
+               3FCF61121257C272008D8BB1 /* xdr_mapname.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52844D11478C200058CCB0 /* xdr_mapname.c */; };
+               3FCF61131257C272008D8BB1 /* xdr_peername.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52844E11478C200058CCB0 /* xdr_peername.c */; };
+               3FCF61141257C272008D8BB1 /* xdr_valdat.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52844F11478C200058CCB0 /* xdr_valdat.c */; };
+               3FCF61151257C272008D8BB1 /* xdr_ypbind_binding.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845011478C200058CCB0 /* xdr_ypbind_binding.c */; };
+               3FCF61161257C272008D8BB1 /* xdr_ypbind_resp.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845111478C200058CCB0 /* xdr_ypbind_resp.c */; };
+               3FCF61171257C272008D8BB1 /* xdr_ypbind_resptype.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845211478C200058CCB0 /* xdr_ypbind_resptype.c */; };
+               3FCF61181257C272008D8BB1 /* xdr_ypbind_setdom.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845311478C200058CCB0 /* xdr_ypbind_setdom.c */; };
+               3FCF61191257C272008D8BB1 /* xdr_ypmaplist.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845411478C200058CCB0 /* xdr_ypmaplist.c */; };
+               3FCF611A1257C272008D8BB1 /* xdr_ypreq_key.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845511478C200058CCB0 /* xdr_ypreq_key.c */; };
+               3FCF611B1257C272008D8BB1 /* xdr_ypreq_nokey.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845611478C200058CCB0 /* xdr_ypreq_nokey.c */; };
+               3FCF611C1257C272008D8BB1 /* xdr_ypresp_all.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845711478C200058CCB0 /* xdr_ypresp_all.c */; };
+               3FCF611D1257C272008D8BB1 /* xdr_ypresp_key_val.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845811478C200058CCB0 /* xdr_ypresp_key_val.c */; };
+               3FCF611E1257C272008D8BB1 /* xdr_ypresp_maplist.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845911478C200058CCB0 /* xdr_ypresp_maplist.c */; };
+               3FCF611F1257C272008D8BB1 /* xdr_ypresp_master.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845A11478C200058CCB0 /* xdr_ypresp_master.c */; };
+               3FCF61201257C272008D8BB1 /* xdr_ypresp_order.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845B11478C200058CCB0 /* xdr_ypresp_order.c */; };
+               3FCF61211257C272008D8BB1 /* xdr_ypresp_val.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845C11478C200058CCB0 /* xdr_ypresp_val.c */; };
+               3FCF61221257C272008D8BB1 /* xdr_ypstat.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845D11478C200058CCB0 /* xdr_ypstat.c */; };
+               3FCF61231257C272008D8BB1 /* yp_all.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52846011478C200058CCB0 /* yp_all.c */; };
+               3FCF61241257C272008D8BB1 /* yp_bind.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52846211478C200058CCB0 /* yp_bind.c */; };
+               3FCF61251257C272008D8BB1 /* yp_first.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52846411478C200058CCB0 /* yp_first.c */; };
+               3FCF61261257C272008D8BB1 /* yp_get_default_domain.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52846611478C200058CCB0 /* yp_get_default_domain.c */; };
+               3FCF61271257C272008D8BB1 /* yp_maplist.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52846711478C200058CCB0 /* yp_maplist.c */; };
+               3FCF61281257C272008D8BB1 /* yp_master.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52846911478C200058CCB0 /* yp_master.c */; };
+               3FCF61291257C272008D8BB1 /* yp_order.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52846D11478C200058CCB0 /* yp_order.c */; };
+               3FCF612A1257C272008D8BB1 /* yperr_string.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52847311478C200058CCB0 /* yperr_string.c */; };
+               3FCF612B1257C272008D8BB1 /* ypmatch_cache.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52847511478C200058CCB0 /* ypmatch_cache.c */; };
+               3FCF612C1257C272008D8BB1 /* yppasswdd_xdr.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52847611478C200058CCB0 /* yppasswdd_xdr.c */; };
+               3FCF612D1257C272008D8BB1 /* ypprot_err.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52847811478C200058CCB0 /* ypprot_err.c */; };
+               3FCF612E1257C272008D8BB1 /* auth_none.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52847B11478C200058CCB0 /* auth_none.c */; };
+               3FCF612F1257C272008D8BB1 /* auth_unix.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52847C11478C200058CCB0 /* auth_unix.c */; };
+               3FCF61301257C272008D8BB1 /* authunix_prot.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52847E11478C200058CCB0 /* authunix_prot.c */; };
+               3FCF61311257C272008D8BB1 /* bindresvport.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52848011478C200058CCB0 /* bindresvport.c */; };
+               3FCF61321257C272008D8BB1 /* clnt_generic.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52848211478C200058CCB0 /* clnt_generic.c */; };
+               3FCF61331257C272008D8BB1 /* clnt_perror.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52848311478C200058CCB0 /* clnt_perror.c */; };
+               3FCF61341257C272008D8BB1 /* clnt_raw.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52848411478C200058CCB0 /* clnt_raw.c */; };
+               3FCF61351257C272008D8BB1 /* clnt_simple.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52848511478C200058CCB0 /* clnt_simple.c */; };
+               3FCF61361257C272008D8BB1 /* clnt_tcp.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52848611478C200058CCB0 /* clnt_tcp.c */; };
+               3FCF61371257C272008D8BB1 /* clnt_udp.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52848711478C200058CCB0 /* clnt_udp.c */; };
+               3FCF61381257C272008D8BB1 /* get_myaddress.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52848911478C200058CCB0 /* get_myaddress.c */; };
+               3FCF61391257C272008D8BB1 /* getrpcent.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52848B11478C200058CCB0 /* getrpcent.c */; };
+               3FCF613A1257C272008D8BB1 /* getrpcport.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52848D11478C200058CCB0 /* getrpcport.c */; };
+               3FCF613B1257C272008D8BB1 /* pmap_clnt.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52849011478C200058CCB0 /* pmap_clnt.c */; };
+               3FCF613C1257C272008D8BB1 /* pmap_getmaps.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52849211478C200058CCB0 /* pmap_getmaps.c */; };
+               3FCF613D1257C272008D8BB1 /* pmap_getport.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52849311478C200058CCB0 /* pmap_getport.c */; };
+               3FCF613E1257C272008D8BB1 /* pmap_prot.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52849411478C200058CCB0 /* pmap_prot.c */; };
+               3FCF613F1257C272008D8BB1 /* pmap_prot2.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52849611478C200058CCB0 /* pmap_prot2.c */; };
+               3FCF61401257C272008D8BB1 /* pmap_rmt.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52849711478C200058CCB0 /* pmap_rmt.c */; };
+               3FCF61411257C272008D8BB1 /* pmap_wakeup.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52849911478C200058CCB0 /* pmap_wakeup.c */; };
+               3FCF61421257C272008D8BB1 /* rpc_callmsg.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52849E11478C200058CCB0 /* rpc_callmsg.c */; };
+               3FCF61431257C272008D8BB1 /* rpc_commondata.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52849F11478C200058CCB0 /* rpc_commondata.c */; };
+               3FCF61441257C272008D8BB1 /* rpc_dtablesize.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284A011478C200058CCB0 /* rpc_dtablesize.c */; };
+               3FCF61451257C272008D8BB1 /* rpc_prot.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284A211478C200058CCB0 /* rpc_prot.c */; };
+               3FCF61461257C272008D8BB1 /* svc.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284A311478C200058CCB0 /* svc.c */; };
+               3FCF61471257C272008D8BB1 /* svc_auth.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284A511478C200058CCB0 /* svc_auth.c */; };
+               3FCF61481257C272008D8BB1 /* svc_auth_unix.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284A711478C200058CCB0 /* svc_auth_unix.c */; };
+               3FCF61491257C272008D8BB1 /* svc_raw.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284A811478C200058CCB0 /* svc_raw.c */; };
+               3FCF614A1257C272008D8BB1 /* svc_run.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284A911478C200058CCB0 /* svc_run.c */; };
+               3FCF614B1257C272008D8BB1 /* svc_simple.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284AA11478C200058CCB0 /* svc_simple.c */; };
+               3FCF614C1257C272008D8BB1 /* svc_tcp.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284AB11478C200058CCB0 /* svc_tcp.c */; };
+               3FCF614D1257C272008D8BB1 /* svc_udp.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284AC11478C200058CCB0 /* svc_udp.c */; };
+               3FCF614E1257C272008D8BB1 /* xdr.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284AF11478C200058CCB0 /* xdr.c */; };
+               3FCF614F1257C272008D8BB1 /* xdr_array.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284B111478C200058CCB0 /* xdr_array.c */; };
+               3FCF61501257C272008D8BB1 /* xdr_float.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284B211478C200058CCB0 /* xdr_float.c */; };
+               3FCF61511257C272008D8BB1 /* xdr_mem.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284B311478C200058CCB0 /* xdr_mem.c */; };
+               3FCF61521257C272008D8BB1 /* xdr_rec.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284B411478C200058CCB0 /* xdr_rec.c */; };
+               3FCF61531257C272008D8BB1 /* xdr_reference.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284B511478C200058CCB0 /* xdr_reference.c */; };
+               3FCF61541257C272008D8BB1 /* xdr_sizeof.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284B611478C200058CCB0 /* xdr_sizeof.c */; };
+               3FCF61551257C272008D8BB1 /* xdr_stdio.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284B711478C200058CCB0 /* xdr_stdio.c */; };
+               3FCF61561257C272008D8BB1 /* hton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284BA11478C200058CCB0 /* hton.c */; };
+               3FCF61571257C272008D8BB1 /* putpwpasswd.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284BC11478C200058CCB0 /* putpwpasswd.c */; };
+               3FCF61581257C272008D8BB1 /* rcmd.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284BE11478C200058CCB0 /* rcmd.c */; };
+               3FCF61591257C272008D8BB1 /* rcmdsh.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284BF11478C200058CCB0 /* rcmdsh.c */; };
+               3FCF615D1257C272008D8BB1 /* ether_addr.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5285F6114793400058CCB0 /* ether_addr.c */; };
+               FC5284C011478C200058CCB0 /* herror.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5283EE11478C200058CCB0 /* herror.c */; };
+               FC5284C811478C200058CCB0 /* res_comp.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5283F711478C200058CCB0 /* res_comp.c */; };
+               FC5284C911478C200058CCB0 /* res_data.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5283F811478C200058CCB0 /* res_data.c */; };
+               FC5284CA11478C200058CCB0 /* res_debug.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5283F911478C200058CCB0 /* res_debug.c */; };
+               FC5284CB11478C200058CCB0 /* res_init.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5283FA11478C200058CCB0 /* res_init.c */; };
+               FC5284CC11478C200058CCB0 /* res_mkquery.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5283FB11478C200058CCB0 /* res_mkquery.c */; };
+               FC5284CD11478C200058CCB0 /* res_query.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5283FC11478C200058CCB0 /* res_query.c */; };
+               FC5284CF11478C200058CCB0 /* res_send.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5283FE11478C200058CCB0 /* res_send.c */; };
+               FC5284D211478C200058CCB0 /* getifaddrs.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52840411478C200058CCB0 /* getifaddrs.c */; };
+               FC5284D311478C200058CCB0 /* if_indextoname.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52840A11478C200058CCB0 /* if_indextoname.c */; };
+               FC5284D411478C200058CCB0 /* if_nameindex.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52840B11478C200058CCB0 /* if_nameindex.c */; };
+               FC5284D511478C200058CCB0 /* if_nametoindex.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52840C11478C200058CCB0 /* if_nametoindex.c */; };
+               FC5284D711478C200058CCB0 /* inet_ntop.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52841011478C200058CCB0 /* inet_ntop.c */; };
+               FC5284D811478C200058CCB0 /* inet_pton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52841111478C200058CCB0 /* inet_pton.c */; };
+               FC5284D911478C200058CCB0 /* ip6opt.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52841211478C200058CCB0 /* ip6opt.c */; };
+               FC5284DB11478C200058CCB0 /* map_v4v6.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52841411478C200058CCB0 /* map_v4v6.c */; };
+               FC5284DC11478C200058CCB0 /* rthdr.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52841511478C200058CCB0 /* rthdr.c */; };
+               FC5284DD11478C200058CCB0 /* vars.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52841611478C200058CCB0 /* vars.c */; };
+               FC5284E011478C200058CCB0 /* cache_module.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52841B11478C200058CCB0 /* cache_module.c */; };
+               FC5284E111478C200058CCB0 /* ds_module.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52841C11478C200058CCB0 /* ds_module.c */; };
+               FC5284E211478C200058CCB0 /* file_module.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52841D11478C200058CCB0 /* file_module.c */; };
+               FC5284E311478C200058CCB0 /* ils.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52842611478C200058CCB0 /* ils.c */; };
+               FC5284E511478C200058CCB0 /* kvbuf.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52842911478C200058CCB0 /* kvbuf.c */; };
+               FC5284E711478C200058CCB0 /* libinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52842B11478C200058CCB0 /* libinfo.c */; };
+               FC5284EA11478C200058CCB0 /* mdns_module.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52842E11478C200058CCB0 /* mdns_module.c */; };
+               FC5284EE11478C200058CCB0 /* search_module.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52843211478C200058CCB0 /* search_module.c */; };
+               FC5284EF11478C200058CCB0 /* si_data.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52843311478C200058CCB0 /* si_data.c */; };
+               FC5284F111478C200058CCB0 /* si_getaddrinfo.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52843511478C200058CCB0 /* si_getaddrinfo.c */; };
+               FC5284F211478C200058CCB0 /* si_module.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52843611478C200058CCB0 /* si_module.c */; };
+               FC5284F411478C200058CCB0 /* thread_data.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52843811478C200058CCB0 /* thread_data.c */; };
+               FC5284F711478C200058CCB0 /* membership.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52843E11478C200058CCB0 /* membership.c */; };
+               FC5284FC11478C200058CCB0 /* ni_stub.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52844411478C200058CCB0 /* ni_stub.c */; };
+               FC5284FD11478C200058CCB0 /* getdomainname.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52844611478C200058CCB0 /* getdomainname.c */; };
+               FC5284FE11478C200058CCB0 /* getnetgrent.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52844711478C200058CCB0 /* getnetgrent.c */; };
+               FC5284FF11478C200058CCB0 /* innetgr.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52844811478C200058CCB0 /* innetgr.c */; };
+               FC52850111478C200058CCB0 /* setdomainname.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52844A11478C200058CCB0 /* setdomainname.c */; };
+               FC52850211478C200058CCB0 /* xdr_domainname.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52844B11478C200058CCB0 /* xdr_domainname.c */; };
+               FC52850311478C200058CCB0 /* xdr_keydat.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52844C11478C200058CCB0 /* xdr_keydat.c */; };
+               FC52850411478C200058CCB0 /* xdr_mapname.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52844D11478C200058CCB0 /* xdr_mapname.c */; };
+               FC52850511478C200058CCB0 /* xdr_peername.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52844E11478C200058CCB0 /* xdr_peername.c */; };
+               FC52850611478C200058CCB0 /* xdr_valdat.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52844F11478C200058CCB0 /* xdr_valdat.c */; };
+               FC52850711478C200058CCB0 /* xdr_ypbind_binding.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845011478C200058CCB0 /* xdr_ypbind_binding.c */; };
+               FC52850811478C200058CCB0 /* xdr_ypbind_resp.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845111478C200058CCB0 /* xdr_ypbind_resp.c */; };
+               FC52850911478C200058CCB0 /* xdr_ypbind_resptype.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845211478C200058CCB0 /* xdr_ypbind_resptype.c */; };
+               FC52850A11478C200058CCB0 /* xdr_ypbind_setdom.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845311478C200058CCB0 /* xdr_ypbind_setdom.c */; };
+               FC52850B11478C200058CCB0 /* xdr_ypmaplist.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845411478C200058CCB0 /* xdr_ypmaplist.c */; };
+               FC52850C11478C200058CCB0 /* xdr_ypreq_key.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845511478C200058CCB0 /* xdr_ypreq_key.c */; };
+               FC52850D11478C200058CCB0 /* xdr_ypreq_nokey.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845611478C200058CCB0 /* xdr_ypreq_nokey.c */; };
+               FC52850E11478C200058CCB0 /* xdr_ypresp_all.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845711478C200058CCB0 /* xdr_ypresp_all.c */; };
+               FC52850F11478C200058CCB0 /* xdr_ypresp_key_val.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845811478C200058CCB0 /* xdr_ypresp_key_val.c */; };
+               FC52851011478C200058CCB0 /* xdr_ypresp_maplist.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845911478C200058CCB0 /* xdr_ypresp_maplist.c */; };
+               FC52851111478C200058CCB0 /* xdr_ypresp_master.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845A11478C200058CCB0 /* xdr_ypresp_master.c */; };
+               FC52851211478C200058CCB0 /* xdr_ypresp_order.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845B11478C200058CCB0 /* xdr_ypresp_order.c */; };
+               FC52851311478C200058CCB0 /* xdr_ypresp_val.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845C11478C200058CCB0 /* xdr_ypresp_val.c */; };
+               FC52851411478C200058CCB0 /* xdr_ypstat.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52845D11478C200058CCB0 /* xdr_ypstat.c */; };
+               FC52851511478C200058CCB0 /* yp_all.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52846011478C200058CCB0 /* yp_all.c */; };
+               FC52851611478C200058CCB0 /* yp_bind.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52846211478C200058CCB0 /* yp_bind.c */; };
+               FC52851711478C200058CCB0 /* yp_first.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52846411478C200058CCB0 /* yp_first.c */; };
+               FC52851811478C200058CCB0 /* yp_get_default_domain.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52846611478C200058CCB0 /* yp_get_default_domain.c */; };
+               FC52851911478C200058CCB0 /* yp_maplist.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52846711478C200058CCB0 /* yp_maplist.c */; };
+               FC52851A11478C200058CCB0 /* yp_master.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52846911478C200058CCB0 /* yp_master.c */; };
+               FC52851B11478C200058CCB0 /* yp_order.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52846D11478C200058CCB0 /* yp_order.c */; };
+               FC52851E11478C200058CCB0 /* yperr_string.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52847311478C200058CCB0 /* yperr_string.c */; };
+               FC52852011478C200058CCB0 /* ypmatch_cache.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52847511478C200058CCB0 /* ypmatch_cache.c */; };
+               FC52852111478C200058CCB0 /* yppasswdd_xdr.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52847611478C200058CCB0 /* yppasswdd_xdr.c */; };
+               FC52852211478C200058CCB0 /* ypprot_err.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52847811478C200058CCB0 /* ypprot_err.c */; };
+               FC52852411478C200058CCB0 /* auth_none.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52847B11478C200058CCB0 /* auth_none.c */; };
+               FC52852511478C200058CCB0 /* auth_unix.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52847C11478C200058CCB0 /* auth_unix.c */; };
+               FC52852711478C200058CCB0 /* authunix_prot.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52847E11478C200058CCB0 /* authunix_prot.c */; };
+               FC52852811478C200058CCB0 /* bindresvport.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52848011478C200058CCB0 /* bindresvport.c */; };
+               FC52852A11478C200058CCB0 /* clnt_generic.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52848211478C200058CCB0 /* clnt_generic.c */; };
+               FC52852B11478C200058CCB0 /* clnt_perror.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52848311478C200058CCB0 /* clnt_perror.c */; };
+               FC52852C11478C200058CCB0 /* clnt_raw.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52848411478C200058CCB0 /* clnt_raw.c */; };
+               FC52852D11478C200058CCB0 /* clnt_simple.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52848511478C200058CCB0 /* clnt_simple.c */; };
+               FC52852E11478C200058CCB0 /* clnt_tcp.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52848611478C200058CCB0 /* clnt_tcp.c */; };
+               FC52852F11478C200058CCB0 /* clnt_udp.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52848711478C200058CCB0 /* clnt_udp.c */; };
+               FC52853011478C200058CCB0 /* get_myaddress.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52848911478C200058CCB0 /* get_myaddress.c */; };
+               FC52853111478C200058CCB0 /* getrpcent.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52848B11478C200058CCB0 /* getrpcent.c */; };
+               FC52853211478C200058CCB0 /* getrpcport.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52848D11478C200058CCB0 /* getrpcport.c */; };
+               FC52853511478C200058CCB0 /* pmap_clnt.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52849011478C200058CCB0 /* pmap_clnt.c */; };
+               FC52853711478C200058CCB0 /* pmap_getmaps.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52849211478C200058CCB0 /* pmap_getmaps.c */; };
+               FC52853811478C200058CCB0 /* pmap_getport.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52849311478C200058CCB0 /* pmap_getport.c */; };
+               FC52853911478C200058CCB0 /* pmap_prot.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52849411478C200058CCB0 /* pmap_prot.c */; };
+               FC52853B11478C200058CCB0 /* pmap_prot2.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52849611478C200058CCB0 /* pmap_prot2.c */; };
+               FC52853C11478C200058CCB0 /* pmap_rmt.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52849711478C200058CCB0 /* pmap_rmt.c */; };
+               FC52853E11478C200058CCB0 /* pmap_wakeup.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52849911478C200058CCB0 /* pmap_wakeup.c */; };
+               FC52854111478C200058CCB0 /* rpc_callmsg.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52849E11478C200058CCB0 /* rpc_callmsg.c */; };
+               FC52854211478C200058CCB0 /* rpc_commondata.c in Sources */ = {isa = PBXBuildFile; fileRef = FC52849F11478C200058CCB0 /* rpc_commondata.c */; };
+               FC52854311478C200058CCB0 /* rpc_dtablesize.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284A011478C200058CCB0 /* rpc_dtablesize.c */; };
+               FC52854511478C200058CCB0 /* rpc_prot.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284A211478C200058CCB0 /* rpc_prot.c */; };
+               FC52854611478C200058CCB0 /* svc.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284A311478C200058CCB0 /* svc.c */; };
+               FC52854811478C200058CCB0 /* svc_auth.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284A511478C200058CCB0 /* svc_auth.c */; };
+               FC52854A11478C200058CCB0 /* svc_auth_unix.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284A711478C200058CCB0 /* svc_auth_unix.c */; };
+               FC52854B11478C200058CCB0 /* svc_raw.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284A811478C200058CCB0 /* svc_raw.c */; };
+               FC52854C11478C200058CCB0 /* svc_run.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284A911478C200058CCB0 /* svc_run.c */; };
+               FC52854D11478C200058CCB0 /* svc_simple.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284AA11478C200058CCB0 /* svc_simple.c */; };
+               FC52854E11478C200058CCB0 /* svc_tcp.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284AB11478C200058CCB0 /* svc_tcp.c */; };
+               FC52854F11478C200058CCB0 /* svc_udp.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284AC11478C200058CCB0 /* svc_udp.c */; };
+               FC52855111478C200058CCB0 /* xdr.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284AF11478C200058CCB0 /* xdr.c */; };
+               FC52855311478C200058CCB0 /* xdr_array.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284B111478C200058CCB0 /* xdr_array.c */; };
+               FC52855411478C200058CCB0 /* xdr_float.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284B211478C200058CCB0 /* xdr_float.c */; };
+               FC52855511478C200058CCB0 /* xdr_mem.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284B311478C200058CCB0 /* xdr_mem.c */; };
+               FC52855611478C200058CCB0 /* xdr_rec.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284B411478C200058CCB0 /* xdr_rec.c */; };
+               FC52855711478C200058CCB0 /* xdr_reference.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284B511478C200058CCB0 /* xdr_reference.c */; };
+               FC52855811478C200058CCB0 /* xdr_sizeof.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284B611478C200058CCB0 /* xdr_sizeof.c */; };
+               FC52855911478C200058CCB0 /* xdr_stdio.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284B711478C200058CCB0 /* xdr_stdio.c */; };
+               FC52855A11478C200058CCB0 /* hton.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284BA11478C200058CCB0 /* hton.c */; };
+               FC52855C11478C200058CCB0 /* putpwpasswd.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284BC11478C200058CCB0 /* putpwpasswd.c */; };
+               FC52855D11478C200058CCB0 /* rcmd.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284BE11478C200058CCB0 /* rcmd.c */; };
+               FC52855E11478C200058CCB0 /* rcmdsh.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5284BF11478C200058CCB0 /* rcmdsh.c */; };
+               FC5285D4114791B50058CCB0 /* DSlibinfoMIG.defs in Sources */ = {isa = PBXBuildFile; fileRef = FC5285D1114791B50058CCB0 /* DSlibinfoMIG.defs */; };
+               FC5285D5114791B50058CCB0 /* DSlibinfoMIGAsyncReply.defs in Sources */ = {isa = PBXBuildFile; fileRef = FC5285D2114791B50058CCB0 /* DSlibinfoMIGAsyncReply.defs */; settings = {ATTRIBUTES = (Server, ); }; };
+               FC5285D6114791B50058CCB0 /* DSmemberdMIG.defs in Sources */ = {isa = PBXBuildFile; fileRef = FC5285D3114791B50058CCB0 /* DSmemberdMIG.defs */; };
+               FC5285F7114793400058CCB0 /* ether_addr.c in Sources */ = {isa = PBXBuildFile; fileRef = FC5285F6114793400058CCB0 /* ether_addr.c */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXFileReference section */
+               2D31A0FA128074E700D5A84C /* getifmaddrs.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = getifmaddrs.3; sourceTree = "<group>"; };
+               2D31A0FB128074E700D5A84C /* getifmaddrs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = getifmaddrs.c; sourceTree = "<group>"; };
+               2D4070B0129354A700FE81ED /* getnameinfo_link.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = getnameinfo_link.c; sourceTree = "<group>"; };
+               2D4D4AB1122C5B83009791E5 /* inet6_rth_space.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = inet6_rth_space.3; sourceTree = "<group>"; };
+               2DBB147712DBD63300D710E3 /* inet6_opt_init.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = inet6_opt_init.3; sourceTree = "<group>"; };
+               3FCF61621257C272008D8BB1 /* libsystem_sim_info.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libsystem_sim_info.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
+               D2AAC0630554660B00DB518D /* libsystem_info.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libsystem_info.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
+               FC5283EE11478C200058CCB0 /* herror.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = herror.c; sourceTree = "<group>"; };
+               FC5283EF11478C200058CCB0 /* inet.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = inet.h; sourceTree = "<group>"; };
+               FC5283F311478C200058CCB0 /* nameser8_compat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = nameser8_compat.h; sourceTree = "<group>"; };
+               FC5283F511478C200058CCB0 /* options.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = options.h; sourceTree = "<group>"; };
+               FC5283F611478C200058CCB0 /* portability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = portability.h; sourceTree = "<group>"; };
+               FC5283F711478C200058CCB0 /* res_comp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = res_comp.c; sourceTree = "<group>"; };
+               FC5283F811478C200058CCB0 /* res_data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = res_data.c; sourceTree = "<group>"; };
+               FC5283F911478C200058CCB0 /* res_debug.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = res_debug.c; sourceTree = "<group>"; };
+               FC5283FA11478C200058CCB0 /* res_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = res_init.c; sourceTree = "<group>"; };
+               FC5283FB11478C200058CCB0 /* res_mkquery.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = res_mkquery.c; sourceTree = "<group>"; };
+               FC5283FC11478C200058CCB0 /* res_query.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = res_query.c; sourceTree = "<group>"; };
+               FC5283FE11478C200058CCB0 /* res_send.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = res_send.c; sourceTree = "<group>"; };
+               FC5283FF11478C200058CCB0 /* resolv8_compat.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = resolv8_compat.h; sourceTree = "<group>"; };
+               FC52840211478C200058CCB0 /* gethostbyname.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = gethostbyname.3; sourceTree = "<group>"; };
+               FC52840311478C200058CCB0 /* getifaddrs.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = getifaddrs.3; sourceTree = "<group>"; };
+               FC52840411478C200058CCB0 /* getifaddrs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = getifaddrs.c; sourceTree = "<group>"; };
+               FC52840511478C200058CCB0 /* getipnodebyname.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = getipnodebyname.3; sourceTree = "<group>"; };
+               FC52840611478C200058CCB0 /* getnetent.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = getnetent.3; sourceTree = "<group>"; };
+               FC52840711478C200058CCB0 /* getprotoent.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = getprotoent.3; sourceTree = "<group>"; };
+               FC52840811478C200058CCB0 /* getservent.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = getservent.3; sourceTree = "<group>"; };
+               FC52840911478C200058CCB0 /* if_indextoname.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = if_indextoname.3; sourceTree = "<group>"; };
+               FC52840A11478C200058CCB0 /* if_indextoname.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = if_indextoname.c; sourceTree = "<group>"; };
+               FC52840B11478C200058CCB0 /* if_nameindex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = if_nameindex.c; sourceTree = "<group>"; };
+               FC52840C11478C200058CCB0 /* if_nametoindex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = if_nametoindex.c; sourceTree = "<group>"; };
+               FC52840D11478C200058CCB0 /* ifaddrs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ifaddrs.h; sourceTree = "<group>"; };
+               FC52840E11478C200058CCB0 /* inet6_option_space.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = inet6_option_space.3; sourceTree = "<group>"; };
+               FC52840F11478C200058CCB0 /* inet6_rthdr_space.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = inet6_rthdr_space.3; sourceTree = "<group>"; };
+               FC52841011478C200058CCB0 /* inet_ntop.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = inet_ntop.c; sourceTree = "<group>"; };
+               FC52841111478C200058CCB0 /* inet_pton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = inet_pton.c; sourceTree = "<group>"; };
+               FC52841211478C200058CCB0 /* ip6opt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ip6opt.c; sourceTree = "<group>"; };
+               FC52841411478C200058CCB0 /* map_v4v6.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = map_v4v6.c; sourceTree = "<group>"; };
+               FC52841511478C200058CCB0 /* rthdr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rthdr.c; sourceTree = "<group>"; };
+               FC52841611478C200058CCB0 /* vars.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vars.c; sourceTree = "<group>"; };
+               FC52841811478C200058CCB0 /* aliasdb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aliasdb.h; sourceTree = "<group>"; };
+               FC52841911478C200058CCB0 /* bootparams.5 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = bootparams.5; sourceTree = "<group>"; };
+               FC52841A11478C200058CCB0 /* bootparams.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bootparams.h; sourceTree = "<group>"; };
+               FC52841B11478C200058CCB0 /* cache_module.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cache_module.c; sourceTree = "<group>"; };
+               FC52841C11478C200058CCB0 /* ds_module.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ds_module.c; sourceTree = "<group>"; };
+               FC52841D11478C200058CCB0 /* file_module.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = file_module.c; sourceTree = "<group>"; };
+               FC52841E11478C200058CCB0 /* gai_strerror.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = gai_strerror.3; sourceTree = "<group>"; };
+               FC52841F11478C200058CCB0 /* getaddrinfo.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = getaddrinfo.3; sourceTree = "<group>"; };
+               FC52842011478C200058CCB0 /* getfsent.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = getfsent.3; sourceTree = "<group>"; };
+               FC52842111478C200058CCB0 /* getgrent.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = getgrent.3; sourceTree = "<group>"; };
+               FC52842211478C200058CCB0 /* getgrouplist.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = getgrouplist.3; sourceTree = "<group>"; };
+               FC52842311478C200058CCB0 /* getnameinfo.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = getnameinfo.3; sourceTree = "<group>"; };
+               FC52842411478C200058CCB0 /* getnetgrent.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = getnetgrent.3; sourceTree = "<group>"; };
+               FC52842511478C200058CCB0 /* getpwent.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = getpwent.3; sourceTree = "<group>"; };
+               FC52842611478C200058CCB0 /* ils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ils.c; sourceTree = "<group>"; };
+               FC52842711478C200058CCB0 /* ils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ils.h; sourceTree = "<group>"; };
+               FC52842811478C200058CCB0 /* initgroups.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = initgroups.3; sourceTree = "<group>"; };
+               FC52842911478C200058CCB0 /* kvbuf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = kvbuf.c; sourceTree = "<group>"; };
+               FC52842A11478C200058CCB0 /* kvbuf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = kvbuf.h; sourceTree = "<group>"; };
+               FC52842B11478C200058CCB0 /* libinfo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = libinfo.c; sourceTree = "<group>"; };
+               FC52842C11478C200058CCB0 /* libinfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = libinfo.h; sourceTree = "<group>"; };
+               FC52842E11478C200058CCB0 /* mdns_module.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mdns_module.c; sourceTree = "<group>"; };
+               FC52842F11478C200058CCB0 /* netdb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = netdb.h; sourceTree = "<group>"; };
+               FC52843011478C200058CCB0 /* netdb_async.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = netdb_async.h; sourceTree = "<group>"; };
+               FC52843111478C200058CCB0 /* printerdb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = printerdb.h; sourceTree = "<group>"; };
+               FC52843211478C200058CCB0 /* search_module.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = search_module.c; sourceTree = "<group>"; };
+               FC52843311478C200058CCB0 /* si_data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = si_data.c; sourceTree = "<group>"; };
+               FC52843411478C200058CCB0 /* si_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = si_data.h; sourceTree = "<group>"; };
+               FC52843511478C200058CCB0 /* si_getaddrinfo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = si_getaddrinfo.c; sourceTree = "<group>"; };
+               FC52843611478C200058CCB0 /* si_module.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = si_module.c; sourceTree = "<group>"; };
+               FC52843711478C200058CCB0 /* si_module.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = si_module.h; sourceTree = "<group>"; };
+               FC52843811478C200058CCB0 /* thread_data.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = thread_data.c; sourceTree = "<group>"; };
+               FC52843911478C200058CCB0 /* thread_data.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = thread_data.h; sourceTree = "<group>"; };
+               FC52843C11478C200058CCB0 /* mbr_check_membership.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mbr_check_membership.3; sourceTree = "<group>"; };
+               FC52843D11478C200058CCB0 /* mbr_uid_to_uuid.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mbr_uid_to_uuid.3; sourceTree = "<group>"; };
+               FC52843E11478C200058CCB0 /* membership.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = membership.c; sourceTree = "<group>"; };
+               FC52843F11478C200058CCB0 /* membership.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = membership.h; sourceTree = "<group>"; };
+               FC52844011478C200058CCB0 /* membershipPriv.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = membershipPriv.h; sourceTree = "<group>"; };
+               FC52844111478C200058CCB0 /* ntsid.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ntsid.h; sourceTree = "<group>"; };
+               FC52844411478C200058CCB0 /* ni_stub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ni_stub.c; sourceTree = "<group>"; };
+               FC52844611478C200058CCB0 /* getdomainname.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = getdomainname.c; sourceTree = "<group>"; };
+               FC52844711478C200058CCB0 /* getnetgrent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = getnetgrent.c; sourceTree = "<group>"; };
+               FC52844811478C200058CCB0 /* innetgr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = innetgr.c; sourceTree = "<group>"; };
+               FC52844A11478C200058CCB0 /* setdomainname.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = setdomainname.c; sourceTree = "<group>"; };
+               FC52844B11478C200058CCB0 /* xdr_domainname.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_domainname.c; sourceTree = "<group>"; };
+               FC52844C11478C200058CCB0 /* xdr_keydat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_keydat.c; sourceTree = "<group>"; };
+               FC52844D11478C200058CCB0 /* xdr_mapname.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_mapname.c; sourceTree = "<group>"; };
+               FC52844E11478C200058CCB0 /* xdr_peername.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_peername.c; sourceTree = "<group>"; };
+               FC52844F11478C200058CCB0 /* xdr_valdat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_valdat.c; sourceTree = "<group>"; };
+               FC52845011478C200058CCB0 /* xdr_ypbind_binding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_ypbind_binding.c; sourceTree = "<group>"; };
+               FC52845111478C200058CCB0 /* xdr_ypbind_resp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_ypbind_resp.c; sourceTree = "<group>"; };
+               FC52845211478C200058CCB0 /* xdr_ypbind_resptype.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_ypbind_resptype.c; sourceTree = "<group>"; };
+               FC52845311478C200058CCB0 /* xdr_ypbind_setdom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_ypbind_setdom.c; sourceTree = "<group>"; };
+               FC52845411478C200058CCB0 /* xdr_ypmaplist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_ypmaplist.c; sourceTree = "<group>"; };
+               FC52845511478C200058CCB0 /* xdr_ypreq_key.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_ypreq_key.c; sourceTree = "<group>"; };
+               FC52845611478C200058CCB0 /* xdr_ypreq_nokey.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_ypreq_nokey.c; sourceTree = "<group>"; };
+               FC52845711478C200058CCB0 /* xdr_ypresp_all.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_ypresp_all.c; sourceTree = "<group>"; };
+               FC52845811478C200058CCB0 /* xdr_ypresp_key_val.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_ypresp_key_val.c; sourceTree = "<group>"; };
+               FC52845911478C200058CCB0 /* xdr_ypresp_maplist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_ypresp_maplist.c; sourceTree = "<group>"; };
+               FC52845A11478C200058CCB0 /* xdr_ypresp_master.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_ypresp_master.c; sourceTree = "<group>"; };
+               FC52845B11478C200058CCB0 /* xdr_ypresp_order.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_ypresp_order.c; sourceTree = "<group>"; };
+               FC52845C11478C200058CCB0 /* xdr_ypresp_val.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_ypresp_val.c; sourceTree = "<group>"; };
+               FC52845D11478C200058CCB0 /* xdr_ypstat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_ypstat.c; sourceTree = "<group>"; };
+               FC52845E11478C200058CCB0 /* yp.8 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = yp.8; sourceTree = "<group>"; };
+               FC52845F11478C200058CCB0 /* yp_all.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = yp_all.3; sourceTree = "<group>"; };
+               FC52846011478C200058CCB0 /* yp_all.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yp_all.c; sourceTree = "<group>"; };
+               FC52846111478C200058CCB0 /* yp_bind.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = yp_bind.3; sourceTree = "<group>"; };
+               FC52846211478C200058CCB0 /* yp_bind.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yp_bind.c; sourceTree = "<group>"; };
+               FC52846311478C200058CCB0 /* yp_first.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = yp_first.3; sourceTree = "<group>"; };
+               FC52846411478C200058CCB0 /* yp_first.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yp_first.c; sourceTree = "<group>"; };
+               FC52846511478C200058CCB0 /* yp_get_default_domain.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = yp_get_default_domain.3; sourceTree = "<group>"; };
+               FC52846611478C200058CCB0 /* yp_get_default_domain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yp_get_default_domain.c; sourceTree = "<group>"; };
+               FC52846711478C200058CCB0 /* yp_maplist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yp_maplist.c; sourceTree = "<group>"; };
+               FC52846811478C200058CCB0 /* yp_master.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = yp_master.3; sourceTree = "<group>"; };
+               FC52846911478C200058CCB0 /* yp_master.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yp_master.c; sourceTree = "<group>"; };
+               FC52846A11478C200058CCB0 /* yp_match.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = yp_match.3; sourceTree = "<group>"; };
+               FC52846B11478C200058CCB0 /* yp_next.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = yp_next.3; sourceTree = "<group>"; };
+               FC52846C11478C200058CCB0 /* yp_order.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = yp_order.3; sourceTree = "<group>"; };
+               FC52846D11478C200058CCB0 /* yp_order.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yp_order.c; sourceTree = "<group>"; };
+               FC52846E11478C200058CCB0 /* yp_prot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = yp_prot.h; sourceTree = "<group>"; };
+               FC52846F11478C200058CCB0 /* yp_unbind.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = yp_unbind.3; sourceTree = "<group>"; };
+               FC52847011478C200058CCB0 /* ypclnt.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ypclnt.3; sourceTree = "<group>"; };
+               FC52847111478C200058CCB0 /* ypclnt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ypclnt.h; sourceTree = "<group>"; };
+               FC52847211478C200058CCB0 /* yperr_string.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = yperr_string.3; sourceTree = "<group>"; };
+               FC52847311478C200058CCB0 /* yperr_string.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yperr_string.c; sourceTree = "<group>"; };
+               FC52847411478C200058CCB0 /* ypinternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ypinternal.h; sourceTree = "<group>"; };
+               FC52847511478C200058CCB0 /* ypmatch_cache.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ypmatch_cache.c; sourceTree = "<group>"; };
+               FC52847611478C200058CCB0 /* yppasswdd_xdr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = yppasswdd_xdr.c; sourceTree = "<group>"; };
+               FC52847711478C200058CCB0 /* ypprot_err.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ypprot_err.3; sourceTree = "<group>"; };
+               FC52847811478C200058CCB0 /* ypprot_err.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ypprot_err.c; sourceTree = "<group>"; };
+               FC52847A11478C200058CCB0 /* auth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = auth.h; sourceTree = "<group>"; };
+               FC52847B11478C200058CCB0 /* auth_none.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = auth_none.c; sourceTree = "<group>"; };
+               FC52847C11478C200058CCB0 /* auth_unix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = auth_unix.c; sourceTree = "<group>"; };
+               FC52847D11478C200058CCB0 /* auth_unix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = auth_unix.h; sourceTree = "<group>"; };
+               FC52847E11478C200058CCB0 /* authunix_prot.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = authunix_prot.c; sourceTree = "<group>"; };
+               FC52847F11478C200058CCB0 /* bindresvport.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = bindresvport.3; sourceTree = "<group>"; };
+               FC52848011478C200058CCB0 /* bindresvport.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bindresvport.c; sourceTree = "<group>"; };
+               FC52848111478C200058CCB0 /* clnt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = clnt.h; sourceTree = "<group>"; };
+               FC52848211478C200058CCB0 /* clnt_generic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = clnt_generic.c; sourceTree = "<group>"; };
+               FC52848311478C200058CCB0 /* clnt_perror.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = clnt_perror.c; sourceTree = "<group>"; };
+               FC52848411478C200058CCB0 /* clnt_raw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = clnt_raw.c; sourceTree = "<group>"; };
+               FC52848511478C200058CCB0 /* clnt_simple.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = clnt_simple.c; sourceTree = "<group>"; };
+               FC52848611478C200058CCB0 /* clnt_tcp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = clnt_tcp.c; sourceTree = "<group>"; };
+               FC52848711478C200058CCB0 /* clnt_udp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = clnt_udp.c; sourceTree = "<group>"; };
+               FC52848811478C200058CCB0 /* DISCLAIMER */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DISCLAIMER; sourceTree = "<group>"; };
+               FC52848911478C200058CCB0 /* get_myaddress.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = get_myaddress.c; sourceTree = "<group>"; };
+               FC52848A11478C200058CCB0 /* getrpcent.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = getrpcent.3; sourceTree = "<group>"; };
+               FC52848B11478C200058CCB0 /* getrpcent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = getrpcent.c; sourceTree = "<group>"; };
+               FC52848C11478C200058CCB0 /* getrpcport.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = getrpcport.3; sourceTree = "<group>"; };
+               FC52848D11478C200058CCB0 /* getrpcport.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = getrpcport.c; sourceTree = "<group>"; };
+               FC52849011478C200058CCB0 /* pmap_clnt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pmap_clnt.c; sourceTree = "<group>"; };
+               FC52849111478C200058CCB0 /* pmap_clnt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pmap_clnt.h; sourceTree = "<group>"; };
+               FC52849211478C200058CCB0 /* pmap_getmaps.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pmap_getmaps.c; sourceTree = "<group>"; };
+               FC52849311478C200058CCB0 /* pmap_getport.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pmap_getport.c; sourceTree = "<group>"; };
+               FC52849411478C200058CCB0 /* pmap_prot.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pmap_prot.c; sourceTree = "<group>"; };
+               FC52849511478C200058CCB0 /* pmap_prot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pmap_prot.h; sourceTree = "<group>"; };
+               FC52849611478C200058CCB0 /* pmap_prot2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pmap_prot2.c; sourceTree = "<group>"; };
+               FC52849711478C200058CCB0 /* pmap_rmt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pmap_rmt.c; sourceTree = "<group>"; };
+               FC52849811478C200058CCB0 /* pmap_rmt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pmap_rmt.h; sourceTree = "<group>"; };
+               FC52849911478C200058CCB0 /* pmap_wakeup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pmap_wakeup.c; sourceTree = "<group>"; };
+               FC52849A11478C200058CCB0 /* pmap_wakeup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pmap_wakeup.h; sourceTree = "<group>"; };
+               FC52849B11478C200058CCB0 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+               FC52849C11478C200058CCB0 /* rpc.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rpc.3; sourceTree = "<group>"; };
+               FC52849D11478C200058CCB0 /* rpc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rpc.h; sourceTree = "<group>"; };
+               FC52849E11478C200058CCB0 /* rpc_callmsg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rpc_callmsg.c; sourceTree = "<group>"; };
+               FC52849F11478C200058CCB0 /* rpc_commondata.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rpc_commondata.c; sourceTree = "<group>"; };
+               FC5284A011478C200058CCB0 /* rpc_dtablesize.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rpc_dtablesize.c; sourceTree = "<group>"; };
+               FC5284A111478C200058CCB0 /* rpc_msg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rpc_msg.h; sourceTree = "<group>"; };
+               FC5284A211478C200058CCB0 /* rpc_prot.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rpc_prot.c; sourceTree = "<group>"; };
+               FC5284A311478C200058CCB0 /* svc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = svc.c; sourceTree = "<group>"; };
+               FC5284A411478C200058CCB0 /* svc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = svc.h; sourceTree = "<group>"; };
+               FC5284A511478C200058CCB0 /* svc_auth.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = svc_auth.c; sourceTree = "<group>"; };
+               FC5284A611478C200058CCB0 /* svc_auth.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = svc_auth.h; sourceTree = "<group>"; };
+               FC5284A711478C200058CCB0 /* svc_auth_unix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = svc_auth_unix.c; sourceTree = "<group>"; };
+               FC5284A811478C200058CCB0 /* svc_raw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = svc_raw.c; sourceTree = "<group>"; };
+               FC5284A911478C200058CCB0 /* svc_run.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = svc_run.c; sourceTree = "<group>"; };
+               FC5284AA11478C200058CCB0 /* svc_simple.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = svc_simple.c; sourceTree = "<group>"; };
+               FC5284AB11478C200058CCB0 /* svc_tcp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = svc_tcp.c; sourceTree = "<group>"; };
+               FC5284AC11478C200058CCB0 /* svc_udp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = svc_udp.c; sourceTree = "<group>"; };
+               FC5284AD11478C200058CCB0 /* types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = "<group>"; };
+               FC5284AE11478C200058CCB0 /* xdr.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = xdr.3; sourceTree = "<group>"; };
+               FC5284AF11478C200058CCB0 /* xdr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr.c; sourceTree = "<group>"; };
+               FC5284B011478C200058CCB0 /* xdr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = xdr.h; sourceTree = "<group>"; };
+               FC5284B111478C200058CCB0 /* xdr_array.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_array.c; sourceTree = "<group>"; };
+               FC5284B211478C200058CCB0 /* xdr_float.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_float.c; sourceTree = "<group>"; };
+               FC5284B311478C200058CCB0 /* xdr_mem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_mem.c; sourceTree = "<group>"; };
+               FC5284B411478C200058CCB0 /* xdr_rec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_rec.c; sourceTree = "<group>"; };
+               FC5284B511478C200058CCB0 /* xdr_reference.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_reference.c; sourceTree = "<group>"; };
+               FC5284B611478C200058CCB0 /* xdr_sizeof.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_sizeof.c; sourceTree = "<group>"; };
+               FC5284B711478C200058CCB0 /* xdr_stdio.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xdr_stdio.c; sourceTree = "<group>"; };
+               FC5284B911478C200058CCB0 /* hosts.equiv.5 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = hosts.equiv.5; sourceTree = "<group>"; };
+               FC5284BA11478C200058CCB0 /* hton.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hton.c; sourceTree = "<group>"; };
+               FC5284BC11478C200058CCB0 /* putpwpasswd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = putpwpasswd.c; sourceTree = "<group>"; };
+               FC5284BD11478C200058CCB0 /* rcmd.3 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rcmd.3; sourceTree = "<group>"; };
+               FC5284BE11478C200058CCB0 /* rcmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rcmd.c; sourceTree = "<group>"; };
+               FC5284BF11478C200058CCB0 /* rcmdsh.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rcmdsh.c; sourceTree = "<group>"; };
+               FC5285D1114791B50058CCB0 /* DSlibinfoMIG.defs */ = {isa = PBXFileReference; explicitFileType = sourcecode.mig; fileEncoding = 4; name = DSlibinfoMIG.defs; path = usr/local/include/opendirectory/DSlibinfoMIG.defs; sourceTree = SDKROOT; };
+               FC5285D2114791B50058CCB0 /* DSlibinfoMIGAsyncReply.defs */ = {isa = PBXFileReference; explicitFileType = sourcecode.mig; fileEncoding = 4; name = DSlibinfoMIGAsyncReply.defs; path = usr/local/include/opendirectory/DSlibinfoMIGAsyncReply.defs; sourceTree = SDKROOT; };
+               FC5285D3114791B50058CCB0 /* DSmemberdMIG.defs */ = {isa = PBXFileReference; explicitFileType = sourcecode.mig; fileEncoding = 4; name = DSmemberdMIG.defs; path = usr/local/include/opendirectory/DSmemberdMIG.defs; sourceTree = SDKROOT; };
+               FC5285F6114793400058CCB0 /* ether_addr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ether_addr.c; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+               3FCF615E1257C272008D8BB1 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               D289988505E68E00004EDB86 /* Frameworks */ = {
+                       isa = PBXFrameworksBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+               08FB7794FE84155DC02AAC07 /* Libinfo */ = {
+                       isa = PBXGroup;
+                       children = (
+                               FC5283ED11478C200058CCB0 /* dns.subproj */,
+                               FC52840011478C200058CCB0 /* gen.subproj */,
+                               FC52841711478C200058CCB0 /* lookup.subproj */,
+                               FC52843A11478C200058CCB0 /* membership.subproj */,
+                               FC52844211478C200058CCB0 /* netinfo.subproj */,
+                               FC52844511478C200058CCB0 /* nis.subproj */,
+                               FC52847911478C200058CCB0 /* rpc.subproj */,
+                               FC5284B811478C200058CCB0 /* util.subproj */,
+                               1AB674ADFE9D54B511CA2CBB /* Products */,
+                       );
+                       name = Libinfo;
+                       sourceTree = "<group>";
+               };
+               1AB674ADFE9D54B511CA2CBB /* Products */ = {
+                       isa = PBXGroup;
+                       children = (
+                               D2AAC0630554660B00DB518D /* libsystem_info.dylib */,
+                               3FCF61621257C272008D8BB1 /* libsystem_sim_info.dylib */,
+                       );
+                       name = Products;
+                       sourceTree = "<group>";
+               };
+               FC5283ED11478C200058CCB0 /* dns.subproj */ = {
+                       isa = PBXGroup;
+                       children = (
+                               FC5283EE11478C200058CCB0 /* herror.c */,
+                               FC5283EF11478C200058CCB0 /* inet.h */,
+                               FC5283F311478C200058CCB0 /* nameser8_compat.h */,
+                               FC5283F511478C200058CCB0 /* options.h */,
+                               FC5283F611478C200058CCB0 /* portability.h */,
+                               FC5283F711478C200058CCB0 /* res_comp.c */,
+                               FC5283F811478C200058CCB0 /* res_data.c */,
+                               FC5283F911478C200058CCB0 /* res_debug.c */,
+                               FC5283FA11478C200058CCB0 /* res_init.c */,
+                               FC5283FB11478C200058CCB0 /* res_mkquery.c */,
+                               FC5283FC11478C200058CCB0 /* res_query.c */,
+                               FC5283FE11478C200058CCB0 /* res_send.c */,
+                               FC5283FF11478C200058CCB0 /* resolv8_compat.h */,
+                       );
+                       path = dns.subproj;
+                       sourceTree = "<group>";
+               };
+               FC52840011478C200058CCB0 /* gen.subproj */ = {
+                       isa = PBXGroup;
+                       children = (
+                               2DBB147712DBD63300D710E3 /* inet6_opt_init.3 */,
+                               2D31A0FA128074E700D5A84C /* getifmaddrs.3 */,
+                               2D31A0FB128074E700D5A84C /* getifmaddrs.c */,
+                               FC5285F6114793400058CCB0 /* ether_addr.c */,
+                               FC52840211478C200058CCB0 /* gethostbyname.3 */,
+                               FC52840311478C200058CCB0 /* getifaddrs.3 */,
+                               FC52840411478C200058CCB0 /* getifaddrs.c */,
+                               FC52840511478C200058CCB0 /* getipnodebyname.3 */,
+                               FC52840611478C200058CCB0 /* getnetent.3 */,
+                               FC52840711478C200058CCB0 /* getprotoent.3 */,
+                               FC52840811478C200058CCB0 /* getservent.3 */,
+                               FC52840911478C200058CCB0 /* if_indextoname.3 */,
+                               FC52840A11478C200058CCB0 /* if_indextoname.c */,
+                               FC52840B11478C200058CCB0 /* if_nameindex.c */,
+                               FC52840C11478C200058CCB0 /* if_nametoindex.c */,
+                               FC52840D11478C200058CCB0 /* ifaddrs.h */,
+                               FC52840E11478C200058CCB0 /* inet6_option_space.3 */,
+                               FC52840F11478C200058CCB0 /* inet6_rthdr_space.3 */,
+                               2D4D4AB1122C5B83009791E5 /* inet6_rth_space.3 */,
+                               FC52841011478C200058CCB0 /* inet_ntop.c */,
+                               FC52841111478C200058CCB0 /* inet_pton.c */,
+                               FC52841211478C200058CCB0 /* ip6opt.c */,
+                               FC52841411478C200058CCB0 /* map_v4v6.c */,
+                               FC52841511478C200058CCB0 /* rthdr.c */,
+                               FC52841611478C200058CCB0 /* vars.c */,
+                       );
+                       path = gen.subproj;
+                       sourceTree = "<group>";
+               };
+               FC52841711478C200058CCB0 /* lookup.subproj */ = {
+                       isa = PBXGroup;
+                       children = (
+                               2D4070B0129354A700FE81ED /* getnameinfo_link.c */,
+                               FC5285D1114791B50058CCB0 /* DSlibinfoMIG.defs */,
+                               FC5285D2114791B50058CCB0 /* DSlibinfoMIGAsyncReply.defs */,
+                               FC52841811478C200058CCB0 /* aliasdb.h */,
+                               FC52841911478C200058CCB0 /* bootparams.5 */,
+                               FC52841A11478C200058CCB0 /* bootparams.h */,
+                               FC52841B11478C200058CCB0 /* cache_module.c */,
+                               FC52841C11478C200058CCB0 /* ds_module.c */,
+                               FC52841D11478C200058CCB0 /* file_module.c */,
+                               FC52841E11478C200058CCB0 /* gai_strerror.3 */,
+                               FC52841F11478C200058CCB0 /* getaddrinfo.3 */,
+                               FC52842011478C200058CCB0 /* getfsent.3 */,
+                               FC52842111478C200058CCB0 /* getgrent.3 */,
+                               FC52842211478C200058CCB0 /* getgrouplist.3 */,
+                               FC52842311478C200058CCB0 /* getnameinfo.3 */,
+                               FC52842411478C200058CCB0 /* getnetgrent.3 */,
+                               FC52842511478C200058CCB0 /* getpwent.3 */,
+                               FC52842611478C200058CCB0 /* ils.c */,
+                               FC52842711478C200058CCB0 /* ils.h */,
+                               FC52842811478C200058CCB0 /* initgroups.3 */,
+                               FC52842911478C200058CCB0 /* kvbuf.c */,
+                               FC52842A11478C200058CCB0 /* kvbuf.h */,
+                               FC52842B11478C200058CCB0 /* libinfo.c */,
+                               FC52842C11478C200058CCB0 /* libinfo.h */,
+                               FC52842E11478C200058CCB0 /* mdns_module.c */,
+                               FC52842F11478C200058CCB0 /* netdb.h */,
+                               FC52843011478C200058CCB0 /* netdb_async.h */,
+                               FC52843111478C200058CCB0 /* printerdb.h */,
+                               FC52843211478C200058CCB0 /* search_module.c */,
+                               FC52843311478C200058CCB0 /* si_data.c */,
+                               FC52843411478C200058CCB0 /* si_data.h */,
+                               FC52843511478C200058CCB0 /* si_getaddrinfo.c */,
+                               FC52843611478C200058CCB0 /* si_module.c */,
+                               FC52843711478C200058CCB0 /* si_module.h */,
+                               FC52843811478C200058CCB0 /* thread_data.c */,
+                               FC52843911478C200058CCB0 /* thread_data.h */,
+                       );
+                       path = lookup.subproj;
+                       sourceTree = "<group>";
+               };
+               FC52843A11478C200058CCB0 /* membership.subproj */ = {
+                       isa = PBXGroup;
+                       children = (
+                               FC5285D3114791B50058CCB0 /* DSmemberdMIG.defs */,
+                               FC52843C11478C200058CCB0 /* mbr_check_membership.3 */,
+                               FC52843D11478C200058CCB0 /* mbr_uid_to_uuid.3 */,
+                               FC52843E11478C200058CCB0 /* membership.c */,
+                               FC52843F11478C200058CCB0 /* membership.h */,
+                               FC52844011478C200058CCB0 /* membershipPriv.h */,
+                               FC52844111478C200058CCB0 /* ntsid.h */,
+                       );
+                       path = membership.subproj;
+                       sourceTree = "<group>";
+               };
+               FC52844211478C200058CCB0 /* netinfo.subproj */ = {
+                       isa = PBXGroup;
+                       children = (
+                               FC52844411478C200058CCB0 /* ni_stub.c */,
+                       );
+                       path = netinfo.subproj;
+                       sourceTree = "<group>";
+               };
+               FC52844511478C200058CCB0 /* nis.subproj */ = {
+                       isa = PBXGroup;
+                       children = (
+                               FC52844611478C200058CCB0 /* getdomainname.c */,
+                               FC52844711478C200058CCB0 /* getnetgrent.c */,
+                               FC52844811478C200058CCB0 /* innetgr.c */,
+                               FC52844A11478C200058CCB0 /* setdomainname.c */,
+                               FC52844B11478C200058CCB0 /* xdr_domainname.c */,
+                               FC52844C11478C200058CCB0 /* xdr_keydat.c */,
+                               FC52844D11478C200058CCB0 /* xdr_mapname.c */,
+                               FC52844E11478C200058CCB0 /* xdr_peername.c */,
+                               FC52844F11478C200058CCB0 /* xdr_valdat.c */,
+                               FC52845011478C200058CCB0 /* xdr_ypbind_binding.c */,
+                               FC52845111478C200058CCB0 /* xdr_ypbind_resp.c */,
+                               FC52845211478C200058CCB0 /* xdr_ypbind_resptype.c */,
+                               FC52845311478C200058CCB0 /* xdr_ypbind_setdom.c */,
+                               FC52845411478C200058CCB0 /* xdr_ypmaplist.c */,
+                               FC52845511478C200058CCB0 /* xdr_ypreq_key.c */,
+                               FC52845611478C200058CCB0 /* xdr_ypreq_nokey.c */,
+                               FC52845711478C200058CCB0 /* xdr_ypresp_all.c */,
+                               FC52845811478C200058CCB0 /* xdr_ypresp_key_val.c */,
+                               FC52845911478C200058CCB0 /* xdr_ypresp_maplist.c */,
+                               FC52845A11478C200058CCB0 /* xdr_ypresp_master.c */,
+                               FC52845B11478C200058CCB0 /* xdr_ypresp_order.c */,
+                               FC52845C11478C200058CCB0 /* xdr_ypresp_val.c */,
+                               FC52845D11478C200058CCB0 /* xdr_ypstat.c */,
+                               FC52845E11478C200058CCB0 /* yp.8 */,
+                               FC52845F11478C200058CCB0 /* yp_all.3 */,
+                               FC52846011478C200058CCB0 /* yp_all.c */,
+                               FC52846111478C200058CCB0 /* yp_bind.3 */,
+                               FC52846211478C200058CCB0 /* yp_bind.c */,
+                               FC52846311478C200058CCB0 /* yp_first.3 */,
+                               FC52846411478C200058CCB0 /* yp_first.c */,
+                               FC52846511478C200058CCB0 /* yp_get_default_domain.3 */,
+                               FC52846611478C200058CCB0 /* yp_get_default_domain.c */,
+                               FC52846711478C200058CCB0 /* yp_maplist.c */,
+                               FC52846811478C200058CCB0 /* yp_master.3 */,
+                               FC52846911478C200058CCB0 /* yp_master.c */,
+                               FC52846A11478C200058CCB0 /* yp_match.3 */,
+                               FC52846B11478C200058CCB0 /* yp_next.3 */,
+                               FC52846C11478C200058CCB0 /* yp_order.3 */,
+                               FC52846D11478C200058CCB0 /* yp_order.c */,
+                               FC52846E11478C200058CCB0 /* yp_prot.h */,
+                               FC52846F11478C200058CCB0 /* yp_unbind.3 */,
+                               FC52847011478C200058CCB0 /* ypclnt.3 */,
+                               FC52847111478C200058CCB0 /* ypclnt.h */,
+                               FC52847211478C200058CCB0 /* yperr_string.3 */,
+                               FC52847311478C200058CCB0 /* yperr_string.c */,
+                               FC52847411478C200058CCB0 /* ypinternal.h */,
+                               FC52847511478C200058CCB0 /* ypmatch_cache.c */,
+                               FC52847611478C200058CCB0 /* yppasswdd_xdr.c */,
+                               FC52847711478C200058CCB0 /* ypprot_err.3 */,
+                               FC52847811478C200058CCB0 /* ypprot_err.c */,
+                       );
+                       path = nis.subproj;
+                       sourceTree = "<group>";
+               };
+               FC52847911478C200058CCB0 /* rpc.subproj */ = {
+                       isa = PBXGroup;
+                       children = (
+                               FC52847A11478C200058CCB0 /* auth.h */,
+                               FC52847B11478C200058CCB0 /* auth_none.c */,
+                               FC52847C11478C200058CCB0 /* auth_unix.c */,
+                               FC52847D11478C200058CCB0 /* auth_unix.h */,
+                               FC52847E11478C200058CCB0 /* authunix_prot.c */,
+                               FC52847F11478C200058CCB0 /* bindresvport.3 */,
+                               FC52848011478C200058CCB0 /* bindresvport.c */,
+                               FC52848111478C200058CCB0 /* clnt.h */,
+                               FC52848211478C200058CCB0 /* clnt_generic.c */,
+                               FC52848311478C200058CCB0 /* clnt_perror.c */,
+                               FC52848411478C200058CCB0 /* clnt_raw.c */,
+                               FC52848511478C200058CCB0 /* clnt_simple.c */,
+                               FC52848611478C200058CCB0 /* clnt_tcp.c */,
+                               FC52848711478C200058CCB0 /* clnt_udp.c */,
+                               FC52848811478C200058CCB0 /* DISCLAIMER */,
+                               FC52848911478C200058CCB0 /* get_myaddress.c */,
+                               FC52848A11478C200058CCB0 /* getrpcent.3 */,
+                               FC52848B11478C200058CCB0 /* getrpcent.c */,
+                               FC52848C11478C200058CCB0 /* getrpcport.3 */,
+                               FC52848D11478C200058CCB0 /* getrpcport.c */,
+                               FC52849011478C200058CCB0 /* pmap_clnt.c */,
+                               FC52849111478C200058CCB0 /* pmap_clnt.h */,
+                               FC52849211478C200058CCB0 /* pmap_getmaps.c */,
+                               FC52849311478C200058CCB0 /* pmap_getport.c */,
+                               FC52849411478C200058CCB0 /* pmap_prot.c */,
+                               FC52849511478C200058CCB0 /* pmap_prot.h */,
+                               FC52849611478C200058CCB0 /* pmap_prot2.c */,
+                               FC52849711478C200058CCB0 /* pmap_rmt.c */,
+                               FC52849811478C200058CCB0 /* pmap_rmt.h */,
+                               FC52849911478C200058CCB0 /* pmap_wakeup.c */,
+                               FC52849A11478C200058CCB0 /* pmap_wakeup.h */,
+                               FC52849B11478C200058CCB0 /* README */,
+                               FC52849C11478C200058CCB0 /* rpc.3 */,
+                               FC52849D11478C200058CCB0 /* rpc.h */,
+                               FC52849E11478C200058CCB0 /* rpc_callmsg.c */,
+                               FC52849F11478C200058CCB0 /* rpc_commondata.c */,
+                               FC5284A011478C200058CCB0 /* rpc_dtablesize.c */,
+                               FC5284A111478C200058CCB0 /* rpc_msg.h */,
+                               FC5284A211478C200058CCB0 /* rpc_prot.c */,
+                               FC5284A311478C200058CCB0 /* svc.c */,
+                               FC5284A411478C200058CCB0 /* svc.h */,
+                               FC5284A511478C200058CCB0 /* svc_auth.c */,
+                               FC5284A611478C200058CCB0 /* svc_auth.h */,
+                               FC5284A711478C200058CCB0 /* svc_auth_unix.c */,
+                               FC5284A811478C200058CCB0 /* svc_raw.c */,
+                               FC5284A911478C200058CCB0 /* svc_run.c */,
+                               FC5284AA11478C200058CCB0 /* svc_simple.c */,
+                               FC5284AB11478C200058CCB0 /* svc_tcp.c */,
+                               FC5284AC11478C200058CCB0 /* svc_udp.c */,
+                               FC5284AD11478C200058CCB0 /* types.h */,
+                               FC5284AE11478C200058CCB0 /* xdr.3 */,
+                               FC5284AF11478C200058CCB0 /* xdr.c */,
+                               FC5284B011478C200058CCB0 /* xdr.h */,
+                               FC5284B111478C200058CCB0 /* xdr_array.c */,
+                               FC5284B211478C200058CCB0 /* xdr_float.c */,
+                               FC5284B311478C200058CCB0 /* xdr_mem.c */,
+                               FC5284B411478C200058CCB0 /* xdr_rec.c */,
+                               FC5284B511478C200058CCB0 /* xdr_reference.c */,
+                               FC5284B611478C200058CCB0 /* xdr_sizeof.c */,
+                               FC5284B711478C200058CCB0 /* xdr_stdio.c */,
+                       );
+                       path = rpc.subproj;
+                       sourceTree = "<group>";
+               };
+               FC5284B811478C200058CCB0 /* util.subproj */ = {
+                       isa = PBXGroup;
+                       children = (
+                               FC5284B911478C200058CCB0 /* hosts.equiv.5 */,
+                               FC5284BA11478C200058CCB0 /* hton.c */,
+                               FC5284BC11478C200058CCB0 /* putpwpasswd.c */,
+                               FC5284BD11478C200058CCB0 /* rcmd.3 */,
+                               FC5284BE11478C200058CCB0 /* rcmd.c */,
+                               FC5284BF11478C200058CCB0 /* rcmdsh.c */,
+                       );
+                       path = util.subproj;
+                       sourceTree = "<group>";
+               };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+               3FCF60EA1257C272008D8BB1 /* Libinfo_Sim */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 3FCF61601257C272008D8BB1 /* Build configuration list for PBXNativeTarget "Libinfo_Sim" */;
+                       buildPhases = (
+                               3FCF60EB1257C272008D8BB1 /* Sources */,
+                               3FCF615E1257C272008D8BB1 /* Frameworks */,
+                               3FCF615F1257C272008D8BB1 /* Install Files */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = Libinfo_Sim;
+                       productName = Libinfo;
+                       productReference = 3FCF61621257C272008D8BB1 /* libsystem_sim_info.dylib */;
+                       productType = "com.apple.product-type.library.dynamic";
+               };
+               D2AAC0620554660B00DB518D /* Libinfo */ = {
+                       isa = PBXNativeTarget;
+                       buildConfigurationList = 1DEB914A08733D8E0010E9CD /* Build configuration list for PBXNativeTarget "Libinfo" */;
+                       buildPhases = (
+                               D2AAC0610554660B00DB518D /* Sources */,
+                               D289988505E68E00004EDB86 /* Frameworks */,
+                               FC52866A114795BD0058CCB0 /* Install Files */,
+                       );
+                       buildRules = (
+                       );
+                       dependencies = (
+                       );
+                       name = Libinfo;
+                       productName = Libinfo;
+                       productReference = D2AAC0630554660B00DB518D /* libsystem_info.dylib */;
+                       productType = "com.apple.product-type.library.dynamic";
+               };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+               08FB7793FE84155DC02AAC07 /* Project object */ = {
+                       isa = PBXProject;
+                       buildConfigurationList = 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "Libinfo" */;
+                       compatibilityVersion = "Xcode 3.1";
+                       developmentRegion = English;
+                       hasScannedForEncodings = 1;
+                       knownRegions = (
+                               English,
+                               Japanese,
+                               French,
+                               German,
+                       );
+                       mainGroup = 08FB7794FE84155DC02AAC07 /* Libinfo */;
+                       projectDirPath = "";
+                       projectRoot = "";
+                       targets = (
+                               D2AAC0620554660B00DB518D /* Libinfo */,
+                               3FCF60EA1257C272008D8BB1 /* Libinfo_Sim */,
+                       );
+               };
+/* End PBXProject section */
+
+/* Begin PBXShellScriptBuildPhase section */
+               3FCF615F1257C272008D8BB1 /* Install Files */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 8;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Install Files";
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+                       shellPath = /bin/sh;
+                       shellScript = "\"$PROJECT_DIR\"/xcodescripts/install_files.sh";
+               };
+               FC52866A114795BD0058CCB0 /* Install Files */ = {
+                       isa = PBXShellScriptBuildPhase;
+                       buildActionMask = 8;
+                       files = (
+                       );
+                       inputPaths = (
+                       );
+                       name = "Install Files";
+                       outputPaths = (
+                       );
+                       runOnlyForDeploymentPostprocessing = 1;
+                       shellPath = /bin/sh;
+                       shellScript = "\"$PROJECT_DIR\"/xcodescripts/install_files.sh";
+               };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+               3FCF60EB1257C272008D8BB1 /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               3FCF60EC1257C272008D8BB1 /* herror.c in Sources */,
+                               3FCF60ED1257C272008D8BB1 /* res_comp.c in Sources */,
+                               3FCF60EE1257C272008D8BB1 /* res_data.c in Sources */,
+                               3FCF60EF1257C272008D8BB1 /* res_debug.c in Sources */,
+                               3FCF60F01257C272008D8BB1 /* res_init.c in Sources */,
+                               3FCF60F11257C272008D8BB1 /* res_mkquery.c in Sources */,
+                               3FCF60F21257C272008D8BB1 /* res_query.c in Sources */,
+                               3FCF60F31257C272008D8BB1 /* res_send.c in Sources */,
+                               3FCF60F41257C272008D8BB1 /* getifaddrs.c in Sources */,
+                               3FCF60F51257C272008D8BB1 /* if_indextoname.c in Sources */,
+                               3FCF60F61257C272008D8BB1 /* if_nameindex.c in Sources */,
+                               3FCF60F71257C272008D8BB1 /* if_nametoindex.c in Sources */,
+                               3FCF60F81257C272008D8BB1 /* inet_ntop.c in Sources */,
+                               3FCF60F91257C272008D8BB1 /* inet_pton.c in Sources */,
+                               3FCF60FA1257C272008D8BB1 /* ip6opt.c in Sources */,
+                               3FCF60FB1257C272008D8BB1 /* map_v4v6.c in Sources */,
+                               3FCF60FC1257C272008D8BB1 /* rthdr.c in Sources */,
+                               3FCF60FD1257C272008D8BB1 /* vars.c in Sources */,
+                               3FCF610A1257C272008D8BB1 /* membership.c in Sources */,
+                               3FCF610B1257C272008D8BB1 /* ni_stub.c in Sources */,
+                               3FCF610C1257C272008D8BB1 /* getdomainname.c in Sources */,
+                               3FCF610D1257C272008D8BB1 /* getnetgrent.c in Sources */,
+                               3FCF610E1257C272008D8BB1 /* innetgr.c in Sources */,
+                               3FCF610F1257C272008D8BB1 /* setdomainname.c in Sources */,
+                               3FCF61101257C272008D8BB1 /* xdr_domainname.c in Sources */,
+                               3FCF61111257C272008D8BB1 /* xdr_keydat.c in Sources */,
+                               3FCF61121257C272008D8BB1 /* xdr_mapname.c in Sources */,
+                               3FCF61131257C272008D8BB1 /* xdr_peername.c in Sources */,
+                               3FCF61141257C272008D8BB1 /* xdr_valdat.c in Sources */,
+                               3FCF61151257C272008D8BB1 /* xdr_ypbind_binding.c in Sources */,
+                               3FCF61161257C272008D8BB1 /* xdr_ypbind_resp.c in Sources */,
+                               3FCF61171257C272008D8BB1 /* xdr_ypbind_resptype.c in Sources */,
+                               3FCF61181257C272008D8BB1 /* xdr_ypbind_setdom.c in Sources */,
+                               3FCF61191257C272008D8BB1 /* xdr_ypmaplist.c in Sources */,
+                               3FCF611A1257C272008D8BB1 /* xdr_ypreq_key.c in Sources */,
+                               3FCF611B1257C272008D8BB1 /* xdr_ypreq_nokey.c in Sources */,
+                               3FCF611C1257C272008D8BB1 /* xdr_ypresp_all.c in Sources */,
+                               3FCF611D1257C272008D8BB1 /* xdr_ypresp_key_val.c in Sources */,
+                               3FCF611E1257C272008D8BB1 /* xdr_ypresp_maplist.c in Sources */,
+                               3FCF611F1257C272008D8BB1 /* xdr_ypresp_master.c in Sources */,
+                               3FCF61201257C272008D8BB1 /* xdr_ypresp_order.c in Sources */,
+                               3FCF61211257C272008D8BB1 /* xdr_ypresp_val.c in Sources */,
+                               3FCF61221257C272008D8BB1 /* xdr_ypstat.c in Sources */,
+                               3FCF61231257C272008D8BB1 /* yp_all.c in Sources */,
+                               3FCF61241257C272008D8BB1 /* yp_bind.c in Sources */,
+                               3FCF61251257C272008D8BB1 /* yp_first.c in Sources */,
+                               3FCF61261257C272008D8BB1 /* yp_get_default_domain.c in Sources */,
+                               3FCF61271257C272008D8BB1 /* yp_maplist.c in Sources */,
+                               3FCF61281257C272008D8BB1 /* yp_master.c in Sources */,
+                               3FCF61291257C272008D8BB1 /* yp_order.c in Sources */,
+                               3FCF612A1257C272008D8BB1 /* yperr_string.c in Sources */,
+                               3FCF612B1257C272008D8BB1 /* ypmatch_cache.c in Sources */,
+                               3FCF612C1257C272008D8BB1 /* yppasswdd_xdr.c in Sources */,
+                               3FCF612D1257C272008D8BB1 /* ypprot_err.c in Sources */,
+                               3FCF612E1257C272008D8BB1 /* auth_none.c in Sources */,
+                               3FCF612F1257C272008D8BB1 /* auth_unix.c in Sources */,
+                               3FCF61301257C272008D8BB1 /* authunix_prot.c in Sources */,
+                               3FCF61311257C272008D8BB1 /* bindresvport.c in Sources */,
+                               3FCF61321257C272008D8BB1 /* clnt_generic.c in Sources */,
+                               3FCF61331257C272008D8BB1 /* clnt_perror.c in Sources */,
+                               3FCF61341257C272008D8BB1 /* clnt_raw.c in Sources */,
+                               3FCF61351257C272008D8BB1 /* clnt_simple.c in Sources */,
+                               3FCF61361257C272008D8BB1 /* clnt_tcp.c in Sources */,
+                               3FCF61371257C272008D8BB1 /* clnt_udp.c in Sources */,
+                               3FCF61381257C272008D8BB1 /* get_myaddress.c in Sources */,
+                               3FCF61391257C272008D8BB1 /* getrpcent.c in Sources */,
+                               3FCF613A1257C272008D8BB1 /* getrpcport.c in Sources */,
+                               3FCF613B1257C272008D8BB1 /* pmap_clnt.c in Sources */,
+                               3FCF613C1257C272008D8BB1 /* pmap_getmaps.c in Sources */,
+                               3FCF613D1257C272008D8BB1 /* pmap_getport.c in Sources */,
+                               3FCF613E1257C272008D8BB1 /* pmap_prot.c in Sources */,
+                               3FCF613F1257C272008D8BB1 /* pmap_prot2.c in Sources */,
+                               3FCF61401257C272008D8BB1 /* pmap_rmt.c in Sources */,
+                               3FCF61411257C272008D8BB1 /* pmap_wakeup.c in Sources */,
+                               3FCF61421257C272008D8BB1 /* rpc_callmsg.c in Sources */,
+                               3FCF61431257C272008D8BB1 /* rpc_commondata.c in Sources */,
+                               3FCF61441257C272008D8BB1 /* rpc_dtablesize.c in Sources */,
+                               3FCF61451257C272008D8BB1 /* rpc_prot.c in Sources */,
+                               3FCF61461257C272008D8BB1 /* svc.c in Sources */,
+                               3FCF61471257C272008D8BB1 /* svc_auth.c in Sources */,
+                               3FCF61481257C272008D8BB1 /* svc_auth_unix.c in Sources */,
+                               3FCF61491257C272008D8BB1 /* svc_raw.c in Sources */,
+                               3FCF614A1257C272008D8BB1 /* svc_run.c in Sources */,
+                               3FCF614B1257C272008D8BB1 /* svc_simple.c in Sources */,
+                               3FCF614C1257C272008D8BB1 /* svc_tcp.c in Sources */,
+                               3FCF614D1257C272008D8BB1 /* svc_udp.c in Sources */,
+                               3FCF614E1257C272008D8BB1 /* xdr.c in Sources */,
+                               3FCF614F1257C272008D8BB1 /* xdr_array.c in Sources */,
+                               3FCF61501257C272008D8BB1 /* xdr_float.c in Sources */,
+                               3FCF61511257C272008D8BB1 /* xdr_mem.c in Sources */,
+                               3FCF61521257C272008D8BB1 /* xdr_rec.c in Sources */,
+                               3FCF61531257C272008D8BB1 /* xdr_reference.c in Sources */,
+                               3FCF61541257C272008D8BB1 /* xdr_sizeof.c in Sources */,
+                               3FCF61551257C272008D8BB1 /* xdr_stdio.c in Sources */,
+                               3FCF61561257C272008D8BB1 /* hton.c in Sources */,
+                               3FCF61571257C272008D8BB1 /* putpwpasswd.c in Sources */,
+                               3FCF61581257C272008D8BB1 /* rcmd.c in Sources */,
+                               3FCF61591257C272008D8BB1 /* rcmdsh.c in Sources */,
+                               3FCF615D1257C272008D8BB1 /* ether_addr.c in Sources */,
+                               2D31A0FD128074E700D5A84C /* getifmaddrs.c in Sources */,
+                               2D4070B2129354A700FE81ED /* getnameinfo_link.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+               D2AAC0610554660B00DB518D /* Sources */ = {
+                       isa = PBXSourcesBuildPhase;
+                       buildActionMask = 2147483647;
+                       files = (
+                               FC5284C011478C200058CCB0 /* herror.c in Sources */,
+                               FC5284C811478C200058CCB0 /* res_comp.c in Sources */,
+                               FC5284C911478C200058CCB0 /* res_data.c in Sources */,
+                               FC5284CA11478C200058CCB0 /* res_debug.c in Sources */,
+                               FC5284CB11478C200058CCB0 /* res_init.c in Sources */,
+                               FC5284CC11478C200058CCB0 /* res_mkquery.c in Sources */,
+                               FC5284CD11478C200058CCB0 /* res_query.c in Sources */,
+                               FC5284CF11478C200058CCB0 /* res_send.c in Sources */,
+                               FC5284D211478C200058CCB0 /* getifaddrs.c in Sources */,
+                               FC5284D311478C200058CCB0 /* if_indextoname.c in Sources */,
+                               FC5284D411478C200058CCB0 /* if_nameindex.c in Sources */,
+                               FC5284D511478C200058CCB0 /* if_nametoindex.c in Sources */,
+                               FC5284D711478C200058CCB0 /* inet_ntop.c in Sources */,
+                               FC5284D811478C200058CCB0 /* inet_pton.c in Sources */,
+                               FC5284D911478C200058CCB0 /* ip6opt.c in Sources */,
+                               FC5284DB11478C200058CCB0 /* map_v4v6.c in Sources */,
+                               FC5284DC11478C200058CCB0 /* rthdr.c in Sources */,
+                               FC5284DD11478C200058CCB0 /* vars.c in Sources */,
+                               FC5284E011478C200058CCB0 /* cache_module.c in Sources */,
+                               FC5284E111478C200058CCB0 /* ds_module.c in Sources */,
+                               FC5284E211478C200058CCB0 /* file_module.c in Sources */,
+                               FC5284E311478C200058CCB0 /* ils.c in Sources */,
+                               FC5284E511478C200058CCB0 /* kvbuf.c in Sources */,
+                               FC5284E711478C200058CCB0 /* libinfo.c in Sources */,
+                               FC5284EA11478C200058CCB0 /* mdns_module.c in Sources */,
+                               FC5284EE11478C200058CCB0 /* search_module.c in Sources */,
+                               FC5284EF11478C200058CCB0 /* si_data.c in Sources */,
+                               FC5284F111478C200058CCB0 /* si_getaddrinfo.c in Sources */,
+                               FC5284F211478C200058CCB0 /* si_module.c in Sources */,
+                               FC5284F411478C200058CCB0 /* thread_data.c in Sources */,
+                               FC5284F711478C200058CCB0 /* membership.c in Sources */,
+                               FC5284FC11478C200058CCB0 /* ni_stub.c in Sources */,
+                               FC5284FD11478C200058CCB0 /* getdomainname.c in Sources */,
+                               FC5284FE11478C200058CCB0 /* getnetgrent.c in Sources */,
+                               FC5284FF11478C200058CCB0 /* innetgr.c in Sources */,
+                               FC52850111478C200058CCB0 /* setdomainname.c in Sources */,
+                               FC52850211478C200058CCB0 /* xdr_domainname.c in Sources */,
+                               FC52850311478C200058CCB0 /* xdr_keydat.c in Sources */,
+                               FC52850411478C200058CCB0 /* xdr_mapname.c in Sources */,
+                               FC52850511478C200058CCB0 /* xdr_peername.c in Sources */,
+                               FC52850611478C200058CCB0 /* xdr_valdat.c in Sources */,
+                               FC52850711478C200058CCB0 /* xdr_ypbind_binding.c in Sources */,
+                               FC52850811478C200058CCB0 /* xdr_ypbind_resp.c in Sources */,
+                               FC52850911478C200058CCB0 /* xdr_ypbind_resptype.c in Sources */,
+                               FC52850A11478C200058CCB0 /* xdr_ypbind_setdom.c in Sources */,
+                               FC52850B11478C200058CCB0 /* xdr_ypmaplist.c in Sources */,
+                               FC52850C11478C200058CCB0 /* xdr_ypreq_key.c in Sources */,
+                               FC52850D11478C200058CCB0 /* xdr_ypreq_nokey.c in Sources */,
+                               FC52850E11478C200058CCB0 /* xdr_ypresp_all.c in Sources */,
+                               FC52850F11478C200058CCB0 /* xdr_ypresp_key_val.c in Sources */,
+                               FC52851011478C200058CCB0 /* xdr_ypresp_maplist.c in Sources */,
+                               FC52851111478C200058CCB0 /* xdr_ypresp_master.c in Sources */,
+                               FC52851211478C200058CCB0 /* xdr_ypresp_order.c in Sources */,
+                               FC52851311478C200058CCB0 /* xdr_ypresp_val.c in Sources */,
+                               FC52851411478C200058CCB0 /* xdr_ypstat.c in Sources */,
+                               FC52851511478C200058CCB0 /* yp_all.c in Sources */,
+                               FC52851611478C200058CCB0 /* yp_bind.c in Sources */,
+                               FC52851711478C200058CCB0 /* yp_first.c in Sources */,
+                               FC52851811478C200058CCB0 /* yp_get_default_domain.c in Sources */,
+                               FC52851911478C200058CCB0 /* yp_maplist.c in Sources */,
+                               FC52851A11478C200058CCB0 /* yp_master.c in Sources */,
+                               FC52851B11478C200058CCB0 /* yp_order.c in Sources */,
+                               FC52851E11478C200058CCB0 /* yperr_string.c in Sources */,
+                               FC52852011478C200058CCB0 /* ypmatch_cache.c in Sources */,
+                               FC52852111478C200058CCB0 /* yppasswdd_xdr.c in Sources */,
+                               FC52852211478C200058CCB0 /* ypprot_err.c in Sources */,
+                               FC52852411478C200058CCB0 /* auth_none.c in Sources */,
+                               FC52852511478C200058CCB0 /* auth_unix.c in Sources */,
+                               FC52852711478C200058CCB0 /* authunix_prot.c in Sources */,
+                               FC52852811478C200058CCB0 /* bindresvport.c in Sources */,
+                               FC52852A11478C200058CCB0 /* clnt_generic.c in Sources */,
+                               FC52852B11478C200058CCB0 /* clnt_perror.c in Sources */,
+                               FC52852C11478C200058CCB0 /* clnt_raw.c in Sources */,
+                               FC52852D11478C200058CCB0 /* clnt_simple.c in Sources */,
+                               FC52852E11478C200058CCB0 /* clnt_tcp.c in Sources */,
+                               FC52852F11478C200058CCB0 /* clnt_udp.c in Sources */,
+                               FC52853011478C200058CCB0 /* get_myaddress.c in Sources */,
+                               FC52853111478C200058CCB0 /* getrpcent.c in Sources */,
+                               FC52853211478C200058CCB0 /* getrpcport.c in Sources */,
+                               FC52853511478C200058CCB0 /* pmap_clnt.c in Sources */,
+                               FC52853711478C200058CCB0 /* pmap_getmaps.c in Sources */,
+                               FC52853811478C200058CCB0 /* pmap_getport.c in Sources */,
+                               FC52853911478C200058CCB0 /* pmap_prot.c in Sources */,
+                               FC52853B11478C200058CCB0 /* pmap_prot2.c in Sources */,
+                               FC52853C11478C200058CCB0 /* pmap_rmt.c in Sources */,
+                               FC52853E11478C200058CCB0 /* pmap_wakeup.c in Sources */,
+                               FC52854111478C200058CCB0 /* rpc_callmsg.c in Sources */,
+                               FC52854211478C200058CCB0 /* rpc_commondata.c in Sources */,
+                               FC52854311478C200058CCB0 /* rpc_dtablesize.c in Sources */,
+                               FC52854511478C200058CCB0 /* rpc_prot.c in Sources */,
+                               FC52854611478C200058CCB0 /* svc.c in Sources */,
+                               FC52854811478C200058CCB0 /* svc_auth.c in Sources */,
+                               FC52854A11478C200058CCB0 /* svc_auth_unix.c in Sources */,
+                               FC52854B11478C200058CCB0 /* svc_raw.c in Sources */,
+                               FC52854C11478C200058CCB0 /* svc_run.c in Sources */,
+                               FC52854D11478C200058CCB0 /* svc_simple.c in Sources */,
+                               FC52854E11478C200058CCB0 /* svc_tcp.c in Sources */,
+                               FC52854F11478C200058CCB0 /* svc_udp.c in Sources */,
+                               FC52855111478C200058CCB0 /* xdr.c in Sources */,
+                               FC52855311478C200058CCB0 /* xdr_array.c in Sources */,
+                               FC52855411478C200058CCB0 /* xdr_float.c in Sources */,
+                               FC52855511478C200058CCB0 /* xdr_mem.c in Sources */,
+                               FC52855611478C200058CCB0 /* xdr_rec.c in Sources */,
+                               FC52855711478C200058CCB0 /* xdr_reference.c in Sources */,
+                               FC52855811478C200058CCB0 /* xdr_sizeof.c in Sources */,
+                               FC52855911478C200058CCB0 /* xdr_stdio.c in Sources */,
+                               FC52855A11478C200058CCB0 /* hton.c in Sources */,
+                               FC52855C11478C200058CCB0 /* putpwpasswd.c in Sources */,
+                               FC52855D11478C200058CCB0 /* rcmd.c in Sources */,
+                               FC52855E11478C200058CCB0 /* rcmdsh.c in Sources */,
+                               FC5285D4114791B50058CCB0 /* DSlibinfoMIG.defs in Sources */,
+                               FC5285D5114791B50058CCB0 /* DSlibinfoMIGAsyncReply.defs in Sources */,
+                               FC5285D6114791B50058CCB0 /* DSmemberdMIG.defs in Sources */,
+                               FC5285F7114793400058CCB0 /* ether_addr.c in Sources */,
+                               2D31A0FC128074E700D5A84C /* getifmaddrs.c in Sources */,
+                               2D4070B1129354A700FE81ED /* getnameinfo_link.c in Sources */,
+                       );
+                       runOnlyForDeploymentPostprocessing = 0;
+               };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+               1DEB914C08733D8E0010E9CD /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               EXECUTABLE_PREFIX = libsystem_;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "__DARWIN_NON_CANCELABLE=1",
+                                       "__MigTypeCheck=1",
+                                       "INET6=1",
+                                       USE_OPTIONS_H,
+                               );
+                               "GCC_PREPROCESSOR_DEFINITIONS[sdk=iphone*][arch=*]" = (
+                                       CONFIG_IPHONE,
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS)",
+                               );
+                               "GCC_PREPROCESSOR_DEFINITIONS[sdk=macosx*][arch=*]" = (
+                                       CONFIG_MAC,
+                                       DS_AVAILABLE,
+                                       SYNTH_ROOTFS,
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS)",
+                               );
+                               INSTALLHDRS_SCRIPT_PHASE = YES;
+                               INSTALL_PATH = /usr/lib/system;
+                               PRODUCT_NAME = info;
+                               VERSION_INFO_EXPORT_DECL = static;
+                               VERSION_INFO_PREFIX = __;
+                       };
+                       name = Release;
+               };
+               1DEB915008733D8E0010E9CD /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+                               BUILD_VARIANTS = (
+                                       normal,
+                                       profile,
+                                       debug,
+                               );
+                               CODE_SIGN_IDENTITY = "-";
+                               CURRENT_PROJECT_VERSION = "$(RC_ProjectSourceVersion)";
+                               DEAD_CODE_STRIPPING = YES;
+                               DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+                               GCC_C_LANGUAGE_STANDARD = gnu99;
+                               GCC_TREAT_WARNINGS_AS_ERRORS = YES;
+                               GCC_WARN_ABOUT_RETURN_TYPE = YES;
+                               GCC_WARN_UNUSED_VARIABLE = YES;
+                               PREBINDING = NO;
+                               VERSIONING_SYSTEM = "apple-generic";
+                               WARNING_LDFLAGS = "-Wall";
+                       };
+                       name = Release;
+               };
+               3FCF61611257C272008D8BB1 /* Release */ = {
+                       isa = XCBuildConfiguration;
+                       buildSettings = {
+                               EXECUTABLE_PREFIX = libsystem_sim_;
+                               GCC_PREPROCESSOR_DEFINITIONS = (
+                                       "__DARWIN_NON_CANCELABLE=1",
+                                       "__MigTypeCheck=1",
+                                       "INET6=1",
+                                       USE_OPTIONS_H,
+                               );
+                               "GCC_PREPROCESSOR_DEFINITIONS[sdk=iphone*][arch=*]" = (
+                                       CONFIG_IPHONE,
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS)",
+                               );
+                               "GCC_PREPROCESSOR_DEFINITIONS[sdk=macosx*][arch=*]" = (
+                                       CONFIG_MAC,
+                                       DS_AVAILABLE,
+                                       SYNTH_ROOTFS,
+                                       "$(GCC_PREPROCESSOR_DEFINITIONS)",
+                               );
+                               INSTALLHDRS_SCRIPT_PHASE = YES;
+                               INSTALL_PATH = "$(SDKROOT)/usr/lib/system";
+                               PRODUCT_NAME = info;
+                               VERSION_INFO_EXPORT_DECL = static;
+                               VERSION_INFO_PREFIX = __;
+                       };
+                       name = Release;
+               };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+               1DEB914A08733D8E0010E9CD /* Build configuration list for PBXNativeTarget "Libinfo" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               1DEB914C08733D8E0010E9CD /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "Libinfo" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               1DEB915008733D8E0010E9CD /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+               3FCF61601257C272008D8BB1 /* Build configuration list for PBXNativeTarget "Libinfo_Sim" */ = {
+                       isa = XCConfigurationList;
+                       buildConfigurations = (
+                               3FCF61611257C272008D8BB1 /* Release */,
+                       );
+                       defaultConfigurationIsVisible = 0;
+                       defaultConfigurationName = Release;
+               };
+/* End XCConfigurationList section */
+       };
+       rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
+}
diff --git a/Makefile b/Makefile
deleted file mode 100644 (file)
index bd8fd83..0000000
--- a/Makefile
+++ /dev/null
@@ -1,24 +0,0 @@
-Project = info
-ProductType = staticlib
-Install_Dir = /usr/local/lib/system
-BuildDebug = YES
-BuildProfile = YES
-
-DIRS = dns gen lookup membership netinfo nis rpc util
-
-SubProjects = $(foreach DIR, $(DIRS), $(DIR).subproj)
-
-include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
-
-after_install:
-       $(LIBTOOL) -static -o $(SYMROOT)/libinfo.a \
-               $(foreach DIR, $(DIRS), $(SYMROOT)/lib$(DIR).a)
-       $(LIBTOOL) -static -o $(SYMROOT)/libinfo_debug.a \
-               $(foreach DIR, $(DIRS), $(SYMROOT)/lib$(DIR)_debug.a)
-       $(LIBTOOL) -static -o $(SYMROOT)/libinfo_profile.a \
-               $(foreach DIR, $(DIRS), $(SYMROOT)/lib$(DIR)_profile.a)
-       $(INSTALL_DIRECTORY) $(DSTROOT)/usr/local/lib/system
-       $(INSTALL_LIBRARY) $(SYMROOT)/libinfo.a $(DSTROOT)/usr/local/lib/system
-       $(INSTALL_LIBRARY) $(SYMROOT)/libinfo_debug.a $(DSTROOT)/usr/local/lib/system
-       $(INSTALL_LIBRARY) $(SYMROOT)/libinfo_profile.a $(DSTROOT)/usr/local/lib/system
-       $(RMDIR) $(DSTROOT)/scratch
diff --git a/dns.subproj/Makefile b/dns.subproj/Makefile
deleted file mode 100644 (file)
index 2c168da..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-Project = dns
-ProductType = staticlib
-Install_Dir = /scratch
-BuildDebug = YES
-BuildProfile = YES
-
-Install_Headers_Directory = /usr/include/arpa
-Install_Headers = inet.h
-
-CFILES = herror.c res_comp.c res_data.c res_debug.c\
-        res_init.c res_mkquery.c res_query.c res_send.c
-
-Extra_CC_Flags = -Wall -fno-common -I. \
-       -I../gen.subproj -I../lookup.subproj \
-       -DUSE_OPTIONS_H -D__DARWIN_NON_CANCELABLE=1
-
-include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
diff --git a/dns.subproj/Makefile.dist b/dns.subproj/Makefile.dist
deleted file mode 100644 (file)
index 385c8a9..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-#
-#      from @(#)Makefile       5.16 (Berkeley) 3/14/88
-#      $Id: Makefile.dist,v 1.1 1999/04/13 23:15:30 wsanchez Exp $
-#
-
-## ++Copyright++ 1988, 1995
-## -
-## Copyright (c) 1988, 1995
-##    The Regents of the University of California.  All rights reserved.
-## 
-## Redistribution and use in source and binary forms, with or without
-## modification, are permitted provided that the following conditions
-## are met:
-## 1. Redistributions of source code must retain the above copyright
-##    notice, this list of conditions and the following disclaimer.
-## 2. Redistributions in binary form must reproduce the above copyright
-##    notice, this list of conditions and the following disclaimer in the
-##    documentation and/or other materials provided with the distribution.
-## 3. All advertising materials mentioning features or use of this software
-##    must display the following acknowledgement:
-##     This product includes software developed by the University of
-##     California, Berkeley and its contributors.
-## 4. Neither the name of the University nor the names of its contributors
-##    may be used to endorse or promote products derived from this software
-##    without specific prior written permission.
-## 
-## THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
-## ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-## IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-## ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
-## FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-## DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
-## OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
-## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-## LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-## OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
-## SUCH DAMAGE.
-## -
-## Portions Copyright (c) 1993 by Digital Equipment Corporation.
-## 
-## Permission to use, copy, modify, and distribute this software for any
-## purpose with or without fee is hereby granted, provided that the above
-## copyright notice and this permission notice appear in all copies, and that
-## the name of Digital Equipment Corporation not be used in advertising or
-## publicity pertaining to distribution of the document or software without
-## specific, written prior permission.
-## 
-## THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
-## WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
-## OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
-## CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
-## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
-## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
-## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
-## SOFTWARE.
-## -
-## --Copyright--
-
-DESTDIR =
-DESTLIB = /usr/lib
-CC= cc
-SHELL= /bin/sh
-CDEBUG= -O
-INCL = ../include
-COMPINCL = ../compat/include
-AR= ar cru
-RANLIB= ranlib
-DEFS=  
-LOCDEFS= -DUSE_OPTIONS_H
-
-AROBJS= ${ARPREF} ${OBJS} ${ARSUFF}
-
-CFLAGS=        ${CDEBUG} -I${INCL} -I${COMPINCL} ${DEFS} ${LOCDEFS}
-
-SRCS=  herror.c res_debug.c \
-       res_comp.c res_init.c res_mkquery.c res_query.c res_send.c \
-       getnetbyaddr.c getnetbyname.c getnetent.c getnetnamadr.c \
-       gethnamaddr.c sethostent.c nsap_addr.c inet_addr.c hostnamelen.c
-
-OBJS=  herror.o res_debug.o \
-       res_comp.o res_init.o res_mkquery.o res_query.o res_send.o \
-       getnetbyaddr.o getnetbyname.o getnetent.o getnetnamadr.o \
-       gethnamaddr.o sethostent.o nsap_addr.o inet_addr.o hostnamelen.o
-
-all: libresolv.a
-
-libresolv.a: ${OBJS}
-       ${AR} libresolv.a ${AROBJS}
-       $(RANLIB) libresolv.a
-
-install: ${DESTDIR}${DESTLIB}/libresolv.a
-
-${DESTDIR}${DESTLIB}/libresolv.a: libresolv.a
-       ${INSTALL} -c -o bin -g bin -m 644 libresolv.a ${DESTDIR}${DESTLIB}/
-       ( cd ${DESTDIR}${DESTLIB} ; $(RANLIB) libresolv.a )
-
-.c.o:
-       ${CC} ${CPPFLAGS} ${CFLAGS} -c $*.c
-       -${LDS} ld -x -r $*.o
-       ${LDS} mv a.out $*.o
-
-clean: FRC
-       rm -f errs a.out core libresolv.a tags .depend
-       rm -f *.o *.BAK *.CKP *~ *.orig
-
-depend: FRC
-       mkdep ${CPPFLAGS} -I${INCL} -I${COMPINCL} ${DEFS} ${SRCS}
-
-FRC:
-
-# DO NOT DELETE THIS LINE -- mkdep uses it.
-# DO NOT PUT ANYTHING AFTER THIS LINE, IT WILL GO AWAY.
diff --git a/gen.subproj/Makefile b/gen.subproj/Makefile
deleted file mode 100644 (file)
index f8484cc..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-Project = gen
-ProductType = staticlib
-Install_Dir = /scratch
-BuildDebug = YES
-BuildProfile = YES
-
-CFILES = ether_addr.c getifaddrs.c \
-       if_indextoname.c if_nameindex.c if_nametoindex.c \
-       inet_ntop.c inet_pton.c map_v4v6.c ip6opt.c rthdr.c vars.c \
-       $(OBJROOT)/_version.c
-
-MANPAGES = getifaddrs.3 if_indextoname.3 inet6_rthdr_space.3 \
-       gethostbyname.3 inet6_option_space.3 \
-       getprotoent.3 gethostbyname.3 getipnodebyname.3 \
-       getnetent.3 getservent.3 inet6_option_space.3
-
-Install_Headers = ifaddrs.h
-
-Extra_CC_Flags = -Wall -fno-common -I. \
-       -I../dns.subproj -I../lookup.subproj \
-       -D__DARWIN_NON_CANCELABLE=1 -DINET6=1
-       
-
-include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
-
-$(OBJROOT)/_version.c:
-       /Developer/Makefiles/bin/version.pl Libinfo > $@
-
-after_install:
-       @for LINK in endhostent.3 gethostbyaddr.3 gethostbyname2.3 \
-               gethostent.3 herror.3 hstrerror.3 sethostent.3 ; do \
-               $(LN) -f "$(DSTROOT)/usr/share/man/man3/gethostbyname.3" \
-                       "$(DSTROOT)/usr/share/man/man3/$${LINK}" ; \
-       done
-       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getifaddrs.3" \
-               "$(DSTROOT)/usr/share/man/man3/freeifaddrs.3"
-       @for LINK in freehostent.3 getipnodebyaddr.3 ; do \
-               $(LN) -f "$(DSTROOT)/usr/share/man/man3/getipnodebyname.3" \
-                       "$(DSTROOT)/usr/share/man/man3/$${LINK}" ; \
-       done
-       @for LINK in endnetent.3 getnetbyaddr.3 getnetbyname.3 \
-               setnetent.3 ; do \
-               $(LN) -f "$(DSTROOT)/usr/share/man/man3/getnetent.3" \
-                       "$(DSTROOT)/usr/share/man/man3/$${LINK}" ; \
-       done
-       @for LINK in endprotoent.3 getprotobyname.3 getprotobynumber.3 \
-               setprotoent.3 ; do \
-               $(LN) -f "$(DSTROOT)/usr/share/man/man3/getprotoent.3" \
-                       "$(DSTROOT)/usr/share/man/man3/$${LINK}" ; \
-       done
-       @for LINK in endservent.3 getservbyname.3 getservbyport.3 \
-               setservent.3  ; do \
-               $(LN) -f "$(DSTROOT)/usr/share/man/man3/getservent.3" \
-                       "$(DSTROOT)/usr/share/man/man3/$${LINK}" ; \
-       done
-       @for LINK in if_freenameindex.3 if_nameindex.3 if_nametoindex.3 ; do \
-               $(LN) -f "$(DSTROOT)/usr/share/man/man3/if_indextoname.3" \
-                       "$(DSTROOT)/usr/share/man/man3/$${LINK}" ; \
-       done
-       @for LINK in inet6_option_alloc.3 inet6_option_append.3 \
-               inet6_option_find.3 inet6_option_init.3 inet6_option_next.3 ; do \
-               $(LN) -f "$(DSTROOT)/usr/share/man/man3/inet6_option_space.3" \
-                       "$(DSTROOT)/usr/share/man/man3/$${LINK}" ; \
-       done
-       @for LINK in inet6_rthdr_add.3 inet6_rthdr_getaddr.3 \
-               inet6_rthdr_getflags.3 inet6_rthdr_init.3 \
-               inet6_rthdr_lasthop.3 inet6_rthdr_reverse.3 \
-               inet6_rthdr_segments.3 ; do \
-               $(LN) -f "$(DSTROOT)/usr/share/man/man3/inet6_rthdr_space.3" \
-                       "$(DSTROOT)/usr/share/man/man3/$${LINK}" ; \
-       done
diff --git a/gen.subproj/getifmaddrs.3 b/gen.subproj/getifmaddrs.3
new file mode 100644 (file)
index 0000000..3c9b911
--- /dev/null
@@ -0,0 +1,116 @@
+.\" Copyright (c) 2003 Bruce M. Simpson. All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY Bruce M. Simpson ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL Bruce M. Simpson BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD: src/lib/libc/net/getifmaddrs.3,v 1.3.22.1.4.1 2010/06/14 02:09:06 kensmith Exp $
+.\"
+.Dd November 14, 2003
+.Dt GETIFMADDRS 3
+.Os
+.Sh NAME
+.Nm getifmaddrs
+.Nd get multicast group memberships
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/socket.h
+.In ifaddrs.h
+.Ft int
+.Fn getifmaddrs "struct ifmaddrs **ifmap"
+.Ft void
+.Fn freeifmaddrs "struct ifmaddrs *ifmp"
+.Sh DESCRIPTION
+The
+.Fn getifmaddrs
+function stores a reference to a linked list of the multicast memberships
+on the local machine in the memory referenced by
+.Fa ifmap .
+The list consists of
+.Vt ifmaddrs
+structures, as defined in the include file
+.In ifaddrs.h .
+The
+.Vt ifmaddrs
+structure contains at least the following entries:
+.Bd -literal
+    struct ifmaddrs   *ifma_next;     /* Pointer to next struct */
+    struct sockaddr   *ifma_name;     /* Interface name (AF_LINK) */
+    struct sockaddr   *ifma_addr;     /* Multicast address */
+    struct sockaddr   *ifma_lladdr;   /* Link-layer translation, if any */
+.Ed
+.Pp
+The
+.Va ifma_next
+field contains a pointer to the next structure on the list.
+This field is
+.Dv NULL
+in last structure on the list.
+.Pp
+The
+.Va ifma_name
+field references an
+.Dv AF_LINK
+address structure, containing the name of the
+interface where the membership exists.
+.Pp
+The
+.Va ifma_addr
+references the address that this membership is for.
+.Pp
+The
+.Va ifma_lladdr
+field references a link-layer translation for the protocol-level address in
+.Va ifma_addr ,
+if one is set, otherwise it is
+.Dv NULL .
+.Pp
+The data returned by
+.Fn getifmaddrs
+is dynamically allocated and should be freed using
+.Fn freeifmaddrs
+when no longer needed.
+.Sh RETURN VALUES
+.Rv -std getifmaddrs
+.Sh ERRORS
+The
+.Fn getifmaddrs
+may fail and set
+.Va errno
+for any of the errors specified for the library routines
+.Xr malloc 3
+or
+.Xr sysctl 3 .
+.Sh SEE ALSO
+.Xr sysctl 3 ,
+.Xr networking 4 ,
+.Xr ifconfig 8
+.Sh HISTORY
+The
+.Fn getifmaddrs
+function first appeared in
+.Fx 5.2 .
+.Sh BUGS
+If both
+.In net/if.h
+and
+.In ifaddrs.h
+are being included,
+.In net/if.h
+.Em must
+be included before
+.In ifaddrs.h .
diff --git a/gen.subproj/getifmaddrs.c b/gen.subproj/getifmaddrs.c
new file mode 100644 (file)
index 0000000..93049ff
--- /dev/null
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 2003 Bruce M. Simpson.
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *        This product includes software developed by Bruce M. Simpson.
+ * 4. Neither the name of Bruce M. Simpson nor the names of other
+ *    contributors may be used to endorse or promote products derived
+ *    from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BRUCE M. SIMPSON AND AFFILIATES
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL BRUCE M. SIMPSON OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/route.h>
+#include <errno.h>
+#include <ifaddrs.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+
+#define        SALIGN  (sizeof(uint32_t) - 1)
+#define        SA_RLEN(sa)     ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : \
+(SALIGN + 1))
+#define        MAX_SYSCTL_TRY  5
+#define        RTA_MASKS       (RTA_GATEWAY | RTA_IFP | RTA_IFA)
+
+/* FreeBSD uses NET_RT_IFMALIST and RTM_NEWMADDR from <sys/socket.h> */
+/* We can use NET_RT_IFLIST2 and RTM_NEWMADDR2 on Darwin */
+#define DARWIN_COMPAT
+
+#ifdef DARWIN_COMPAT
+#define GIM_SYSCTL_MIB NET_RT_IFLIST2
+#define GIM_RTM_ADDR RTM_NEWMADDR2
+#else
+#define GIM_SYSCTL_MIB NET_RT_IFMALIST
+#define GIM_RTM_ADDR RTM_NEWMADDR
+#endif
+
+int
+getifmaddrs(struct ifmaddrs **pif)
+{
+       int icnt = 1;
+       int dcnt = 0;
+       int ntry = 0;
+       size_t len;
+       size_t needed;
+       int mib[6];
+       int i;
+       char *buf;
+       char *data;
+       char *next;
+       char *p;
+       struct ifma_msghdr2 *ifmam;
+       struct ifmaddrs *ifa, *ift;
+       struct rt_msghdr *rtm;
+       struct sockaddr *sa;
+
+       mib[0] = CTL_NET;
+       mib[1] = PF_ROUTE;
+       mib[2] = 0;             /* protocol */
+       mib[3] = 0;             /* wildcard address family */
+       mib[4] = GIM_SYSCTL_MIB;
+       mib[5] = 0;             /* no flags */
+       do {
+               if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
+                       return (-1);
+               if ((buf = malloc(needed)) == NULL)
+                       return (-1);
+               if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
+                       if (errno != ENOMEM || ++ntry >= MAX_SYSCTL_TRY) {
+                               free(buf);
+                               return (-1);
+                       }
+                       free(buf);
+                       buf = NULL;
+               } 
+       } while (buf == NULL);
+
+       for (next = buf; next < buf + needed; next += rtm->rtm_msglen) {
+               rtm = (struct rt_msghdr *)(void *)next;
+               if (rtm->rtm_version != RTM_VERSION)
+                       continue;
+               switch (rtm->rtm_type) {
+                       case GIM_RTM_ADDR:
+                               ifmam = (struct ifma_msghdr2 *)(void *)rtm;
+                               if ((ifmam->ifmam_addrs & RTA_IFA) == 0)
+                                       break;
+                               icnt++;
+                               p = (char *)(ifmam + 1);
+                               for (i = 0; i < RTAX_MAX; i++) {
+                                       if ((RTA_MASKS & ifmam->ifmam_addrs &
+                                                (1 << i)) == 0)
+                                               continue;
+                                       sa = (struct sockaddr *)(void *)p;
+                                       len = SA_RLEN(sa);
+                                       dcnt += len;
+                                       p += len;
+                               }
+                               break;
+               }
+       }
+
+       data = malloc(sizeof(struct ifmaddrs) * icnt + dcnt);
+       if (data == NULL) {
+               free(buf);
+               return (-1);
+       }
+
+       ifa = (struct ifmaddrs *)(void *)data;
+       data += sizeof(struct ifmaddrs) * icnt;
+
+       memset(ifa, 0, sizeof(struct ifmaddrs) * icnt);
+       ift = ifa;
+
+       for (next = buf; next < buf + needed; next += rtm->rtm_msglen) {
+               rtm = (struct rt_msghdr *)(void *)next;
+               if (rtm->rtm_version != RTM_VERSION)
+                       continue;
+
+               switch (rtm->rtm_type) {
+                       case GIM_RTM_ADDR:
+                               ifmam = (struct ifma_msghdr2 *)(void *)rtm;
+                               if ((ifmam->ifmam_addrs & RTA_IFA) == 0)
+                                       break;
+
+                               p = (char *)(ifmam + 1);
+                               for (i = 0; i < RTAX_MAX; i++) {
+                                       if ((RTA_MASKS & ifmam->ifmam_addrs &
+                                                (1 << i)) == 0)
+                                               continue;
+                                       sa = (struct sockaddr *)(void *)p;
+                                       len = SA_RLEN(sa);
+                                       switch (i) {
+                                               case RTAX_GATEWAY:
+                                                       ift->ifma_lladdr =
+                                                       (struct sockaddr *)(void *)data;
+                                                       memcpy(data, p, len);
+                                                       data += len;
+                                                       break;
+
+                                               case RTAX_IFP:
+                                                       ift->ifma_name =
+                                                       (struct sockaddr *)(void *)data;
+                                                       memcpy(data, p, len);
+                                                       data += len;
+                                                       break;
+
+                                               case RTAX_IFA:
+                                                       ift->ifma_addr =
+                                                       (struct sockaddr *)(void *)data;
+                                                       memcpy(data, p, len);
+                                                       data += len;
+                                                       break;
+
+                                               default:
+                                                       data += len;
+                                                       break;
+                                       }
+                                       p += len;
+                               }
+                               ift->ifma_next = ift + 1;
+                               ift = ift->ifma_next;
+                               break;
+               }
+       }
+
+       free(buf);
+
+       if (ift > ifa) {
+               ift--;
+               ift->ifma_next = NULL;
+               *pif = ifa;
+       } else {
+               *pif = NULL;
+               free(ifa);
+       }
+       return (0);
+}
+
+void
+freeifmaddrs(struct ifmaddrs *ifmp)
+{
+       free(ifmp);
+}
index e26459680c92e9f22bec40d1c48884447692e5f0..97cc6cafc5b44074636f0010c7942495010b492b 100644 (file)
@@ -1,4 +1,4 @@
-/*     $KAME: ifaddrs.h,v 1.3 2001/01/26 08:14:55 itojun Exp $ */
+/*     $FreeBSD: src/include/ifaddrs.h,v 1.3.32.1.4.1 2010/06/14 02:09:06 kensmith Exp $       */
 
 /*
  * Copyright (c) 1995, 1999
 
 /*
  * Copyright (c) 1995, 1999
 #ifndef        _IFADDRS_H_
 #define        _IFADDRS_H_
 
 #ifndef        _IFADDRS_H_
 #define        _IFADDRS_H_
 
+#include <Availability.h>
+
 struct ifaddrs {
        struct ifaddrs  *ifa_next;
        char            *ifa_name;
 struct ifaddrs {
        struct ifaddrs  *ifa_next;
        char            *ifa_name;
-       unsigned int             ifa_flags;
+       unsigned int     ifa_flags;
        struct sockaddr *ifa_addr;
        struct sockaddr *ifa_netmask;
        struct sockaddr *ifa_dstaddr;
        struct sockaddr *ifa_addr;
        struct sockaddr *ifa_netmask;
        struct sockaddr *ifa_dstaddr;
@@ -46,11 +48,20 @@ struct ifaddrs {
 #define        ifa_broadaddr   ifa_dstaddr     /* broadcast address interface */
 #endif
 
 #define        ifa_broadaddr   ifa_dstaddr     /* broadcast address interface */
 #endif
 
+struct ifmaddrs {
+       struct ifmaddrs *ifma_next;
+       struct sockaddr *ifma_name;
+       struct sockaddr *ifma_addr;
+       struct sockaddr *ifma_lladdr;
+};
+
 #include <sys/cdefs.h>
 
 __BEGIN_DECLS
 #include <sys/cdefs.h>
 
 __BEGIN_DECLS
-extern int getifaddrs __P((struct ifaddrs **));
-extern void freeifaddrs __P((struct ifaddrs *));
+extern int getifaddrs(struct ifaddrs **);
+extern void freeifaddrs(struct ifaddrs *);
+extern int getifmaddrs(struct ifmaddrs **) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
+extern void freeifmaddrs(struct ifmaddrs *) __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_4_3);
 __END_DECLS
 
 #endif
 __END_DECLS
 
 #endif
diff --git a/gen.subproj/inet6_opt_init.3 b/gen.subproj/inet6_opt_init.3
new file mode 100644 (file)
index 0000000..ffb9cc9
--- /dev/null
@@ -0,0 +1,337 @@
+.\"    $KAME: inet6_opt_init.3,v 1.7 2004/12/27 05:08:23 itojun Exp $
+.\"
+.\" Copyright (C) 2004 WIDE Project.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the project nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD: src/lib/libc/net/inet6_opt_init.3,v 1.10.10.1.4.1 2010/06/14 02:09:06 kensmith Exp $
+.\"
+.Dd December 23, 2004
+.Dt INET6_OPT_INIT 3
+.Os
+.\"
+.Sh NAME
+.Nm inet6_opt_init ,
+.Nm inet6_opt_append ,
+.Nm inet6_opt_finish ,
+.Nm inet6_opt_set_val ,
+.Nm inet6_opt_next ,
+.Nm inet6_opt_find ,
+.Nm inet6_opt_get_val
+.Nd IPv6 Hop-by-Hop and Destination Options manipulation
+.\"
+.Sh SYNOPSIS
+.In netinet/in.h
+.Ft "int"
+.Fn inet6_opt_init "void *extbuf" "socklen_t extlen"
+.Ft "int"
+.Fn inet6_opt_append "void *extbuf" "socklen_t extlen" "int offset" "u_int8_t type" "socklen_t len" "u_int8_t align" "void **databufp"
+.Ft "int"
+.Fn inet6_opt_finish "void *extbuf" "socklen_t extlen" "int offset"
+.Ft "int"
+.Fn inet6_opt_set_val "void *databuf" "int offset" "void *val" "socklen_t vallen"
+.Ft "int"
+.Fn inet6_opt_next "void *extbuf" "socklen_t extlen" "int offset" "u_int8_t *typep" "socklen_t *lenp" "void **databufp"
+.Ft "int"
+.Fn inet6_opt_find "void *extbuf" "socklen_t extlen" "int offset" "u_int8_t type" "socklen_t *lenp" "void **databufp"
+.Ft "int"
+.Fn inet6_opt_get_val "void *databuf" "int offset" "void *val" "socklen_t vallen"
+.\"
+.Sh DESCRIPTION
+Building and parsing the Hop-by-Hop and Destination options is
+complicated.
+The advanced sockets API defines a set of functions to
+help applications create and manipulate Hop-by-Hop and Destination
+options.
+This man page describes the functions specified in
+IETF Draft RFC3542.
+These functions use the
+formatting rules specified in Appendix B in RFC2460, i.e., that the
+largest field is placed last in the option.
+The function prototypes
+for these functions are all contained in the
+.In netinet/in.h
+header file.
+.\"
+.Ss inet6_opt_init
+The
+.Fn inet6_opt_init
+function
+returns the number of bytes needed for an empty
+extension header, one without any options.
+If the
+.Fa extbuf
+argument points to a valid section of memory
+then the
+.Fn inet6_opt_init
+function also initializes the extension header's length field.
+When attempting to initialize an extension buffer passed in the
+.Fa extbuf
+argument,
+.Fa extlen
+must be a positive multiple of 8 or else the function fails and
+returns \-1 to the caller.
+.\"
+.Ss inet6_opt_append
+The
+.Fn inet6_opt_append
+function can perform two different jobs.
+When a valid
+.Fa extbuf
+argument is supplied it appends an option to the extension buffer and
+returns the updated total length as well as a pointer to the newly
+created option in
+.Fa databufp .
+If the value
+of
+.Fa extbuf
+is
+.Dv NULL
+then the
+.Fn inet6_opt_append
+function only reports what the total length would
+be if the option were actually appended.
+The
+.Fa len
+and
+.Fa align
+arguments specify the length of the option and the required data
+alignment which must be used when appending the option.
+The
+.Fa offset
+argument should be the length returned by the
+.Fn inet6_opt_init
+function or a previous call to
+.Fn inet6_opt_append .
+.Pp
+The
+.Fa type
+argument is the 8-bit option type.
+.Pp
+After
+.Fn inet6_opt_append
+has been called, the application can use the buffer pointed to by
+.Fa databufp
+directly, or use
+.Fn inet6_opt_set_val
+to specify the data to be contained in the option.
+.Pp
+Option types of
+.Li 0
+and
+.Li 1
+are reserved for the
+.Li Pad1
+and
+.Li PadN
+options.
+All other values from 2 through 255 may be used by applications.
+.Pp
+The length of the option data is contained in an 8-bit value and so
+may contain any value from 0 through 255.
+.Pp
+The
+.Fa align
+parameter must have a value of 1, 2, 4, or 8 and cannot exceed the
+value of
+.Fa len .
+The alignment values represent no alignment, 16 bit, 32 bit and 64 bit
+alignments, respectively.
+.\"
+.Ss inet6_opt_finish
+The
+.Fn inet6_opt_finish
+function
+calculates the final padding necessary to make the extension header a
+multiple of 8 bytes, as required by the IPv6 extension header
+specification, and returns the extension header's updated total
+length.
+The
+.Fa offset
+argument should be the length returned by
+.Fn inet6_opt_init
+or
+.Fn inet6_opt_append .
+When
+.Fa extbuf
+is not
+.Dv NULL
+the function also sets up the appropriate padding bytes by inserting a
+Pad1 or PadN option of the proper length.
+.Pp
+If the extension header is too small to contain the proper padding
+then an error of \-1 is returned to the caller.
+.\"
+.Ss inet6_opt_set_val
+The
+.Fn inet6_opt_set_val
+function inserts data items of various sizes into the data portion of
+the option.
+The
+.Fa databuf
+argument is a pointer to memory that was returned by the
+.Fn inet6_opt_append
+call and the
+.Fa offset
+argument specifies where the option should be placed in the
+data buffer.
+The
+.Fa val
+argument points to an area of memory containing the data to be
+inserted into the extension header, and the
+.Fa vallen
+argument indicates how much data to copy.
+.Pp
+The caller should ensure that each field is aligned on its natural
+boundaries as described in Appendix B of RFC2460.
+.Pp
+The function returns the offset for the next field which is calculated as
+.Fa offset
++
+.Fa vallen
+and is used when composing options with multiple fields.
+.\"
+.Ss inet6_opt_next
+The
+.Fn inet6_opt_next
+function parses received extension headers.
+The
+.Fa extbuf
+and
+.Fa extlen
+arguments specify the location and length of the extension header
+being parsed.
+The
+.Fa offset
+argument should either be zero, for the first option, or the length value
+returned by a previous call to
+.Fn inet6_opt_next
+or
+.Fn inet6_opt_find .
+The return value specifies the position where to continue scanning the
+extension buffer.
+The option is returned in the arguments
+.Fa typep , lenp ,
+and
+.Fa databufp ,
+which
+point to the 8-bit option type, the 8-bit option length and the option
+data, respectively.
+This function does not return any PAD1 or PADN options.
+When an error occurs or there are no more options, the return
+value is \-1.
+.\"
+.Ss inet6_opt_find
+The
+.Fn inet6_opt_find
+function searches the extension buffer for a particular option type,
+passed in through the
+.Fa type
+argument.
+If the option is found then the
+.Fa lenp
+and
+.Fa databufp
+arguments are updated to point to the option's length and data,
+respectively.
+The
+.Fa extbuf
+and
+.Fa extlen
+arguments
+must point to a valid extension buffer and give its length.
+The
+.Fa offset
+argument can be used to search from a location anywhere in the
+extension header.
+.Ss inet6_opt_get_val
+The
+.Fn inet6_opt_get_val
+function extracts data items of various sizes in the data portion of
+the option.
+The
+.Fa databuf
+is a pointer returned by the
+.Fn inet6_opt_next
+or
+.Fn inet6_opt_find
+functions.
+The
+.Fa val
+argument points where the data will be extracted.
+The
+.Fa offset
+argument specifies from where in the data portion of the option the
+value should be extracted; the first byte of option data is specified
+by an offset of zero.
+.Pp
+It is expected that each field is aligned on its natural boundaries as
+described in Appendix B of RFC2460.
+.Pp
+The function returns the offset for the next field
+by calculating
+.Fa offset
++
+.Fa vallen
+which can be used when extracting option content with multiple fields.
+Robust receivers must verify alignment before calling this function.
+.\"
+.Sh RETURN VALUES
+All the functions return
+\-1
+on an error.
+.\"
+.Sh EXAMPLES
+RFC3542 gives comprehensive examples in Section 23.
+.Pp
+KAME also provides examples in the
+.Pa advapitest
+directory of its kit.
+.\"
+.Sh SEE ALSO
+.Rs
+.%A W. Stevens
+.%A M. Thomas
+.%A E. Nordmark
+.%A T. Jinmei
+.%T "Advanced Sockets API for IPv6"
+.%N RFC3542
+.%D October 2002
+.Re
+.Rs
+.%A S. Deering
+.%A R. Hinden
+.%T "Internet Protocol, Version 6 (IPv6) Specification"
+.%N RFC2460
+.%D December 1998
+.Re
+.Sh STANDARDS
+The functions are documented in
+.Dq Advanced Sockets API for IPv6
+.Pq RFC3542 .
+.\"
+.Sh HISTORY
+The implementation first appeared in KAME advanced networking kit.
diff --git a/gen.subproj/inet6_rth_space.3 b/gen.subproj/inet6_rth_space.3
new file mode 100644 (file)
index 0000000..654bd5a
--- /dev/null
@@ -0,0 +1,224 @@
+.\"    $KAME: inet6_rth_space.3,v 1.7 2005/01/05 03:00:44 itojun Exp $
+.\"
+.\" Copyright (C) 2004 WIDE Project.
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\"    notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\"    notice, this list of conditions and the following disclaimer in the
+.\"    documentation and/or other materials provided with the distribution.
+.\" 3. Neither the name of the project nor the names of its contributors
+.\"    may be used to endorse or promote products derived from this software
+.\"    without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+.\" SUCH DAMAGE.
+.\"
+.\" $FreeBSD: src/lib/libc/net/inet6_rth_space.3,v 1.10.10.1.4.1 2010/06/14 02:09:06 kensmith Exp $
+.\"
+.Dd December 24, 2004
+.Dt INET6_RTH_SPACE 3
+.Os
+.\"
+.Sh NAME
+.Nm inet6_rth_space ,
+.Nm inet6_rth_init ,
+.Nm inet6_rth_add ,
+.Nm inet6_rth_reverse ,
+.Nm inet6_rth_segments ,
+.Nm inet6_rth_getaddr
+.Nd IPv6 Routing Header Options manipulation
+.\"
+.Sh SYNOPSIS
+.Fd #include <netinet6/in6.h>
+.Ft socklen_t
+.Fn inet6_rth_space "int" "int"
+.Ft "void *"
+.Fn inet6_rth_init "void *" "socklen_t" "int" "int"
+.Ft int
+.Fn inet6_rth_add "void *" "const struct in6_addr *"
+.Ft int
+.Fn inet6_rth_reverse "const void *" "void *"
+.Ft int
+.Fn inet6_rth_segments "const void *"
+.Ft "struct in6_addr *"
+.Fn inet6_rth_getaddr "const void *" "int"
+.\"
+.Sh DESCRIPTION
+The IPv6 Advanced API, RFC 3542, defines the functions that an
+application calls to build and examine IPv6 Routing headers.
+Routing headers are used to perform source routing in IPv6 networks.
+The RFC uses the word
+.Dq segments
+to describe addresses and that is the term used here as well.
+All of the functions are defined in the
+.In netinet/in.h
+header file.
+The functions described in this manual page all operate
+on routing header structures which are defined in
+.In netinet/ip6.h
+but which should not need to be modified outside the use of this API.
+The size and shape of the route header structures may change, so using
+the APIs is a more portable, long term, solution.
+.Pp
+The functions in the API are split into two groups, those that build a
+routing header and those that parse a received routing header.
+We will describe the builder functions followed by the parser functions.
+.Ss inet6_rth_space
+The
+.Fn inet6_rth_space
+function returns the number of bytes required to hold a Routing Header
+of the type, specified in the
+.Fa type
+argument and containing the number of addresses specified in the
+.Fa segments
+argument.
+When the type is
+.Dv IPV6_RTHDR_TYPE_0
+the number of segments must be from 0 through 127.
+Routing headers of type
+.Dv IPV6_RTHDR_TYPE_2
+contain only one segment, and are only used with Mobile IPv6.
+The return value from this function is the number of bytes required to
+store the routing header.
+If the value 0 is returned then either the
+route header type was not recognized or another error occurred.
+.Ss inet6_rth_init
+The
+.Fn inet6_rth_init
+function initializes the pre-allocated buffer pointed to by
+.Fa bp
+to contain a routing header of the specified type The
+.Fa bp_len
+argument is used to verify that the buffer is large enough.
+The caller must allocate the buffer pointed to by bp.
+The necessary buffer size should be determined by calling
+.Fn inet6_rth_space
+described in the previous sections.
+.Pp
+The
+.Fn inet6_rth_init
+function returns a pointer to
+.Fa bp
+on success and
+.Dv NULL
+when there is an error.
+.Ss inet6_rth_add
+The
+.Fn inet6_rth_add
+function adds the IPv6 address pointed to by
+.Fa addr
+to the end of the routing header being constructed.
+.Pp
+A successful addition results in the function returning 0, otherwise
+\-1 is returned.
+.Ss inet6_rth_reverse
+The
+.Fn inet6_rth_reverse
+function takes a routing header, pointed to by the
+argument
+.Fa in ,
+and writes a new routing header into the argument pointed to by
+.Fa out .
+The routing header at that sends datagrams along the reverse of that
+route.
+Both arguments are allowed to point to the same buffer meaning
+that the reversal can occur in place.
+.Pp
+The return value of the function is 0 on success, or \-1 when
+there is an error.
+.\"
+.Pp
+The next set of functions operate on a routing header that the
+application wants to parse.
+In the usual case such a routing header
+is received from the network, although these functions can also be
+used with routing headers that the application itself created.
+.Ss inet6_rth_segments
+The
+.Fn inet6_rth_segments
+function returns the number of segments contained in the
+routing header pointed to by
+.Fa bp .
+The return value is the number of segments contained in the routing
+header, or \-1 if an error occurred.
+It is not an error for 0 to be
+returned as a routing header may contain 0 segments.
+.\"
+.Ss inet6_rth_getaddr
+The
+.Fn inet6_rth_getaddr
+function is used to retrieve a single address from a routing header.
+The
+.Fa index
+is the location in the routing header from which the application wants
+to retrieve an address.
+The
+.Fa index
+parameter must have a value between 0 and one less than the number of
+segments present in the routing header.
+The
+.Fn inet6_rth_segments
+function, described in the last section, should be used to determine
+the total number of segments in the routing header.
+The
+.Fn inet6_rth_getaddr
+function returns a pointer to an IPv6 address on success or
+.Dv NULL
+when an error has occurred.
+.\"
+.Sh EXAMPLES
+RFC 3542 gives extensive examples in Section 21, Appendix B.
+.Pp
+KAME also provides examples in the advapitest directory of its kit.
+.\"
+.Sh DIAGNOSTICS
+The
+.Fn inet6_rth_space
+and
+.Fn inet6_rth_getaddr
+functions return 0 on errors.
+.Pp
+The
+.Fn inet6_rthdr_init
+function returns
+.Dv NULL
+on error.
+The
+.Fn inet6_rth_add
+and
+.Fn inet6_rth_reverse
+functions return 0 on success, or \-1 upon an error.
+.\"
+.Sh SEE ALSO
+.Rs
+.%A W. Stevens
+.%A M. Thomas
+.%A E. Nordmark
+.%A T. Jinmei
+.%T "Advanced Sockets API for IPv6"
+.%N RFC 3542
+.%D May 2003
+.Re
+.Rs
+.%A S. Deering
+.%A R. Hinden
+.%T "Internet Protocol, Version 6 (IPv6) Specification"
+.%N RFC2460
+.%D December 1998
+.Re
+.Sh HISTORY
+The implementation first appeared in KAME advanced networking kit.
index 0dd526477986f0524c9259eed2eedf32be66034f..10d36b19a1121480f739cb06f51cecc696be2ea7 100644 (file)
@@ -1,3 +1,5 @@
+/*     $KAME: ip6opt.c,v 1.13 2003/06/06 10:08:20 suz Exp $    */
+
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  * All rights reserved.
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  * All rights reserved.
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libc/net/ip6opt.c,v 1.1 1999/12/16 18:32:01 shin Exp $
+ * $FreeBSD: src/lib/libc/net/ip6opt.c,v 1.8.10.2.2.1 2010/06/14 02:09:06 kensmith Exp $
+ */
+
+/*
+ * These routines support RFC 3542
+ * __APPLE_USE_RFC_3542 selects the appropriate API in <netinet6/in6.h>
  */
  */
+#define __APPLE_USE_RFC_3542
+
+#include <sys/cdefs.h>
 
 #include <sys/param.h>
 #include <sys/types.h>
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -52,8 +62,7 @@ static void inet6_insert_padopt(u_char *p, int len);
  * byte, the length byte, and the option data.
  */
 int
  * byte, the length byte, and the option data.
  */
 int
-inet6_option_space(nbytes)
-       int nbytes;
+inet6_option_space(int nbytes)
 {
        nbytes += 2;    /* we need space for nxt-hdr and length fields */
        return(CMSG_SPACE((nbytes + 7) & ~7));
 {
        nbytes += 2;    /* we need space for nxt-hdr and length fields */
        return(CMSG_SPACE((nbytes + 7) & ~7));
@@ -65,12 +74,9 @@ inet6_option_space(nbytes)
  * success or -1 on an error.
  */
 int
  * success or -1 on an error.
  */
 int
-inet6_option_init(bp, cmsgp, type)
-       void *bp;
-       struct cmsghdr **cmsgp;
-       int type;
+inet6_option_init(void *bp, struct cmsghdr **cmsgp, int type)
 {
 {
-       register struct cmsghdr *ch = (struct cmsghdr *)bp;
+       struct cmsghdr *ch = (struct cmsghdr *)bp;
 
        /* argument validation */
        if (type != IPV6_HOPOPTS && type != IPV6_DSTOPTS)
 
        /* argument validation */
        if (type != IPV6_HOPOPTS && type != IPV6_DSTOPTS)
@@ -95,14 +101,11 @@ inet6_option_init(bp, cmsgp, type)
  * earlier.  It must have a value between 0 and 7, inclusive.
  */
 int
  * earlier.  It must have a value between 0 and 7, inclusive.
  */
 int
-inet6_option_append(cmsg, typep, multx, plusy)
-       struct cmsghdr *cmsg;
-       const u_int8_t *typep;
-       int multx;
-       int plusy;
+inet6_option_append(struct cmsghdr *cmsg, const u_int8_t *typep, int multx,
+    int plusy)
 {
        int padlen, optlen, off;
 {
        int padlen, optlen, off;
-       register u_char *bp = (u_char *)cmsg + cmsg->cmsg_len;
+       u_char *bp = (u_char *)cmsg + cmsg->cmsg_len;
        struct ip6_ext *eh = (struct ip6_ext *)CMSG_DATA(cmsg);
 
        /* argument validation */
        struct ip6_ext *eh = (struct ip6_ext *)CMSG_DATA(cmsg);
 
        /* argument validation */
@@ -126,6 +129,7 @@ inet6_option_append(cmsg, typep, multx, plusy)
        padlen = (((off % multx) + (multx - 1)) & ~(multx - 1)) -
                (off % multx);
        padlen += plusy;
        padlen = (((off % multx) + (multx - 1)) & ~(multx - 1)) -
                (off % multx);
        padlen += plusy;
+       padlen %= multx;        /* keep the pad as short as possible */
        /* insert padding */
        inet6_insert_padopt(bp, padlen);
        cmsg->cmsg_len += padlen;
        /* insert padding */
        inet6_insert_padopt(bp, padlen);
        cmsg->cmsg_len += padlen;
@@ -167,14 +171,10 @@ inet6_option_append(cmsg, typep, multx, plusy)
  * 
  */
 u_int8_t *
  * 
  */
 u_int8_t *
-inet6_option_alloc(cmsg, datalen, multx, plusy)
-       struct cmsghdr *cmsg;
-       int datalen;
-       int multx;
-       int plusy;
+inet6_option_alloc(struct cmsghdr *cmsg, int datalen, int multx, int plusy)
 {
        int padlen, off;
 {
        int padlen, off;
-       register u_int8_t *bp = (u_char *)cmsg + cmsg->cmsg_len;
+       u_int8_t *bp = (u_char *)cmsg + cmsg->cmsg_len;
        u_int8_t *retval;
        struct ip6_ext *eh = (struct ip6_ext *)CMSG_DATA(cmsg);
 
        u_int8_t *retval;
        struct ip6_ext *eh = (struct ip6_ext *)CMSG_DATA(cmsg);
 
@@ -199,6 +199,7 @@ inet6_option_alloc(cmsg, datalen, multx, plusy)
        padlen = (((off % multx) + (multx - 1)) & ~(multx - 1)) -
                (off % multx);
        padlen += plusy;
        padlen = (((off % multx) + (multx - 1)) & ~(multx - 1)) -
                (off % multx);
        padlen += plusy;
+       padlen %= multx;        /* keep the pad as short as possible */
        /* insert padding */
        inet6_insert_padopt(bp, padlen);
        cmsg->cmsg_len += padlen;
        /* insert padding */
        inet6_insert_padopt(bp, padlen);
        cmsg->cmsg_len += padlen;
@@ -233,9 +234,7 @@ inet6_option_alloc(cmsg, datalen, multx, plusy)
  * (RFC 2292, 6.3.5)
  */
 int
  * (RFC 2292, 6.3.5)
  */
 int
-inet6_option_next(cmsg, tptrp)
-       const struct cmsghdr *cmsg;
-       u_int8_t **tptrp;
+inet6_option_next(const struct cmsghdr *cmsg, u_int8_t **tptrp)
 {
        struct ip6_ext *ip6e;
        int hdrlen, optlen;
 {
        struct ip6_ext *ip6e;
        int hdrlen, optlen;
@@ -291,10 +290,7 @@ inet6_option_next(cmsg, tptrp)
  *       it's a typo. The variable should be type of u_int8_t **.
  */
 int
  *       it's a typo. The variable should be type of u_int8_t **.
  */
 int
-inet6_option_find(cmsg, tptrp, type)
-       const struct cmsghdr *cmsg;
-       u_int8_t **tptrp;
-       int type;
+inet6_option_find(const struct cmsghdr *cmsg, u_int8_t **tptrp, int type)
 {
        struct ip6_ext *ip6e;
        int hdrlen, optlen;
 {
        struct ip6_ext *ip6e;
        int hdrlen, optlen;
@@ -347,8 +343,7 @@ inet6_option_find(cmsg, tptrp, type)
  * calculated length and the limitation of the buffer.
  */
 static int
  * calculated length and the limitation of the buffer.
  */
 static int
-ip6optlen(opt, lim)
-       u_int8_t *opt, *lim;
+ip6optlen(u_int8_t *opt, u_int8_t *lim)
 {
        int optlen;
 
 {
        int optlen;
 
@@ -382,3 +377,219 @@ inet6_insert_padopt(u_char *p, int len)
                 return;
        }
 }
                 return;
        }
 }
+
+/*
+ * The following functions are defined in RFC3542, which is a successor
+ * of RFC2292.
+ */
+
+int
+inet6_opt_init(void *extbuf, socklen_t extlen)
+{
+       struct ip6_ext *ext = (struct ip6_ext *)extbuf;
+
+       if (extlen == 0 || (extlen % 8)) {
+               return(-1);
+       }
+
+       if (ext) {
+               ext->ip6e_len = (extlen >> 3) - 1;
+       }
+
+       return(2);              /* sizeof the next and the length fields */
+}
+
+int
+inet6_opt_append(void *extbuf, socklen_t extlen, int offset, u_int8_t type, socklen_t len, u_int8_t align, void **databufp)
+{
+       int currentlen = offset, padlen = 0;
+
+       /*
+        * The option type must have a value from 2 to 255, inclusive.
+        * (0 and 1 are reserved for the Pad1 and PadN options, respectively.)
+        */
+       if (type < 2)
+               return(-1);
+
+       /*
+        * The option data length must have a value between 0 and 255,
+        * inclusive, and is the length of the option data that follows.
+        */
+       if (len > 255) {
+               return(-1);
+       }
+
+       /*
+        * The align parameter must have a value of 1, 2, 4, or 8.
+        * The align value can not exceed the value of len.
+        */
+       if (align != 1 && align != 2 && align != 4 && align != 8)
+               return(-1);
+       if (align > len)
+               return(-1);
+
+       /* Calculate the padding length. */
+       currentlen += 2 + len;  /* 2 means "type + len" */
+       if (currentlen % align)
+               padlen = align - (currentlen % align);
+
+       /* The option must fit in the extension header buffer. */
+       currentlen += padlen;
+       if (extlen &&           /* XXX: right? */
+           currentlen > extlen)
+               return(-1);
+
+       if (extbuf) {
+               u_int8_t *optp = (u_int8_t *)extbuf + offset;
+
+               if (padlen == 1) {
+                       /* insert a Pad1 option */
+                       *optp = IP6OPT_PAD1;
+                       optp++;
+               }
+               else if (padlen > 0) {
+                       /* insert a PadN option for alignment */
+                       *optp++ = IP6OPT_PADN;
+                       *optp++ = padlen - 2;
+                       memset(optp, 0, padlen - 2);
+                       optp += (padlen - 2);
+               }
+
+               *optp++ = type;
+               *optp++ = len;
+
+               *databufp = optp;
+       }
+
+       return(currentlen);
+}
+
+int
+inet6_opt_finish(void *extbuf, socklen_t extlen, int offset)
+{
+       int updatelen = offset > 0 ? (1 + ((offset - 1) | 7)) : 0;;
+
+       if (extbuf) {
+               u_int8_t *padp;
+               int padlen = updatelen - offset;
+
+               if (updatelen > extlen)
+                       return(-1);
+
+               padp = (u_int8_t *)extbuf + offset;
+               if (padlen == 1)
+                       *padp = IP6OPT_PAD1;
+               else if (padlen > 0) {
+                       *padp++ = IP6OPT_PADN;
+                       *padp++ = (padlen - 2);
+                       memset(padp, 0, padlen - 2);
+               }
+       }
+
+       return(updatelen);
+}
+
+int
+inet6_opt_set_val(void *databuf, int offset, void *val, socklen_t vallen)
+{
+       memcpy((u_int8_t *)databuf + offset, val, vallen);
+       return(offset + vallen);
+}
+
+int
+inet6_opt_next(void *extbuf, socklen_t extlen, int offset, u_int8_t *typep, socklen_t *lenp, void **databufp)
+{
+       u_int8_t *optp, *lim;
+       int optlen;
+
+       /* Validate extlen. XXX: is the variable really necessary?? */
+       if (extlen == 0 || (extlen % 8))
+               return(-1);
+       lim = (u_int8_t *)extbuf + extlen;
+
+       /*
+        * If this is the first time this function called for this options
+        * header, simply return the 1st option.
+        * Otherwise, search the option list for the next option.
+        */
+       if (offset == 0) {
+               optp = (u_int8_t *)((struct ip6_hbh *)extbuf + 1);
+       }
+       else
+               optp = (u_int8_t *)extbuf + offset;
+
+       /* Find the next option skipping any padding options. */
+       while(optp < lim) {
+               switch(*optp) {
+               case IP6OPT_PAD1:
+                       optp++;
+                       break;
+               case IP6OPT_PADN:
+                       if ((optlen = ip6optlen(optp, lim)) == 0)
+                               goto optend;
+                       optp += optlen;
+                       break;
+               default:        /* found */
+                       if ((optlen = ip6optlen(optp, lim)) == 0)
+                               goto optend;
+                       *typep = *optp;
+                       *lenp = optlen - 2;
+                       *databufp = optp + 2;
+                       return(optp + optlen - (u_int8_t *)extbuf);
+               }
+       }
+
+  optend:
+       *databufp = NULL; /* for safety */
+       return(-1);
+}
+
+int
+inet6_opt_find(void *extbuf, socklen_t extlen, int offset, u_int8_t type, socklen_t *lenp, void **databufp)
+{
+       u_int8_t *optp, *lim;
+       int optlen;
+
+       /* Validate extlen. XXX: is the variable really necessary?? */
+       if (extlen == 0 || (extlen % 8))
+               return(-1);
+       lim = (u_int8_t *)extbuf + extlen;
+
+       /*
+        * If this is the first time this function called for this options
+        * header, simply return the 1st option.
+        * Otherwise, search the option list for the next option.
+        */
+       if (offset == 0) {
+               optp = (u_int8_t *)((struct ip6_hbh *)extbuf + 1);
+       }
+       else
+               optp = (u_int8_t *)extbuf + offset;
+
+       /* Find the specified option */
+       while(optp < lim) {
+               if ((optlen = ip6optlen(optp, lim)) == 0)
+                       goto optend;
+
+               if (*optp == type) { /* found */
+                       *lenp = optlen - 2;
+                       *databufp = optp + 2;
+                       return(optp + optlen - (u_int8_t *)extbuf);
+               }
+
+               optp += optlen;
+       }
+
+  optend:
+       *databufp = NULL; /* for safety */
+       return(-1);
+}
+
+int
+inet6_opt_get_val(void *databuf, int offset, void *val, socklen_t vallen)
+{
+       /* we can't assume alignment here */
+       memcpy(val, (u_int8_t *)databuf + offset, vallen);
+
+       return(offset + vallen);
+}
index 4f2385ea813d8a2db1121c4de5107ec88b777a92..1031311d6c985ade6ccbc29f6d3ff98e90f94346 100644 (file)
@@ -1,3 +1,5 @@
+/*     $KAME: rthdr.c,v 1.19 2003/06/06 10:48:51 itojun Exp $  */
+
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  * All rights reserved.
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  * All rights reserved.
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/libc/net/rthdr.c,v 1.2 2000/03/03 11:12:59 shin Exp $
  */
 
  */
 
+/* __FBSDID("$FreeBSD: src/lib/libc/net/rthdr.c,v 1.9.10.1.4.1 2010/06/14 02:09:06 kensmith Exp $"); */
+
+/*
+ * These routines support RFC 2292.
+ * __APPLE_USE_RFC_2292 selects the appropriate API in <netinet6/in6.h>
+ */
+#define __APPLE_USE_RFC_2292
+
+#include <sys/cdefs.h>
+
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <string.h>
 #include <stdio.h>
 
 #include <string.h>
 #include <stdio.h>
 
+/*
+ * RFC2292 API
+ */
+
 size_t
 inet6_rthdr_space(type, seg)
 size_t
 inet6_rthdr_space(type, seg)
-    int type, seg;
+int type, seg;
 {
 {
-    switch(type) {
-     case IPV6_RTHDR_TYPE_0:
-        if (seg < 1 || seg > 23)
-            return(0);
-        return(CMSG_SPACE(sizeof(struct in6_addr) * (seg - 1)
-                          + sizeof(struct ip6_rthdr0)));
-     default:
-#ifdef DEBUG
-        fprintf(stderr, "inet6_rthdr_space: unknown type(%d)\n", type);
+       switch (type) {
+               case IPV6_RTHDR_TYPE_0:
+                       if (seg < 1 || seg > 23)
+                               return (0);
+#ifdef COMPAT_RFC2292
+                       return (CMSG_SPACE(sizeof(struct in6_addr) * (seg - 1) +
+                                                          sizeof(struct ip6_rthdr0)));
+#else
+                       return (CMSG_SPACE(sizeof(struct in6_addr) * seg +
+                                                          sizeof(struct ip6_rthdr0)));
 #endif 
 #endif 
-        return(0);
-    }
+               default:
+                       return (0);
+       }
 }
 
 struct cmsghdr *
 inet6_rthdr_init(bp, type)
 }
 
 struct cmsghdr *
 inet6_rthdr_init(bp, type)
-    void *bp;
-    int type;
+void *bp;
+int type;
 {
 {
-    register struct cmsghdr *ch = (struct cmsghdr *)bp;
-    register struct ip6_rthdr *rthdr;
-
-    rthdr = (struct ip6_rthdr *)CMSG_DATA(ch);
-
-    ch->cmsg_level = IPPROTO_IPV6;
-    ch->cmsg_type = IPV6_RTHDR;
-
-    switch(type) {
-     case IPV6_RTHDR_TYPE_0:
-        ch->cmsg_len = CMSG_LEN(sizeof(struct ip6_rthdr0) - sizeof(struct in6_addr));
-        bzero(rthdr, sizeof(struct ip6_rthdr0));
-        rthdr->ip6r_type = IPV6_RTHDR_TYPE_0;
-        return(ch);
-     default:
-#ifdef DEBUG
-        fprintf(stderr, "inet6_rthdr_init: unknown type(%d)\n", type);
+       struct cmsghdr *ch = (struct cmsghdr *)bp;
+       struct ip6_rthdr *rthdr;
+
+       rthdr = (struct ip6_rthdr *)CMSG_DATA(ch);
+
+       ch->cmsg_level = IPPROTO_IPV6;
+       ch->cmsg_type = IPV6_RTHDR;
+
+       switch (type) {
+               case IPV6_RTHDR_TYPE_0:
+#ifdef COMPAT_RFC2292
+                       ch->cmsg_len = CMSG_LEN(sizeof(struct ip6_rthdr0) -
+                                                                       sizeof(struct in6_addr));
+#else
+                       ch->cmsg_len = CMSG_LEN(sizeof(struct ip6_rthdr0));
 #endif 
 #endif 
-        return(NULL);
-    }
+
+                       bzero(rthdr, sizeof(struct ip6_rthdr0));
+                       rthdr->ip6r_type = IPV6_RTHDR_TYPE_0;
+                       return (ch);
+               default:
+                       return (NULL);
+       }
 }
 
 }
 
+/* ARGSUSED */
 int
 inet6_rthdr_add(cmsg, addr, flags)
 int
 inet6_rthdr_add(cmsg, addr, flags)
-    struct cmsghdr *cmsg;
-    const struct in6_addr *addr;
-    u_int flags;
+struct cmsghdr *cmsg;
+const struct in6_addr *addr;
+u_int flags;
 {
 {
-    register struct ip6_rthdr *rthdr;
-
-    rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
-
-    switch(rthdr->ip6r_type) {
-     case IPV6_RTHDR_TYPE_0:
-     {
-        struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
-        if (flags != IPV6_RTHDR_LOOSE && flags != IPV6_RTHDR_STRICT) {
-#ifdef DEBUG
-            fprintf(stderr, "inet6_rthdr_add: unsupported flag(%d)\n", flags);
+       struct ip6_rthdr *rthdr;
+
+       rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
+
+       switch (rthdr->ip6r_type) {
+               case IPV6_RTHDR_TYPE_0:
+               {
+                       struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
+                       if (flags != IPV6_RTHDR_LOOSE && flags != IPV6_RTHDR_STRICT)
+                               return (-1);
+                       if (rt0->ip6r0_segleft == 23)
+                               return (-1);
+
+#ifdef COMPAT_RFC1883          /* XXX */
+                       if (flags == IPV6_RTHDR_STRICT) {
+                               int c, b;
+                               c = rt0->ip6r0_segleft / 8;
+                               b = rt0->ip6r0_segleft % 8;
+                               rt0->ip6r0_slmap[c] |= (1 << (7 - b));
+                       }
+#else
+                       if (flags != IPV6_RTHDR_LOOSE)
+                               return (-1);
 #endif 
 #endif 
-            return(-1);
-        }
-        if (rt0->ip6r0_segleft == 23) {
-#ifdef DEBUG
-            fprintf(stderr, "inet6_rthdr_add: segment overflow\n");
-#endif 
-            return(-1);
-        }
-        if (flags == IPV6_RTHDR_STRICT) {
-            int c, b;
-            c = rt0->ip6r0_segleft / 8;
-            b = rt0->ip6r0_segleft % 8;
-            rt0->ip6r0_slmap[c] |= (1 << (7 - b));
-        }
-        rt0->ip6r0_segleft++;
-        bcopy(addr, (caddr_t)rt0 + ((rt0->ip6r0_len + 1) << 3),
-              sizeof(struct in6_addr));
-        rt0->ip6r0_len += sizeof(struct in6_addr) >> 3;
-        cmsg->cmsg_len = CMSG_LEN((rt0->ip6r0_len + 1) << 3);
-        break;
-     }
-     default:
-#ifdef DEBUG
-        fprintf(stderr, "inet6_rthdr_add: unknown type(%d)\n",
-                rthdr->ip6r_type);
-#endif 
-        return(-1);
-    }
+                       rt0->ip6r0_segleft++;
+                       bcopy(addr, (caddr_t)rt0 + ((rt0->ip6r0_len + 1) << 3),
+                                 sizeof(struct in6_addr));
+                       rt0->ip6r0_len += sizeof(struct in6_addr) >> 3;
+                       cmsg->cmsg_len = CMSG_LEN((rt0->ip6r0_len + 1) << 3);
+                       break;
+               }
+               default:
+                       return (-1);
+       }
 
 
-    return(0);
+       return (0);
 }
 
 }
 
+/* ARGSUSED */
 int
 inet6_rthdr_lasthop(cmsg, flags)
 int
 inet6_rthdr_lasthop(cmsg, flags)
-    struct cmsghdr *cmsg;
-    unsigned int flags;
+struct cmsghdr *cmsg;
+unsigned int flags;
 {
 {
-    register struct ip6_rthdr *rthdr;
-
-    rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
-
-    switch(rthdr->ip6r_type) {
-     case IPV6_RTHDR_TYPE_0:
-     {
-        struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
-        if (flags != IPV6_RTHDR_LOOSE && flags != IPV6_RTHDR_STRICT) {
-#ifdef DEBUG
-            fprintf(stderr, "inet6_rthdr_lasthop: unsupported flag(%d)\n", flags);
-#endif 
-            return(-1);
-        }
-        if (rt0->ip6r0_segleft > 23) {
-#ifdef DEBUG
-            fprintf(stderr, "inet6_rthdr_add: segment overflow\n");
-#endif 
-            return(-1);
-        }
-        if (flags == IPV6_RTHDR_STRICT) {
-            int c, b;
-            c = rt0->ip6r0_segleft / 8;
-            b = rt0->ip6r0_segleft % 8;
-            rt0->ip6r0_slmap[c] |= (1 << (7 - b));
-        }
-        break;
-     }
-     default:
-#ifdef DEBUG
-        fprintf(stderr, "inet6_rthdr_lasthop: unknown type(%d)\n",
-                rthdr->ip6r_type);
-#endif 
-        return(-1);
-    }
+       struct ip6_rthdr *rthdr;
+
+       rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
+
+       switch (rthdr->ip6r_type) {
+               case IPV6_RTHDR_TYPE_0:
+               {
+                       struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
+#ifdef COMPAT_RFC1883          /* XXX */
+                       if (flags != IPV6_RTHDR_LOOSE && flags != IPV6_RTHDR_STRICT)
+                               return (-1);
+#endif /* COMPAT_RFC1883 */
+                       if (rt0->ip6r0_segleft > 23)
+                               return (-1);
+#ifdef COMPAT_RFC1883          /* XXX */
+                       if (flags == IPV6_RTHDR_STRICT) {
+                               int c, b;
+                               c = rt0->ip6r0_segleft / 8;
+                               b = rt0->ip6r0_segleft % 8;
+                               rt0->ip6r0_slmap[c] |= (1 << (7 - b));
+                       }
+#else
+                       if (flags != IPV6_RTHDR_LOOSE)
+                               return (-1);
+#endif /* COMPAT_RFC1883 */
+                       break;
+               }
+               default:
+                       return (-1);
+       }
 
 
-    return(0);
+       return (0);
 }
 
 #if 0
 int
 inet6_rthdr_reverse(in, out)
 }
 
 #if 0
 int
 inet6_rthdr_reverse(in, out)
-    const struct cmsghdr *in;
-    struct cmsghdr *out;
+const struct cmsghdr *in;
+struct cmsghdr *out;
 {
 {
-#ifdef DEBUG
-    fprintf(stderr, "inet6_rthdr_reverse: not implemented yet\n");
-#endif 
-    return -1;
+
+       return (-1);
 }
 #endif
 
 int
 inet6_rthdr_segments(cmsg)
 }
 #endif
 
 int
 inet6_rthdr_segments(cmsg)
-    const struct cmsghdr *cmsg;
+const struct cmsghdr *cmsg;
 {
 {
-    register struct ip6_rthdr *rthdr;
+       struct ip6_rthdr *rthdr;
 
 
-    rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
+       rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
 
 
-    switch(rthdr->ip6r_type) {
-    case IPV6_RTHDR_TYPE_0:
-      {
-       struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
+       switch (rthdr->ip6r_type) {
+               case IPV6_RTHDR_TYPE_0:
+               {
+                       struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
 
 
-       if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len) {
-#ifdef DEBUG
-           fprintf(stderr, "inet6_rthdr_segments: invalid size(%d)\n",
-               rt0->ip6r0_len);
-#endif 
-           return -1;
-       }
+                       if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len)
+                               return (-1);
 
 
-       return (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
-      }
+                       return (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
+               }
 
 
-    default:
-#ifdef DEBUG
-       fprintf(stderr, "inet6_rthdr_segments: unknown type(%d)\n",
-           rthdr->ip6r_type);
-#endif 
-       return -1;
-    }
+               default:
+                       return (-1);
+       }
 }
 
 struct in6_addr *
 }
 
 struct in6_addr *
-inet6_rthdr_getaddr(cmsg, index)
-    struct cmsghdr *cmsg;
-    int index;
+inet6_rthdr_getaddr(cmsg, idx)
+struct cmsghdr *cmsg;
+int idx;
 {
 {
-    register struct ip6_rthdr *rthdr;
+       struct ip6_rthdr *rthdr;
+
+       rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
+
+       switch (rthdr->ip6r_type) {
+               case IPV6_RTHDR_TYPE_0:
+               {
+                       struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
+                       int naddr;
+
+                       if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len)
+                               return NULL;
+                       naddr = (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
+                       if (idx <= 0 || naddr < idx)
+                               return NULL;
+#ifdef COMPAT_RFC2292
+                       return (((struct in6_addr *)(rt0 + 1)) + idx - 1);
+#else
+                       return (((struct in6_addr *)(rt0 + 1)) + idx);
+#endif
+               }
 
 
-    rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
+               default:
+                       return NULL;
+       }
+}
 
 
-    switch(rthdr->ip6r_type) {
-    case IPV6_RTHDR_TYPE_0:
-      {
-       struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
-       int naddr;
+int
+inet6_rthdr_getflags(cmsg, idx)
+const struct cmsghdr *cmsg;
+int idx;
+{
+       struct ip6_rthdr *rthdr;
+
+       rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
+
+       switch (rthdr->ip6r_type) {
+               case IPV6_RTHDR_TYPE_0:
+               {
+                       struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
+                       int naddr;
+
+                       if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len)
+                               return (-1);
+                       naddr = (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
+                       if (idx < 0 || naddr < idx)
+                               return (-1);
+#ifdef COMPAT_RFC1883          /* XXX */
+                       if (rt0->ip6r0_slmap[idx / 8] & (0x80 >> (idx % 8)))
+                               return IPV6_RTHDR_STRICT;
+                       else
+                               return IPV6_RTHDR_LOOSE;
+#else
+                       return IPV6_RTHDR_LOOSE;
+#endif /* COMPAT_RFC1883 */
+               }
+
+               default:
+                       return (-1);
+       }
+}
 
 
-       if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len) {
-#ifdef DEBUG
-           fprintf(stderr, "inet6_rthdr_getaddr: invalid size(%d)\n",
-               rt0->ip6r0_len);
-#endif 
-           return NULL;
+/*
+ * RFC3542 API
+ */
+
+socklen_t
+inet6_rth_space(int type, int segments)
+{
+       switch (type) {
+               case IPV6_RTHDR_TYPE_0:
+                       if ((segments >= 0) && (segments <= 127))
+                               return (((segments * 2) + 1) << 3);
+                       /* FALLTHROUGH */
+               default:
+                       return (0);     /* type not suppported */
        }
        }
-       naddr = (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
-       if (index <= 0 || naddr < index) {
-#ifdef DEBUG
-           fprintf(stderr, "inet6_rthdr_getaddr: invalid index(%d)\n", index);
-#endif 
-           return NULL;
+}
+
+void *
+inet6_rth_init(void *bp, socklen_t bp_len, int type, int segments)
+{
+       struct ip6_rthdr *rth = (struct ip6_rthdr *)bp;
+       struct ip6_rthdr0 *rth0;
+
+       switch (type) {
+               case IPV6_RTHDR_TYPE_0:
+                       /* length validation */
+                       if (bp_len < inet6_rth_space(IPV6_RTHDR_TYPE_0, segments))
+                               return (NULL);
+                       /* segment validation */
+                       if ((segments < 0) || (segments > 127))
+                               return (NULL);
+
+                       memset(bp, 0, bp_len);
+                       rth0 = (struct ip6_rthdr0 *)rth;
+                       rth0->ip6r0_len = segments * 2;
+                       rth0->ip6r0_type = IPV6_RTHDR_TYPE_0;
+                       rth0->ip6r0_segleft = 0;
+                       rth0->ip6r0_reserved = 0;
+                       break;
+               default:
+                       return (NULL);  /* type not supported */
        }
        }
-       return &rt0->ip6r0_addr[index - 1];
-      }
 
 
-    default:
-#ifdef DEBUG
-       fprintf(stderr, "inet6_rthdr_getaddr: unknown type(%d)\n",
-           rthdr->ip6r_type);
-#endif 
-       return NULL;
-    }
+       return (bp);
 }
 
 int
 }
 
 int
-inet6_rthdr_getflags(cmsg, index)
-    const struct cmsghdr *cmsg;
-    int index;
+inet6_rth_add(void *bp, const struct in6_addr *addr)
 {
 {
-    register struct ip6_rthdr *rthdr;
+       struct ip6_rthdr *rth = (struct ip6_rthdr *)bp;
+       struct ip6_rthdr0 *rth0;
+       struct in6_addr *nextaddr;
+
+       switch (rth->ip6r_type) {
+               case IPV6_RTHDR_TYPE_0:
+                       rth0 = (struct ip6_rthdr0 *)rth;
+                       /* Don't exceed the number of stated segments */
+                       if (rth0->ip6r0_segleft == (rth0->ip6r0_len / 2))
+                               return (-1);
+                       nextaddr = (struct in6_addr *)(rth0 + 1) + rth0->ip6r0_segleft;
+                       *nextaddr = *addr;
+                       rth0->ip6r0_segleft++;
+                       break;
+               default:
+                       return (-1);    /* type not supported */
+       }
+
+       return (0);
+}
 
 
-    rthdr = (struct ip6_rthdr *)CMSG_DATA(cmsg);
+int
+inet6_rth_reverse(const void *in, void *out)
+{
+       struct ip6_rthdr *rth_in = (struct ip6_rthdr *)in;
+       struct ip6_rthdr0 *rth0_in, *rth0_out;
+       int i, segments;
+
+       switch (rth_in->ip6r_type) {
+               case IPV6_RTHDR_TYPE_0:
+                       rth0_in = (struct ip6_rthdr0 *)in;
+                       rth0_out = (struct ip6_rthdr0 *)out;
+
+                       /* parameter validation XXX too paranoid? */
+                       if (rth0_in->ip6r0_len % 2)
+                               return (-1);
+                       segments = rth0_in->ip6r0_len / 2;
+
+                       /* we can't use memcpy here, since in and out may overlap */
+                       memmove((void *)rth0_out, (void *)rth0_in,
+                                       ((rth0_in->ip6r0_len) + 1) << 3);
+                       rth0_out->ip6r0_segleft = segments;
+
+                       /* reverse the addresses */
+                       for (i = 0; i < segments / 2; i++) {
+                               struct in6_addr addr_tmp, *addr1, *addr2;
+
+                               addr1 = (struct in6_addr *)(rth0_out + 1) + i;
+                               addr2 = (struct in6_addr *)(rth0_out + 1) +
+                               (segments - i - 1);
+                               addr_tmp = *addr1;
+                               *addr1 = *addr2;
+                               *addr2 = addr_tmp;
+                       }
+
+                       break;
+               default:
+                       return (-1);    /* type not supported */
+       }
 
 
-    switch(rthdr->ip6r_type) {
-    case IPV6_RTHDR_TYPE_0:
-      {
-       struct ip6_rthdr0 *rt0 = (struct ip6_rthdr0 *)rthdr;
-       int naddr;
+       return (0);
+}
 
 
-       if (rt0->ip6r0_len % 2 || 46 < rt0->ip6r0_len) {
-#ifdef DEBUG
-           fprintf(stderr, "inet6_rthdr_getflags: invalid size(%d)\n",
-               rt0->ip6r0_len);
-#endif 
-           return -1;
+int
+inet6_rth_segments(const void *bp)
+{
+       struct ip6_rthdr *rh = (struct ip6_rthdr *)bp;
+       struct ip6_rthdr0 *rh0;
+       int addrs;
+
+       switch (rh->ip6r_type) {
+               case IPV6_RTHDR_TYPE_0:
+                       rh0 = (struct ip6_rthdr0 *)bp;
+
+                       /*
+                        * Validation for a type-0 routing header.
+                        * Is this too strict?
+                        */
+                       if ((rh0->ip6r0_len % 2) != 0 ||
+                               (addrs = (rh0->ip6r0_len >> 1)) < rh0->ip6r0_segleft)
+                               return (-1);
+
+                       return (addrs);
+               default:
+                       return (-1);    /* unknown type */
        }
        }
-       naddr = (rt0->ip6r0_len * 8) / sizeof(struct in6_addr);
-       if (index < 0 || naddr < index) {
-#ifdef DEBUG
-           fprintf(stderr, "inet6_rthdr_getflags: invalid index(%d)\n", index);
-#endif 
-           return -1;
+}
+
+struct in6_addr *
+inet6_rth_getaddr(const void *bp, int idx)
+{
+       struct ip6_rthdr *rh = (struct ip6_rthdr *)bp;
+       struct ip6_rthdr0 *rh0;
+       int addrs;
+
+       switch (rh->ip6r_type) {
+               case IPV6_RTHDR_TYPE_0:
+                       rh0 = (struct ip6_rthdr0 *)bp;
+
+                       /*
+                        * Validation for a type-0 routing header.
+                        * Is this too strict?
+                        */
+                       if ((rh0->ip6r0_len % 2) != 0 ||
+                               (addrs = (rh0->ip6r0_len >> 1)) < rh0->ip6r0_segleft)
+                               return (NULL);
+
+                       if (idx < 0 || addrs <= idx)
+                               return (NULL);
+
+                       return (((struct in6_addr *)(rh0 + 1)) + idx);
+               default:
+                       return (NULL);  /* unknown type */
+                       break;
        }
        }
-       if (rt0->ip6r0_slmap[index / 8] & (0x80 >> (index % 8)))
-           return IPV6_RTHDR_STRICT;
-       else
-           return IPV6_RTHDR_LOOSE;
-      }
-
-    default:
-#ifdef DEBUG
-       fprintf(stderr, "inet6_rthdr_getflags: unknown type(%d)\n",
-           rthdr->ip6r_type);
-#endif 
-       return -1;
-    }
 }
 }
diff --git a/lookup.subproj/Makefile b/lookup.subproj/Makefile
deleted file mode 100644 (file)
index f7b15bd..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-Project = lookup
-ProductType = staticlib
-Install_Dir = /scratch
-BuildDebug = YES
-BuildProfile = YES
-
-PRODUCT = $(shell tconf --product)
-
-HFILES = aliasdb.h bootparams.h ils.h kvbuf.h libinfo.h netdb.h netdb_async.h \
-       printerdb.h si_data.h si_module.h thread_data.h
-
-CFILES = cache_module.c file_module.c ils.c kvbuf.c libinfo.c\
-       mdns_module.c \
-         search_module.c si_data.c si_getaddrinfo.c si_module.c thread_data.c
-
-ifeq ($(PRODUCT),MacOSX)
-CFILES += ds_module.c
-USERDEFS = /usr/local/include/DSlibinfoMIG.defs
-SERVERDEFS = /usr/local/include/DSlibinfoMIGAsyncReply.defs
-endif
-
-MANPAGES = bootparams.5 gai_strerror.3 getaddrinfo.3 getfsent.3 getgrent.3 \
-       getgrouplist.3 getnameinfo.3 getnetgrent.3 getpwent.3 initgroups.3
-
-Install_Headers = aliasdb.h bootparams.h netdb.h printerdb.h
-Install_Private_Headers = ils.h kvbuf.h libinfo.h netdb_async.h si_data.h \
-       si_module.h thread_data.h
-
-Extra_CC_Flags = -Wall -Werror -fno-common -I. \
-       -I../gen.subproj \
-       -D__MigTypeCheck=1 -D__DARWIN_NON_CANCELABLE=1
-
-ifeq ($(PRODUCT),MacOSX)
-Extra_CC_Flags += -DCONFIG_MAC -DDS_AVAILABLE -DSYNTH_ROOTFS
-endif
-ifeq ($(PRODUCT),AppleTV)
-Extra_CC_Flags += -DCONFIG_APPLETV
-endif
-ifeq ($(PRODUCT),iPhone)
-Extra_CC_Flags += -DCONFIG_IPHONE
-endif
-
-include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
-
-after_install:
-       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getaddrinfo.3" \
-               "$(DSTROOT)/usr/share/man/man3/freeaddrinfo.3"
-       @for LINK in endfsent.3 getfsfile.3 getfsspec.3 getfstype.3 \
-               setfsent.3 ; do \
-               $(LN) -f "$(DSTROOT)/usr/share/man/man3/getfsent.3" \
-                       "$(DSTROOT)/usr/share/man/man3/$${LINK}" ; \
-       done
-       @for LINK in endgrent.3 getgrgid.3 getgrgid_r.3 getgrnam.3 \
-               getgrnam_r.3 setgrent.3 setgroupent.3 ; do \
-               $(LN) -f "$(DSTROOT)/usr/share/man/man3/getgrent.3" \
-                       "$(DSTROOT)/usr/share/man/man3/$${LINK}" ; \
-       done
-       @for LINK in endnetgrent.3 innetgr.3 setnetgrent.3 ; do \
-               $(LN) -f "$(DSTROOT)/usr/share/man/man3/getnetgrent.3" \
-                       "$(DSTROOT)/usr/share/man/man3/$${LINK}" ; \
-       done
-       @for LINK in endpwent.3 getpwnam.3 getpwnam_r.3 getpwuid.3 \
-               getpwuid_r.3 setpassent.3 setpwent.3 setpwfile.3 ; do \
-               $(LN) -f "$(DSTROOT)/usr/share/man/man3/getpwent.3" \
-                       "$(DSTROOT)/usr/share/man/man3/$${LINK}" ; \
-       done
index 3fa0071dbebc2fb2dd9c77db80ccb6e8bf6f09fe..6a55ee1eb34360234447270dc2f88a404165e162 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2008-2009 Apple Inc.  All rights reserved.
+ * Copyright (c) 2008-2010 Apple Inc.  All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -31,6 +31,7 @@
 #include <sys/stat.h>
 #include <ils.h>
 #include <libkern/OSAtomic.h>
 #include <sys/stat.h>
 #include <ils.h>
 #include <libkern/OSAtomic.h>
+#include <dispatch/dispatch.h>
 
 /* GLOBAL */
 uint32_t gL1CacheEnabled = 1;
 
 /* GLOBAL */
 uint32_t gL1CacheEnabled = 1;
@@ -153,61 +154,61 @@ cache_fetch_list(si_mod_t *si, int cat)
        return list;
 }
 
        return list;
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 cache_user_byname(si_mod_t *si, const char *name)
 {
        return cache_fetch_item(si, CATEGORY_USER, name, 0, SEL_NAME);
 }
 
 cache_user_byname(si_mod_t *si, const char *name)
 {
        return cache_fetch_item(si, CATEGORY_USER, name, 0, SEL_NAME);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 cache_user_byuid(si_mod_t *si, uid_t uid)
 {
        return cache_fetch_item(si, CATEGORY_USER, NULL, uid, SEL_NUMBER);
 }
 
 cache_user_byuid(si_mod_t *si, uid_t uid)
 {
        return cache_fetch_item(si, CATEGORY_USER, NULL, uid, SEL_NUMBER);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 cache_user_all(si_mod_t *si)
 {
        return cache_fetch_list(si, CATEGORY_USER);
 }
 
 cache_user_all(si_mod_t *si)
 {
        return cache_fetch_list(si, CATEGORY_USER);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 cache_group_byname(si_mod_t *si, const char *name)
 {
        return cache_fetch_item(si, CATEGORY_GROUP, name, 0, SEL_NAME);
 }
 
 cache_group_byname(si_mod_t *si, const char *name)
 {
        return cache_fetch_item(si, CATEGORY_GROUP, name, 0, SEL_NAME);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 cache_group_bygid(si_mod_t *si, gid_t gid)
 {
        return cache_fetch_item(si, CATEGORY_GROUP, NULL, gid, SEL_NUMBER);
 }
 
 cache_group_bygid(si_mod_t *si, gid_t gid)
 {
        return cache_fetch_item(si, CATEGORY_GROUP, NULL, gid, SEL_NUMBER);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 cache_group_all(si_mod_t *si)
 {
        return cache_fetch_list(si, CATEGORY_GROUP);
 }
 
 cache_group_all(si_mod_t *si)
 {
        return cache_fetch_list(si, CATEGORY_GROUP);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 cache_grouplist(si_mod_t *si, const char *name)
 {
        return cache_fetch_item(si, CATEGORY_GROUPLIST, name, 0, SEL_NAME);
 }
 
 cache_grouplist(si_mod_t *si, const char *name)
 {
        return cache_fetch_item(si, CATEGORY_GROUPLIST, name, 0, SEL_NAME);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 cache_alias_byname(si_mod_t *si, const char *name)
 {
        return cache_fetch_item(si, CATEGORY_ALIAS, name, 0, SEL_NAME);
 }
 
 cache_alias_byname(si_mod_t *si, const char *name)
 {
        return cache_fetch_item(si, CATEGORY_ALIAS, name, 0, SEL_NAME);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 cache_alias_all(si_mod_t *si)
 {
        return cache_fetch_list(si, CATEGORY_ALIAS);
 }
 
 cache_alias_all(si_mod_t *si)
 {
        return cache_fetch_list(si, CATEGORY_ALIAS);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 cache_host_byname(si_mod_t *si, const char *name, int af, const char *ignored, uint32_t *err)
 {
        si_item_t *item;
 cache_host_byname(si_mod_t *si, const char *name, int af, const char *ignored, uint32_t *err)
 {
        si_item_t *item;
@@ -223,7 +224,7 @@ cache_host_byname(si_mod_t *si, const char *name, int af, const char *ignored, u
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 cache_host_byaddr(si_mod_t *si, const void *addr, int af, const char *ignored, uint32_t *err)
 {
        si_item_t *item;
 cache_host_byaddr(si_mod_t *si, const void *addr, int af, const char *ignored, uint32_t *err)
 {
        si_item_t *item;
@@ -239,31 +240,31 @@ cache_host_byaddr(si_mod_t *si, const void *addr, int af, const char *ignored, u
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 cache_host_all(si_mod_t *si)
 {
        return cache_fetch_list(si, CATEGORY_HOST);
 }
 
 cache_host_all(si_mod_t *si)
 {
        return cache_fetch_list(si, CATEGORY_HOST);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 cache_network_byname(si_mod_t *si, const char *name)
 {
        return cache_fetch_item(si, CATEGORY_NETWORK, name, 0, SEL_NAME);
 }
 
 cache_network_byname(si_mod_t *si, const char *name)
 {
        return cache_fetch_item(si, CATEGORY_NETWORK, name, 0, SEL_NAME);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 cache_network_byaddr(si_mod_t *si, uint32_t addr)
 {
        return cache_fetch_item(si, CATEGORY_NETWORK, NULL, addr, SEL_NUMBER);
 }
 
 cache_network_byaddr(si_mod_t *si, uint32_t addr)
 {
        return cache_fetch_item(si, CATEGORY_NETWORK, NULL, addr, SEL_NUMBER);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 cache_network_all(si_mod_t *si)
 {
        return cache_fetch_list(si, CATEGORY_NETWORK);
 }
 
 cache_network_all(si_mod_t *si)
 {
        return cache_fetch_list(si, CATEGORY_NETWORK);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 cache_service_byname(si_mod_t *si, const char *name, const char *proto)
 {
        uint32_t pn;
 cache_service_byname(si_mod_t *si, const char *name, const char *proto)
 {
        uint32_t pn;
@@ -277,91 +278,91 @@ cache_service_byname(si_mod_t *si, const char *name, const char *proto)
        return cache_fetch_item(si, CATEGORY_SERVICE, name, pn, SEL_NAME);
 }
 
        return cache_fetch_item(si, CATEGORY_SERVICE, name, pn, SEL_NAME);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 cache_service_byport(si_mod_t *si, int port, const char *proto)
 {
        return cache_fetch_item(si, CATEGORY_SERVICE, proto, port, SEL_NUMBER);
 }
 
 cache_service_byport(si_mod_t *si, int port, const char *proto)
 {
        return cache_fetch_item(si, CATEGORY_SERVICE, proto, port, SEL_NUMBER);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 cache_service_all(si_mod_t *si)
 {
        return cache_fetch_list(si, CATEGORY_SERVICE);
 }
 
 cache_service_all(si_mod_t *si)
 {
        return cache_fetch_list(si, CATEGORY_SERVICE);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 cache_protocol_byname(si_mod_t *si, const char *name)
 {
        return cache_fetch_item(si, CATEGORY_PROTOCOL, name, 0, SEL_NAME);
 }
 
 cache_protocol_byname(si_mod_t *si, const char *name)
 {
        return cache_fetch_item(si, CATEGORY_PROTOCOL, name, 0, SEL_NAME);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 cache_protocol_bynumber(si_mod_t *si, int number)
 {
        return cache_fetch_item(si, CATEGORY_PROTOCOL, NULL, number, SEL_NUMBER);
 }
 
 cache_protocol_bynumber(si_mod_t *si, int number)
 {
        return cache_fetch_item(si, CATEGORY_PROTOCOL, NULL, number, SEL_NUMBER);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 cache_protocol_all(si_mod_t *si)
 {
        return cache_fetch_list(si, CATEGORY_PROTOCOL);
 }
 
 cache_protocol_all(si_mod_t *si)
 {
        return cache_fetch_list(si, CATEGORY_PROTOCOL);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 cache_rpc_byname(si_mod_t *si, const char *name)
 {
        return cache_fetch_item(si, CATEGORY_RPC, name, 0, SEL_NAME);
 }
 
 cache_rpc_byname(si_mod_t *si, const char *name)
 {
        return cache_fetch_item(si, CATEGORY_RPC, name, 0, SEL_NAME);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 cache_rpc_bynumber(si_mod_t *si, int number)
 {
        return cache_fetch_item(si, CATEGORY_RPC, NULL, number, SEL_NUMBER);
 }
 
 cache_rpc_bynumber(si_mod_t *si, int number)
 {
        return cache_fetch_item(si, CATEGORY_RPC, NULL, number, SEL_NUMBER);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 cache_rpc_all(si_mod_t *si)
 {
        return cache_fetch_list(si, CATEGORY_RPC);
 }
 
 cache_rpc_all(si_mod_t *si)
 {
        return cache_fetch_list(si, CATEGORY_RPC);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 cache_fs_byspec(si_mod_t *si, const char *name)
 {
        return cache_fetch_item(si, CATEGORY_FS, name, 0, SEL_NAME);
 }
 
 cache_fs_byspec(si_mod_t *si, const char *name)
 {
        return cache_fetch_item(si, CATEGORY_FS, name, 0, SEL_NAME);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 cache_fs_byfile(si_mod_t *si, const char *name)
 {
        return cache_fetch_item(si, CATEGORY_FS, name, 0, SEL_NUMBER);
 }
 
 cache_fs_byfile(si_mod_t *si, const char *name)
 {
        return cache_fetch_item(si, CATEGORY_FS, name, 0, SEL_NUMBER);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 cache_fs_all(si_mod_t *si)
 {
        return cache_fetch_list(si, CATEGORY_FS);
 }
 
 cache_fs_all(si_mod_t *si)
 {
        return cache_fetch_list(si, CATEGORY_FS);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 cache_mac_byname(si_mod_t *si, const char *name)
 {
        return cache_fetch_item(si, CATEGORY_MAC, name, 0, SEL_NAME);
 }
 
 cache_mac_byname(si_mod_t *si, const char *name)
 {
        return cache_fetch_item(si, CATEGORY_MAC, name, 0, SEL_NAME);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 cache_mac_bymac(si_mod_t *si, const char *mac)
 {
        return cache_fetch_item(si, CATEGORY_MAC, mac, 0, SEL_NUMBER);
 }
 
 cache_mac_bymac(si_mod_t *si, const char *mac)
 {
        return cache_fetch_item(si, CATEGORY_MAC, mac, 0, SEL_NUMBER);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 cache_mac_all(si_mod_t *si)
 {
        return cache_fetch_list(si, CATEGORY_MAC);
 }
 
 cache_mac_all(si_mod_t *si)
 {
        return cache_fetch_list(si, CATEGORY_MAC);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 cache_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *ignored, uint32_t *err)
 {
        /*
 cache_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *ignored, uint32_t *err)
 {
        /*
@@ -374,7 +375,7 @@ cache_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *i
        return NULL;
 }
 
        return NULL;
 }
 
-__private_extern__ void
+static void
 cache_close(si_mod_t *si)
 {
        cache_si_private_t *pp;
 cache_close(si_mod_t *si)
 {
        cache_si_private_t *pp;
@@ -396,92 +397,89 @@ cache_close(si_mod_t *si)
                }
        }
 
                }
        }
 
-       free(si->private);
+       free(pp);
 }
 
 }
 
-__private_extern__ si_mod_t *
-si_module_static_cache()
+si_mod_t *
+si_module_static_cache(void)
 {
 {
-       si_mod_t *out;
-       char *outname;
-       cache_si_private_t *pp;
-
-       out = (si_mod_t *)calloc(1, sizeof(si_mod_t));
-       outname = strdup("cache");
-       pp = (cache_si_private_t *)calloc(1, sizeof(cache_si_private_t));
-
-       if ((out == NULL) || (outname == NULL) || (pp == NULL))
+       static const struct si_mod_vtable_s cache_vtable =
        {
        {
-               if (out != NULL) free(out);
-               if (outname != NULL) free(outname);
-               if (pp != NULL) free(pp);
+               .sim_close = &cache_close,
 
 
-               errno = ENOMEM;
-               return NULL;
-       }
+               .sim_user_byname = &cache_user_byname,
+               .sim_user_byuid = &cache_user_byuid,
+               .sim_user_all = &cache_user_all,
 
 
-       out->name = outname;
-       out->vers = 1;
-       out->refcount = 1;
-       out->private = pp;
+               .sim_group_byname = &cache_group_byname,
+               .sim_group_bygid = &cache_group_bygid,
+               .sim_group_all = &cache_group_all,
 
 
-       out->sim_close = cache_close;
+               .sim_grouplist = &cache_grouplist,
 
 
-       out->sim_user_byname = cache_user_byname;
-       out->sim_user_byuid = cache_user_byuid;
-       out->sim_user_all = cache_user_all;
+               /* no netgroup support */
+               .sim_netgroup_byname = NULL,
+               .sim_in_netgroup = NULL,
 
 
-       out->sim_group_byname = cache_group_byname;
-       out->sim_group_bygid = cache_group_bygid;
-       out->sim_group_all = cache_group_all;
+               .sim_alias_byname = &cache_alias_byname,
+               .sim_alias_all = &cache_alias_all,
 
 
-       out->sim_grouplist = cache_grouplist;
+               .sim_host_byname = &cache_host_byname,
+               .sim_host_byaddr = &cache_host_byaddr,
+               .sim_host_all = &cache_host_all,
 
 
-       /* no netgroup support */
-       out->sim_netgroup_byname = NULL;
-       out->sim_in_netgroup = NULL;
+               .sim_network_byname = &cache_network_byname,
+               .sim_network_byaddr = &cache_network_byaddr,
+               .sim_network_all = &cache_network_all,
 
 
-       out->sim_alias_byname = cache_alias_byname;
-       out->sim_alias_all = cache_alias_all;
+               .sim_service_byname = &cache_service_byname,
+               .sim_service_byport = &cache_service_byport,
+               .sim_service_all = &cache_service_all,
 
 
-       out->sim_host_byname = cache_host_byname;
-       out->sim_host_byaddr = cache_host_byaddr;
-       out->sim_host_all = cache_host_all;
+               .sim_protocol_byname = &cache_protocol_byname,
+               .sim_protocol_bynumber = &cache_protocol_bynumber,
+               .sim_protocol_all = &cache_protocol_all,
 
 
-       out->sim_network_byname = cache_network_byname;
-       out->sim_network_byaddr = cache_network_byaddr;
-       out->sim_network_all = cache_network_all;
+               .sim_rpc_byname = &cache_rpc_byname,
+               .sim_rpc_bynumber = &cache_rpc_bynumber,
+               .sim_rpc_all = &cache_rpc_all,
 
 
-       out->sim_service_byname = cache_service_byname;
-       out->sim_service_byport = cache_service_byport;
-       out->sim_service_all = cache_service_all;
+               .sim_fs_byspec = &cache_fs_byspec,
+               .sim_fs_byfile = &cache_fs_byfile,
+               .sim_fs_all = &cache_fs_all,
 
 
-       out->sim_protocol_byname = cache_protocol_byname;
-       out->sim_protocol_bynumber = cache_protocol_bynumber;
-       out->sim_protocol_all = cache_protocol_all;
+               .sim_mac_byname = &cache_mac_byname,
+               .sim_mac_bymac = &cache_mac_bymac,
+               .sim_mac_all = &cache_mac_all,
 
 
-       out->sim_rpc_byname = cache_rpc_byname;
-       out->sim_rpc_bynumber = cache_rpc_bynumber;
-       out->sim_rpc_all = cache_rpc_all;
+               /* no addrinfo support */
+               .sim_wants_addrinfo = NULL,
+               .sim_addrinfo = NULL,
 
 
-       out->sim_fs_byspec = cache_fs_byspec;
-       out->sim_fs_byfile = cache_fs_byfile;
-       out->sim_fs_all = cache_fs_all;
+               .sim_nameinfo = &cache_nameinfo,
+       };
+
+       static si_mod_t si =
+       {
+               .vers = 1,
+               .refcount = 1,
+               .flags = SI_MOD_FLAG_STATIC,
 
 
-       out->sim_mac_byname = cache_mac_byname;
-       out->sim_mac_bymac = cache_mac_bymac;
-       out->sim_mac_all = cache_mac_all;
+               .private = NULL,
+               .vtable = &cache_vtable,
+       };
 
 
-       /* no addrinfo support */
-       out->sim_wants_addrinfo = NULL;
-       out->sim_addrinfo = NULL;
+       static dispatch_once_t once;
 
 
-       out->sim_nameinfo = cache_nameinfo;
+       dispatch_once(&once, ^{
+               si.name = strdup("cache");
+               si.private = calloc(1, sizeof(cache_si_private_t));
+       });
 
 
-       return out;
+       return &si;
 }
 
 }
 
-__private_extern__ void
+void
 si_cache_add_item(si_mod_t *si, si_mod_t *src, si_item_t *item)
 {
        cache_si_private_t *pp;
 si_cache_add_item(si_mod_t *si, si_mod_t *src, si_item_t *item)
 {
        cache_si_private_t *pp;
@@ -516,7 +514,7 @@ si_cache_add_item(si_mod_t *si, si_mod_t *src, si_item_t *item)
        OSSpinLockUnlock(&(pp->cache_store[cat].lock));
 }
 
        OSSpinLockUnlock(&(pp->cache_store[cat].lock));
 }
 
-__private_extern__ void
+void
 si_cache_add_list(si_mod_t *si, si_mod_t *src, si_list_t *list)
 {
        cache_si_private_t *pp;
 si_cache_add_list(si_mod_t *si, si_mod_t *src, si_list_t *list)
 {
        cache_si_private_t *pp;
index ac3af3dcce77ce518383e0a90e4368f6bb92526b..8d363601555e96f272f01634fbb2d60776fb63cf 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2008-2009 Apple Inc.  All rights reserved.
+ * Copyright (c) 2008-2010 Apple Inc.  All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
+#include <mach/mach.h>
+
+kern_return_t
+libinfoDSmig_do_Response_async(mach_port_t server, char *reply, mach_msg_type_number_t replyCnt, vm_offset_t ooreply, mach_msg_type_number_t ooreplyCnt, mach_vm_address_t callbackAddr, security_token_t servertoken)
+{
+       return KERN_SUCCESS;
+}
+
+#ifdef DS_AVAILABLE
+
 #include <stdio.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
 #include <time.h>
 #include <errno.h>
 #include <arpa/inet.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <string.h>
 #include <time.h>
 #include <errno.h>
 #include <arpa/inet.h>
 #include <sys/stat.h>
-#include <mach/mach.h>
 #include <ils.h>
 #include <ils.h>
-#include <kvbuf.h>
+#include "kvbuf.h"
 #include <pwd.h>
 #include <grp.h>
 #include <fstab.h>
 #include <netdb.h>
 #include <notify.h>
 #include <pwd.h>
 #include <grp.h>
 #include <fstab.h>
 #include <netdb.h>
 #include <notify.h>
+#include <notify_keys.h>
 #include <si_data.h>
 #include <si_module.h>
 #include <netdb_async.h>
 #include <net/if.h>
 #include <servers/bootstrap.h>
 #include <si_data.h>
 #include <si_module.h>
 #include <netdb_async.h>
 #include <net/if.h>
 #include <servers/bootstrap.h>
-#include <DSlibinfoMIG.h>
-#include <DSmemberdMIG.h>
+#include <bootstrap_priv.h>
+#include "DSlibinfoMIG.h"
+#include "DSmemberdMIG.h"
 #ifdef DEBUG
 #include <asl.h>
 #endif
 #ifdef DEBUG
 #include <asl.h>
 #endif
 /* ONLY TO BE USED BY getipv6nodebyaddr */
 #define WANT_A6_OR_MAPPED_A4_IF_NO_A6 5
 
 /* ONLY TO BE USED BY getipv6nodebyaddr */
 #define WANT_A6_OR_MAPPED_A4_IF_NO_A6 5
 
-#define DS_NOTIFICATION_KEY_GLOBAL  "com.apple.system.DirectoryService.InvalidateCache"
-#define DS_NOTIFICATION_KEY_USER    "com.apple.system.DirectoryService.InvalidateCache.user"
-#define DS_NOTIFICATION_KEY_GROUP   "com.apple.system.DirectoryService.InvalidateCache.group"
-#define DS_NOTIFICATION_KEY_HOST    "com.apple.system.DirectoryService.InvalidateCache.host"
-#define DS_NOTIFICATION_KEY_SERVICE "com.apple.system.DirectoryService.InvalidateCache.service"
-
 #define MAX_LOOKUP_ATTEMPTS 10
 
 #define INET_NTOP_AF_INET_OFFSET 4
 #define INET_NTOP_AF_INET6_OFFSET 8
 
 #define MAX_LOOKUP_ATTEMPTS 10
 
 #define INET_NTOP_AF_INET_OFFSET 4
 #define INET_NTOP_AF_INET6_OFFSET 8
 
-extern mach_port_t _ds_port;
-extern int _ds_running();
+mach_port_t _ds_port;
+mach_port_t _mbr_port;
+
 extern uint32_t gL1CacheEnabled;
 
 static pthread_key_t _ds_serv_cache_key = 0;
 
 static void
 extern uint32_t gL1CacheEnabled;
 
 static pthread_key_t _ds_serv_cache_key = 0;
 
 static void
-_ds_serv_cache_free(void *x)
+_ds_child(void)
 {
 {
-       if (x != NULL) si_item_release(x);
+       _ds_port = MACH_PORT_NULL;
+       _mbr_port = MACH_PORT_NULL;
 }
 
 }
 
-__private_extern__ kern_return_t
-libinfoDSmig_do_Response_async(mach_port_t server, char *reply, mach_msg_type_number_t replyCnt, vm_offset_t ooreply, mach_msg_type_number_t ooreplyCnt, mach_vm_address_t callbackAddr, security_token_t servertoken)
+static int _si_opendirectory_disabled;
+
+void
+_si_disable_opendirectory(void)
 {
 {
-       return KERN_SUCCESS;
+       _si_opendirectory_disabled = 1;
+       _ds_port = MACH_PORT_NULL;
+       _mbr_port = MACH_PORT_NULL;
 }
 
 }
 
-__private_extern__ kern_return_t
+int
+_ds_running(void)
+{
+       kern_return_t status;
+       char *od_debug_mode = NULL;
+       
+       if (_ds_port != MACH_PORT_NULL) return 1;
+       
+       if (_si_opendirectory_disabled) return 0;
+       pthread_atfork(NULL, NULL, _ds_child);
+       
+       if (!issetugid()) {
+               od_debug_mode = getenv("OD_DEBUG_MODE");
+       }
+       
+       if (od_debug_mode) {
+               status = bootstrap_look_up(bootstrap_port, kDSStdMachDSLookupPortName "_debug", &_ds_port);
+       } else {
+               status = bootstrap_look_up2(bootstrap_port, kDSStdMachDSLookupPortName, 
+                                                                       &_ds_port, 0, BOOTSTRAP_PRIVILEGED_SERVER);
+       }
+       if ((status != BOOTSTRAP_SUCCESS) && (status != BOOTSTRAP_UNKNOWN_SERVICE)) _ds_port = MACH_PORT_NULL;
+       
+       if (od_debug_mode) {
+               status = bootstrap_look_up(bootstrap_port, kDSStdMachDSMembershipPortName "_debug", &_mbr_port);
+       } else {
+               status = bootstrap_look_up2(bootstrap_port, kDSStdMachDSMembershipPortName, 
+                                                                       &_mbr_port, 0, BOOTSTRAP_PRIVILEGED_SERVER);
+       }
+       if ((status != BOOTSTRAP_SUCCESS) && (status != BOOTSTRAP_UNKNOWN_SERVICE)) _mbr_port = MACH_PORT_NULL;
+       
+       return (_ds_port != MACH_PORT_NULL);
+}
+
+static void
+_ds_serv_cache_free(void *x)
+{
+       if (x != NULL) si_item_release(x);
+}
+
+static kern_return_t
 LI_DSLookupGetProcedureNumber(const char *name, int32_t *procno)
 {
        kern_return_t status;
 LI_DSLookupGetProcedureNumber(const char *name, int32_t *procno)
 {
        kern_return_t status;
@@ -117,7 +169,7 @@ LI_DSLookupGetProcedureNumber(const char *name, int32_t *procno)
                if (status == MACH_SEND_INVALID_DEST)
                {
                        mach_port_mod_refs(mach_task_self(), _ds_port, MACH_PORT_RIGHT_SEND, -1);
                if (status == MACH_SEND_INVALID_DEST)
                {
                        mach_port_mod_refs(mach_task_self(), _ds_port, MACH_PORT_RIGHT_SEND, -1);
-                       status = bootstrap_look_up(bootstrap_port, kDSStdMachDSLookupPortName, &_ds_port);
+                       status = bootstrap_look_up2(bootstrap_port, kDSStdMachDSLookupPortName, &_ds_port, 0, BOOTSTRAP_PRIVILEGED_SERVER);
                        if ((status != BOOTSTRAP_SUCCESS) && (status != BOOTSTRAP_UNKNOWN_SERVICE)) _ds_port = MACH_PORT_NULL;
                        status = MIG_SERVER_DIED;
                }
                        if ((status != BOOTSTRAP_SUCCESS) && (status != BOOTSTRAP_UNKNOWN_SERVICE)) _ds_port = MACH_PORT_NULL;
                        status = MIG_SERVER_DIED;
                }
@@ -145,7 +197,7 @@ LI_DSLookupGetProcedureNumber(const char *name, int32_t *procno)
        return status;
 }
 
        return status;
 }
 
-__private_extern__ kern_return_t
+static kern_return_t
 LI_DSLookupQuery(int32_t procno, kvbuf_t *request, kvarray_t **reply)
 {
        kern_return_t status;
 LI_DSLookupQuery(int32_t procno, kvbuf_t *request, kvarray_t **reply)
 {
        kern_return_t status;
@@ -185,7 +237,7 @@ LI_DSLookupQuery(int32_t procno, kvbuf_t *request, kvarray_t **reply)
                if (status == MACH_SEND_INVALID_DEST)
                {
                        mach_port_mod_refs(mach_task_self(), _ds_port, MACH_PORT_RIGHT_SEND, -1);
                if (status == MACH_SEND_INVALID_DEST)
                {
                        mach_port_mod_refs(mach_task_self(), _ds_port, MACH_PORT_RIGHT_SEND, -1);
-                       status = bootstrap_look_up(bootstrap_port, kDSStdMachDSLookupPortName, &_ds_port);
+                       status = bootstrap_look_up2(bootstrap_port, kDSStdMachDSLookupPortName, &_ds_port, 0, BOOTSTRAP_PRIVILEGED_SERVER);
                        if ((status != BOOTSTRAP_SUCCESS) && (status != BOOTSTRAP_UNKNOWN_SERVICE)) _ds_port = MACH_PORT_NULL;
                        status = MIG_SERVER_DIED;
                }
                        if ((status != BOOTSTRAP_SUCCESS) && (status != BOOTSTRAP_UNKNOWN_SERVICE)) _ds_port = MACH_PORT_NULL;
                        status = MIG_SERVER_DIED;
                }
@@ -204,18 +256,18 @@ LI_DSLookupQuery(int32_t procno, kvbuf_t *request, kvarray_t **reply)
 #ifdef DEBUG
                asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "_DSLookupQuery %d auth failure uid=%d", procno, token.val[0]);
 #endif
 #ifdef DEBUG
                asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "_DSLookupQuery %d auth failure uid=%d", procno, token.val[0]);
 #endif
-               if (oolen > 0) vm_deallocate(mach_task_self(), (vm_address_t)oobuf, oolen);
+               if ((oolen > 0) && (oobuf != 0)) vm_deallocate(mach_task_self(), (vm_address_t)oobuf, oolen);
                return KERN_FAILURE;
        }
 
        out = (kvbuf_t *)calloc(1, sizeof(kvbuf_t));
        if (out == NULL)
        {
                return KERN_FAILURE;
        }
 
        out = (kvbuf_t *)calloc(1, sizeof(kvbuf_t));
        if (out == NULL)
        {
-               if (oolen > 0) vm_deallocate(mach_task_self(), (vm_address_t)oobuf, oolen);
+               if ((oolen > 0) && (oobuf != 0)) vm_deallocate(mach_task_self(), (vm_address_t)oobuf, oolen);
                return KERN_FAILURE;
        }
 
                return KERN_FAILURE;
        }
 
-       if (oolen > 0)
+       if ((oolen > 0) && (oobuf != 0))
        {
                out->datalen = oolen;
                out->databuf = malloc(oolen);
        {
                out->datalen = oolen;
                out->databuf = malloc(oolen);
@@ -1195,7 +1247,7 @@ extract_mac_mac(si_mod_t *si, kvarray_t *in, void *extra, uint64_t valid_global,
                if ((cmac == NULL) && (string_equal(in->dict[d].key[k], "mac")))
                {
                        if (in->dict[d].vcount[k] == 0) continue;
                if ((cmac == NULL) && (string_equal(in->dict[d].key[k], "mac")))
                {
                        if (in->dict[d].vcount[k] == 0) continue;
-                       cmac = si_canonical_mac_address(in->dict[d].val[k][0]);
+                       cmac = si_standardize_mac_address(in->dict[d].val[k][0]);
                        if (cmac == NULL) return NULL;
                }
        }
                        if (cmac == NULL) return NULL;
                }
        }
@@ -1241,7 +1293,7 @@ extract_mac_name(si_mod_t *si, kvarray_t *in, void *extra, uint64_t valid_global
        return out;
 }
 
        return out;
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 ds_user_byname(si_mod_t *si, const char *name)
 {
        static int proc = -1;
 ds_user_byname(si_mod_t *si, const char *name)
 {
        static int proc = -1;
@@ -1257,7 +1309,7 @@ ds_user_byname(si_mod_t *si, const char *name)
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 ds_user_byuid(si_mod_t *si, uid_t uid)
 {
        static int proc = -1;
 ds_user_byuid(si_mod_t *si, uid_t uid)
 {
        static int proc = -1;
@@ -1275,7 +1327,7 @@ ds_user_byuid(si_mod_t *si, uid_t uid)
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 ds_user_all(si_mod_t *si)
 {
        static int proc = -1;
 ds_user_all(si_mod_t *si)
 {
        static int proc = -1;
@@ -1283,7 +1335,7 @@ ds_user_all(si_mod_t *si)
        return ds_list(si, CATEGORY_USER, "getpwent", &proc, NULL, extract_user, NULL);
 }
 
        return ds_list(si, CATEGORY_USER, "getpwent", &proc, NULL, extract_user, NULL);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 ds_group_byname(si_mod_t *si, const char *name)
 {
        static int proc = -1;
 ds_group_byname(si_mod_t *si, const char *name)
 {
        static int proc = -1;
@@ -1299,7 +1351,7 @@ ds_group_byname(si_mod_t *si, const char *name)
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 ds_group_bygid(si_mod_t *si, gid_t gid)
 {
        static int proc = -1;
 ds_group_bygid(si_mod_t *si, gid_t gid)
 {
        static int proc = -1;
@@ -1317,7 +1369,7 @@ ds_group_bygid(si_mod_t *si, gid_t gid)
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 ds_group_all(si_mod_t *si)
 {
        static int proc = -1;
 ds_group_all(si_mod_t *si)
 {
        static int proc = -1;
@@ -1325,11 +1377,11 @@ ds_group_all(si_mod_t *si)
        return ds_list(si, CATEGORY_GROUP, "getgrent", &proc, NULL, extract_group, NULL);
 }
 
        return ds_list(si, CATEGORY_GROUP, "getgrent", &proc, NULL, extract_group, NULL);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 ds_grouplist(si_mod_t *si, const char *name)
 {
        struct passwd *pw;
 ds_grouplist(si_mod_t *si, const char *name)
 {
        struct passwd *pw;
-       kern_return_t kstatus;
+       kern_return_t kstatus, ks2;
        uint32_t i, j, count, uid, basegid, gidptrCnt;
        int32_t *gidp;
        gid_t *gidptr;
        uint32_t i, j, count, uid, basegid, gidptrCnt;
        int32_t *gidp;
        gid_t *gidptr;
@@ -1338,6 +1390,7 @@ ds_grouplist(si_mod_t *si, const char *name)
        char **gidlist;
        uint64_t va, vb;
        size_t gidptrsz;
        char **gidlist;
        uint64_t va, vb;
        size_t gidptrsz;
+       int n;
 
        if (name == NULL) return NULL;
 
 
        if (name == NULL) return NULL;
 
@@ -1356,10 +1409,32 @@ ds_grouplist(si_mod_t *si, const char *name)
        gidptrsz = 0;
        memset(&token, 0, sizeof(audit_token_t));
 
        gidptrsz = 0;
        memset(&token, 0, sizeof(audit_token_t));
 
-       kstatus = memberdDSmig_GetAllGroups(_ds_port, uid, &count, &gidptr, &gidptrCnt, &token);
+       if (_mbr_port == MACH_PORT_NULL)
+       {
+               kstatus = bootstrap_look_up2(bootstrap_port, kDSStdMachDSMembershipPortName, &_mbr_port, 0, BOOTSTRAP_PRIVILEGED_SERVER);
+       }
+
+       for (n = 0; n < MAX_LOOKUP_ATTEMPTS; n++)
+       {
+               kstatus = memberdDSmig_GetAllGroups(_mbr_port, uid, &count, &gidptr, &gidptrCnt, &token);
+               if (kstatus != MACH_SEND_INVALID_DEST) break;
+
+               mach_port_mod_refs(mach_task_self(), _mbr_port, MACH_PORT_RIGHT_SEND, -1);
+
+               ks2 = bootstrap_look_up2(bootstrap_port, kDSStdMachDSMembershipPortName, &_mbr_port, 0, BOOTSTRAP_PRIVILEGED_SERVER);
+               if ((ks2 != BOOTSTRAP_SUCCESS) && (ks2 != BOOTSTRAP_UNKNOWN_SERVICE))
+               {
+                       _mbr_port = MACH_PORT_NULL;
+                       break;
+               }
+       }
+
        if (kstatus != KERN_SUCCESS) return NULL;
        if (kstatus != KERN_SUCCESS) return NULL;
+       if (gidptr == NULL) return NULL;
 
 
-       gidptrsz = gidptrCnt * sizeof(gid_t);
+       /* gidptrCnt is the size, but it was set to number of groups (by DS) in 10.6 and earlier */
+       gidptrsz = gidptrCnt;
+       if (count == gidptrCnt) gidptrsz = gidptrCnt * sizeof(gid_t);
 
        if ((audit_token_uid(token) != 0) || (count == 0))
        {
 
        if ((audit_token_uid(token) != 0) || (count == 0))
        {
@@ -1409,7 +1484,7 @@ ds_grouplist(si_mod_t *si, const char *name)
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 ds_netgroup_byname(si_mod_t *si, const char *name)
 {
        static int proc = -1;
 ds_netgroup_byname(si_mod_t *si, const char *name)
 {
        static int proc = -1;
@@ -1450,7 +1525,7 @@ check_innetgr(kvarray_t *in)
        return 0;
 }
 
        return 0;
 }
 
-__private_extern__ int
+static int
 ds_in_netgroup(si_mod_t *si, const char *group, const char *host, const char *user, const char *domain)
 {
        int is_innetgr;
 ds_in_netgroup(si_mod_t *si, const char *group, const char *host, const char *user, const char *domain)
 {
        int is_innetgr;
@@ -1487,7 +1562,7 @@ ds_in_netgroup(si_mod_t *si, const char *group, const char *host, const char *us
        return is_innetgr;
 }
 
        return is_innetgr;
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 ds_alias_byname(si_mod_t *si, const char *name)
 {
        static int proc = -1;
 ds_alias_byname(si_mod_t *si, const char *name)
 {
        static int proc = -1;
@@ -1503,7 +1578,7 @@ ds_alias_byname(si_mod_t *si, const char *name)
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 ds_alias_all(si_mod_t *si)
 {
        static int proc = -1;
 ds_alias_all(si_mod_t *si)
 {
        static int proc = -1;
@@ -1511,7 +1586,7 @@ ds_alias_all(si_mod_t *si)
        return ds_list(si, CATEGORY_ALIAS, "alias_getent", &proc, NULL, extract_alias, NULL);
 }
 
        return ds_list(si, CATEGORY_ALIAS, "alias_getent", &proc, NULL, extract_alias, NULL);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 ds_host_byname(si_mod_t *si, const char *name, int af, const char *ignored, uint32_t *err)
 {
        static int proc = -1;
 ds_host_byname(si_mod_t *si, const char *name, int af, const char *ignored, uint32_t *err)
 {
        static int proc = -1;
@@ -1563,7 +1638,7 @@ ds_host_byname(si_mod_t *si, const char *name, int af, const char *ignored, uint
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 ds_host_byaddr(si_mod_t *si, const void *addr, int af, const char *ignored, uint32_t *err)
 {
        static int proc = -1;
 ds_host_byaddr(si_mod_t *si, const void *addr, int af, const char *ignored, uint32_t *err)
 {
        static int proc = -1;
@@ -1626,7 +1701,7 @@ ds_host_byaddr(si_mod_t *si, const void *addr, int af, const char *ignored, uint
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 ds_host_all(si_mod_t *si)
 {
        static int proc = -1;
 ds_host_all(si_mod_t *si)
 {
        static int proc = -1;
@@ -1634,7 +1709,7 @@ ds_host_all(si_mod_t *si)
        return ds_list(si, CATEGORY_HOST_IPV4, "gethostent", &proc, NULL, extract_host, NULL);
 }
 
        return ds_list(si, CATEGORY_HOST_IPV4, "gethostent", &proc, NULL, extract_host, NULL);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 ds_network_byname(si_mod_t *si, const char *name)
 {
        static int proc = -1;
 ds_network_byname(si_mod_t *si, const char *name)
 {
        static int proc = -1;
@@ -1650,7 +1725,7 @@ ds_network_byname(si_mod_t *si, const char *name)
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 ds_network_byaddr(si_mod_t *si, uint32_t addr)
 {
        static int proc = -1;
 ds_network_byaddr(si_mod_t *si, uint32_t addr)
 {
        static int proc = -1;
@@ -1678,7 +1753,7 @@ ds_network_byaddr(si_mod_t *si, uint32_t addr)
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 ds_network_all(si_mod_t *si)
 {
        static int proc = -1;
 ds_network_all(si_mod_t *si)
 {
        static int proc = -1;
@@ -1686,7 +1761,7 @@ ds_network_all(si_mod_t *si)
        return ds_list(si, CATEGORY_NETWORK, "getnetent", &proc, NULL, extract_network, NULL);
 }
 
        return ds_list(si, CATEGORY_NETWORK, "getnetent", &proc, NULL, extract_network, NULL);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 ds_service_byname(si_mod_t *si, const char *name, const char *proto)
 {
        static int proc = -1;
 ds_service_byname(si_mod_t *si, const char *name, const char *proto)
 {
        static int proc = -1;
@@ -1714,7 +1789,7 @@ ds_service_byname(si_mod_t *si, const char *name, const char *proto)
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 ds_service_byport(si_mod_t *si, int port, const char *proto)
 {
        static int proc = -1;
 ds_service_byport(si_mod_t *si, int port, const char *proto)
 {
        static int proc = -1;
@@ -1737,7 +1812,7 @@ ds_service_byport(si_mod_t *si, int port, const char *proto)
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 ds_service_all(si_mod_t *si)
 {
        static int proc = -1;
 ds_service_all(si_mod_t *si)
 {
        static int proc = -1;
@@ -1745,7 +1820,7 @@ ds_service_all(si_mod_t *si)
        return ds_list(si, CATEGORY_SERVICE, "getservent", &proc, NULL, extract_service, NULL);
 }
 
        return ds_list(si, CATEGORY_SERVICE, "getservent", &proc, NULL, extract_service, NULL);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 ds_protocol_byname(si_mod_t *si, const char *name)
 {
        static int proc = -1;
 ds_protocol_byname(si_mod_t *si, const char *name)
 {
        static int proc = -1;
@@ -1761,7 +1836,7 @@ ds_protocol_byname(si_mod_t *si, const char *name)
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 ds_protocol_bynumber(si_mod_t *si, int number)
 {
        static int proc = -1;
 ds_protocol_bynumber(si_mod_t *si, int number)
 {
        static int proc = -1;
@@ -1779,7 +1854,7 @@ ds_protocol_bynumber(si_mod_t *si, int number)
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 ds_protocol_all(si_mod_t *si)
 {
        static int proc = -1;
 ds_protocol_all(si_mod_t *si)
 {
        static int proc = -1;
@@ -1787,7 +1862,7 @@ ds_protocol_all(si_mod_t *si)
        return ds_list(si, CATEGORY_PROTOCOL, "getprotoent", &proc, NULL, extract_protocol, NULL);
 }
 
        return ds_list(si, CATEGORY_PROTOCOL, "getprotoent", &proc, NULL, extract_protocol, NULL);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 ds_rpc_byname(si_mod_t *si, const char *name)
 {
        static int proc = -1;
 ds_rpc_byname(si_mod_t *si, const char *name)
 {
        static int proc = -1;
@@ -1803,7 +1878,7 @@ ds_rpc_byname(si_mod_t *si, const char *name)
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 ds_rpc_bynumber(si_mod_t *si, int number)
 {
        static int proc = -1;
 ds_rpc_bynumber(si_mod_t *si, int number)
 {
        static int proc = -1;
@@ -1821,7 +1896,7 @@ ds_rpc_bynumber(si_mod_t *si, int number)
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 ds_rpc_all(si_mod_t *si)
 {
        static int proc = -1;
 ds_rpc_all(si_mod_t *si)
 {
        static int proc = -1;
@@ -1829,7 +1904,7 @@ ds_rpc_all(si_mod_t *si)
        return ds_list(si, CATEGORY_RPC, "getrpcent", &proc, NULL, extract_rpc, NULL);
 }
 
        return ds_list(si, CATEGORY_RPC, "getrpcent", &proc, NULL, extract_rpc, NULL);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 ds_fs_byspec(si_mod_t *si, const char *name)
 {
        static int proc = -1;
 ds_fs_byspec(si_mod_t *si, const char *name)
 {
        static int proc = -1;
@@ -1845,7 +1920,7 @@ ds_fs_byspec(si_mod_t *si, const char *name)
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 ds_fs_all(si_mod_t *si)
 {
        static int proc = -1;
 ds_fs_all(si_mod_t *si)
 {
        static int proc = -1;
@@ -1853,7 +1928,7 @@ ds_fs_all(si_mod_t *si)
        return ds_list(si, CATEGORY_FS, "getfsent", &proc, NULL, extract_fstab, NULL);
 }
 
        return ds_list(si, CATEGORY_FS, "getfsent", &proc, NULL, extract_fstab, NULL);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 ds_fs_byfile(si_mod_t *si, const char *name)
 {
        si_item_t *item;
 ds_fs_byfile(si_mod_t *si, const char *name)
 {
        si_item_t *item;
@@ -1877,7 +1952,7 @@ ds_fs_byfile(si_mod_t *si, const char *name)
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 ds_mac_byname(si_mod_t *si, const char *name)
 {
        static int proc = -1;
 ds_mac_byname(si_mod_t *si, const char *name)
 {
        static int proc = -1;
@@ -1893,7 +1968,7 @@ ds_mac_byname(si_mod_t *si, const char *name)
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 ds_mac_bymac(si_mod_t *si, const char *mac)
 {
        static int proc = -1;
 ds_mac_bymac(si_mod_t *si, const char *mac)
 {
        static int proc = -1;
@@ -1901,7 +1976,7 @@ ds_mac_bymac(si_mod_t *si, const char *mac)
        si_item_t *item;
        char *cmac;
 
        si_item_t *item;
        char *cmac;
 
-       cmac = si_canonical_mac_address(mac);
+       cmac = si_standardize_mac_address(mac);
        if (cmac == NULL) return NULL;
 
        request = kvbuf_query_key_val("mac", cmac);
        if (cmac == NULL) return NULL;
 
        request = kvbuf_query_key_val("mac", cmac);
@@ -1953,7 +2028,7 @@ ds_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, u
 
        if (node != NULL)
        {
 
        if (node != NULL)
        {
-               wantv4 = (family != AF_INET6);
+               wantv4 = ((family != AF_INET6) || (flags & AI_V4MAPPED));
                wantv6 = (family != AF_INET);
        }
 
                wantv6 = (family != AF_INET);
        }
 
@@ -2050,7 +2125,7 @@ ds_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, u
                                h_aliases_cnt = dict->vcount[k];
                                h_aliases = (const char **)calloc(h_aliases_cnt, sizeof(char *));
                                if (h_aliases == NULL) h_aliases_cnt = 0;
                                h_aliases_cnt = dict->vcount[k];
                                h_aliases = (const char **)calloc(h_aliases_cnt, sizeof(char *));
                                if (h_aliases == NULL) h_aliases_cnt = 0;
-                               
+
                                for (i = 0; i < h_aliases_cnt; ++i)
                                {
                                        h_aliases[i] = dict->val[k][i];
                                for (i = 0; i < h_aliases_cnt; ++i)
                                {
                                        h_aliases[i] = dict->val[k][i];
@@ -2073,7 +2148,7 @@ ds_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, u
                                a6_cnt = dict->vcount[k];
                                a6 = calloc(a6_cnt, sizeof(struct in6_addr));
                                if (a6 == NULL) a6_cnt = 0;
                                a6_cnt = dict->vcount[k];
                                a6 = calloc(a6_cnt, sizeof(struct in6_addr));
                                if (a6 == NULL) a6_cnt = 0;
-                               
+
                                for (i = 0; i < a6_cnt; ++i)
                                {
                                        memset(&a6[i], 0, sizeof(struct in6_addr));
                                for (i = 0; i < a6_cnt; ++i)
                                {
                                        memset(&a6[i], 0, sizeof(struct in6_addr));
@@ -2095,7 +2170,7 @@ ds_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, u
                                s_aliases_cnt = dict->vcount[k];
                                s_aliases = (const char **)calloc(s_aliases_cnt+1, sizeof(char *));
                                if (s_aliases == NULL) s_aliases_cnt = 0;
                                s_aliases_cnt = dict->vcount[k];
                                s_aliases = (const char **)calloc(s_aliases_cnt+1, sizeof(char *));
                                if (s_aliases == NULL) s_aliases_cnt = 0;
-                               
+
                                for (i = 0; i < s_aliases_cnt; ++i)
                                {
                                        s_aliases[i] = dict->val[k][i];
                                for (i = 0; i < s_aliases_cnt; ++i)
                                {
                                        s_aliases[i] = dict->val[k][i];
@@ -2115,7 +2190,7 @@ ds_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, u
        if (((wantv4 || wantv6) && (a4_cnt == 0) && (a6_cnt == 0)) || ((serv != NULL) && (s_port == 0)))
        {
                if (err != NULL) *err = SI_STATUS_EAI_NONAME;
        if (((wantv4 || wantv6) && (a4_cnt == 0) && (a6_cnt == 0)) || ((serv != NULL) && (s_port == 0)))
        {
                if (err != NULL) *err = SI_STATUS_EAI_NONAME;
-       
+
                free(h_name);
                free(h_aliases);
                free(s_aliases);
                free(h_name);
                free(h_aliases);
                free(s_aliases);
@@ -2157,14 +2232,14 @@ ds_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, u
        out = NULL;
        for (i = 0; i < a6_cnt; i++)
        {
        out = NULL;
        for (i = 0; i < a6_cnt; i++)
        {
-               list = si_addrinfo_list(si, socktype, proto, NULL, &a6[i], s_port, scope, NULL, h_name);
+               list = si_addrinfo_list(si, flags, socktype, proto, NULL, &a6[i], s_port, scope, NULL, h_name);
                out = si_list_concat(out, list);
                si_list_release(list);
        }
 
        for (i = 0; i < a4_cnt; i++)
        {
                out = si_list_concat(out, list);
                si_list_release(list);
        }
 
        for (i = 0; i < a4_cnt; i++)
        {
-               list = si_addrinfo_list(si, socktype, proto, &a4[i], NULL, s_port, 0, h_name, NULL);
+               list = si_addrinfo_list(si, flags, socktype, proto, &a4[i], NULL, s_port, 0, h_name, NULL);
                out = si_list_concat(out, list);
                si_list_release(list);
        }
                out = si_list_concat(out, list);
                si_list_release(list);
        }
@@ -2178,7 +2253,7 @@ ds_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, u
        return out;
 }
 
        return out;
 }
 
-__private_extern__ int
+static int
 ds_is_valid(si_mod_t *si, si_item_t *item)
 {
        si_mod_t *src;
 ds_is_valid(si_mod_t *si, si_item_t *item)
 {
        si_mod_t *src;
@@ -2225,108 +2300,110 @@ ds_is_valid(si_mod_t *si, si_item_t *item)
        return 1;
 }
 
        return 1;
 }
 
-__private_extern__ si_mod_t *
-si_module_static_ds()
+si_mod_t *
+si_module_static_ds(void)
 {
 {
-       si_mod_t *out;
-       char *outname;
-       ds_si_private_t *pp;
-       int status;
-
-       out = (si_mod_t *)calloc(1, sizeof(si_mod_t));
-       outname = strdup("ds");
-       pp = (ds_si_private_t *)calloc(1, sizeof(ds_si_private_t));
-
-       if ((out == NULL) || (outname == NULL) || (pp == NULL))
+       static const struct si_mod_vtable_s ds_vtable =
        {
        {
-               if (out != NULL) free(out);
-               if (outname != NULL) free(outname);
-               if (pp != NULL) free(pp);
+               .sim_is_valid = &ds_is_valid,
 
 
-               errno = ENOMEM;
-               return NULL;
-       }
+               .sim_user_byname = &ds_user_byname,
+               .sim_user_byuid = &ds_user_byuid,
+               .sim_user_all = &ds_user_all,
 
 
-       pthread_key_create(&_ds_serv_cache_key, _ds_serv_cache_free);
+               .sim_group_byname = &ds_group_byname,
+               .sim_group_bygid = &ds_group_bygid,
+               .sim_group_all = &ds_group_all,
 
 
-       pp->notify_token_global = -1;
-       pp->notify_token_user = -1;
-       pp->notify_token_group = -1;
-       pp->notify_token_host = -1;
-       pp->notify_token_service = -1;
+               .sim_grouplist = &ds_grouplist,
 
 
-       /*
-        * Don't register for notifications if the cache is disabled.
-        * notifyd (notably) disables the cache to prevent deadlocks.
-        */
-       if (gL1CacheEnabled != 0)
-       {
-               /*
-                * Errors in registering for cache invalidation notifications are ignored.
-                * If there are failures, the tokens remain set to -1 which just causes 
-                * cached items to be invalidated. 
-                */
-               status = notify_register_check(DS_NOTIFICATION_KEY_GLOBAL, &(pp->notify_token_global));
-               status = notify_register_check(DS_NOTIFICATION_KEY_GLOBAL, &(pp->notify_token_user));
-               status = notify_register_check(DS_NOTIFICATION_KEY_GLOBAL, &(pp->notify_token_group));
-               status = notify_register_check(DS_NOTIFICATION_KEY_GLOBAL, &(pp->notify_token_host));
-               status = notify_register_check(DS_NOTIFICATION_KEY_GLOBAL, &(pp->notify_token_service));
-       }
+               .sim_netgroup_byname = &ds_netgroup_byname,
+               .sim_in_netgroup = &ds_in_netgroup,
 
 
-       out->name = outname;
-       out->vers = 1;
-       out->refcount = 1;
-       out->private = pp;
+               .sim_alias_byname = &ds_alias_byname,
+               .sim_alias_all = &ds_alias_all,
 
 
-       out->sim_is_valid = ds_is_valid;
+               .sim_host_byname = &ds_host_byname,
+               .sim_host_byaddr = &ds_host_byaddr,
+               .sim_host_all = &ds_host_all,
 
 
-       out->sim_user_byname = ds_user_byname;
-       out->sim_user_byuid = ds_user_byuid;
-       out->sim_user_all = ds_user_all;
+               .sim_network_byname = &ds_network_byname,
+               .sim_network_byaddr = &ds_network_byaddr,
+               .sim_network_all = &ds_network_all,
 
 
-       out->sim_group_byname = ds_group_byname;
-       out->sim_group_bygid = ds_group_bygid;
-       out->sim_group_all = ds_group_all;
+               .sim_service_byname = &ds_service_byname,
+               .sim_service_byport = &ds_service_byport,
+               .sim_service_all = &ds_service_all,
 
 
-       out->sim_grouplist = ds_grouplist;
+               .sim_protocol_byname = &ds_protocol_byname,
+               .sim_protocol_bynumber = &ds_protocol_bynumber,
+               .sim_protocol_all = &ds_protocol_all,
 
 
-       out->sim_netgroup_byname = ds_netgroup_byname;
-       out->sim_in_netgroup = ds_in_netgroup;
+               .sim_rpc_byname = &ds_rpc_byname,
+               .sim_rpc_bynumber = &ds_rpc_bynumber,
+               .sim_rpc_all = &ds_rpc_all,
 
 
-       out->sim_alias_byname = ds_alias_byname;
-       out->sim_alias_all = ds_alias_all;
+               .sim_fs_byspec = &ds_fs_byspec,
+               .sim_fs_byfile = &ds_fs_byfile,
+               .sim_fs_all = &ds_fs_all,
 
 
-       out->sim_host_byname = ds_host_byname;
-       out->sim_host_byaddr = ds_host_byaddr;
-       out->sim_host_all = ds_host_all;
+               .sim_mac_byname = &ds_mac_byname,
+               .sim_mac_bymac = &ds_mac_bymac,
 
 
-       out->sim_network_byname = ds_network_byname;
-       out->sim_network_byaddr = ds_network_byaddr;
-       out->sim_network_all = ds_network_all;
+               /* si_mac_all not supported */
+               .sim_mac_all = NULL,
 
 
-       out->sim_service_byname = ds_service_byname;
-       out->sim_service_byport = ds_service_byport;
-       out->sim_service_all = ds_service_all;
+               .sim_addrinfo = &ds_addrinfo,
+       };
 
 
-       out->sim_protocol_byname = ds_protocol_byname;
-       out->sim_protocol_bynumber = ds_protocol_bynumber;
-       out->sim_protocol_all = ds_protocol_all;
+       static si_mod_t si =
+       {
+               .vers = 1,
+               .refcount = 1,
+               .flags = SI_MOD_FLAG_STATIC,
 
 
-       out->sim_rpc_byname = ds_rpc_byname;
-       out->sim_rpc_bynumber = ds_rpc_bynumber;
-       out->sim_rpc_all = ds_rpc_all;
+               .private = NULL,
+               .vtable = &ds_vtable,
+       };
 
 
-       out->sim_fs_byspec = ds_fs_byspec;
-       out->sim_fs_byfile = ds_fs_byfile;
-       out->sim_fs_all = ds_fs_all;
+       static dispatch_once_t once;
+       dispatch_once(&once, ^{
+               pthread_key_create(&_ds_serv_cache_key, _ds_serv_cache_free);
 
 
-       out->sim_mac_byname = ds_mac_byname;
-       out->sim_mac_bymac = ds_mac_bymac;
+               si.name = strdup("ds");
+               ds_si_private_t *pp = calloc(1, sizeof(ds_si_private_t));
 
 
-       /* si_mac_all not supported */
-       out->sim_mac_all = NULL;
+               if (pp != NULL)
+               {
+                       pp->notify_token_global = -1;
+                       pp->notify_token_user = -1;
+                       pp->notify_token_group = -1;
+                       pp->notify_token_host = -1;
+                       pp->notify_token_service = -1;
+               }
 
 
-       out->sim_addrinfo = ds_addrinfo;
+               /*
+                * Don't register for notifications if the cache is disabled.
+                * notifyd (notably) disables the cache to prevent deadlocks.
+                */
+               if (gL1CacheEnabled != 0)
+               {
+                       /*
+                        * Errors in registering for cache invalidation notifications are ignored.
+                        * If there are failures, the tokens remain set to -1 which just causes 
+                        * cached items to be invalidated.
+                        */
+                       notify_register_check(kNotifyDSCacheInvalidation, &(pp->notify_token_global));
+                       notify_register_check(kNotifyDSCacheInvalidationUser, &(pp->notify_token_user));
+                       notify_register_check(kNotifyDSCacheInvalidationGroup, &(pp->notify_token_group));
+                       notify_register_check(kNotifyDSCacheInvalidationHost, &(pp->notify_token_host));
+                       notify_register_check(kNotifyDSCacheInvalidationService, &(pp->notify_token_service));
+               }
 
 
-       return out;
+               si.private = pp;
+       });
+
+       return &si;
 }
 }
+
+#endif /* DS_AVAILABLE */
index 28e38eb14a74a588d196d18683eac92d3013b62a..7db0b896bac9ebbb03a6bc0ce933e16dee9c1b24 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2008-2009 Apple Inc.  All rights reserved.
+ * Copyright (c) 2008-2011 Apple Inc.  All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include <time.h>
 #include <dirent.h>
 #include <errno.h>
 #include <time.h>
 #include <dirent.h>
 #include <errno.h>
+#include <notify.h>
 #include <arpa/inet.h>
 #include <sys/param.h>
 #include <sys/mount.h>
 #include <sys/stat.h>
 #include <ils.h>
 #include <arpa/inet.h>
 #include <sys/param.h>
 #include <sys/mount.h>
 #include <sys/stat.h>
 #include <ils.h>
+#include <dispatch/dispatch.h>
+
+/* notify SPI */
+uint32_t notify_peek(int token, uint32_t *val);
+
+extern uint32_t gL1CacheEnabled;
 
 /* These really should be in netdb.h & etc. */
 #define _PATH_RPCS "/etc/rpc"
 #define _PATH_ALIASES "/etc/aliases"
 #define _PATH_ETHERS "/etc/ethers"
 
 /* These really should be in netdb.h & etc. */
 #define _PATH_RPCS "/etc/rpc"
 #define _PATH_ALIASES "/etc/aliases"
 #define _PATH_ETHERS "/etc/ethers"
+#define _PATH_NETGROUP "/etc/netgroup"
 
 
+static dispatch_once_t rootfs_once;
 static si_item_t *rootfs = NULL;
 
 static si_item_t *rootfs = NULL;
 
+#define CHUNK 256
+#define FNG_MEM 0x00000010
+#define FNG_GRP 0x00000020
+
+#define forever for(;;)
+
+#define VALIDATION_PASSWD 0
+#define VALIDATION_MASTER_PASSWD 1
+#define VALIDATION_GROUP 2
+#define VALIDATION_NETGROUP 3
+#define VALIDATION_ALIASES 4
+#define VALIDATION_HOSTS 5
+#define VALIDATION_NETWORKS 6
+#define VALIDATION_SERVICES 7
+#define VALIDATION_PROTOCOLS 8
+#define VALIDATION_RPC 9
+#define VALIDATION_FSTAB 10
+#define VALIDATION_ETHERS 11
+#define VALIDATION_COUNT 12
+
+#define VALIDATION_MASK_PASSWD                 0x00000001
+#define VALIDATION_MASK_MASTER_PASSWD  0x00000002
+#define VALIDATION_MASK_MASK_GROUP             0x00000004
+#define VALIDATION_MASK_NETGROUP                               0x00000008
+#define VALIDATION_MASK_ALIASES                        0x00000010
+#define VALIDATION_MASK_HOSTS                  0x00000020
+#define VALIDATION_MASK_NETWORKS               0x00000040
+#define VALIDATION_MASK_SERVICES               0x00000080
+#define VALIDATION_MASK_PROTOCOLS              0x00000100
+#define VALIDATION_MASK_RPC                            0x00000200
+#define VALIDATION_MASK_FSTAB                  0x00000400
+#define VALIDATION_MASK_ETHERS                 0x00000800
+
+typedef struct file_netgroup_member_s
+{
+       uint32_t flags;
+       char *host;
+       char *user;
+       char *domain;
+       struct file_netgroup_member_s *next;
+} file_netgroup_member_t;
+
+typedef struct file_netgroup_s
+{
+       char *name;
+       uint32_t flags;
+       file_netgroup_member_t *members;
+       struct file_netgroup_s *next;
+} file_netgroup_t;
+
+typedef struct
+{
+       uint32_t validation_notify_mask;
+       int notify_token[VALIDATION_COUNT];
+       file_netgroup_t *file_netgroup_cache;
+       uint64_t netgroup_validation_a;
+       uint64_t netgroup_validation_b;
+} file_si_private_t;
+
+static pthread_mutex_t file_mutex = PTHREAD_MUTEX_INITIALIZER;
+
 static char *
 _fsi_copy_string(char *s)
 {
 static char *
 _fsi_copy_string(char *s)
 {
@@ -80,7 +150,7 @@ _fsi_append_string(char *s, char **l)
        return l;
 }
 
        return l;
 }
 
-__private_extern__ char **
+char **
 _fsi_tokenize(char *data, const char *sep, int trailing_empty, int *ntokens)
 {
        char **tokens;
 _fsi_tokenize(char *data, const char *sep, int trailing_empty, int *ntokens)
 {
        char **tokens;
@@ -161,7 +231,7 @@ _fsi_tokenize(char *data, const char *sep, int trailing_empty, int *ntokens)
        return tokens;
 }
 
        return tokens;
 }
 
-__private_extern__ char *
+char *
 _fsi_get_line(FILE *fp)
 {
        char s[4096];
 _fsi_get_line(FILE *fp)
 {
        char s[4096];
@@ -178,14 +248,526 @@ _fsi_get_line(FILE *fp)
        return out;
 }
 
        return out;
 }
 
+static const char *
+_fsi_validation_path(int vtype)
+{
+       if (vtype == VALIDATION_PASSWD) return _PATH_PASSWD;
+       else if (vtype == VALIDATION_MASTER_PASSWD) return _PATH_MASTERPASSWD;
+       else if (vtype == VALIDATION_GROUP) return _PATH_GROUP;
+       else if (vtype == VALIDATION_NETGROUP) return _PATH_NETGROUP;
+       else if (vtype == VALIDATION_ALIASES) return _PATH_ALIASES;
+       else if (vtype == VALIDATION_HOSTS) return _PATH_HOSTS;
+       else if (vtype == VALIDATION_NETWORKS) return _PATH_NETWORKS;
+       else if (vtype == VALIDATION_SERVICES) return _PATH_SERVICES;
+       else if (vtype == VALIDATION_PROTOCOLS) return _PATH_PROTOCOLS;
+       else if (vtype == VALIDATION_RPC) return _PATH_RPCS;
+       else if (vtype == VALIDATION_FSTAB) return _PATH_FSTAB;
+       else if (vtype == VALIDATION_ETHERS) return _PATH_ETHERS;
+
+       return NULL;
+}
+
+static void
+_fsi_get_validation(si_mod_t *si, int vtype, const char *path, FILE *f, uint64_t *a, uint64_t *b)
+{
+       struct stat sb;
+       file_si_private_t *pp;
+       uint32_t peek, bit;
+       int status;
+
+       if (a != NULL) *a = 0;
+       if (b != NULL) *a = 0;
+
+       if (si == NULL) return;
+       if (path == NULL) return;
+       if (gL1CacheEnabled == 0) return;
+
+       pp = (file_si_private_t *)si->private;
+       if (pp == NULL) return;
+
+       if (vtype >= VALIDATION_COUNT) return;
+
+       bit = 1 << vtype;
+       if (bit & pp->validation_notify_mask)
+       {
+               /* use notify validation for this type */
+               if (pp->notify_token[vtype] < 0)
+               {
+                       char *str = NULL;
+                       asprintf(&str, "com.apple.system.info:%s", path);
+                       if (str == NULL) return;
+
+                       status = notify_register_check(str, &(pp->notify_token[vtype]));
+                       free(str);
+               }
+
+               if (a != NULL)
+               {
+                       status = notify_peek(pp->notify_token[vtype], &peek);
+                       if (status == NOTIFY_STATUS_OK) *a = ntohl(peek);
+               }
+
+               if (b != NULL) *b = vtype;
+       }
+       else
+       {
+               /* use stat() and last mod time for this type */
+               memset(&sb, 0, sizeof(struct stat));
+               if (f != NULL)
+               {
+                       if (fstat(fileno(f), &sb) == 0)
+                       {
+                               if (a != NULL) *a = sb.st_mtimespec.tv_sec;
+                               if (b != NULL) *b = sb.st_mtimespec.tv_nsec;
+                       }
+               }
+               else
+               {
+                       path = _fsi_validation_path(vtype);
+                       if (path != NULL)
+                       {
+                               memset(&sb, 0, sizeof(struct stat));
+                               if (stat(path, &sb) == 0)
+                               {
+                                       if (a != NULL) *a = sb.st_mtimespec.tv_sec;
+                                       if (b != NULL) *b = sb.st_mtimespec.tv_nsec;
+                               }
+                       }
+               }
+       }
+}
+
+static int
+_fsi_validate(si_mod_t *si, int cat, uint64_t va, uint64_t vb)
+{
+       struct stat sb;
+       const char *path;
+       uint32_t item_val, curr_val, vtype;
+       file_si_private_t *pp;
+       int status;
+
+       if (si == NULL) return 0;
+
+       pp = (file_si_private_t *)si->private;
+       if (pp == NULL) return 0;
+
+       vtype = UINT32_MAX;
+       switch (cat)
+       {
+               case CATEGORY_USER:
+               {
+                       if (geteuid() == 0) vtype = VALIDATION_MASTER_PASSWD;
+                       else vtype = VALIDATION_PASSWD;
+                       break;
+               }
+               case CATEGORY_GROUP:
+               {
+                       vtype = VALIDATION_GROUP;
+                       break;
+               }
+               case CATEGORY_GROUPLIST:
+               {
+                       vtype = VALIDATION_GROUP;
+                       break;
+               }
+               case CATEGORY_NETGROUP:
+               {
+                       vtype = VALIDATION_NETGROUP;
+                       break;
+               }
+               case CATEGORY_ALIAS:
+               {
+                       vtype = VALIDATION_ALIASES;
+                       break;
+               }
+               case CATEGORY_HOST_IPV4:
+               {
+                       vtype = VALIDATION_HOSTS;
+                       break;
+               }
+               case CATEGORY_HOST_IPV6:
+               {
+                       vtype = VALIDATION_HOSTS;
+                       break;
+               }
+               case CATEGORY_NETWORK:
+               {
+                       vtype = VALIDATION_NETWORKS;
+                       break;
+               }
+               case CATEGORY_SERVICE:
+               {
+                       vtype = VALIDATION_SERVICES;
+                       break;
+               }
+               case CATEGORY_PROTOCOL:
+               {
+                       vtype = VALIDATION_PROTOCOLS;
+                       break;
+               }
+               case CATEGORY_RPC:
+               {
+                       vtype = VALIDATION_RPC;
+                       break;
+               }
+               case CATEGORY_FS:
+               {
+                       vtype = VALIDATION_FSTAB;
+                       break;
+               }
+               case CATEGORY_MAC:
+               {
+                       vtype = VALIDATION_ETHERS;
+                       break;
+               }
+               default: return 0;
+       }
+
+       if (pp->notify_token[vtype] < 0)
+       {
+               path = _fsi_validation_path(vtype);
+               if (path == NULL) return 0;
+
+               memset(&sb, 0, sizeof(struct stat));
+               if (stat(path, &sb) != 0) return 0;
+               if (va != sb.st_mtimespec.tv_sec) return 0;
+               if (vb != sb.st_mtimespec.tv_nsec) return 0;
+       }
+       else
+       {
+               item_val = va;
+               curr_val = -1;
+               status = notify_peek(pp->notify_token[vtype], &curr_val);
+               if (status != NOTIFY_STATUS_OK) return 0;
+
+               curr_val = ntohl(curr_val);
+               if (item_val != curr_val) return 0;
+       }
+
+       return 1;
+}
+
+/* netgroup support */
+static char *
+_fsi_append_char_to_line(char c, char *buf, size_t *x)
+{
+       if (x == NULL) return NULL;
+
+       if (buf == NULL) *x = 0;
+
+       if ((*x % CHUNK) == 0)
+       {
+               buf = reallocf(buf, *x + CHUNK);
+               memset(buf + *x, 0, CHUNK);
+       }
+
+       buf[*x] = c;
+       *x = *x + 1;
+
+       return buf;
+}
+
+static char *
+_fsi_read_netgroup_line(FILE *f)
+{
+       char *out = NULL;
+       size_t x = 0;
+       int white = 0;
+       int paren = 0;
+
+       if (f == NULL) return NULL;
+       forever
+       {
+               int c = getc(f);
+
+               if (c == EOF)
+               {
+                       if (out == NULL) return NULL;
+                       return _fsi_append_char_to_line('\0', out, &x);
+               }
+
+               if (c == '\n') return _fsi_append_char_to_line('\0', out, &x);
+               if (c == '(') paren = 1;
+               else if (c == ')') paren = 0;
+
+               if ((c == ' ') || (c == '\t'))
+               {
+                       if ((white == 0) && (paren == 0)) out = _fsi_append_char_to_line(' ', out, &x);
+                       white = 1;
+               }
+               else if (c == '\\')
+               {
+                       forever
+                       {
+                               c = getc(f);
+                               if (c == EOF) return _fsi_append_char_to_line('\0', out, &x);
+                               if (c == '\n') break;
+                       }
+               }
+               else
+               {
+                       out = _fsi_append_char_to_line(c, out, &x);
+                       white = 0;
+               }
+       }
+}
+
+static file_netgroup_t *
+_fsi_find_netgroup(file_netgroup_t **list, const char *name, int create)
+{
+       file_netgroup_t *n;
+
+       if (list == NULL) return NULL;
+
+       for (n = *list; n != NULL; n = n->next)
+       {
+               if (!strcmp(name, n->name)) return n;
+       }
+
+       if (create == 0) return NULL;
+
+       n = (file_netgroup_t *)calloc(1, sizeof(file_netgroup_t));
+       if (n == NULL) return NULL;
+
+       n->name = strdup(name);
+
+       n->next = *list;
+       *list = n;
+       return n;
+}
+
+void
+_fsi_free_file_netgroup(file_netgroup_t *n)
+{
+       file_netgroup_member_t *m;
+
+       if (n == NULL) return;
+       free(n->name);
+
+       m = n->members;
+       while (m != NULL)
+       {
+               file_netgroup_member_t *x = m;
+               m = m->next;
+               free(x->host);
+               free(x->user);
+               free(x->domain);
+               free(x);
+       }
+
+       free(n);
+}
+
+static void
+_fsi_add_netgroup_group(file_netgroup_t *n, char *grp)
+{
+       file_netgroup_member_t *g;
+
+       if (n == NULL) return;
+
+       g = (file_netgroup_member_t *)calloc(1, sizeof(file_netgroup_member_t));
+       if (g == NULL) return;
+
+       g->flags = FNG_GRP;
+       g->host = strdup(grp);
+
+       g->next = n->members;
+       n->members = g;
+
+       return;
+}
+
+static void
+_fsi_add_netgroup_member(file_netgroup_t *n, char *mem)
+{
+       char **tokens;
+       file_netgroup_member_t *m;
+       int ntokens;
+
+       if (n == NULL) return;
+
+       m = (file_netgroup_member_t *)calloc(1, sizeof(file_netgroup_member_t));
+       if (m == NULL) return;
+
+       tokens = _fsi_tokenize(mem + 1, ",)", 0, &ntokens);
+
+       if (tokens == NULL)
+       {
+               free(m);
+               return;
+       }
+
+       if ((ntokens > 0) && (tokens[0][0] != '\0')) m->host = strdup(tokens[0]);
+       if ((ntokens > 1) && (tokens[1][0] != '\0')) m->user = strdup(tokens[1]);
+       if ((ntokens > 2) && (tokens[2][0] != '\0')) m->domain = strdup(tokens[2]);
+
+       free(tokens);
+
+       m->flags = FNG_MEM;
+       m->next = n->members;
+       n->members = m;
+}
+
+static file_netgroup_t *
+_fsi_process_netgroup_line(file_netgroup_t **pass1, char *line)
+{
+       file_netgroup_t *n;
+       char **tokens;
+       int i, ntokens = 0;
+
+       tokens = _fsi_tokenize(line, " ", 0, &ntokens);
+       if (tokens == NULL) return NULL;
+       if (tokens[0] == NULL)
+       {
+               free(tokens);
+               return NULL;
+       }
+
+       n = _fsi_find_netgroup(pass1, tokens[0], 1);
+
+       for (i = 1; tokens[i] != NULL; i++)
+       {
+               if (tokens[i][0] == '(') _fsi_add_netgroup_member(n, tokens[i]);
+               else if (tokens[i][0] != '\0') _fsi_add_netgroup_group(n, tokens[i]);
+       }
+
+       free(tokens);
+       return n;
+}
+
+static void
+_fsi_flatten_netgroup(file_netgroup_t *pass1, file_netgroup_t **top, file_netgroup_t *n, file_netgroup_member_t *m)
+{
+       if (n == NULL) return;
+
+       if (n->flags == 1) return;
+       n->flags = 1;
+
+       if (*top == NULL)
+       {
+               *top = (file_netgroup_t *)calloc(1, sizeof(file_netgroup_t));
+               if (*top == NULL) return;
+               (*top)->name = strdup(n->name);
+               if ((*top)->name == NULL)
+               {
+                       free(*top);
+                       *top = NULL;
+                       return;
+               }
+       }
+
+       while (m!= NULL)
+       {
+               if (m->flags & FNG_MEM)
+               {
+                       file_netgroup_member_t *x = (file_netgroup_member_t *)calloc(1, sizeof(file_netgroup_member_t));
+                       if (x == NULL) return;
+
+                       x->flags = FNG_MEM;
+                       if (m->host != NULL) x->host = strdup(m->host);
+                       if (m->user != NULL) x->user = strdup(m->user);
+                       if (m->domain != NULL) x->domain = strdup(m->domain);
+
+                       x->next = (*top)->members;
+                       (*top)->members = x;
+               }
+               else
+               {
+                       file_netgroup_t *g = _fsi_find_netgroup(&pass1, m->host, 0);
+                       if (g == NULL) continue;
+
+                       _fsi_flatten_netgroup(pass1, top, g, g->members);
+               }
+
+               m = m->next;
+       }
+}
+
+static void
+_fsi_check_netgroup_cache(si_mod_t *si)
+{
+       file_netgroup_t *p1, *n, *x, *a;
+       char *line;
+       FILE *f;
+       file_si_private_t *pp;
+
+       if (si == NULL) return;
+
+       pp = (file_si_private_t *)si->private;
+       if (pp == NULL) return;
+
+       pthread_mutex_lock(&file_mutex);
+
+       if (_fsi_validate(si, CATEGORY_NETGROUP, pp->netgroup_validation_a, pp->netgroup_validation_b))
+       {
+               pthread_mutex_unlock(&file_mutex);
+               return;
+       }
+
+       n = pp->file_netgroup_cache;
+       while (n != NULL)
+       {
+               x = n;
+               n = n->next;
+               _fsi_free_file_netgroup(x);
+       }
+
+       pp->file_netgroup_cache = NULL;
+
+       f = fopen(_PATH_NETGROUP, "r");
+       if (f == NULL)
+       {
+               pthread_mutex_unlock(&file_mutex);
+               return;
+       }
+
+       _fsi_get_validation(si, VALIDATION_NETGROUP, _PATH_NETGROUP, f, &(pp->netgroup_validation_a), &(pp->netgroup_validation_b));
+
+       p1 = NULL;
+
+       line = _fsi_read_netgroup_line(f);
+       while (line != NULL)
+       {
+               n = _fsi_process_netgroup_line(&p1, line);
+
+               free(line);
+               line = _fsi_read_netgroup_line(f);
+       }
+
+       fclose(f);
+
+       for (n = p1; n != NULL; n = n->next)
+       {
+               a = NULL;
+               _fsi_flatten_netgroup(p1, &a, n, n->members);
+               for (x = p1; x != NULL; x = x->next) x->flags = 0;
+
+               if (a != NULL)
+               {
+                       a->next = pp->file_netgroup_cache;
+                       pp->file_netgroup_cache = a;
+               }
+       }
+
+       n = p1;
+       while (n != NULL)
+       {
+               x = n;
+               n = n->next;
+               _fsi_free_file_netgroup(x);
+       }
+
+       pthread_mutex_unlock(&file_mutex);
+}
+
 /* USERS */
 
 static si_item_t *
 /* USERS */
 
 static si_item_t *
-_fsi_parse_user(si_mod_t *si, const char *name, uid_t uid, int which, char *data, int format, uint64_t sec, uint64_t nsec)
+_fsi_parse_user(si_mod_t *si, const char *name, uid_t uid, int which, char *data, int format, uint64_t va, uint64_t vb)
 {
        char **tokens;
        int ntokens, match;
 {
        char **tokens;
        int ntokens, match;
-       time_t change, exsire;
+       time_t change, expire;
        si_item_t *item;
        uid_t xuid;
 
        si_item_t *item;
        uid_t xuid;
 
@@ -215,17 +797,17 @@ _fsi_parse_user(si_mod_t *si, const char *name, uid_t uid, int which, char *data
 
        if (format == 0)
        {
 
        if (format == 0)
        {
-               /* master.passwd: name[0] passwd[1] uid[2] gid[3] class[4] change[5] exsire[6] gecos[7] dir[8] shell[9] */
-               /* struct pwd: name[0] passwd[1] uid[2] gid[3] change[5] class[4] gecos[7] dir[8] shell[9] exsire[6] */
+               /* master.passwd: name[0] passwd[1] uid[2] gid[3] class[4] change[5] expire[6] gecos[7] dir[8] shell[9] */
+               /* struct pwd: name[0] passwd[1] uid[2] gid[3] change[5] class[4] gecos[7] dir[8] shell[9] expire[6] */
                change = atoi(tokens[5]);
                change = atoi(tokens[5]);
-               exsire = atoi(tokens[6]);
-               item = (si_item_t *)LI_ils_create("L4488ss44LssssL", (unsigned long)si, CATEGORY_USER, 1, sec, nsec, tokens[0], tokens[1], xuid, atoi(tokens[3]), change, tokens[4], tokens[7], tokens[8], tokens[9], exsire);
+               expire = atoi(tokens[6]);
+               item = (si_item_t *)LI_ils_create("L4488ss44LssssL", (unsigned long)si, CATEGORY_USER, 1, va, vb, tokens[0], tokens[1], xuid, atoi(tokens[3]), change, tokens[4], tokens[7], tokens[8], tokens[9], expire);
        }
        else
        {
                /* passwd: name[0] passwd[1] uid[2] gid[3] gecos[4] dir[5] shell[6] */
        }
        else
        {
                /* passwd: name[0] passwd[1] uid[2] gid[3] gecos[4] dir[5] shell[6] */
-               /* struct pwd: name[0] passwd[1] uid[2] gid[3] change[-] class[-] gecos[4] dir[5] shell[6] exsire[-] */
-               item = (si_item_t *)LI_ils_create("L4488ss44LssssL", (unsigned long)si, CATEGORY_USER, 1, sec, nsec, tokens[0], tokens[1], xuid, atoi(tokens[3]), 0, "", tokens[4], tokens[5], tokens[6], 0);
+               /* struct pwd: name[0] passwd[1] uid[2] gid[3] change[-] class[-] gecos[4] dir[5] shell[6] expire[-] */
+               item = (si_item_t *)LI_ils_create("L4488ss44LssssL", (unsigned long)si, CATEGORY_USER, 1, va, vb, tokens[0], tokens[1], xuid, atoi(tokens[3]), 0, "", tokens[4], tokens[5], tokens[6], 0);
        }
 
        free(tokens); 
        }
 
        free(tokens); 
@@ -240,35 +822,30 @@ _fsi_get_user(si_mod_t *si, const char *name, uid_t uid, int which)
        int fmt;
        FILE *f;
        si_list_t *all;
        int fmt;
        FILE *f;
        si_list_t *all;
-       struct stat sb;
-       uint64_t sec, nsec;
+       uint64_t va, vb;
 
        if ((which == SEL_NAME) && (name == NULL)) return NULL;
 
        all = NULL;
        f = NULL;
        fmt = 0;
 
        if ((which == SEL_NAME) && (name == NULL)) return NULL;
 
        all = NULL;
        f = NULL;
        fmt = 0;
-       sec = 0;
-       nsec = 0;
+       va = 0;
+       vb = 0;
 
        if (geteuid() == 0)
        {
                f = fopen(_PATH_MASTERPASSWD, "r");
 
        if (geteuid() == 0)
        {
                f = fopen(_PATH_MASTERPASSWD, "r");
+               _fsi_get_validation(si, VALIDATION_MASTER_PASSWD, _PATH_MASTERPASSWD, f, &va, &vb);
        }
        else
        {
                f = fopen(_PATH_PASSWD, "r");
        }
        else
        {
                f = fopen(_PATH_PASSWD, "r");
+               _fsi_get_validation(si, VALIDATION_PASSWD, _PATH_PASSWD, f, &va, &vb);
                fmt = 1;
        }
 
        if (f == NULL) return NULL;
 
                fmt = 1;
        }
 
        if (f == NULL) return NULL;
 
-       memset(&sb, 0, sizeof(struct stat));
-       if (fstat(fileno(f), &sb) == 0)
-       {
-               sec = sb.st_mtimespec.tv_sec;
-               nsec = sb.st_mtimespec.tv_nsec;
-       }
 
        forever
        {
 
        forever
        {
@@ -282,7 +859,7 @@ _fsi_get_user(si_mod_t *si, const char *name, uid_t uid, int which)
                        continue;
                }
 
                        continue;
                }
 
-               item = _fsi_parse_user(si, name, uid, which, line, fmt, sec, nsec);
+               item = _fsi_parse_user(si, name, uid, which, line, fmt, va, vb);
                free(line);
                line = NULL;
 
                free(line);
                line = NULL;
 
@@ -305,7 +882,7 @@ _fsi_get_user(si_mod_t *si, const char *name, uid_t uid, int which)
 /* GROUPS */
 
 static si_item_t *
 /* GROUPS */
 
 static si_item_t *
-_fsi_parse_group(si_mod_t *si, const char *name, gid_t gid, int which, char *data, uint64_t sec, uint64_t nsec)
+_fsi_parse_group(si_mod_t *si, const char *name, gid_t gid, int which, char *data, uint64_t va, uint64_t vb)
 {
        char **tokens, **members;
        int ntokens, match;
 {
        char **tokens, **members;
        int ntokens, match;
@@ -338,7 +915,7 @@ _fsi_parse_group(si_mod_t *si, const char *name, gid_t gid, int which, char *dat
        ntokens = 0;
        members = _fsi_tokenize(tokens[3], ",", 1, &ntokens);
 
        ntokens = 0;
        members = _fsi_tokenize(tokens[3], ",", 1, &ntokens);
 
-       item = (si_item_t *)LI_ils_create("L4488ss4*", (unsigned long)si, CATEGORY_GROUP, 1, sec, nsec, tokens[0], tokens[1], xgid, members);
+       item = (si_item_t *)LI_ils_create("L4488ss4*", (unsigned long)si, CATEGORY_GROUP, 1, va, vb, tokens[0], tokens[1], xgid, members);
 
        free(tokens); 
        free(members);
 
        free(tokens); 
        free(members);
@@ -353,25 +930,17 @@ _fsi_get_group(si_mod_t *si, const char *name, gid_t gid, int which)
        si_item_t *item;
        FILE *f;
        si_list_t *all;
        si_item_t *item;
        FILE *f;
        si_list_t *all;
-       struct stat sb;
-       uint64_t sec, nsec;
+       uint64_t va, vb;
 
        if ((which == SEL_NAME) && (name == NULL)) return NULL;
 
        all = NULL;
        f = NULL;
 
        if ((which == SEL_NAME) && (name == NULL)) return NULL;
 
        all = NULL;
        f = NULL;
-       sec = 0;
-       nsec = 0;
 
        f = fopen(_PATH_GROUP, "r");
        if (f == NULL) return NULL;
 
 
        f = fopen(_PATH_GROUP, "r");
        if (f == NULL) return NULL;
 
-       memset(&sb, 0, sizeof(struct stat));
-       if (fstat(fileno(f), &sb) == 0)
-       {
-               sec = sb.st_mtimespec.tv_sec;
-               nsec = sb.st_mtimespec.tv_nsec;
-       }
+       _fsi_get_validation(si, VALIDATION_GROUP, _PATH_GROUP, f, &va, &vb);
 
        forever
        {
 
        forever
        {
@@ -385,7 +954,7 @@ _fsi_get_group(si_mod_t *si, const char *name, gid_t gid, int which)
                        continue;
                }
 
                        continue;
                }
 
-               item = _fsi_parse_group(si, name, gid, which, line, sec, nsec);
+               item = _fsi_parse_group(si, name, gid, which, line, va, vb);
                free(line);
                line = NULL;
 
                free(line);
                line = NULL;
 
@@ -414,8 +983,7 @@ _fsi_get_grouplist(si_mod_t *si, const char *user)
        char *line;
        si_item_t *item;
        FILE *f;
        char *line;
        si_item_t *item;
        FILE *f;
-       struct stat sb;
-       uint64_t sec, nsec;
+       uint64_t va, vb;
        int32_t gid, basegid, *gidp;
        char **gidlist;
        struct passwd *pw;
        int32_t gid, basegid, *gidp;
        char **gidlist;
        struct passwd *pw;
@@ -425,11 +993,9 @@ _fsi_get_grouplist(si_mod_t *si, const char *user)
        gidlist = NULL;
        gidcount = 0;
        f = NULL;
        gidlist = NULL;
        gidcount = 0;
        f = NULL;
-       sec = 0;
-       nsec = 0;
        basegid = -1;
 
        basegid = -1;
 
-       item = si->sim_user_byname(si, user);
+       item = si->vtable->sim_user_byname(si, user);
        if (item != NULL)
        {
                pw = (struct passwd *)((uintptr_t)item + sizeof(si_item_t));
        if (item != NULL)
        {
                pw = (struct passwd *)((uintptr_t)item + sizeof(si_item_t));
@@ -440,12 +1006,7 @@ _fsi_get_grouplist(si_mod_t *si, const char *user)
        f = fopen(_PATH_GROUP, "r");
        if (f == NULL) return NULL;
 
        f = fopen(_PATH_GROUP, "r");
        if (f == NULL) return NULL;
 
-       memset(&sb, 0, sizeof(struct stat));
-       if (fstat(fileno(f), &sb) == 0)
-       {
-               sec = sb.st_mtimespec.tv_sec;
-               nsec = sb.st_mtimespec.tv_nsec;
-       }
+       _fsi_get_validation(si, VALIDATION_GROUP, _PATH_GROUP, f, &va, &vb);
 
        forever
        {
 
        forever
        {
@@ -520,7 +1081,7 @@ _fsi_get_grouplist(si_mod_t *si, const char *user)
        if (gidlist == NULL) return NULL;
        gidlist[gidcount] = NULL;
 
        if (gidlist == NULL) return NULL;
        gidlist[gidcount] = NULL;
 
-       item = (si_item_t *)LI_ils_create("L4488s44a", (unsigned long)si, CATEGORY_GROUPLIST, 1, sec, nsec, user, basegid, gidcount, gidlist);
+       item = (si_item_t *)LI_ils_create("L4488s44a", (unsigned long)si, CATEGORY_GROUPLIST, 1, va, vb, user, basegid, gidcount, gidlist);
 
        for (i = 0; i <= gidcount; i++) free(gidlist[i]);
        free(gidlist);
 
        for (i = 0; i <= gidcount; i++) free(gidlist[i]);
        free(gidlist);
@@ -531,7 +1092,7 @@ _fsi_get_grouplist(si_mod_t *si, const char *user)
 /* ALIASES */
 
 static si_item_t *
 /* ALIASES */
 
 static si_item_t *
-_fsi_parse_alias(si_mod_t *si, const char *name, int which, char *data, uint64_t sec, uint64_t nsec)
+_fsi_parse_alias(si_mod_t *si, const char *name, int which, char *data, uint64_t va, uint64_t vb)
 {
        char **tokens, **members;
        int ntokens, match;
 {
        char **tokens, **members;
        int ntokens, match;
@@ -559,9 +1120,9 @@ _fsi_parse_alias(si_mod_t *si, const char *name, int which, char *data, uint64_t
        }
 
        ntokens = 0;
        }
 
        ntokens = 0;
-       members = _fsi_tokenize(tokens[3], ",", 1, &ntokens);
+       members = _fsi_tokenize(tokens[1], ",", 1, &ntokens);
 
 
-       item = (si_item_t *)LI_ils_create("L4488s4*4", (unsigned long)si, CATEGORY_ALIAS, 1, sec, nsec, tokens[0], ntokens, members, 1);
+       item = (si_item_t *)LI_ils_create("L4488s4*4", (unsigned long)si, CATEGORY_ALIAS, 1, va, vb, tokens[0], ntokens, members, 1);
 
        free(tokens); 
        free(members);
 
        free(tokens); 
        free(members);
@@ -576,25 +1137,17 @@ _fsi_get_alias(si_mod_t *si, const char *name, int which)
        si_item_t *item;
        FILE *f;
        si_list_t *all;
        si_item_t *item;
        FILE *f;
        si_list_t *all;
-       struct stat sb;
-       uint64_t sec, nsec;
+       uint64_t va, vb;
 
        if ((which == SEL_NAME) && (name == NULL)) return NULL;
 
        all = NULL;
        f = NULL;
 
        if ((which == SEL_NAME) && (name == NULL)) return NULL;
 
        all = NULL;
        f = NULL;
-       sec = 0;
-       nsec = 0;
 
        f = fopen(_PATH_ALIASES, "r");
        if (f == NULL) return NULL;
 
 
        f = fopen(_PATH_ALIASES, "r");
        if (f == NULL) return NULL;
 
-       memset(&sb, 0, sizeof(struct stat));
-       if (fstat(fileno(f), &sb) == 0)
-       {
-               sec = sb.st_mtimespec.tv_sec;
-               nsec = sb.st_mtimespec.tv_nsec;
-       }
+       _fsi_get_validation(si, VALIDATION_ALIASES, _PATH_ALIASES, f, &va, &vb);
 
        forever
        {
 
        forever
        {
@@ -608,7 +1161,7 @@ _fsi_get_alias(si_mod_t *si, const char *name, int which)
                        continue;
                }
 
                        continue;
                }
 
-               item = _fsi_parse_alias(si, name, which, line, sec, nsec);
+               item = _fsi_parse_alias(si, name, which, line, va, vb);
                free(line);
                line = NULL;
 
                free(line);
                line = NULL;
 
@@ -632,7 +1185,7 @@ _fsi_get_alias(si_mod_t *si, const char *name, int which)
 /* ETHERS */
 
 static si_item_t *
 /* ETHERS */
 
 static si_item_t *
-_fsi_parse_ether(si_mod_t *si, const char *name, int which, char *data, uint64_t sec, uint64_t nsec)
+_fsi_parse_ether(si_mod_t *si, const char *name, int which, char *data, uint64_t va, uint64_t vb)
 {
        char **tokens;
        char *cmac;
 {
        char **tokens;
        char *cmac;
@@ -649,7 +1202,7 @@ _fsi_parse_ether(si_mod_t *si, const char *name, int which, char *data, uint64_t
                return NULL;
        }
 
                return NULL;
        }
 
-       cmac = si_canonical_mac_address(tokens[1]);
+       cmac = si_standardize_mac_address(tokens[0]);
        if (cmac == NULL)
        {
                free(tokens);
        if (cmac == NULL)
        {
                free(tokens);
@@ -658,7 +1211,7 @@ _fsi_parse_ether(si_mod_t *si, const char *name, int which, char *data, uint64_t
 
        match = 0;
        if (which == SEL_ALL) match = 1;
 
        match = 0;
        if (which == SEL_ALL) match = 1;
-       else if ((which == SEL_NAME) && (string_equal(name, tokens[0]))) match = 1;
+       else if ((which == SEL_NAME) && (string_equal(name, tokens[1]))) match = 1;
        else if ((which == SEL_NUMBER) && (string_equal(name, cmac))) match = 1;
 
        if (match == 0)
        else if ((which == SEL_NUMBER) && (string_equal(name, cmac))) match = 1;
 
        if (match == 0)
@@ -668,7 +1221,7 @@ _fsi_parse_ether(si_mod_t *si, const char *name, int which, char *data, uint64_t
                return NULL;
        }
 
                return NULL;
        }
 
-       item = (si_item_t *)LI_ils_create("L4488ss", (unsigned long)si, CATEGORY_MAC, 1, sec, nsec, tokens[0], cmac);
+       item = (si_item_t *)LI_ils_create("L4488ss", (unsigned long)si, CATEGORY_MAC, 1, va, vb, tokens[1], cmac);
 
        free(tokens); 
        free(cmac);
 
        free(tokens); 
        free(cmac);
@@ -683,32 +1236,24 @@ _fsi_get_ether(si_mod_t *si, const char *name, int which)
        si_item_t *item;
        FILE *f;
        si_list_t *all;
        si_item_t *item;
        FILE *f;
        si_list_t *all;
-       struct stat sb;
-       uint64_t sec, nsec;
+       uint64_t va, vb;
 
        if ((which != SEL_ALL) && (name == NULL)) return NULL;
 
        cmac = NULL;
        if (which == SEL_NUMBER)
        {
 
        if ((which != SEL_ALL) && (name == NULL)) return NULL;
 
        cmac = NULL;
        if (which == SEL_NUMBER)
        {
-               cmac = si_canonical_mac_address(name);
+               cmac = si_standardize_mac_address(name);
                if (cmac == NULL) return NULL;
        }
 
        all = NULL;
        f = NULL;
                if (cmac == NULL) return NULL;
        }
 
        all = NULL;
        f = NULL;
-       sec = 0;
-       nsec = 0;
 
        f = fopen(_PATH_ETHERS, "r");
        if (f == NULL) return NULL;
 
 
        f = fopen(_PATH_ETHERS, "r");
        if (f == NULL) return NULL;
 
-       memset(&sb, 0, sizeof(struct stat));
-       if (fstat(fileno(f), &sb) == 0)
-       {
-               sec = sb.st_mtimespec.tv_sec;
-               nsec = sb.st_mtimespec.tv_nsec;
-       }
+       _fsi_get_validation(si, VALIDATION_ETHERS, _PATH_ETHERS, f, &va, &vb);
 
        forever
        {
 
        forever
        {
@@ -723,8 +1268,8 @@ _fsi_get_ether(si_mod_t *si, const char *name, int which)
                }
 
                item = NULL;
                }
 
                item = NULL;
-               if (which == SEL_NUMBER) item = _fsi_parse_ether(si, cmac, which, line, sec, nsec);
-               else item = _fsi_parse_ether(si, name, which, line, sec, nsec);
+               if (which == SEL_NUMBER) item = _fsi_parse_ether(si, cmac, which, line, va, vb);
+               else item = _fsi_parse_ether(si, name, which, line, va, vb);
 
                free(line);
                line = NULL;
 
                free(line);
                line = NULL;
@@ -749,10 +1294,10 @@ _fsi_get_ether(si_mod_t *si, const char *name, int which)
 /* HOSTS */
 
 static si_item_t *
 /* HOSTS */
 
 static si_item_t *
-_fsi_parse_host(si_mod_t *si, const char *name, const void *addr, int af, int which, char *data, uint64_t sec, uint64_t nsec)
+_fsi_parse_host(si_mod_t *si, const char *name, const void *addr, int af, int which, char *data, uint64_t va, uint64_t vb)
 {
        char **tokens, **h_aliases, *null_alias;
 {
        char **tokens, **h_aliases, *null_alias;
-       int i, ntokens, match, xaf, h_length;
+       int i, ntokens, match, h_addrtype, h_length;
        struct in_addr a4;
        struct in6_addr a6;
        si_item_t *item;
        struct in_addr a4;
        struct in6_addr a6;
        si_item_t *item;
@@ -773,23 +1318,23 @@ _fsi_parse_host(si_mod_t *si, const char *name, const void *addr, int af, int wh
 
        h_addr_list[1] = NULL;
 
 
        h_addr_list[1] = NULL;
 
-       xaf = AF_UNSPEC;
+       h_addrtype = AF_UNSPEC;
        if (inet_pton(AF_INET, tokens[0], &a4) == 1)
        {
        if (inet_pton(AF_INET, tokens[0], &a4) == 1)
        {
-               xaf = AF_INET;
+               h_addrtype = AF_INET;
                h_length = sizeof(struct in_addr);
                memcpy(h_addr_4, &a4, 4);
                h_addr_list[0] = h_addr_4;
        }
        else if (inet_pton(AF_INET6, tokens[0], &a6) == 1)
        {
                h_length = sizeof(struct in_addr);
                memcpy(h_addr_4, &a4, 4);
                h_addr_list[0] = h_addr_4;
        }
        else if (inet_pton(AF_INET6, tokens[0], &a6) == 1)
        {
-               xaf = AF_INET6;
+               h_addrtype = AF_INET6;
                h_length = sizeof(struct in6_addr);
                memcpy(h_addr_6, &a6, 16);
                h_addr_list[0] = h_addr_6;
        }
 
                h_length = sizeof(struct in6_addr);
                memcpy(h_addr_6, &a6, 16);
                h_addr_list[0] = h_addr_6;
        }
 
-       if (xaf == AF_UNSPEC)
+       if (h_addrtype == AF_UNSPEC)
        {
                free(tokens);
                return NULL;
        {
                free(tokens);
                return NULL;
@@ -803,7 +1348,7 @@ _fsi_parse_host(si_mod_t *si, const char *name, const void *addr, int af, int wh
        if (which == SEL_ALL) match = 1;
        else
        {
        if (which == SEL_ALL) match = 1;
        else
        {
-               if (af == xaf)
+               if (h_addrtype == af)
                {
                        if (which == SEL_NAME)
                        {
                {
                        if (which == SEL_NAME)
                        {
@@ -831,13 +1376,13 @@ _fsi_parse_host(si_mod_t *si, const char *name, const void *addr, int af, int wh
 
        if (h_aliases == NULL) h_aliases = &null_alias;
 
 
        if (h_aliases == NULL) h_aliases = &null_alias;
 
-       if (af == AF_INET)
+       if (h_addrtype == AF_INET)
        {
        {
-               item = (si_item_t *)LI_ils_create("L4488s*44a", (unsigned long)si, CATEGORY_HOST_IPV4, 1, sec, nsec, tokens[1], h_aliases, af, h_length, h_addr_list);
+               item = (si_item_t *)LI_ils_create("L4488s*44a", (unsigned long)si, CATEGORY_HOST_IPV4, 1, va, vb, tokens[1], h_aliases, h_addrtype, h_length, h_addr_list);
        }
        else
        {
        }
        else
        {
-               item = (si_item_t *)LI_ils_create("L4488s*44c", (unsigned long)si, CATEGORY_HOST_IPV6, 1, sec, nsec, tokens[1], h_aliases, af, h_length, h_addr_list);
+               item = (si_item_t *)LI_ils_create("L4488s*44c", (unsigned long)si, CATEGORY_HOST_IPV6, 1, va, vb, tokens[1], h_aliases, h_addrtype, h_length, h_addr_list);
        }
 
        free(tokens);
        }
 
        free(tokens);
@@ -852,11 +1397,7 @@ _fsi_get_host(si_mod_t *si, const char *name, const void *addr, int af, int whic
        si_item_t *item;
        FILE *f;
        si_list_t *all;
        si_item_t *item;
        FILE *f;
        si_list_t *all;
-       struct stat sb;
-       uint64_t sec, nsec;
-
-       sec = 0;
-       nsec = 0;
+       uint64_t va, vb;
 
        if ((which == SEL_NAME) && (name == NULL))
        {
 
        if ((which == SEL_NAME) && (name == NULL))
        {
@@ -877,12 +1418,7 @@ _fsi_get_host(si_mod_t *si, const char *name, const void *addr, int af, int whic
                return NULL;
        }
 
                return NULL;
        }
 
-       memset(&sb, 0, sizeof(struct stat));
-       if (fstat(fileno(f), &sb) == 0)
-       {
-               sec = sb.st_mtimespec.tv_sec;
-               nsec = sb.st_mtimespec.tv_nsec;
-       }
+       _fsi_get_validation(si, VALIDATION_HOSTS, _PATH_HOSTS, f, &va, &vb);
 
        all = NULL;
 
 
        all = NULL;
 
@@ -898,7 +1434,7 @@ _fsi_get_host(si_mod_t *si, const char *name, const void *addr, int af, int whic
                        continue;
                }
 
                        continue;
                }
 
-               item = _fsi_parse_host(si, name, addr, af, which, line, sec, nsec);
+               item = _fsi_parse_host(si, name, addr, af, which, line, va, vb);
                free(line);
                line = NULL;
 
                free(line);
                line = NULL;
 
@@ -922,7 +1458,7 @@ _fsi_get_host(si_mod_t *si, const char *name, const void *addr, int af, int whic
 /* SERVICE */
 
 static si_item_t *
 /* SERVICE */
 
 static si_item_t *
-_fsi_parse_service(si_mod_t *si, const char *name, const char *proto, int port, int which, char *data, uint64_t sec, uint64_t nsec)
+_fsi_parse_service(si_mod_t *si, const char *name, const char *proto, int port, int which, char *data, uint64_t va, uint64_t vb)
 {
        char **tokens, **s_aliases, *xproto;
        int i, ntokens, match;
 {
        char **tokens, **s_aliases, *xproto;
        int i, ntokens, match;
@@ -983,7 +1519,7 @@ _fsi_parse_service(si_mod_t *si, const char *name, const char *proto, int port,
        /* strange but correct */
        xport = htons(xport);
 
        /* strange but correct */
        xport = htons(xport);
 
-       item = (si_item_t *)LI_ils_create("L4488s*4s", (unsigned long)si, CATEGORY_SERVICE, 1, sec, nsec, tokens[0], s_aliases, xport, xproto);
+       item = (si_item_t *)LI_ils_create("L4488s*4s", (unsigned long)si, CATEGORY_SERVICE, 1, va, vb, tokens[0], s_aliases, xport, xproto);
 
        free(tokens);
 
 
        free(tokens);
 
@@ -997,11 +1533,7 @@ _fsi_get_service(si_mod_t *si, const char *name, const char *proto, int port, in
        si_item_t *item;
        FILE *f;
        si_list_t *all;
        si_item_t *item;
        FILE *f;
        si_list_t *all;
-       struct stat sb;
-       uint64_t sec, nsec;
-
-       sec = 0;
-       nsec = 0;
+       uint64_t va, vb;
 
        if ((which == SEL_NAME) && (name == NULL)) return NULL;
        if ((which == SEL_NUMBER) && (port == 0)) return NULL;
 
        if ((which == SEL_NAME) && (name == NULL)) return NULL;
        if ((which == SEL_NUMBER) && (port == 0)) return NULL;
@@ -1009,12 +1541,7 @@ _fsi_get_service(si_mod_t *si, const char *name, const char *proto, int port, in
        f = fopen(_PATH_SERVICES, "r");
        if (f == NULL) return NULL;
 
        f = fopen(_PATH_SERVICES, "r");
        if (f == NULL) return NULL;
 
-       memset(&sb, 0, sizeof(struct stat));
-       if (fstat(fileno(f), &sb) == 0)
-       {
-               sec = sb.st_mtimespec.tv_sec;
-               nsec = sb.st_mtimespec.tv_nsec;
-       }
+       _fsi_get_validation(si, VALIDATION_SERVICES, _PATH_SERVICES, f, &va, &vb);
 
        all = NULL;
 
 
        all = NULL;
 
@@ -1033,7 +1560,7 @@ _fsi_get_service(si_mod_t *si, const char *name, const char *proto, int port, in
                p = strchr(line, '#');
                if (p != NULL) *p = '\0';
 
                p = strchr(line, '#');
                if (p != NULL) *p = '\0';
 
-               item = _fsi_parse_service(si, name, proto, port, which, line, sec, nsec);
+               item = _fsi_parse_service(si, name, proto, port, which, line, va, vb);
                free(line);
                line = NULL;
 
                free(line);
                line = NULL;
 
@@ -1060,7 +1587,7 @@ _fsi_get_service(si_mod_t *si, const char *name, const char *proto, int port, in
  */
 
 static si_item_t *
  */
 
 static si_item_t *
-_fsi_parse_name_num_aliases(si_mod_t *si, const char *name, int num, int which, char *data, uint64_t sec, uint64_t nsec, int cat)
+_fsi_parse_name_num_aliases(si_mod_t *si, const char *name, int num, int which, char *data, uint64_t va, uint64_t vb, int cat)
 {
        char **tokens, **aliases;
        int i, ntokens, match, xnum;
 {
        char **tokens, **aliases;
        int i, ntokens, match, xnum;
@@ -1101,7 +1628,20 @@ _fsi_parse_name_num_aliases(si_mod_t *si, const char *name, int num, int which,
                return NULL;
        }
 
                return NULL;
        }
 
-       item = (si_item_t *)LI_ils_create("L4488s*4", (unsigned long)si, cat, 1, sec, nsec, tokens[0], aliases, xnum);
+       switch (cat) {
+               case CATEGORY_NETWORK:
+                       // struct netent
+                       item = (si_item_t *)LI_ils_create("L4488s*44", (unsigned long)si, cat, 1, va, vb, tokens[0], aliases, AF_INET, xnum);
+                       break;
+               case CATEGORY_PROTOCOL:
+               case CATEGORY_RPC:
+                       // struct protoent
+                       // struct rpcent
+                       item = (si_item_t *)LI_ils_create("L4488s*4", (unsigned long)si, cat, 1, va, vb, tokens[0], aliases, xnum);
+                       break;
+               default:
+                       abort();
+       }
 
        free(tokens);
 
 
        free(tokens);
 
@@ -1109,27 +1649,37 @@ _fsi_parse_name_num_aliases(si_mod_t *si, const char *name, int num, int which,
 }
 
 static void *
 }
 
 static void *
-_fsi_get_name_number_aliases(si_mod_t *si, const char *name, int num, int which, int cat, const char *path)
+_fsi_get_name_number_aliases(si_mod_t *si, const char *name, int num, int which, int cat)
 {
        char *p, *line;
        si_item_t *item;
        FILE *f;
        si_list_t *all;
 {
        char *p, *line;
        si_item_t *item;
        FILE *f;
        si_list_t *all;
-       struct stat sb;
-       uint64_t sec, nsec;
+       uint64_t va, vb;
+       const char *path;
+       int vtype;
 
 
-       sec = 0;
-       nsec = 0;
+       switch (cat) {
+               case CATEGORY_NETWORK:
+                       vtype = VALIDATION_NETWORKS;
+                       path = _PATH_NETWORKS;
+                       break;
+               case CATEGORY_PROTOCOL:
+                       vtype = VALIDATION_PROTOCOLS;
+                       path = _PATH_PROTOCOLS;
+                       break;
+               case CATEGORY_RPC:
+                       vtype = VALIDATION_RPC;
+                       path = _PATH_RPCS;
+                       break;
+               default:
+                       abort();
+       }
 
        f = fopen(path, "r");
        if (f == NULL) return NULL;
 
 
        f = fopen(path, "r");
        if (f == NULL) return NULL;
 
-       memset(&sb, 0, sizeof(struct stat));
-       if (fstat(fileno(f), &sb) == 0)
-       {
-               sec = sb.st_mtimespec.tv_sec;
-               nsec = sb.st_mtimespec.tv_nsec;
-       }
+       _fsi_get_validation(si, vtype, path, f, &va, &vb);
 
        all = NULL;
 
 
        all = NULL;
 
@@ -1148,7 +1698,7 @@ _fsi_get_name_number_aliases(si_mod_t *si, const char *name, int num, int which,
                p = strchr(line, '#');
                if (p != NULL) *p = '\0';
 
                p = strchr(line, '#');
                if (p != NULL) *p = '\0';
 
-               item = _fsi_parse_name_num_aliases(si, name, num, which, line, sec, nsec, cat);
+               item = _fsi_parse_name_num_aliases(si, name, num, which, line, va, vb, cat);
                free(line);
                line = NULL;
 
                free(line);
                line = NULL;
 
@@ -1172,7 +1722,7 @@ _fsi_get_name_number_aliases(si_mod_t *si, const char *name, int num, int which,
 /* MOUNT */
 
 static si_item_t *
 /* MOUNT */
 
 static si_item_t *
-_fsi_parse_fs(si_mod_t *si, const char *name, int which, char *data, uint64_t sec, uint64_t nsec)
+_fsi_parse_fs(si_mod_t *si, const char *name, int which, char *data, uint64_t va, uint64_t vb)
 {
        char **tokens, *tmp, **opts, *fstype;
        int ntokens, match, i, freq, passno;
 {
        char **tokens, *tmp, **opts, *fstype;
        int ntokens, match, i, freq, passno;
@@ -1233,7 +1783,7 @@ _fsi_parse_fs(si_mod_t *si, const char *name, int which, char *data, uint64_t se
                return NULL;
        }
 
                return NULL;
        }
 
-       item = (si_item_t *)LI_ils_create("L4488sssss44", (unsigned long)si, CATEGORY_FS, 1, sec, nsec, tokens[0], tokens[1], tokens[2], tokens[3], (fstype == NULL) ? "rw" : fstype, freq, passno);
+       item = (si_item_t *)LI_ils_create("L4488sssss44", (unsigned long)si, CATEGORY_FS, 1, va, vb, tokens[0], tokens[1], tokens[2], tokens[3], (fstype == NULL) ? "rw" : fstype, freq, passno);
 
        free(tokens); 
        free(opts); 
 
        free(tokens); 
        free(opts); 
@@ -1284,7 +1834,7 @@ _fsi_get_device_path(dev_t target_dev)
             /* reset dev to _PATH_DEV and try again */
             dev[sizeof(_PATH_DEV) - 1] = '\0';
         }
             /* reset dev to _PATH_DEV and try again */
             dev[sizeof(_PATH_DEV) - 1] = '\0';
         }
-               
+
                if (dirp) closedir(dirp);
     }
        else
                if (dirp) closedir(dirp);
     }
        else
@@ -1300,33 +1850,30 @@ _fsi_get_device_path(dev_t target_dev)
 static si_item_t *
 _fsi_fs_root(si_mod_t *si)
 {
 static si_item_t *
 _fsi_fs_root(si_mod_t *si)
 {
-       struct stat rootstat;
-       struct statfs rootfsinfo;
-       char *root_spec;
-       const char *root_path;
-
-       if (rootfs != NULL) return si_item_retain(rootfs);
-
-       root_path = "/";
-
-       if (stat(root_path, &rootstat) < 0) return NULL;
-       if (statfs(root_path, &rootfsinfo) < 0) return NULL;
+       dispatch_once(&rootfs_once, ^{
+               struct stat rootstat;
+               struct statfs rootfsinfo;
+               char *root_spec;
+               const char *root_path = "/";
+
+               if (stat(root_path, &rootstat) < 0) return;
+               if (statfs(root_path, &rootfsinfo) < 0) return;
+
+               // Check to make sure we're not looking at a synthetic root:
+               if (string_equal(rootfsinfo.f_fstypename, "synthfs")) {
+                       root_path = "/root";
+                       if (stat(root_path, &rootstat) < 0) return;
+                       if (statfs(root_path, &rootfsinfo) < 0) return;
+               }
 
 
-       /* Check to make sure we're not looking at a synthetic root: */
-       if (string_equal(rootfsinfo.f_fstypename, "synthfs"))
-       {
-               root_path = "/root";
-        if (stat(root_path, &rootstat) < 0) return NULL;
-               if (statfs(root_path, &rootfsinfo) < 0) return NULL;
-       }
+               root_spec = _fsi_get_device_path(rootstat.st_dev);
 
 
-       root_spec = _fsi_get_device_path(rootstat.st_dev);
+               rootfs = (si_item_t *)LI_ils_create("L4488sssss44", (unsigned long)si, CATEGORY_FS, 1, 0LL, 0LL, root_spec, root_path, rootfsinfo.f_fstypename, FSTAB_RW, FSTAB_RW, 0, 1);
+       });
 
 
-       rootfs = (si_item_t *)LI_ils_create("L4488sssss44", (unsigned long)si, CATEGORY_FS, 1, 0LL, 0LL, root_spec, root_path, rootfsinfo.f_fstypename, FSTAB_RW, FSTAB_RW, 0, 1);
-       return rootfs;
+       return si_item_retain(rootfs);
 }
 
 }
 
-
 static void *
 _fsi_get_fs(si_mod_t *si, const char *name, int which)
 {
 static void *
 _fsi_get_fs(si_mod_t *si, const char *name, int which)
 {
@@ -1334,8 +1881,7 @@ _fsi_get_fs(si_mod_t *si, const char *name, int which)
        si_item_t *item;
        FILE *f;
        si_list_t *all;
        si_item_t *item;
        FILE *f;
        si_list_t *all;
-       struct stat sb;
-       uint64_t sec, nsec;
+       uint64_t va, vb;
        int synthesize_root;
        struct fstab *rfs;
 
        int synthesize_root;
        struct fstab *rfs;
 
@@ -1343,8 +1889,6 @@ _fsi_get_fs(si_mod_t *si, const char *name, int which)
 
        all = NULL;
        f = NULL;
 
        all = NULL;
        f = NULL;
-       sec = 0;
-       nsec = 0;
 #ifdef SYNTH_ROOTFS
        synthesize_root = 1;
 #else
 #ifdef SYNTH_ROOTFS
        synthesize_root = 1;
 #else
@@ -1394,12 +1938,7 @@ _fsi_get_fs(si_mod_t *si, const char *name, int which)
 
        if (f == NULL) return all;
 
 
        if (f == NULL) return all;
 
-       memset(&sb, 0, sizeof(struct stat));
-       if (fstat(fileno(f), &sb) == 0)
-       {
-               sec = sb.st_mtimespec.tv_sec;
-               nsec = sb.st_mtimespec.tv_nsec;
-       }
+       _fsi_get_validation(si, VALIDATION_FSTAB, _PATH_FSTAB, f, &va, &vb);
 
        forever
        {
 
        forever
        {
@@ -1413,7 +1952,7 @@ _fsi_get_fs(si_mod_t *si, const char *name, int which)
                        continue;
                }
 
                        continue;
                }
 
-               item = _fsi_parse_fs(si, name, which, line, sec, nsec);
+               item = _fsi_parse_fs(si, name, which, line, va, vb);
                free(line);
                line = NULL;
 
                free(line);
                line = NULL;
 
@@ -1434,12 +1973,9 @@ _fsi_get_fs(si_mod_t *si, const char *name, int which)
        return all;
 }
 
        return all;
 }
 
-__private_extern__ int
+static int
 file_is_valid(si_mod_t *si, si_item_t *item)
 {
 file_is_valid(si_mod_t *si, si_item_t *item)
 {
-       struct stat sb;
-       uint64_t sec, nsec;
-       const char *path;
        si_mod_t *src;
 
        if (si == NULL) return 0;
        si_mod_t *src;
 
        if (si == NULL) return 0;
@@ -1454,76 +1990,142 @@ file_is_valid(si_mod_t *si, si_item_t *item)
 
        if (item == rootfs) return 1;
 
 
        if (item == rootfs) return 1;
 
-       path = NULL;
-       memset(&sb, 0, sizeof(struct stat));
-       sec = item->validation_a;
-       nsec = item->validation_b;
-
-       if (item->type == CATEGORY_USER)
-       {
-               if (geteuid() == 0) path = _PATH_MASTERPASSWD;
-               else path = _PATH_PASSWD;
-       }
-       else if (item->type == CATEGORY_GROUP) path = _PATH_GROUP;
-       else if (item->type == CATEGORY_HOST_IPV4) path = _PATH_HOSTS;
-       else if (item->type == CATEGORY_HOST_IPV6) path = _PATH_HOSTS;
-       else if (item->type == CATEGORY_NETWORK) path = _PATH_NETWORKS;
-       else if (item->type == CATEGORY_SERVICE) path = _PATH_SERVICES;
-       else if (item->type == CATEGORY_PROTOCOL) path = _PATH_PROTOCOLS;
-       else if (item->type == CATEGORY_RPC) path = _PATH_RPCS;
-       else if (item->type == CATEGORY_FS) path = _PATH_FSTAB;
-
-       if (path == NULL) return 0;
-       if (stat(path, &sb) != 0) return 0;
-       if (sec != sb.st_mtimespec.tv_sec) return 0;
-       if (nsec != sb.st_mtimespec.tv_nsec) return 0;
-
-       return 1;
+       return _fsi_validate(si, item->type, item->validation_a, item->validation_b);
 }
 
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 file_user_byname(si_mod_t *si, const char *name)
 {
        return _fsi_get_user(si, name, 0, SEL_NAME);
 }
 
 file_user_byname(si_mod_t *si, const char *name)
 {
        return _fsi_get_user(si, name, 0, SEL_NAME);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 file_user_byuid(si_mod_t *si, uid_t uid)
 {
        return _fsi_get_user(si, NULL, uid, SEL_NUMBER);
 }
 
 file_user_byuid(si_mod_t *si, uid_t uid)
 {
        return _fsi_get_user(si, NULL, uid, SEL_NUMBER);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 file_user_all(si_mod_t *si)
 {
        return _fsi_get_user(si, NULL, 0, SEL_ALL);
 }
 
 file_user_all(si_mod_t *si)
 {
        return _fsi_get_user(si, NULL, 0, SEL_ALL);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 file_group_byname(si_mod_t *si, const char *name)
 {
        return _fsi_get_group(si, name, 0, SEL_NAME);
 }
 
 file_group_byname(si_mod_t *si, const char *name)
 {
        return _fsi_get_group(si, name, 0, SEL_NAME);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 file_group_bygid(si_mod_t *si, gid_t gid)
 {
        return _fsi_get_group(si, NULL, gid, SEL_NUMBER);
 }
 
 file_group_bygid(si_mod_t *si, gid_t gid)
 {
        return _fsi_get_group(si, NULL, gid, SEL_NUMBER);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 file_group_all(si_mod_t *si)
 {
        return _fsi_get_group(si, NULL, 0, SEL_ALL);
 }
 
 file_group_all(si_mod_t *si)
 {
        return _fsi_get_group(si, NULL, 0, SEL_ALL);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 file_grouplist(si_mod_t *si, const char *name)
 {
        return _fsi_get_grouplist(si, name);
 }
 
 file_grouplist(si_mod_t *si, const char *name)
 {
        return _fsi_get_grouplist(si, name);
 }
 
-__private_extern__ si_item_t *
+static si_list_t *
+file_netgroup_byname(si_mod_t *si, const char *name)
+{
+       si_list_t *list = NULL;
+       si_item_t *item;
+       uint64_t va, vb;
+       file_netgroup_t *n;
+       file_si_private_t *pp;
+
+       if (name == NULL) return NULL;
+
+       pp = (file_si_private_t *)si->private;
+       if (pp == NULL) return NULL;
+
+       _fsi_check_netgroup_cache(si);
+
+       pthread_mutex_lock(&file_mutex);
+
+       n = _fsi_find_netgroup(&(pp->file_netgroup_cache), name, 0);
+       if (n != NULL)
+       {
+               file_netgroup_member_t *m = n->members;
+               while (m != NULL)
+               {
+                       item = (si_item_t *)LI_ils_create("L4488sss", (unsigned long)si, CATEGORY_NETGROUP, 1, va, vb, m->host, m->user, m->domain);
+                       list = si_list_add(list, item);
+                       m = m->next;
+               }
+       }
+
+       pthread_mutex_unlock(&file_mutex);
+
+       return list;
+}
+
+static int
+file_in_netgroup(si_mod_t *si, const char *group, const char *host, const char *user, const char *domain)
+{
+       file_netgroup_t *n;
+       file_netgroup_member_t *m;
+       file_si_private_t *pp;
+
+       if (group == NULL) return 0;
+
+       pp = (file_si_private_t *)si->private;
+       if (pp == NULL) return 0;
+
+       _fsi_check_netgroup_cache(si);
+
+       pthread_mutex_lock(&file_mutex);
+
+       n = _fsi_find_netgroup(&(pp->file_netgroup_cache), group, 0);
+       if (n == NULL)
+       {
+               pthread_mutex_unlock(&file_mutex);
+               return 0;
+       }
+
+       m = n->members;
+       while (m != NULL)
+       {
+               file_netgroup_member_t *x = m;
+               m = m->next;
+
+               if (host != NULL)
+               {
+                       if (x->host == NULL) continue;
+                       if (strcmp(host, x->host)) continue;
+               }
+
+               if (user != NULL)
+               {
+                       if (x->user == NULL) continue;
+                       if (strcmp(user, x->user)) continue;
+               }
+
+               if (domain != NULL)
+               {
+                       if (x->domain == NULL) continue;
+                       if (strcmp(domain, x->domain)) continue;
+               }
+
+               pthread_mutex_unlock(&file_mutex);
+               return 1;
+       }
+
+       pthread_mutex_unlock(&file_mutex);
+       return 0;
+}
+
+static si_item_t *
 file_host_byname(si_mod_t *si, const char *name, int af, const char *ignored, uint32_t *err)
 {
        si_item_t *item;
 file_host_byname(si_mod_t *si, const char *name, int af, const char *ignored, uint32_t *err)
 {
        si_item_t *item;
@@ -1536,7 +2138,7 @@ file_host_byname(si_mod_t *si, const char *name, int af, const char *ignored, ui
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 file_host_byaddr(si_mod_t *si, const void *addr, int af, const char *ignored, uint32_t *err)
 {
        si_item_t *item;
 file_host_byaddr(si_mod_t *si, const void *addr, int af, const char *ignored, uint32_t *err)
 {
        si_item_t *item;
@@ -1549,130 +2151,130 @@ file_host_byaddr(si_mod_t *si, const void *addr, int af, const char *ignored, ui
        return item;
 }
 
        return item;
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 file_host_all(si_mod_t *si)
 {
        return _fsi_get_host(si, NULL, NULL, 0, SEL_ALL, NULL);
 }
 
 file_host_all(si_mod_t *si)
 {
        return _fsi_get_host(si, NULL, NULL, 0, SEL_ALL, NULL);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 file_network_byname(si_mod_t *si, const char *name)
 {
        if (name == NULL) return NULL;
 file_network_byname(si_mod_t *si, const char *name)
 {
        if (name == NULL) return NULL;
-       return _fsi_get_name_number_aliases(si, name, 0, SEL_NAME, CATEGORY_NETWORK, _PATH_NETWORKS);
+       return _fsi_get_name_number_aliases(si, name, 0, SEL_NAME, CATEGORY_NETWORK);
 }
 
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 file_network_byaddr(si_mod_t *si, uint32_t addr)
 {
 file_network_byaddr(si_mod_t *si, uint32_t addr)
 {
-       return _fsi_get_name_number_aliases(si, NULL, (int)addr, SEL_NUMBER, CATEGORY_NETWORK, _PATH_NETWORKS);
+       return _fsi_get_name_number_aliases(si, NULL, (int)addr, SEL_NUMBER, CATEGORY_NETWORK);
 }
 
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 file_network_all(si_mod_t *si)
 {
 file_network_all(si_mod_t *si)
 {
-       return _fsi_get_name_number_aliases(si, NULL, 0, SEL_ALL, CATEGORY_NETWORK, _PATH_NETWORKS);
+       return _fsi_get_name_number_aliases(si, NULL, 0, SEL_ALL, CATEGORY_NETWORK);
 }
 
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 file_service_byname(si_mod_t *si, const char *name, const char *proto)
 {
        return _fsi_get_service(si, name, proto, 0, SEL_NAME);
 }
 
 file_service_byname(si_mod_t *si, const char *name, const char *proto)
 {
        return _fsi_get_service(si, name, proto, 0, SEL_NAME);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 file_service_byport(si_mod_t *si, int port, const char *proto)
 {
        return _fsi_get_service(si, NULL, proto, port, SEL_NUMBER);
 }
 
 file_service_byport(si_mod_t *si, int port, const char *proto)
 {
        return _fsi_get_service(si, NULL, proto, port, SEL_NUMBER);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 file_service_all(si_mod_t *si)
 {
        return _fsi_get_service(si, NULL, NULL, 0, SEL_ALL);
 }
 
 file_service_all(si_mod_t *si)
 {
        return _fsi_get_service(si, NULL, NULL, 0, SEL_ALL);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 file_protocol_byname(si_mod_t *si, const char *name)
 {
        if (name == NULL) return NULL;
 file_protocol_byname(si_mod_t *si, const char *name)
 {
        if (name == NULL) return NULL;
-       return _fsi_get_name_number_aliases(si, name, 0, SEL_NAME, CATEGORY_PROTOCOL, _PATH_PROTOCOLS);
+       return _fsi_get_name_number_aliases(si, name, 0, SEL_NAME, CATEGORY_PROTOCOL);
 }
 
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 file_protocol_bynumber(si_mod_t *si, int number)
 {
 file_protocol_bynumber(si_mod_t *si, int number)
 {
-       return _fsi_get_name_number_aliases(si, NULL, number, SEL_NUMBER, CATEGORY_PROTOCOL, _PATH_PROTOCOLS);
+       return _fsi_get_name_number_aliases(si, NULL, number, SEL_NUMBER, CATEGORY_PROTOCOL);
 }
 
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 file_protocol_all(si_mod_t *si)
 {
 file_protocol_all(si_mod_t *si)
 {
-       return _fsi_get_name_number_aliases(si, NULL, 0, SEL_ALL, CATEGORY_PROTOCOL, _PATH_PROTOCOLS);
+       return _fsi_get_name_number_aliases(si, NULL, 0, SEL_ALL, CATEGORY_PROTOCOL);
 }
 
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 file_rpc_byname(si_mod_t *si, const char *name)
 {
        if (name == NULL) return NULL;
 file_rpc_byname(si_mod_t *si, const char *name)
 {
        if (name == NULL) return NULL;
-       return _fsi_get_name_number_aliases(si, name, 0, SEL_NAME, CATEGORY_RPC, _PATH_RPCS);
+       return _fsi_get_name_number_aliases(si, name, 0, SEL_NAME, CATEGORY_RPC);
 }
 
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 file_rpc_bynumber(si_mod_t *si, int number)
 {
 file_rpc_bynumber(si_mod_t *si, int number)
 {
-       return _fsi_get_name_number_aliases(si, NULL, number, SEL_NUMBER, CATEGORY_RPC, _PATH_RPCS);
+       return _fsi_get_name_number_aliases(si, NULL, number, SEL_NUMBER, CATEGORY_RPC);
 }
 
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 file_rpc_all(si_mod_t *si)
 {
 file_rpc_all(si_mod_t *si)
 {
-       return _fsi_get_name_number_aliases(si, NULL, 0, SEL_ALL, CATEGORY_RPC, _PATH_RPCS);
+       return _fsi_get_name_number_aliases(si, NULL, 0, SEL_ALL, CATEGORY_RPC);
 }
 
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 file_fs_byspec(si_mod_t *si, const char *spec)
 {
        return _fsi_get_fs(si, spec, SEL_NAME);
 }
 
 file_fs_byspec(si_mod_t *si, const char *spec)
 {
        return _fsi_get_fs(si, spec, SEL_NAME);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 file_fs_byfile(si_mod_t *si, const char *file)
 {
        return _fsi_get_fs(si, file, SEL_NUMBER);
 }
 
 file_fs_byfile(si_mod_t *si, const char *file)
 {
        return _fsi_get_fs(si, file, SEL_NUMBER);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 file_fs_all(si_mod_t *si)
 {
        return _fsi_get_fs(si, NULL, SEL_ALL);
 }
 
 file_fs_all(si_mod_t *si)
 {
        return _fsi_get_fs(si, NULL, SEL_ALL);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 file_alias_byname(si_mod_t *si, const char *name)
 {
        return _fsi_get_alias(si, name, SEL_NAME);
 }
 
 file_alias_byname(si_mod_t *si, const char *name)
 {
        return _fsi_get_alias(si, name, SEL_NAME);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 file_alias_all(si_mod_t *si)
 {
        return _fsi_get_alias(si, NULL, SEL_ALL);
 }
 
 file_alias_all(si_mod_t *si)
 {
        return _fsi_get_alias(si, NULL, SEL_ALL);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 file_mac_byname(si_mod_t *si, const char *name)
 {
        return _fsi_get_ether(si, name, SEL_NAME);
 }
 
 file_mac_byname(si_mod_t *si, const char *name)
 {
        return _fsi_get_ether(si, name, SEL_NAME);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 file_mac_bymac(si_mod_t *si, const char *mac)
 {
        return _fsi_get_ether(si, mac, SEL_NUMBER);
 }
 
 file_mac_bymac(si_mod_t *si, const char *mac)
 {
        return _fsi_get_ether(si, mac, SEL_NUMBER);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 file_mac_all(si_mod_t *si)
 {
        return _fsi_get_ether(si, NULL, SEL_ALL);
 file_mac_all(si_mod_t *si)
 {
        return _fsi_get_ether(si, NULL, SEL_ALL);
@@ -1685,80 +2287,90 @@ file_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family,
        return _gai_simple(si, node, serv, family, socktype, proto, flags, interface, err);
 }
 
        return _gai_simple(si, node, serv, family, socktype, proto, flags, interface, err);
 }
 
-__private_extern__  si_mod_t *
-si_module_static_file()
+si_mod_t *
+si_module_static_file(void)
 {
 {
-       si_mod_t *out;
-       char *outname;
+       static const struct si_mod_vtable_s file_vtable =
+       {
+               .sim_is_valid = &file_is_valid,
 
 
-       out = (si_mod_t *)calloc(1, sizeof(si_mod_t));
-       outname = strdup("file");
+               .sim_user_byname = &file_user_byname,
+               .sim_user_byuid = &file_user_byuid,
+               .sim_user_all = &file_user_all,
 
 
-       if ((out == NULL) || (outname == NULL))
-       {
-               if (out != NULL) free(out);
-               if (outname != NULL) free(outname);
+               .sim_group_byname = &file_group_byname,
+               .sim_group_bygid = &file_group_bygid,
+               .sim_group_all = &file_group_all,
 
 
-               errno = ENOMEM;
-               return NULL;
-       }
+               .sim_grouplist = &file_grouplist,
 
 
-       out->name = outname;
-       out->vers = 1;
-       out->refcount = 1;
+               .sim_netgroup_byname = &file_netgroup_byname,
+               .sim_in_netgroup = &file_in_netgroup,
 
 
-       out->sim_is_valid = file_is_valid;
+               .sim_alias_byname = &file_alias_byname,
+               .sim_alias_all = &file_alias_all,
 
 
-       out->sim_user_byname = file_user_byname;
-       out->sim_user_byuid = file_user_byuid;
-       out->sim_user_all = file_user_all;
+               .sim_host_byname = &file_host_byname,
+               .sim_host_byaddr = &file_host_byaddr,
+               .sim_host_all = &file_host_all,
 
 
-       out->sim_group_byname = file_group_byname;
-       out->sim_group_bygid = file_group_bygid;
-       out->sim_group_all = file_group_all;
+               .sim_network_byname = &file_network_byname,
+               .sim_network_byaddr = &file_network_byaddr,
+               .sim_network_all = &file_network_all,
 
 
-       out->sim_grouplist = file_grouplist;
+               .sim_service_byname = &file_service_byname,
+               .sim_service_byport = &file_service_byport,
+               .sim_service_all = &file_service_all,
 
 
-       /* NETGROUP SUPPORT NOT IMPLEMENTED */
-       out->sim_netgroup_byname = NULL;
-       out->sim_in_netgroup = NULL;
+               .sim_protocol_byname = &file_protocol_byname,
+               .sim_protocol_bynumber = &file_protocol_bynumber,
+               .sim_protocol_all = &file_protocol_all,
 
 
-       out->sim_alias_byname = file_alias_byname;
-       out->sim_alias_all = file_alias_all;
+               .sim_rpc_byname = &file_rpc_byname,
+               .sim_rpc_bynumber = &file_rpc_bynumber,
+               .sim_rpc_all = &file_rpc_all,
 
 
-       out->sim_host_byname = file_host_byname;
-       out->sim_host_byaddr = file_host_byaddr;
-       out->sim_host_all = file_host_all;
+               .sim_fs_byspec = &file_fs_byspec,
+               .sim_fs_byfile = &file_fs_byfile,
+               .sim_fs_all = &file_fs_all,
 
 
-       out->sim_network_byname = file_network_byname;
-       out->sim_network_byaddr = file_network_byaddr;
-       out->sim_network_all = file_network_all;
+               .sim_mac_byname = &file_mac_byname,
+               .sim_mac_bymac = &file_mac_bymac,
+               .sim_mac_all = &file_mac_all,
 
 
-       out->sim_service_byname = file_service_byname;
-       out->sim_service_byport = file_service_byport;
-       out->sim_service_all = file_service_all;
+               .sim_wants_addrinfo = NULL,
+               .sim_addrinfo = &file_addrinfo,
 
 
-       out->sim_protocol_byname = file_protocol_byname;
-       out->sim_protocol_bynumber = file_protocol_bynumber;
-       out->sim_protocol_all = file_protocol_all;
+               /* no nameinfo support */
+               .sim_nameinfo = NULL,
+       };
 
 
-       out->sim_rpc_byname = file_rpc_byname;
-       out->sim_rpc_bynumber = file_rpc_bynumber;
-       out->sim_rpc_all = file_rpc_all;
+       static si_mod_t si =
+       {
+               .vers = 1,
+               .refcount = 1,
+               .flags = SI_MOD_FLAG_STATIC,
 
 
-       out->sim_fs_byspec = file_fs_byspec;
-       out->sim_fs_byfile = file_fs_byfile;
-       out->sim_fs_all = file_fs_all;
+               .private = NULL,
+               .vtable = &file_vtable,
+       };
 
 
-       out->sim_mac_byname = file_mac_byname;
-       out->sim_mac_bymac = file_mac_bymac;
-       out->sim_mac_all = file_mac_all;
+       static dispatch_once_t once;
 
 
-       out->sim_wants_addrinfo = NULL;
-       out->sim_addrinfo = file_addrinfo;
+       dispatch_once(&once, ^{
+               si.name = strdup("file");
+               file_si_private_t *pp = calloc(1, sizeof(file_si_private_t));
+               if (pp != NULL)
+               {
+                       int i;
+                       for (i = 0; i < VALIDATION_COUNT; i++) pp->notify_token[i] = -1;
 
 
-       /* no nameinfo support */
-       out->sim_nameinfo = NULL;
+                       /* hardwired for now, but we may want to make this configurable someday */
+                       pp->validation_notify_mask = VALIDATION_MASK_HOSTS | VALIDATION_MASK_SERVICES;
+               }
 
 
-       return out;
+               si.private = pp;
+       });
+
+       return (si_mod_t *)&si;
 }
 }
index 2a95a2d9fd77299b053f163a06c248cdb0f42c78..2a2920c7f90b6963fb656324ccd9fe5ea78733c1 100644 (file)
@@ -60,7 +60,7 @@
 .Fn getgrgid_r "gid_t gid" "struct group *grp" "char *buffer" "size_t bufsize" "struct group **result"
 .Ft int
 .Fn setgroupent "int stayopen"
 .Fn getgrgid_r "gid_t gid" "struct group *grp" "char *buffer" "size_t bufsize" "struct group **result"
 .Ft int
 .Fn setgroupent "int stayopen"
-.Ft int
+.Ft void
 .Fn setgrent void
 .Ft void
 .Fn endgrent void
 .Fn setgrent void
 .Ft void
 .Fn endgrent void
@@ -199,14 +199,12 @@ is set to
 .Dv NULL
 and the return value is 0, no matching entry exists.)
 .Pp
 .Dv NULL
 and the return value is 0, no matching entry exists.)
 .Pp
-The functions
 .Fn setgroupent
 .Fn setgroupent
-and
-.Fn setgrent
-return the value 1 if successful, otherwise the value
+returns the value 1 if successful, otherwise the value
 0 is returned.
 The functions
 0 is returned.
 The functions
-.Fn endgrent
+.Fn setgrent ,
+.Fn endgrent ,
 and
 .Fn setgrfile
 have no return value.
 and
 .Fn setgrfile
 have no return value.
index a121a457b547457bf4075c053fdcf7910df03942..ac415967f7d75bcdc2ba8ad6b7edd4fa2637011b 100644 (file)
@@ -47,34 +47,30 @@ and
 functions and is the converse of the
 .Xr getaddrinfo 3
 function.
 functions and is the converse of the
 .Xr getaddrinfo 3
 function.
-.\".Pp
-.\"If a link-layer address is passed to
-.\".Fn getnameinfo ,
-.\"its ASCII representation will be stored in
-.\".Fa host .
-.\"The string pointed to by
-.\".Fa serv
-.\"will be set to the empty string if non-NULL;
-.\".Fa flags
-.\"will always be ignored.
-.\"This is intended as a replacement for the legacy
-.\".Xr link_ntoa 3
-.\"function.
+.Pp
+If a link-layer address is passed to
+.Fn getnameinfo ,
+its ASCII representation will be stored in
+.Fa host .
+The string pointed to by
+.Fa serv
+will be set to the empty string if non-NULL;
+.Fa flags
+will always be ignored.
+This is intended as a replacement for the legacy
+.Xr link_ntoa 3
+function.
 .Pp
 The
 .Li sockaddr
 structure
 .Fa sa
 should point to either a
 .Pp
 The
 .Li sockaddr
 structure
 .Fa sa
 should point to either a
-.\".Li sockaddr_in ,
-.\".Li sockaddr_in6
-.\"or
-.\".Li sockaddr_dl
-.\"structure (for IPv4, IPv6 or link-layer respectively) that is
-.Li sockaddr_in
-or
+.Li sockaddr_in ,
 .Li sockaddr_in6
 .Li sockaddr_in6
-structure (for IPv4 or IPv6 respectively) that is
+or
+.Li sockaddr_dl
+structure (for IPv4, IPv6 or link-layer respectively) that is
 .Fa salen
 bytes long.
 .Pp
 .Fa salen
 bytes long.
 .Pp
diff --git a/lookup.subproj/getnameinfo_link.c b/lookup.subproj/getnameinfo_link.c
new file mode 100644 (file)
index 0000000..35ed743
--- /dev/null
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
+ * Copyright (c) 2000 Ben Harris.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <netdb.h>
+#include <net/if_types.h>
+#include <net/if_dl.h>
+
+static int
+hexname(const uint8_t *cp, size_t len, char *host, size_t hostlen)
+{
+       int i, n;
+       char *outp = host;
+
+       *outp = '\0';
+       for (i = 0; i < len; i++)
+       {
+               n = snprintf(outp, hostlen, "%s%02x", i ? ":" : "", cp[i]);
+               if ((n < 0) || (n >= hostlen))
+               {
+                       *host = '\0';
+                       return EAI_MEMORY;
+               }
+
+               outp += n;
+               hostlen -= n;
+       }
+
+       return 0;
+}
+
+/*
+ * getnameinfo_link():
+ * Format a link-layer address into a printable format, paying attention to
+ * the interface type.
+ */
+__private_extern__ int
+getnameinfo_link(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags)
+{
+       const struct sockaddr_dl *sdl = (const struct sockaddr_dl *)(const void *)sa;
+       int n;
+
+       if (serv != NULL && servlen > 0) *serv = '\0';
+
+       if ((sdl->sdl_nlen == 0) && (sdl->sdl_alen == 0) && (sdl->sdl_slen == 0))
+       {
+               n = snprintf(host, hostlen, "link#%d", sdl->sdl_index);
+               if (n > hostlen)
+               {
+                       *host = '\0';
+                       return EAI_MEMORY;
+               }
+
+               return 0;
+       }
+
+       switch (sdl->sdl_type)
+       {
+                       /*
+                        * The following have zero-length addresses.
+                        * IFT_ATM      (net/if_atmsubr.c)
+                        * IFT_FAITH    (net/if_faith.c)
+                        * IFT_GIF      (net/if_gif.c)
+                        * IFT_LOOP     (net/if_loop.c)
+                        * IFT_PPP      (net/if_ppp.c, net/if_spppsubr.c)
+                        * IFT_SLIP     (net/if_sl.c, net/if_strip.c)
+                        * IFT_STF      (net/if_stf.c)
+                        * IFT_L2VLAN   (net/if_vlan.c)
+                        * IFT_BRIDGE (net/if_bridge.h>
+                        */
+                       /*
+                        * The following use IPv4 addresses as link-layer addresses:
+                        * IFT_OTHER    (net/if_gre.c)
+                        * IFT_OTHER    (netinet/ip_ipip.c)
+                        */
+                       /* default below is believed correct for all these. */
+               case IFT_ARCNET:
+               case IFT_ETHER:
+               case IFT_FDDI:
+               case IFT_HIPPI:
+               case IFT_ISO88025:
+               default:
+                       return hexname((uint8_t *)LLADDR(sdl), (size_t)sdl->sdl_alen, host, hostlen);
+       }
+
+       /* NOTREACHED */
+       return EAI_FAIL;
+}
index 776c6a60f2f87b80870d228b83d0bc0ec6d03096..167ed2e0a555253290537ed42271f4134ec9dd01 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 1999-2009 Apple Inc.  All rights reserved.
+ * Copyright (c) 1999-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -203,7 +203,7 @@ LI_ils_create(char *fmt, ...)
 
                        case '*':
                        {
 
                        case '*':
                        {
-                               /* NULL-terminated list of strings */
+                               // NULL-terminated list of strings
                                if (largest < sizeof(char *)) largest = sizeof(char *);
 
                                csize = sizeof(char *) + padsize(hsize, sizeof(char *), align);
                                if (largest < sizeof(char *)) largest = sizeof(char *);
 
                                csize = sizeof(char *) + padsize(hsize, sizeof(char *), align);
@@ -215,10 +215,11 @@ LI_ils_create(char *fmt, ...)
                                                slen += sizeof(char *);
                                                slen += (strlen(list[i]) + 1);
                                        }
                                                slen += sizeof(char *);
                                                slen += (strlen(list[i]) + 1);
                                        }
-
-                                       slen += sizeof(char *);
                                }
 
                                }
 
+                               // reserve space for the terminator
+                               slen += sizeof(char *);
+
                                break;
                        }
 
                                break;
                        }
 
@@ -499,31 +500,24 @@ LI_ils_create(char *fmt, ...)
 
                                list = va_arg(ap, char **);
 
 
                                list = va_arg(ap, char **);
 
-                               if (list == NULL)
-                               {
-                                       memset(hp, 0, sizeof(char *));
-                               }
-                               else
-                               {
-                                       memcpy(hp, &dp, sizeof(char *));
+                               memcpy(hp, &dp, sizeof(char *));
 
 
-                                       for (i = 0; list[i] != NULL; i++);
+                               for (i = 0; list && list[i] != NULL; i++);
 
 
-                                       lp = dp;
-                                       dp += ((i + 1) * sizeof(char *));
+                               lp = dp;
+                               dp += ((i + 1) * sizeof(char *));
 
 
-                                       for (i = 0; list[i] != NULL; i++)
-                                       {
-                                               memcpy(lp, &dp, sizeof(char *));
-                                               lp += sizeof(char *);
-                                               slen = strlen(list[i]) + 1;
-                                               memcpy(dp, list[i], slen);
-                                               dp += slen;
-                                       }
-
-                                       memset(lp, 0, sizeof(char *));
+                               for (i = 0; list && list[i] != NULL; i++)
+                               {
+                                       memcpy(lp, &dp, sizeof(char *));
+                                       lp += sizeof(char *);
+                                       slen = strlen(list[i]) + 1;
+                                       memcpy(dp, list[i], slen);
+                                       dp += slen;
                                }
 
                                }
 
+                               memset(lp, 0, sizeof(char *));
+
                                hp += sizeof(char *);
                                hsize += sizeof(char *);
 
                                hp += sizeof(char *);
                                hsize += sizeof(char *);
 
index a32a1ef5f8d3d4cdf2fa72f2c8273f403cdfcc17..fa2fb515db09bfaa41258e3db8b65f66e541ddec 100644 (file)
@@ -69,7 +69,7 @@
  * (keys are always strings), "s" denotes a string value,
  * "i" denotes a 32 bit signed int, and "u" denotes an unsigned.
  */
  * (keys are always strings), "s" denotes a string value,
  * "i" denotes a 32 bit signed int, and "u" denotes an unsigned.
  */
-__private_extern__ kvbuf_t *
+kvbuf_t *
 kvbuf_query(char *fmt, ...)
 {
        va_list ap;
 kvbuf_query(char *fmt, ...)
 {
        va_list ap;
@@ -188,7 +188,7 @@ kvbuf_query_key_val(const char *key, const char *val)
        return kv;
 }
 
        return kv;
 }
 
-__private_extern__ kvbuf_t *
+kvbuf_t *
 kvbuf_query_key_int(const char *key, int32_t i)
 {
        char str[32];
 kvbuf_query_key_int(const char *key, int32_t i)
 {
        char str[32];
@@ -197,7 +197,7 @@ kvbuf_query_key_int(const char *key, int32_t i)
        return kvbuf_query_key_val(key, str);
 }
 
        return kvbuf_query_key_val(key, str);
 }
 
-__private_extern__ kvbuf_t *
+kvbuf_t *
 kvbuf_query_key_uint(const char *key, uint32_t u)
 {
        char str[32];
 kvbuf_query_key_uint(const char *key, uint32_t u)
 {
        char str[32];
@@ -248,15 +248,18 @@ kvbuf_init_zone(malloc_zone_t *zone, char *buffer, uint32_t length)
 
        kv->_size = length;
        kv->datalen = length;
 
        kv->_size = length;
        kv->datalen = length;
-       kv->databuf = malloc_zone_calloc(zone, 1, length);
-       if (kv->databuf == NULL)
-       {
-               free(kv);
-               kv = NULL;
-       }
-       else
+       if (length > 0)
        {
        {
-               memcpy(kv->databuf, buffer, length);
+               kv->databuf = malloc_zone_calloc(zone, 1, length);
+               if (kv->databuf == NULL)
+               {
+                       free(kv);
+                       kv = NULL;
+               }
+               else
+               {
+                       memcpy(kv->databuf, buffer, length);
+               }
        }
 
        return kv;
        }
 
        return kv;
@@ -271,24 +274,24 @@ kvbuf_init(char *buffer, uint32_t length)
 static void
 kvbuf_grow(kvbuf_t *kv, uint32_t delta)
 {
 static void
 kvbuf_grow(kvbuf_t *kv, uint32_t delta)
 {
-       uint32_t newlen, n;
-       char *p;
+       uint32_t newlen;
+       char *p, *newbuf;
+       malloc_zone_t *zone;
 
        if (kv == NULL) return;
        if (delta == 0) return;
 
        if (kv->databuf == NULL) delta += sizeof(uint32_t);
 
 
        if (kv == NULL) return;
        if (delta == 0) return;
 
        if (kv->databuf == NULL) delta += sizeof(uint32_t);
 
-       n = (delta + KVBUF_CHUNK - 1) / KVBUF_CHUNK;
-       newlen = kv->datalen + (n * KVBUF_CHUNK);
-
+       newlen = kv->datalen + delta;
        if (newlen <= kv->_size) return;
 
        if (newlen <= kv->_size) return;
 
-       kv->_size = newlen;
+       kv->_size = ((newlen + KVBUF_CHUNK - 1) / KVBUF_CHUNK) * KVBUF_CHUNK;
 
 
+       zone = malloc_zone_from_ptr(kv);
        if (kv->databuf == NULL)
        {
        if (kv->databuf == NULL)
        {
-               kv->databuf = calloc(1, kv->_size);
+               kv->databuf = malloc_zone_calloc(zone, 1, kv->_size);
                if (kv->databuf == NULL)
                {
                        memset(kv, 0, sizeof(kvbuf_t));
                if (kv->databuf == NULL)
                {
                        memset(kv, 0, sizeof(kvbuf_t));
@@ -300,7 +303,9 @@ kvbuf_grow(kvbuf_t *kv, uint32_t delta)
        }
        else
        {
        }
        else
        {
-               kv->databuf = reallocf(kv->databuf, kv->_size);
+               newbuf = malloc_zone_realloc(zone, kv->databuf, kv->_size);
+               if (newbuf == NULL) free(kv->databuf);
+               kv->databuf = newbuf;
                if (kv->databuf == NULL)
                {
                        memset(kv, 0, sizeof(kvbuf_t));
                if (kv->databuf == NULL)
                {
                        memset(kv, 0, sizeof(kvbuf_t));
index 127d78f349dc2330706037b33bfc95cb2ac28821..0f5f2e2a7e9f14a9c5d0b9936e48b5cbbe7e3e25 100644 (file)
@@ -33,7 +33,6 @@
 #include <pthread.h>
 #include <arpa/inet.h>
 #include <netinet/if_ether.h>
 #include <pthread.h>
 #include <arpa/inet.h>
 #include <netinet/if_ether.h>
-#include <libkern/OSAtomic.h>
 #include "si_module.h"
 #include "libinfo.h"
 #include <thread_data.h>
 #include "si_module.h"
 #include "libinfo.h"
 #include <thread_data.h>
 #define IPV6_ADDR_LEN 16
 #define IPV4_ADDR_LEN 4
 
 #define IPV6_ADDR_LEN 16
 #define IPV4_ADDR_LEN 4
 
+/* The kernel's initgroups call */
+extern int __initgroups(u_int gidsetsize, gid_t *gidset, int gmuid);
+
 /* SPI from long ago */
 int _proto_stayopen;
 
 /* SPI from long ago */
 int _proto_stayopen;
 
-__private_extern__ struct addrinfo *si_list_to_addrinfo(si_list_t *list);
+extern struct addrinfo *si_list_to_addrinfo(si_list_t *list);
+extern int getnameinfo_link(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags);
+__private_extern__ void search_set_flags(si_mod_t *si, const char *name, uint32_t flag);
 
 /*
  * Impedence matching for async calls.
 
 /*
  * Impedence matching for async calls.
@@ -68,22 +72,22 @@ typedef struct
        int32_t key_offset;
 } si_context_t;
 
        int32_t key_offset;
 } si_context_t;
 
-__private_extern__ si_mod_t *
+si_mod_t *
 si_search(void)
 {
        static si_mod_t *search = NULL;
 si_search(void)
 {
        static si_mod_t *search = NULL;
-       static OSSpinLock spin = OS_SPINLOCK_INIT;
 
 
-       if (search == NULL)
-       {
-               OSSpinLockLock(&spin);
-               if (search == NULL) search = si_module_with_name("search");
-               OSSpinLockUnlock(&spin);
-       }
+       if (search == NULL) search = si_module_with_name("search");
 
        return search;
 }
 
 
        return search;
 }
 
+void
+si_search_module_set_flags(const char *name, uint32_t flag)
+{
+       search_set_flags(si_search(), name, flag);
+}
+
 static void
 si_libinfo_general_callback(si_item_t *item, uint32_t status, void *ctx)
 {
 static void
 si_libinfo_general_callback(si_item_t *item, uint32_t status, void *ctx)
 {
@@ -555,8 +559,8 @@ endnetgrent(void)
 
 /* GROUPLIST */
 
 
 /* GROUPLIST */
 
-int
-getgrouplist(const char *name, int basegid, int *groups, int *ngroups)
+static int
+getgrouplist_internal(const char *name, int basegid, gid_t *groups, uint32_t *ngroups, int set_thread_data)
 {
        int i, j, x, g, add, max;
        si_item_t *item;
 {
        int i, j, x, g, add, max;
        si_item_t *item;
@@ -584,7 +588,7 @@ getgrouplist(const char *name, int basegid, int *groups, int *ngroups)
        *ngroups = 1;
 
        item = si_grouplist(si_search(), name);
        *ngroups = 1;
 
        item = si_grouplist(si_search(), name);
-       LI_set_thread_item(CATEGORY_GROUPLIST, item);
+       if (set_thread_data != 0) LI_set_thread_item(CATEGORY_GROUPLIST, item);
        if (item == NULL) return 0;
 
        gl = (si_grouplist_t *)((uintptr_t)item + sizeof(si_item_t));
        if (item == NULL) return 0;
 
        gl = (si_grouplist_t *)((uintptr_t)item + sizeof(si_item_t));
@@ -615,6 +619,12 @@ getgrouplist(const char *name, int basegid, int *groups, int *ngroups)
        return 0;
 }
 
        return 0;
 }
 
+int
+getgrouplist(const char *name, int basegid, int *groups, int *ngroups)
+{
+       return getgrouplist_internal(name, basegid, (gid_t *)groups, (uint32_t *)ngroups, 1);
+}
+
 /* XXX to do: async getgrouplist */
 
 static int
 /* XXX to do: async getgrouplist */
 
 static int
@@ -737,7 +747,9 @@ getgroupcount(const char *name, gid_t basegid)
 int
 initgroups(const char *name, int basegid)
 {
 int
 initgroups(const char *name, int basegid)
 {
-       int status, ngroups, groups[NGROUPS];
+       int status;
+       uint32_t ngroups;
+       gid_t groups[NGROUPS];
        uid_t uid;
 #ifdef DS_AVAILABLE
        si_item_t *item;
        uid_t uid;
 #ifdef DS_AVAILABLE
        si_item_t *item;
@@ -765,14 +777,14 @@ initgroups(const char *name, int basegid)
 
        ngroups = NGROUPS;
 
 
        ngroups = NGROUPS;
 
-       status = getgrouplist(name, basegid, groups, &ngroups);
+       status = getgrouplist_internal(name, basegid, groups, &ngroups, 0);
        /*
         * Ignore status.
         * A failure either means that user belongs to more than NGROUPS groups 
         * or no groups at all.
         */
 
        /*
         * Ignore status.
         * A failure either means that user belongs to more than NGROUPS groups 
         * or no groups at all.
         */
 
-       status = syscall(SYS_initgroups, ngroups, groups, uid);
+       status = __initgroups(ngroups, groups, uid);
        if (status < 0) return -1;
 
        return 0;
        if (status < 0) return -1;
 
        return 0;
@@ -1470,7 +1482,7 @@ int
 ether_hostton(const char *name, struct ether_addr *e)
 {
        si_item_t *item;
 ether_hostton(const char *name, struct ether_addr *e)
 {
        si_item_t *item;
-       char *cmac;
+       si_mac_t *mac;
        uint32_t t[6];
        int i;
 
        uint32_t t[6];
        int i;
 
@@ -1485,9 +1497,9 @@ ether_hostton(const char *name, struct ether_addr *e)
        LI_set_thread_item(CATEGORY_MAC + 100, item);
        if (item == NULL) return -1;
 
        LI_set_thread_item(CATEGORY_MAC + 100, item);
        if (item == NULL) return -1;
 
-       cmac = (char *)((uintptr_t)item + sizeof(si_item_t));
+       mac = (si_mac_t *)((uintptr_t)item + sizeof(si_item_t));
 
 
-       i = sscanf(cmac, " %x:%x:%x:%x:%x:%x", &t[0], &t[1], &t[2], &t[3], &t[4], &t[5]);
+       i = sscanf(mac->mac, " %x:%x:%x:%x:%x:%x", &t[0], &t[1], &t[2], &t[3], &t[4], &t[5]);
        if (i != 6) return -1;
 
        for (i = 0; i < 6; i++) e->ether_addr_octet[i] = t[i];
        if (i != 6) return -1;
 
        for (i = 0; i < 6; i++) e->ether_addr_octet[i] = t[i];
@@ -1500,7 +1512,7 @@ int
 ether_ntohost(char *name, const struct ether_addr *e)
 {
        si_item_t *item;
 ether_ntohost(char *name, const struct ether_addr *e)
 {
        si_item_t *item;
-       char *cname;
+       si_mac_t *mac;
        uint32_t i, x[6];
        char str[256];
 
        uint32_t i, x[6];
        char str[256];
 
@@ -1518,9 +1530,9 @@ ether_ntohost(char *name, const struct ether_addr *e)
        LI_set_thread_item(CATEGORY_MAC + 200, item);
        if (item == NULL) return -1;
 
        LI_set_thread_item(CATEGORY_MAC + 200, item);
        if (item == NULL) return -1;
 
-       cname = (char *)((uintptr_t)item + sizeof(si_item_t));
+       mac = (si_mac_t *)((uintptr_t)item + sizeof(si_item_t));
 
 
-       memcpy(name, cname, strlen(cname) + 1);
+       memcpy(name, mac->host, strlen(mac->host) + 1);
        return 0;
 }
 
        return 0;
 }
 
@@ -2264,7 +2276,7 @@ _getaddrinfo_internal(const char *nodename, const char *servname, const struct a
 #endif
 
        list = si_addrinfo(si_search(), nodename, servname, family, socktype, protocol, flags, interface, &status);
 #endif
 
        list = si_addrinfo(si_search(), nodename, servname, family, socktype, protocol, flags, interface, &status);
-       if ((status != SI_STATUS_NO_ERROR) || (list == NULL))
+       if ((status != SI_STATUS_NO_ERROR) || (list == NULL) || (list->count == 0))
        {
                si_list_release(list);
 
        {
                si_list_release(list);
 
@@ -2681,6 +2693,9 @@ _getnameinfo_interface_internal(const struct sockaddr *sa, socklen_t salen, char
 int
 getnameinfo(const struct sockaddr *sa, socklen_t salen, char *node, socklen_t nodelen, char *service, socklen_t servicelen, int flags)
 {
 int
 getnameinfo(const struct sockaddr *sa, socklen_t salen, char *node, socklen_t nodelen, char *service, socklen_t servicelen, int flags)
 {
+       if (sa == NULL) return EAI_FAIL;
+
+       if (sa->sa_family == AF_LINK) return getnameinfo_link(sa, salen, node, nodelen, service, servicelen, flags);
        return _getnameinfo_interface_internal(sa, salen, node, nodelen, service, servicelen, flags, NULL);
 }
 
        return _getnameinfo_interface_internal(sa, salen, node, nodelen, service, servicelen, flags, NULL);
 }
 
index a2ae50b95c4ded841b445e24aa4db313fe39baeb..477d62597d493c9fd91b4cc65d45309996c1482c 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2008 Apple Inc.  All rights reserved.
+ * Copyright (c) 2008-2010 Apple Inc.  All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 
 #include <si_module.h>
 
 
 #include <si_module.h>
 
+/*
+ * SPI to disable / enable modules during Libinfo search.
+ * Currently known module names are "cache", "ds", "file", and "mdns".
+ * Use flag = 0 to disable a module, flag = 1 to enable.
+ */
+void si_search_module_set_flags(const char *name, uint32_t flag);
+
 /*
  * Most of these async callbacks get data that's held in thread-specific
  * memory (specific to the callback thread) that will be re-used by that
 /*
  * Most of these async callbacks get data that's held in thread-specific
  * memory (specific to the callback thread) that will be re-used by that
index 980380e72f473f224faa567430999c98e165c0b1..7f23aadd63f33cc4333171045d481ba6a100a702 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2008-2009 Apple Inc. All rights reserved.
+ * Copyright (c) 2008-2011 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include <dns.h>
 #include <dns_util.h>
 #include <TargetConditionals.h>
 #include <dns.h>
 #include <dns_util.h>
 #include <TargetConditionals.h>
-
-__private_extern__ int si_inet_config(uint32_t *inet4, uint32_t *inet6);
+#include <dispatch/dispatch.h>
 
 /* from dns_util.c */
 #define DNS_MAX_RECEIVE_SIZE 65536
 
 /* from dns_util.c */
 #define DNS_MAX_RECEIVE_SIZE 65536
@@ -139,23 +138,6 @@ static int _mdns_debug = 0;
 // mutex protects DNSServiceProcessResult and DNSServiceRefDeallocate
 static pthread_mutex_t _mdns_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 // mutex protects DNSServiceProcessResult and DNSServiceRefDeallocate
 static pthread_mutex_t _mdns_mutex = PTHREAD_MUTEX_INITIALIZER;
 
-// XXX
-// Options: timeout:n total_timeout attempts
-
-/* _dns_config_token: notify token indicating dns config needs refresh
- */
-static int _dns_config_token = -1;
-
-typedef struct {
-       int32_t rc;
-       dns_config_t *dns;
-       dns_resolver_t *primary;
-       uint32_t n_defaults;
-       dns_resolver_t **defaults;
-       char **search_list;
-       int ndots;
-} mdns_config_t;
-
 typedef struct {
        uint16_t priority;
        uint16_t weight;
 typedef struct {
        uint16_t priority;
        uint16_t weight;
@@ -184,17 +166,12 @@ typedef struct {
 } mdns_reply_t;
 
 static uint32_t _mdns_generation = 0;
 } mdns_reply_t;
 
 static uint32_t _mdns_generation = 0;
-DNSServiceRef _mdns_sdref;
-DNSServiceRef _mdns_old_sdref;
-
-static int _mdns_query_mDNSResponder(const char *name, int class, int type,
-       const char *interface, DNSServiceFlags flags,
-       uint8_t *answer, uint32_t *anslen,
-       mdns_reply_t *reply, uint32_t timeout);
+static DNSServiceRef _mdns_sdref;
+static DNSServiceRef _mdns_old_sdref;
 
 
-static int _mdns_resolver_get_option(dns_resolver_t *resolver, const char* option);
 static void _mdns_hostent_clear(mdns_hostent_t *h);
 static void _mdns_reply_clear(mdns_reply_t *r);
 static void _mdns_hostent_clear(mdns_hostent_t *h);
 static void _mdns_reply_clear(mdns_reply_t *r);
+static int _mdns_search(const char *name, int class, int type, const char *interface, DNSServiceFlags flags, uint8_t *answer, uint32_t *anslen, mdns_reply_t *reply);
 
 static const char hexchar[] = "0123456789abcdef";
 
 
 static const char hexchar[] = "0123456789abcdef";
 
@@ -220,462 +197,6 @@ const static uint8_t hexval[128] = {
        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0           /* 112 - 127 */
 };
 
        0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0           /* 112 - 127 */
 };
 
-/*
- * _mdns_create_search_list
- * Creates a NULL terminated array of strings from the specied resolver's
- * search list, or from the components of the specified resolver's domain
- * if search list is empty.
- * Free the list and elements with free(3) when done.
- */
-static char **
-_mdns_create_search_list(dns_resolver_t *resolver)
-{
-       int n, m;
-       char *p, *domain;
-       char **list;
-
-       if (resolver == NULL) return NULL;
-
-       // return the search list if present
-       if (resolver->n_search > 0) {
-               list = (char **)calloc(resolver->n_search+1, sizeof(char *));
-               if (list == NULL) return NULL;
-               for (n = 0; n < resolver->n_search; ++n) {
-                       list[n] = strdup(resolver->search[n]);
-               }
-               return list;
-       }
-
-       if (resolver->domain == NULL) return NULL;
-       domain = strdup(resolver->domain);
-       if (domain == NULL) return NULL;
-
-       // count dots
-       n = 0;
-       for (p = domain; *p != '\0'; p++) {
-               if (*p == '.') n++;
-       }
-
-       // trim trailing dots
-       for (p--; (p >= domain) && (*p == '.'); p--) {
-               *p = '\0';
-               n--;
-       }
-
-       // make sure the resulting string is not empty
-       if (p < domain) {
-               free(domain);
-               return NULL;
-       }
-
-       // dots are separators, so number of components is one larger
-       n++;
-
-       m = 0;
-       list = (char **)calloc(n+1, sizeof(char *));
-       if (list == NULL) return NULL;
-       // first item in list is domain itself
-       list[m++] = domain;
-
-       // include parent domains with at least LOCALDOMAINPARTS components
-       p = domain;
-       while (n > LOCALDOMAINPARTS) {
-               // find next component
-               while ((*p != '.') && (*p != '\0')) p++;
-               if (*p == '\0') break;
-               p++;
-               // add to the list
-               n--;
-               list[m++] = strdup(p);
-       }
-       return list;
-}
-
-/* _mdns_resolver_get_option
- * Determines whether the specified option is present in the resolver.
- */
-static int
-_mdns_resolver_get_option(dns_resolver_t *resolver, const char* option)
-{
-       if (resolver == NULL) return 0;
-       int len = strlen(option);
-       char *options = resolver->options;
-       if (options == NULL) return 0;
-       // look for "(^| )option( |:|$)"
-       char *ptr = strstr(options, option);
-       while (ptr) {
-               if (ptr == options || ptr[-1] == ' ') {
-                       if (ptr[len] == ' ' || ptr[len] == 0) {
-                               return 1;
-                       } else if (ptr[len] == ':') {
-                               return strtol(&ptr[len+1], NULL, 10);
-                       }
-               }
-               ptr = strstr(ptr, option);
-       }
-       return 0;
-}
-
-/* _mdns_compare_resolvers
- * Compares two dns_resolver_t pointers by search order ascending.
- */
-static int
-_mdns_compare_resolvers(const void *a, const void *b) 
-{
-       dns_resolver_t **x = (dns_resolver_t **)a, **y = (dns_resolver_t **)b;
-       return ((*x)->search_order - (*y)->search_order);
-}
-
-/* _mdns_create_default_resolvers_list
- * Returns an array of dns_resolver_t containing only default resolvers.
- * A resolver is a default resolver if it is the primary resolver or if it
- * contains the "default" configuration option.
- */
-static void
-_mdns_config_init_default_resolvers(mdns_config_t *config)
-{
-       uint32_t count = config->dns->n_resolver;
-       if (count == 0) return;
-       config->defaults = calloc(count, sizeof(dns_resolver_t *));
-       if (config->defaults == NULL) return;
-       int m = 0, i, j;
-       if (config->primary) config->defaults[m++] = config->primary;
-       // iterate the resolvers, add any default resolvers that are not
-       // already in the list.
-       for (i = 0; i < count; ++i) {
-               dns_resolver_t *resolver = config->dns->resolver[i];
-               if (_mdns_resolver_get_option(resolver, "default")) {
-                       int exists = 0;
-                       for (j = 0; j < m; ++j) {
-                               if (config->defaults[j] == resolver) {
-                                       exists = 1;
-                                       break;
-                               }
-                       }
-                       if (!exists) {
-                               config->defaults[m++] = resolver;
-                       }
-               }
-       }
-       config->n_defaults = m;
-       // sort list by search order ascending
-       qsort(config->defaults, config->n_defaults, sizeof(dns_resolver_t *), _mdns_compare_resolvers);
-}
-
-#if 0
-static void
-_mdns_print_dns_resolver(dns_resolver_t *resolver)
-{
-       printf("resolver = {\n");
-       printf("\tdomain = %s\n", resolver->domain);
-       int j;
-       for (j = 0; j < resolver->n_nameserver; ++j) {
-               int res;
-               char host[255], serv[255];
-               res = getnameinfo(resolver->nameserver[j], resolver->nameserver[j]->sa_len, host, sizeof(host), serv, sizeof(serv), NI_NUMERICHOST | NI_NUMERICSERV);
-               if (res == 0) {
-                       printf("\tnameserver[%d] = %s:%s\n", j, host, serv);
-               } else {
-                       printf("\tnameserver[%d] = %s\n", j, gai_strerror(res));
-               }
-       }
-       printf("\tport = %d\n", resolver->port);
-       for (j = 0; j < resolver->n_search; ++j) {
-               printf("\tsearch[%d] = %s\n", j, resolver->search[j]);
-       }
-       // sortaddr
-       printf("\tn_sortaddr = %d\n", resolver->n_sortaddr);
-       // options
-       printf("\toptions = %s\n", resolver->options);
-       printf("\ttimeout = %d\n", resolver->timeout);
-       printf("\tsearch_order = %d\n", resolver->search_order);
-       printf("}\n");
-}
-
-static void
-_mdns_print_dns_config(dns_config_t *config)
-{
-       int i;
-       dns_resolver_t **list = _mdns_create_sorted_resolver_list(config);
-       dns_resolver_t **ptr = list;
-       while (*ptr) {
-               _mdns_print_dns_resolver(*ptr);
-               ptr++;
-       }
-       free(list);
-}
-
-static void
-_mdns_print_hostent(mdns_hostent_t* h)
-{
-       if (h == NULL) return;
-       printf("hostent[%p] = {\n", h);
-       printf("\thost = {\n");
-       printf("\t\th_name = %s\n", h->host.h_name);
-       printf("\t\th_length = %d\n", h->host.h_length);
-       printf("\t\th_addrtype = %d\n", h->host.h_addrtype);
-       char **alias = h->host.h_aliases;
-       while (alias && *alias) {
-               printf("\t\th_aliases = %s\n", *alias++);
-       }
-       char **addr = h->host.h_addr_list;
-       while (addr && *addr) {
-               printf("\t\th_addr_list = %x\n", ntohl(*(uint32_t*)*addr++));
-       }
-       printf("\t}\n");
-       printf("\talias_count = %d\n", h->alias_count);
-       printf("\taddr_count = %d\n", h->addr_count);
-       printf("}\n");
-}
-
-#endif
-
-/* _mdns_config_retain
- * Retain the mdns configuration.
- */
-static mdns_config_t *
-_mdns_config_retain(mdns_config_t *config)
-{
-       int32_t rc;
-
-       if (config == NULL) return NULL;
-       rc = OSAtomicIncrement32Barrier(&config->rc);
-       assert(rc > 1);
-       return config;
-}
-
-/* _mdns_config_release
- * Releases the mdns configuration structure and
- * frees the data if no references remain.
- */
-static void
-_mdns_config_release(mdns_config_t *config)
-{
-       int32_t rc;
-
-       if (config == NULL) return;
-       rc = OSAtomicDecrement32Barrier(&config->rc);
-       assert(rc >= 0);
-       if (rc == 0) {
-               if (config->dns) dns_configuration_free(config->dns);
-               free(config->defaults);
-               char **p = config->search_list;
-               while (p && *p) { free(*p++); }
-               free(config->search_list);
-               free(config);
-       }
-}
-
-/* _mdns_copy_system_config
- * Retrieves DNS configuration from SystemConfiguration.framework.
- * Checks notify notification to determine whether configuration is in need
- * of a refresh.
- */
-static mdns_config_t *
-_mdns_copy_system_config(void)
-{
-       // first call needs refresh
-       static mdns_config_t *current_config;
-       mdns_config_t *config = NULL;
-       int refresh = 1;
-       int res;
-
-       pthread_mutex_lock(&_mdns_mutex);
-
-       // check whether the global configuration has changed
-       if (_dns_config_token == -1) {
-               res = notify_register_check(dns_configuration_notify_key(), &_dns_config_token);
-               if (res != NOTIFY_STATUS_OK) _dns_config_token = -1;
-       }
-
-       if (_dns_config_token != -1) {
-               res = notify_check(_dns_config_token, &refresh);
-               if (res != NOTIFY_STATUS_OK) refresh = 1;
-       }
-
-       // return the current configuration if still valid
-       if (refresh == 0) {
-               mdns_config_t *config = _mdns_config_retain(current_config);
-               pthread_mutex_unlock(&_mdns_mutex);
-               return config;
-       }
-
-       // need to allocate a new configuration
-
-       config = calloc(1, sizeof(mdns_config_t));
-       if (config != NULL) config->dns = dns_configuration_copy();
-
-       // failed to get new config, return previous config
-       if (config == NULL || config->dns == NULL) {
-               free(config);
-               config = _mdns_config_retain(current_config);
-               pthread_mutex_unlock(&_mdns_mutex);
-               return config;
-       }
-
-       config->rc = 1;
-       if (config->dns->n_resolver > 0) {
-               // primary resolver is always index 0 and contains the
-               // search domains
-               config->primary = config->dns->resolver[0];
-               config->search_list = _mdns_create_search_list(config->primary);
-               _mdns_config_init_default_resolvers(config);
-       }
-       config->ndots = _mdns_resolver_get_option(config->primary, "ndots");
-
-       // promote the new configuration to current
-       _mdns_config_release(current_config);
-       current_config = config;
-
-       // return the new configuration
-       config = _mdns_config_retain(config);
-       pthread_mutex_unlock(&_mdns_mutex);
-       return config;
-}
-
-/* _mdns_timeout_for_name
- * Returns the appropriate timeout for the specified name based on the
- * sum of the timeouts of all resolvers that match the name.
- */
-static uint32_t
-_mdns_timeout_for_name(mdns_config_t *config, const char *name)
-{
-       int i;
-       uint32_t timeout = 0;
-
-       if (name == NULL) return 0;
-
-       // use strncasecmp to ignore a trailing '.' in name
-       int len = strlen(name);
-       if ((len - 1) >= 0 && name[len-1] == '.') --len;
-
-       const char *p = name;
-       while (len > 0) {
-               uint32_t count = config->dns->n_resolver;
-               for (i = 0; i < count; ++i) {
-                       dns_resolver_t *resolver = config->dns->resolver[i];
-                       if (resolver->domain == NULL) continue;
-                       if (strncasecmp(resolver->domain, p, len) == 0) {
-                               timeout += resolver->timeout;
-                       }
-               }
-               // discard the current label
-               while (len > 0) {
-                       ++p;
-                       --len;
-                       if (p[-1] == '.') break;
-               }
-       }
-       return timeout;
-}
-
-/* _mdns_query_unqualified
- * Performs a query for the name as an unqualified name (appends each
- * of the default resolver's domains).
- */
-static int
-_mdns_query_unqualified(mdns_config_t *config, const char *name, uint32_t class, uint32_t type, const char *interface, DNSServiceFlags flags, uint8_t *buf, uint32_t *len, mdns_reply_t *reply)
-{
-       int i, res = -1;
-
-       for (i = 0; i < config->n_defaults; ++i) {
-               dns_resolver_t *resolver = config->defaults[i];
-               char *qname;
-
-               asprintf(&qname, "%s.%s", name, resolver->domain ? resolver->domain : "");
-               res = _mdns_query_mDNSResponder(qname, class, type, interface, flags, buf, len, reply, resolver->timeout);
-               free(qname);
-
-               if (res == 0) break;
-               else _mdns_reply_clear(reply);
-       }
-       return res;
-}
-
-/* _mdns_query_absolute
- * Performs a query for the name as an absolute name (does not qualify with any
- * additional domains).
- */
-static int
-_mdns_query_absolute(mdns_config_t *config, const char *name, uint32_t class, uint32_t type, const char *interface, DNSServiceFlags flags, uint32_t fqdn, uint8_t *buf, uint32_t *len, mdns_reply_t *reply)
-{
-       int res = -1;
-       char *qname = (char *)name;
-
-       uint32_t timeout = _mdns_timeout_for_name(config, name);
-
-       if (fqdn == 0) asprintf(&qname, "%s.", name);
-       res = _mdns_query_mDNSResponder(qname, class, type, interface, flags, buf, len, reply, timeout);
-       if (fqdn == 0) free(qname);
-       if (res != 0) _mdns_reply_clear(reply);
-       return res;
-}
-
-static int
-_mdns_search(const char *name, uint32_t class, uint32_t type, const char *interface, DNSServiceFlags flags, uint32_t fqdn, uint32_t recurse, uint8_t *buf, uint32_t *len, mdns_reply_t *reply)
-{
-       int res = -1;
-       int i, n, ndots;
-       char *dot;
-
-       if (name == NULL) return -1;
-
-       mdns_config_t *config = _mdns_copy_system_config();
-       if (config == NULL) return -1;
-
-       // NDOTS is the threshold for trying a qualified name "as is"
-       ndots = config->ndots;
-       if (ndots == 0) ndots = 1;
-
-       // count the dots, and remember position of the last one
-       n = 0;
-       dot = NULL;
-       for (i = 0; name[i] != '\0'; i++) {
-               if (name[i] == '.') {
-                       n++;
-                       dot = (char *)(name + i);
-               }
-       }
-       // FQDN has dot for last character
-       if (fqdn == 0 && dot != NULL && dot[1] == '\0') fqdn = 1;
-
-       // if the name has at least ndots, try first as an absolute query.
-       // FQDN and PTR queries are always absolute.
-       if (n >= ndots || fqdn == 1 || type == ns_t_ptr) {
-               res = _mdns_query_absolute(config, name, class, type, interface, flags, fqdn, buf, len, reply);
-               if (res == 0) {
-                       _mdns_config_release(config);
-                       return res;
-               }
-       }
-
-       // stop if FQDN, PTR, or no recursion requested
-       if (fqdn == 1 || type == ns_t_ptr || recurse == 0) {
-               _mdns_config_release(config);
-               return -1;
-       }
-
-       // Qualify the name with each of the search domains looking for a match.
-       char **search = config->search_list;
-       if (search != NULL) {
-               res = -1;
-               for (i = 0; i < MAXDNSRCH && search[i] != NULL; ++i) {
-                       char *qname;
-                       asprintf(&qname, "%s.%s", name, search[i]);
-                       res = _mdns_search(qname, class, type, interface, flags, 0, 0, buf, len, reply);
-                       free(qname);
-                       if (res == 0) break;
-               }
-       } else {
-               // The name is not fully qualified and there is no search list.
-               // Try each default resolver, qualifying the name with that
-               // resolver's domain.
-               res = _mdns_query_unqualified(config, name, class, type, interface, flags, buf, len, reply);
-       }
-       _mdns_config_release(config);
-       return res;
-}
-
 static char *
 _mdns_reverse_ipv4(const char *addr)
 {
 static char *
 _mdns_reverse_ipv4(const char *addr)
 {
@@ -846,7 +367,7 @@ _mdns_reply_clear(mdns_reply_t *r)
 }
 
 static si_item_t *
 }
 
 static si_item_t *
-_mdns_hostbyname(si_mod_t *si, const char *name, int af, const char *interface, uint32_t *err)
+mdns_hostbyname(si_mod_t *si, const char *name, int af, const char *interface, uint32_t *err)
 {
        uint32_t type;
        mdns_hostent_t h;
 {
        uint32_t type;
        mdns_hostent_t h;
@@ -883,7 +404,7 @@ _mdns_hostbyname(si_mod_t *si, const char *name, int af, const char *interface,
        }
        h.host.h_addrtype = af;
 
        }
        h.host.h_addrtype = af;
 
-       status = _mdns_search(name, ns_c_in, type, interface, flags, 0, 1, NULL, NULL, &reply);
+       status = _mdns_search(name, ns_c_in, type, interface, flags, NULL, NULL, &reply);
        if (status != 0 || h.addr_count == 0) {
                _mdns_reply_clear(&reply);
                if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
        if (status != 0 || h.addr_count == 0) {
                _mdns_reply_clear(&reply);
                if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
@@ -909,7 +430,7 @@ _mdns_hostbyname(si_mod_t *si, const char *name, int af, const char *interface,
 }
 
 static si_item_t *
 }
 
 static si_item_t *
-_mdns_hostbyaddr(si_mod_t *si, const void *addr, int af, const char *interface, uint32_t *err)
+mdns_hostbyaddr(si_mod_t *si, const void *addr, int af, const char *interface, uint32_t *err)
 {
        mdns_hostent_t h;
        mdns_reply_t reply;
 {
        mdns_hostent_t h;
        mdns_reply_t reply;
@@ -949,7 +470,7 @@ _mdns_hostbyaddr(si_mod_t *si, const void *addr, int af, const char *interface,
        }
        h.host.h_addrtype = af;
 
        }
        h.host.h_addrtype = af;
 
-       status = _mdns_search(name, ns_c_in, ns_t_ptr, interface, flags, 0, 1, NULL, NULL, &reply);
+       status = _mdns_search(name, ns_c_in, ns_t_ptr, interface, flags, NULL, NULL, &reply);
        free(name);
        if (status != 0) {
                _mdns_reply_clear(&reply);
        free(name);
        if (status != 0) {
                _mdns_reply_clear(&reply);
@@ -974,14 +495,10 @@ _mdns_hostbyaddr(si_mod_t *si, const void *addr, int af, const char *interface,
 }
 
 static si_list_t *
 }
 
 static si_list_t *
-_mdns_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err)
+mdns_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err)
 {
        int wantv4 = 1;
        int wantv6 = 1;
 {
        int wantv4 = 1;
        int wantv6 = 1;
-       if (family == AF_INET6) wantv4 = 0;
-       else if (family == AF_INET) wantv6 = 0;
-       else if (family != AF_UNSPEC) return NULL;
-
        struct in_addr a4;
        struct in6_addr a6;
        mdns_hostent_t h4;
        struct in_addr a4;
        struct in6_addr a6;
        mdns_hostent_t h4;
@@ -990,6 +507,19 @@ _mdns_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family
        uint32_t type;
        uint16_t port;
 
        uint32_t type;
        uint16_t port;
 
+       if (family == AF_INET6)
+       {
+               if ((flags & AI_V4MAPPED) == 0) wantv4 = 0;
+       }
+       else if (family == AF_INET)
+       {
+               wantv6 = 0;
+       }
+       else if (family != AF_UNSPEC)
+       {
+               return NULL;
+       }
+
        if (err != NULL) *err = SI_STATUS_NO_ERROR;
 
        si_list_t *out = NULL;
        if (err != NULL) *err = SI_STATUS_NO_ERROR;
 
        si_list_t *out = NULL;
@@ -1040,16 +570,16 @@ _mdns_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family
                        p6 = &a6;
                        memcpy(p6, node, sizeof(a6));
                }
                        p6 = &a6;
                        memcpy(p6, node, sizeof(a6));
                }
-               out = si_addrinfo_list(si, socktype, proto, p4, p6, port, 0, cname, cname);
+               out = si_addrinfo_list(si, flags, socktype, proto, p4, p6, port, 0, cname, cname);
        } else {
                DNSServiceFlags dns_flags = 0;
                if (flags & AI_ADDRCONFIG) {
                        dns_flags |= kDNSServiceFlagsSuppressUnusable;
                }
                int res;
        } else {
                DNSServiceFlags dns_flags = 0;
                if (flags & AI_ADDRCONFIG) {
                        dns_flags |= kDNSServiceFlagsSuppressUnusable;
                }
                int res;
-               res = _mdns_search(node, ns_c_in, type, interface, dns_flags, 0, 1, NULL, NULL, &reply);
+               res = _mdns_search(node, ns_c_in, type, interface, dns_flags, NULL, NULL, &reply);
                if (res == 0 && (h4.addr_count > 0 || h6.addr_count > 0)) {
                if (res == 0 && (h4.addr_count > 0 || h6.addr_count > 0)) {
-                       out = si_addrinfo_list_from_hostent(si, socktype, proto,
+                       out = si_addrinfo_list_from_hostent(si, flags, socktype, proto,
                                                                                                port, 0,
                                                                                                (wantv4 ? &h4.host : NULL),
                                                                                                (wantv6 ? &h6.host : NULL));
                                                                                                port, 0,
                                                                                                (wantv4 ? &h4.host : NULL),
                                                                                                (wantv6 ? &h6.host : NULL));
@@ -1062,7 +592,7 @@ _mdns_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family
 }
 
 static si_list_t *
 }
 
 static si_list_t *
-_mdns_srv_byname(si_mod_t* si, const char *qname, const char *interface, uint32_t *err)
+mdns_srv_byname(si_mod_t* si, const char *qname, const char *interface, uint32_t *err)
 {
        si_list_t *out = NULL;
        mdns_reply_t reply;
 {
        si_list_t *out = NULL;
        mdns_reply_t reply;
@@ -1074,7 +604,7 @@ _mdns_srv_byname(si_mod_t* si, const char *qname, const char *interface, uint32_
        if (err != NULL) *err = SI_STATUS_NO_ERROR;
 
        memset(&reply, 0, sizeof(reply));
        if (err != NULL) *err = SI_STATUS_NO_ERROR;
 
        memset(&reply, 0, sizeof(reply));
-       res = _mdns_search(qname, ns_c_in, ns_t_srv, interface, flags, 0, 1, NULL, NULL, &reply);
+       res = _mdns_search(qname, ns_c_in, ns_t_srv, interface, flags, NULL, NULL, &reply);
        if (res == 0) {
                srv = reply.srv;
                while (srv) {
        if (res == 0) {
                srv = reply.srv;
                while (srv) {
@@ -1093,7 +623,7 @@ _mdns_srv_byname(si_mod_t* si, const char *qname, const char *interface, uint32_
  * We support dns_async_start / cancel / handle_reply using dns_item_call
  */
 static si_item_t *
  * We support dns_async_start / cancel / handle_reply using dns_item_call
  */
 static si_item_t *
-_mdns_item_call(si_mod_t *si, int call, const char *name, const char *ignored, const char *interface, uint32_t class, uint32_t type, uint32_t *err)
+mdns_item_call(si_mod_t *si, int call, const char *name, const char *ignored, const char *interface, uint32_t class, uint32_t type, uint32_t *err)
 {
        int res;
        uint8_t buf[DNS_MAX_RECEIVE_SIZE];
 {
        int res;
        uint8_t buf[DNS_MAX_RECEIVE_SIZE];
@@ -1102,23 +632,10 @@ _mdns_item_call(si_mod_t *si, int call, const char *name, const char *ignored, c
        mdns_hostent_t h4;
        mdns_hostent_t h6;
        si_item_t *out;
        mdns_hostent_t h4;
        mdns_hostent_t h6;
        si_item_t *out;
-       int norecurse = 0;
        DNSServiceFlags flags = 0;
 
        if (err != NULL) *err = SI_STATUS_NO_ERROR;
 
        DNSServiceFlags flags = 0;
 
        if (err != NULL) *err = SI_STATUS_NO_ERROR;
 
-       switch (call) {
-               case SI_CALL_DNS_QUERY:
-                       norecurse = 1;
-                       break;
-               case SI_CALL_DNS_SEARCH:
-                       break;
-               default:
-                       if (err) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
-                       return NULL;
-                       break;
-       }
-
        if (name == NULL) {
                if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
                return NULL;
        if (name == NULL) {
                if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
                return NULL;
@@ -1135,7 +652,7 @@ _mdns_item_call(si_mod_t *si, int call, const char *name, const char *ignored, c
        reply.h4 = &h4;
        reply.h6 = &h6;
 
        reply.h4 = &h4;
        reply.h6 = &h6;
 
-       res = _mdns_search(name, class, type, interface, flags, norecurse, 1, buf, &len, &reply);
+       res = _mdns_search(name, class, type, interface, flags, buf, &len, &reply);
        if (res != 0 || len <= 0 || len > DNS_MAX_RECEIVE_SIZE) {
                _mdns_reply_clear(&reply);
                if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
        if (res != 0 || len <= 0 || len > DNS_MAX_RECEIVE_SIZE) {
                _mdns_reply_clear(&reply);
                if (err != NULL) *err = SI_STATUS_H_ERRNO_HOST_NOT_FOUND;
@@ -1162,16 +679,14 @@ _mdns_item_call(si_mod_t *si, int call, const char *name, const char *ignored, c
 }
 
 static int
 }
 
 static int
-_mdns_is_valid(si_mod_t *si, si_item_t *item)
+mdns_is_valid(si_mod_t *si, si_item_t *item)
 {
        return 0;
 }
 
 static void
 {
        return 0;
 }
 
 static void
-_mdns_close(si_mod_t *si)
+mdns_close(si_mod_t *si)
 {
 {
-       if (_dns_config_token != -1) notify_cancel(_dns_config_token);
-       //_mdns_dir_token;
 }
 
 static void
 }
 
 static void
@@ -1194,46 +709,49 @@ _mdns_atfork_child(void)
        // child needs to force re-initialization
        _mdns_old_sdref = _mdns_sdref; // for later deallocation
        _mdns_sdref = NULL;
        // child needs to force re-initialization
        _mdns_old_sdref = _mdns_sdref; // for later deallocation
        _mdns_sdref = NULL;
-       _dns_config_token = -1;
        pthread_mutex_unlock(&_mdns_mutex);
 }
 
        pthread_mutex_unlock(&_mdns_mutex);
 }
 
-__private_extern__ si_mod_t *
-si_module_static_mdns(void)
+static void
+_mdns_init(void)
 {
 {
-       si_mod_t *out = (si_mod_t *)calloc(1, sizeof(si_mod_t));
-       char *outname = strdup("mdns");
-
-       if ((out == NULL) || (outname == NULL))
-       {
-               free(out);
-               free(outname);
-               return NULL;
-       }
-
-       out->name = outname;
-       out->vers = 1;
-       out->refcount = 1;
-       out->private = NULL;
-
-       out->sim_close = _mdns_close;
-       out->sim_is_valid = _mdns_is_valid;
-       out->sim_host_byname = _mdns_hostbyname;
-       out->sim_host_byaddr = _mdns_hostbyaddr;
-       out->sim_item_call = _mdns_item_call;
-       out->sim_addrinfo = _mdns_addrinfo;
-       out->sim_srv_byname = _mdns_srv_byname;
-
-       int res;
-
-       res = notify_register_check(dns_configuration_notify_key(), &_dns_config_token);
-       if (res != NOTIFY_STATUS_OK) _dns_config_token = -1;
-
        pthread_atfork(_mdns_atfork_prepare, _mdns_atfork_parent, _mdns_atfork_child);
 
        _mdns_debug = getenv("RES_DEBUG") != NULL;
        pthread_atfork(_mdns_atfork_prepare, _mdns_atfork_parent, _mdns_atfork_child);
 
        _mdns_debug = getenv("RES_DEBUG") != NULL;
+}
 
 
-       return out;
+si_mod_t *
+si_module_static_mdns(void)
+{
+       static const struct si_mod_vtable_s mdns_vtable =
+       {
+               .sim_close = &mdns_close,
+               .sim_is_valid = &mdns_is_valid,
+               .sim_host_byname = &mdns_hostbyname,
+               .sim_host_byaddr = &mdns_hostbyaddr,
+               .sim_item_call = &mdns_item_call,
+               .sim_addrinfo = &mdns_addrinfo,
+               .sim_srv_byname = &mdns_srv_byname,
+       };
+
+       static si_mod_t si =
+       {
+               .vers = 1,
+               .refcount = 1,
+               .flags = SI_MOD_FLAG_STATIC,
+
+               .private = NULL,
+               .vtable = &mdns_vtable,
+       };
+
+       static dispatch_once_t once;
+       
+       dispatch_once(&once, ^{
+               si.name = strdup("mdns");
+               _mdns_init();
+       });
+
+       return (si_mod_t*)&si;
 }
 
 /*
 }
 
 /*
@@ -1248,7 +766,7 @@ _mdns_parse_domain_name(const uint8_t *data, uint32_t datalen)
        uint32_t len;
        uint32_t domainlen = 0;
        char *domain = NULL;
        uint32_t len;
        uint32_t domainlen = 0;
        char *domain = NULL;
-
+       
        if ((data == NULL) || (datalen == 0)) return NULL;
 
        // i: index into input data
        if ((data == NULL) || (datalen == 0)) return NULL;
 
        // i: index into input data
@@ -1286,8 +804,9 @@ _mdns_parse_domain_name(const uint8_t *data, uint32_t datalen)
 static int
 _mdns_pack_domain_name(const char* str, uint8_t *buf, size_t buflen) {
        int i = 0;
 static int
 _mdns_pack_domain_name(const char* str, uint8_t *buf, size_t buflen) {
        int i = 0;
+       uintptr_t len = 0;
+
        while (i < buflen) {
        while (i < buflen) {
-               uintptr_t len;
                // calculate length to next '.' or '\0'
                char *dot = strchr(str, '.');
                if (dot == NULL) dot = strchr(str, '\0');
                // calculate length to next '.' or '\0'
                char *dot = strchr(str, '.');
                if (dot == NULL) dot = strchr(str, '\0');
@@ -1295,13 +814,21 @@ _mdns_pack_domain_name(const char* str, uint8_t *buf, size_t buflen) {
                if (len > NS_MAXLABEL) return -1;
                // copy data for label
                buf[i++] = len;
                if (len > NS_MAXLABEL) return -1;
                // copy data for label
                buf[i++] = len;
-               while (str < dot) {
+               while (str < dot && i < buflen) {
                        buf[i++] = *str++;
                }
                // skip past '.', break if '\0'
                if (*str++ == '\0') break;
        }
                        buf[i++] = *str++;
                }
                // skip past '.', break if '\0'
                if (*str++ == '\0') break;
        }
+
        if (i >= buflen) return -1;
        if (i >= buflen) return -1;
+
+       if (len > 0) {
+               // no trailing dot - add a null label
+               buf[i++] = 0;
+               if (i >= buflen) return -1;
+       }
+
        buf[i] = '\0';
        return i;
 }
        buf[i] = '\0';
        return i;
 }
@@ -1451,6 +978,9 @@ _mdns_query_start(mdns_query_context_t *ctx, mdns_reply_t *reply, uint8_t *answe
        flags |= kDNSServiceFlagsShareConnection;
        flags |= kDNSServiceFlagsReturnIntermediates;
 
        flags |= kDNSServiceFlagsShareConnection;
        flags |= kDNSServiceFlagsReturnIntermediates;
 
+       /* <rdar://problem/7428439> mDNSResponder is now responsible for timeouts */
+       flags |= kDNSServiceFlagsTimeout;
+
        memset(ctx, 0, sizeof(mdns_query_context_t));
 
        if (answer && anslen) {
        memset(ctx, 0, sizeof(mdns_query_context_t));
 
        if (answer && anslen) {
@@ -1540,11 +1070,13 @@ _mdns_query_clear(mdns_query_context_t *ctx)
        int complete = _mdns_query_is_complete(ctx);
        if (ctx == NULL) return complete;
 
        int complete = _mdns_query_is_complete(ctx);
        if (ctx == NULL) return complete;
 
-       /* only dealloc this DNSServiceRef if the "main" _mdns_sdref has not been deallocated */
-       if (ctx->sd != NULL && ctx->sd_gen == _mdns_generation) {
-               DNSServiceRefDeallocate(ctx->sd);
+       if (ctx->sd != NULL) {
+               /* only dealloc this DNSServiceRef if the "main" _mdns_sdref has not been deallocated */
+               if (ctx->sd != NULL && ctx->sd_gen == _mdns_generation) {
+                       DNSServiceRefDeallocate(ctx->sd);
+               }
        }
        }
-
+       
        ctx->sd = NULL;
        ctx->sd_gen = 0;
        ctx->flags = 0;
        ctx->sd = NULL;
        ctx->sd_gen = 0;
        ctx->flags = 0;
@@ -1794,7 +1326,7 @@ _mdns_timeout(struct timespec *timeout, const struct timespec *deadline)
 }
 
 int
 }
 
 int
-_mdns_query_mDNSResponder(const char *name, int class, int type, const char *interface, DNSServiceFlags flags, uint8_t *answer, uint32_t *anslen, mdns_reply_t *reply, uint32_t timeout_sec)
+_mdns_search(const char *name, int class, int type, const char *interface, DNSServiceFlags flags, uint8_t *answer, uint32_t *anslen, mdns_reply_t *reply)
 {
        DNSServiceErrorType err = 0;
        int kq, n, wait = 1;
 {
        DNSServiceErrorType err = 0;
        int kq, n, wait = 1;
@@ -1809,6 +1341,9 @@ _mdns_query_mDNSResponder(const char *name, int class, int type, const char *int
        si_inet_config(&n_iface_4, NULL);
        if (n_iface_4 > 0) n_iface_4--;
 
        si_inet_config(&n_iface_4, NULL);
        if (n_iface_4 > 0) n_iface_4--;
 
+       // <rdar://problem/7732497> limit the number of initialization retries
+       int initialize_retries = 3;
+
        // 2 for A and AAAA parallel queries
        int n_ctx = 0;
        mdns_query_context_t ctx[2];
        // 2 for A and AAAA parallel queries
        int n_ctx = 0;
        mdns_query_context_t ctx[2];
@@ -1817,7 +1352,7 @@ _mdns_query_mDNSResponder(const char *name, int class, int type, const char *int
 
 #if TARGET_OS_EMBEDDED
        // log a warning for queries from the main thread 
 
 #if TARGET_OS_EMBEDDED
        // log a warning for queries from the main thread 
-       if (pthread_main_np()) asl_log(NULL, NULL, ASL_LEVEL_WARNING, "Warning: Libinfo call to mDNSResponder on main thread");
+       if (pthread_is_threaded_np() && pthread_main_np()) asl_log(NULL, NULL, ASL_LEVEL_WARNING, "Warning: Libinfo call to mDNSResponder on main thread");
 #endif // TARGET_OS_EMBEDDED
 
        // Timeout Logic
 #endif // TARGET_OS_EMBEDDED
 
        // Timeout Logic
@@ -1835,8 +1370,7 @@ _mdns_query_mDNSResponder(const char *name, int class, int type, const char *int
        // for the receipt of a AAAA response.
 
        // determine the maximum time to wait for a result
        // for the receipt of a AAAA response.
 
        // determine the maximum time to wait for a result
-       if (timeout_sec == 0) timeout_sec = RES_MAXRETRANS;
-       delta.tv_sec = timeout_sec;
+       delta.tv_sec = RES_MAXRETRANS + 5;
        delta.tv_nsec = 0;
        _mdns_deadline(&finish, &delta);
        timeout = delta;
        delta.tv_nsec = 0;
        _mdns_deadline(&finish, &delta);
        timeout = delta;
@@ -1870,6 +1404,11 @@ _mdns_query_mDNSResponder(const char *name, int class, int type, const char *int
                                }
                                // (re)initialize the shared connection
                                err = DNSServiceCreateConnection(&_mdns_sdref);
                                }
                                // (re)initialize the shared connection
                                err = DNSServiceCreateConnection(&_mdns_sdref);
+
+                               // limit the number of retries
+                               if (initialize_retries-- <= 0 && err == 0) {
+                                       err = kDNSServiceErr_Unknown;
+                               }
                                if (err != 0) {
                                        wait = 0;
                                        pthread_mutex_unlock(&_mdns_mutex);
                                if (err != 0) {
                                        wait = 0;
                                        pthread_mutex_unlock(&_mdns_mutex);
@@ -1966,7 +1505,7 @@ _mdns_query_mDNSResponder(const char *name, int class, int type, const char *int
                        if (_mdns_debug) printf(";; done\n");
                        break;
                } else if (got_a_response != 0) {
                        if (_mdns_debug) printf(";; done\n");
                        break;
                } else if (got_a_response != 0) {
-                       // Got A record or NXERROR for A query, adjust deadline for AAAA.
+                       // got A, adjust deadline for AAAA
                        struct timespec now, tn, extra;
 
                        // delta = now - start
                        struct timespec now, tn, extra;
 
                        // delta = now - start
@@ -1985,6 +1524,7 @@ _mdns_query_mDNSResponder(const char *name, int class, int type, const char *int
                        } else if (got_a_response == GOT_ERROR) {
                                extra.tv_sec = MEDIUM_AAAA_EXTRA;
                        }
                        } else if (got_a_response == GOT_ERROR) {
                                extra.tv_sec = MEDIUM_AAAA_EXTRA;
                        }
+
                        // tn = 2 * delta
                        _mdns_add_time(&tn, &delta, &delta);
 
                        // tn = 2 * delta
                        _mdns_add_time(&tn, &delta, &delta);
 
index 8ea0f1dee7fba75963632cf5ef8ec3102a139f37..2b17317cacf348fc6f6e1455cb1f7875de3c605a 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2008-2009 Apple Inc.  All rights reserved.
+ * Copyright (c) 2008-2010 Apple Inc.  All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <arpa/inet.h>
 #include <sys/param.h>
 #include <sys/stat.h>
 #include <arpa/inet.h>
+#include <dispatch/dispatch.h>
 #include "si_module.h"
 
 #define _PATH_SI_CONF "/etc/sysinfo.conf"
 
 #include "si_module.h"
 
 #define _PATH_SI_CONF "/etc/sysinfo.conf"
 
-#define SEARCH_FLAG_MAC                                0x00000001
-#define SEARCH_FLAG_APPLETV                    0x00000002
-#define SEARCH_FLAG_IPHONE                     0x00000004
-#define SEARCH_FLAG_CACHE_ENABLED      0x00010000
+#define SEARCH_FLAG_CACHE_ENABLED 0x00000001
+#define SEARCH_MODULE_FLAG_DISABLED 0x00000001
 
 typedef struct
 {
        si_mod_t **module;
 
 typedef struct
 {
        si_mod_t **module;
+       uint32_t *module_flags;
        uint32_t count;
        uint32_t flags;
 } search_list_t;
 
 typedef struct
 {
        uint32_t count;
        uint32_t flags;
 } search_list_t;
 
 typedef struct
 {
-       uint32_t flags;
        search_list_t search_list[CATEGORY_COUNT];
        si_mod_t *cache;
        search_list_t search_list[CATEGORY_COUNT];
        si_mod_t *cache;
-       si_mod_t *dns;
-       si_mod_t *mdns;
-       si_mod_t *file;
-       si_mod_t *ds;
 } search_si_private_t;
 
 } search_si_private_t;
 
-__private_extern__ void si_cache_add_item(si_mod_t *si, si_mod_t *src, si_item_t *item);
-__private_extern__ void si_cache_add_list(si_mod_t *si, si_mod_t *src, si_list_t *list);
+extern void si_cache_add_item(si_mod_t *si, si_mod_t *src, si_item_t *item);
+extern void si_cache_add_list(si_mod_t *si, si_mod_t *src, si_list_t *list);
 
 
-__private_extern__ char **_fsi_tokenize(char *data, const char *sep, int trailing_empty, int *ntokens);
-__private_extern__ char *_fsi_get_line(FILE *fp);
+extern char **_fsi_tokenize(char *data, const char *sep, int trailing_empty, int *ntokens);
+extern char *_fsi_get_line(FILE *fp);
 
 
-#ifdef DS_AVAILABLE
-extern int _ds_running();
-#else
-static inline int _ds_running(void) { return 0; }
-#endif
+static void si_module_config_parse_line(search_si_private_t *pp, char *line);
+static void si_module_config_modules_for_category(search_si_private_t *pp, int cat, int ntokens, const char * const *tokens);
 
 
-static __attribute__((noinline)) si_mod_t *
+static si_mod_t *
 search_get_module(search_si_private_t *pp, int cat, int *n)
 {
        int x;
 search_get_module(search_si_private_t *pp, int cat, int *n)
 {
        int x;
@@ -83,24 +75,49 @@ search_get_module(search_si_private_t *pp, int cat, int *n)
        *n = x + 1;
 
        /* Use custom search list if available */
        *n = x + 1;
 
        /* Use custom search list if available */
-       if (x < pp->search_list[cat].count)
+       if (pp->search_list[cat].count > 0 && x < pp->search_list[cat].count)
        {
                return pp->search_list[cat].module[x];
        }
        {
                return pp->search_list[cat].module[x];
        }
-       
-       /* 
-        * Search order:
-        * 1) cache
-        * 2) DS if available, otherwise flat files
-        * 3) mdns (for host lookups only)
-        */
-       switch (x)
+
+       /* Otherwise use the default search list */
+       while (x < pp->search_list[CATEGORY_DEFAULT].count)
        {
        {
-               case 0: return pp->cache;
-               case 1: if (_ds_running()) return pp->ds;
-                               else return pp->file;
-               case 2: return pp->mdns;
-               default: return NULL;
+               if (pp->search_list[CATEGORY_DEFAULT].module_flags[x] & SEARCH_MODULE_FLAG_DISABLED)
+               {
+                       x++;
+                       *n = x + 1;
+               }
+               else
+               {
+                       return pp->search_list[CATEGORY_DEFAULT].module[x];
+               }
+       }
+
+       return NULL;
+}
+
+__private_extern__ void
+search_set_flags(si_mod_t *si, const char *name, uint32_t flag)
+{
+       search_si_private_t *pp;
+       uint32_t i;
+
+       if (si == NULL) return;
+       if (si->private == NULL) return;
+
+       pp = (search_si_private_t *)si->private;
+
+       for (i = 0; i < pp->search_list[CATEGORY_DEFAULT].count; i++)
+       {
+               si_mod_t *mod = pp->search_list[CATEGORY_DEFAULT].module[i];
+               if ((mod == NULL) || (mod->name == NULL)) continue;
+
+               if (string_equal(name, mod->name))
+               {
+                       pp->search_list[CATEGORY_DEFAULT].module_flags[i] = flag;
+                       break;
+               }
        }
 }
 
        }
 }
 
@@ -108,15 +125,18 @@ static si_mod_t *
 search_cat_cache(search_si_private_t *pp, int cat)
 {
        if (pp == NULL) return NULL;
 search_cat_cache(search_si_private_t *pp, int cat)
 {
        if (pp == NULL) return NULL;
-       if ((cat < 0) || (cat > CATEGORY_COUNT)) return NULL;
+       if (cat < 0 || cat > CATEGORY_COUNT) return NULL;
 
 
-       if (pp->search_list[cat].count > 0)
+       if (pp->search_list[cat].count == 0)
        {
        {
-               if (pp->search_list[cat].flags & SEARCH_FLAG_CACHE_ENABLED) return pp->cache;
-               return NULL;
+               cat = CATEGORY_DEFAULT;
+       }
+
+       if ((pp->search_list[cat].flags & SEARCH_FLAG_CACHE_ENABLED) != 0)
+       {
+               return pp->cache;
        }
 
        }
 
-       if ((pp->flags & SEARCH_FLAG_MAC) || (pp->flags & SEARCH_FLAG_APPLETV) || (pp->flags & SEARCH_FLAG_IPHONE)) return pp->cache;
        return NULL;
 }
 
        return NULL;
 }
 
@@ -131,12 +151,6 @@ search_close(si_mod_t *si)
 
        pp = (search_si_private_t *)si->private;
 
 
        pp = (search_si_private_t *)si->private;
 
-       si_module_release(pp->cache);
-       si_module_release(pp->file);
-       si_module_release(pp->dns);
-       si_module_release(pp->mdns);
-       si_module_release(pp->ds);
-
        for (i = 0; i < CATEGORY_COUNT; i++)
        {
                if (pp->search_list[i].module != NULL)
        for (i = 0; i < CATEGORY_COUNT; i++)
        {
                if (pp->search_list[i].module != NULL)
@@ -212,7 +226,7 @@ search_item_bynumber(si_mod_t *si, uint32_t number, int cat, si_item_t *(*call)(
 static si_list_t *
 search_list(si_mod_t *si, int cat, si_list_t *(*call)(si_mod_t *))
 {
 static si_list_t *
 search_list(si_mod_t *si, int cat, si_list_t *(*call)(si_mod_t *))
 {
-       int i;
+       int i, null_res;
        search_si_private_t *pp;
        si_list_t *list, *all;
        si_mod_t *cache, *src;
        search_si_private_t *pp;
        si_list_t *list, *all;
        si_mod_t *cache, *src;
@@ -233,68 +247,73 @@ search_list(si_mod_t *si, int cat, si_list_t *(*call)(si_mod_t *))
        i = 0;
 
        all = NULL;
        i = 0;
 
        all = NULL;
+       null_res = 0;
 
        while (NULL != (src = search_get_module(pp, cat, &i)))
        {
                if (src == pp->cache) continue;
 
                list = call(src);
 
        while (NULL != (src = search_get_module(pp, cat, &i)))
        {
                if (src == pp->cache) continue;
 
                list = call(src);
-               if (list == NULL) continue;
+               if (list == NULL)
+               {
+                       null_res = 1;
+                       continue;
+               }
 
                all = si_list_concat(all, list);
                si_list_release(list);
        }
 
 
                all = si_list_concat(all, list);
                si_list_release(list);
        }
 
-       si_cache_add_list(cache, si, all);
+       if ((all != NULL) && (null_res == 0)) si_cache_add_list(cache, si, all);
        return all;
 }
 
        return all;
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 search_user_byname(si_mod_t *si, const char *name)
 {
        return search_item_byname(si, name, CATEGORY_USER, si_user_byname);
 }
 
 search_user_byname(si_mod_t *si, const char *name)
 {
        return search_item_byname(si, name, CATEGORY_USER, si_user_byname);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 search_user_byuid(si_mod_t *si, uid_t uid)
 {
        return search_item_bynumber(si, (uint32_t)uid, CATEGORY_USER, si_user_byuid);
 }
 
 search_user_byuid(si_mod_t *si, uid_t uid)
 {
        return search_item_bynumber(si, (uint32_t)uid, CATEGORY_USER, si_user_byuid);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 search_user_all(si_mod_t *si)
 {
        return search_list(si, CATEGORY_USER, si_user_all);
 }
 
 search_user_all(si_mod_t *si)
 {
        return search_list(si, CATEGORY_USER, si_user_all);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 search_group_byname(si_mod_t *si, const char *name)
 {
        return search_item_byname(si, name, CATEGORY_GROUP, si_group_byname);
 }
 
 search_group_byname(si_mod_t *si, const char *name)
 {
        return search_item_byname(si, name, CATEGORY_GROUP, si_group_byname);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 search_group_bygid(si_mod_t *si, gid_t gid)
 {
        return search_item_bynumber(si, (uint32_t)gid, CATEGORY_USER, si_group_bygid);
 }
 
 search_group_bygid(si_mod_t *si, gid_t gid)
 {
        return search_item_bynumber(si, (uint32_t)gid, CATEGORY_USER, si_group_bygid);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 search_group_all(si_mod_t *si)
 {
        return search_list(si, CATEGORY_GROUP, si_group_all);
 }
 
 search_group_all(si_mod_t *si)
 {
        return search_list(si, CATEGORY_GROUP, si_group_all);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 search_groupist(si_mod_t *si, const char *name)
 {
        return search_item_byname(si, name, CATEGORY_GROUPLIST, si_grouplist);
 }
 
 search_groupist(si_mod_t *si, const char *name)
 {
        return search_item_byname(si, name, CATEGORY_GROUPLIST, si_grouplist);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 search_netgroup_byname(si_mod_t *si, const char *name)
 {
 search_netgroup_byname(si_mod_t *si, const char *name)
 {
-       int i, cat;
+       int i, cat, null_res;
        search_si_private_t *pp;
        si_list_t *list, *all;
        si_mod_t *cache, *src;
        search_si_private_t *pp;
        si_list_t *list, *all;
        si_mod_t *cache, *src;
@@ -321,17 +340,21 @@ search_netgroup_byname(si_mod_t *si, const char *name)
                if (src == pp->cache) continue;
 
                list = si_netgroup_byname(src, name);
                if (src == pp->cache) continue;
 
                list = si_netgroup_byname(src, name);
-               if (list == NULL) continue;
+               if (list == NULL)
+               {
+                       null_res = 1;
+                       continue;
+               }
 
                all = si_list_concat(all, list);
                si_list_release(list);
        }
 
 
                all = si_list_concat(all, list);
                si_list_release(list);
        }
 
-       si_cache_add_list(cache, si, all);
+       if ((all != NULL) && (null_res == 0)) si_cache_add_list(cache, si, all);
        return all;
 }
 
        return all;
 }
 
-__private_extern__ int
+static int
 search_in_netgroup(si_mod_t *si, const char *group, const char *host, const char *user, const char *domain)
 {
        int i, cat, innetgr;
 search_in_netgroup(si_mod_t *si, const char *group, const char *host, const char *user, const char *domain)
 {
        int i, cat, innetgr;
@@ -356,19 +379,19 @@ search_in_netgroup(si_mod_t *si, const char *group, const char *host, const char
        return 0;
 }
 
        return 0;
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 search_alias_byname(si_mod_t *si, const char *name)
 {
        return search_item_byname(si, name, CATEGORY_ALIAS, si_alias_byname);
 }
 
 search_alias_byname(si_mod_t *si, const char *name)
 {
        return search_item_byname(si, name, CATEGORY_ALIAS, si_alias_byname);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 search_alias_all(si_mod_t *si)
 {
        return search_list(si, CATEGORY_ALIAS, si_alias_all);
 }
 
 search_alias_all(si_mod_t *si)
 {
        return search_list(si, CATEGORY_ALIAS, si_alias_all);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 search_host_byname(si_mod_t *si, const char *name, int af, const char *interface, uint32_t *err)
 {
        int i, cat;
 search_host_byname(si_mod_t *si, const char *name, int af, const char *interface, uint32_t *err)
 {
        int i, cat;
@@ -410,7 +433,7 @@ search_host_byname(si_mod_t *si, const char *name, int af, const char *interface
        return NULL;
 }
 
        return NULL;
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 search_host_byaddr(si_mod_t *si, const void *addr, int af, const char *interface, uint32_t *err)
 {
        int i, cat;
 search_host_byaddr(si_mod_t *si, const void *addr, int af, const char *interface, uint32_t *err)
 {
        int i, cat;
@@ -435,7 +458,7 @@ search_host_byaddr(si_mod_t *si, const void *addr, int af, const char *interface
 
        cat = CATEGORY_HOST_IPV4;
        if (af == AF_INET6) cat = CATEGORY_HOST_IPV6;
 
        cat = CATEGORY_HOST_IPV4;
        if (af == AF_INET6) cat = CATEGORY_HOST_IPV6;
-       
+
        i = 0;
 
        while (NULL != (src = search_get_module(pp, cat, &i)))
        i = 0;
 
        while (NULL != (src = search_get_module(pp, cat, &i)))
@@ -452,31 +475,31 @@ search_host_byaddr(si_mod_t *si, const void *addr, int af, const char *interface
        return NULL;
 }
 
        return NULL;
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 search_host_all(si_mod_t *si)
 {
        return search_list(si, CATEGORY_HOST, si_host_all);
 }
 
 search_host_all(si_mod_t *si)
 {
        return search_list(si, CATEGORY_HOST, si_host_all);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 search_network_byname(si_mod_t *si, const char *name)
 {
        return search_item_byname(si, name, CATEGORY_NETWORK, si_network_byname);
 }
 
 search_network_byname(si_mod_t *si, const char *name)
 {
        return search_item_byname(si, name, CATEGORY_NETWORK, si_network_byname);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 search_network_byaddr(si_mod_t *si, uint32_t addr)
 {
        return search_item_bynumber(si, addr, CATEGORY_NETWORK, si_network_byaddr);
 }
 
 search_network_byaddr(si_mod_t *si, uint32_t addr)
 {
        return search_item_bynumber(si, addr, CATEGORY_NETWORK, si_network_byaddr);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 search_network_all(si_mod_t *si)
 {
        return search_list(si, CATEGORY_NETWORK, si_network_all);
 }
 
 search_network_all(si_mod_t *si)
 {
        return search_list(si, CATEGORY_NETWORK, si_network_all);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 search_service_byname(si_mod_t *si, const char *name, const char *proto)
 {
        int i, cat;
 search_service_byname(si_mod_t *si, const char *name, const char *proto)
 {
        int i, cat;
@@ -506,7 +529,7 @@ search_service_byname(si_mod_t *si, const char *name, const char *proto)
        return NULL;
 }
 
        return NULL;
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 search_service_byport(si_mod_t *si, int port, const char *proto)
 {
        int i, cat;
 search_service_byport(si_mod_t *si, int port, const char *proto)
 {
        int i, cat;
@@ -535,37 +558,37 @@ search_service_byport(si_mod_t *si, int port, const char *proto)
        return NULL;
 }
 
        return NULL;
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 search_service_all(si_mod_t *si)
 {
        return search_list(si, CATEGORY_SERVICE, si_service_all);
 }
 
 search_service_all(si_mod_t *si)
 {
        return search_list(si, CATEGORY_SERVICE, si_service_all);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 search_protocol_byname(si_mod_t *si, const char *name)
 {
        return search_item_byname(si, name, CATEGORY_PROTOCOL, si_protocol_byname);
 }
 
 search_protocol_byname(si_mod_t *si, const char *name)
 {
        return search_item_byname(si, name, CATEGORY_PROTOCOL, si_protocol_byname);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 search_protocol_bynumber(si_mod_t *si, int number)
 {
        return search_item_bynumber(si, (uint32_t)number, CATEGORY_PROTOCOL, si_protocol_bynumber);
 }
 
 search_protocol_bynumber(si_mod_t *si, int number)
 {
        return search_item_bynumber(si, (uint32_t)number, CATEGORY_PROTOCOL, si_protocol_bynumber);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 search_protocol_all(si_mod_t *si)
 {
        return search_list(si, CATEGORY_PROTOCOL, si_protocol_all);
 }
 
 search_protocol_all(si_mod_t *si)
 {
        return search_list(si, CATEGORY_PROTOCOL, si_protocol_all);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 search_rpc_byname(si_mod_t *si, const char *name)
 {
        return search_item_byname(si, name, CATEGORY_RPC, si_rpc_byname);
 }
 
 search_rpc_byname(si_mod_t *si, const char *name)
 {
        return search_item_byname(si, name, CATEGORY_RPC, si_rpc_byname);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 search_rpc_bynumber(si_mod_t *si, int number)
 {
        int i, cat;
 search_rpc_bynumber(si_mod_t *si, int number)
 {
        int i, cat;
@@ -594,49 +617,49 @@ search_rpc_bynumber(si_mod_t *si, int number)
        return NULL;
 }
 
        return NULL;
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 search_rpc_all(si_mod_t *si)
 {
        return search_list(si, CATEGORY_RPC, si_rpc_all);
 }
 
 search_rpc_all(si_mod_t *si)
 {
        return search_list(si, CATEGORY_RPC, si_rpc_all);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 search_fs_byspec(si_mod_t *si, const char *name)
 {
        return search_item_byname(si, name, CATEGORY_FS, si_fs_byspec);
 }
 
 search_fs_byspec(si_mod_t *si, const char *name)
 {
        return search_item_byname(si, name, CATEGORY_FS, si_fs_byspec);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 search_fs_byfile(si_mod_t *si, const char *name)
 {
        return search_item_byname(si, name, CATEGORY_FS, si_fs_byfile);
 }
 
 search_fs_byfile(si_mod_t *si, const char *name)
 {
        return search_item_byname(si, name, CATEGORY_FS, si_fs_byfile);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 search_fs_all(si_mod_t *si)
 {
        return search_list(si, CATEGORY_FS, si_fs_all);
 }
 
 search_fs_all(si_mod_t *si)
 {
        return search_list(si, CATEGORY_FS, si_fs_all);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 search_mac_byname(si_mod_t *si, const char *name)
 {
        return search_item_byname(si, name, CATEGORY_MAC, si_mac_byname);
 }
 
 search_mac_byname(si_mod_t *si, const char *name)
 {
        return search_item_byname(si, name, CATEGORY_MAC, si_mac_byname);
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 search_mac_bymac(si_mod_t *si, const char *mac)
 {
        return search_item_byname(si, mac, CATEGORY_MAC, si_mac_bymac);
 }
 
 search_mac_bymac(si_mod_t *si, const char *mac)
 {
        return search_item_byname(si, mac, CATEGORY_MAC, si_mac_bymac);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 search_mac_all(si_mod_t *si)
 {
        return search_list(si, CATEGORY_MAC, si_mac_all);
 }
 
 search_mac_all(si_mod_t *si)
 {
        return search_list(si, CATEGORY_MAC, si_mac_all);
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 search_srv_byname(si_mod_t *si, const char* qname, const char *interface, uint32_t *err)
 {
        int i, cat;
 search_srv_byname(si_mod_t *si, const char* qname, const char *interface, uint32_t *err)
 {
        int i, cat;
@@ -656,9 +679,9 @@ search_srv_byname(si_mod_t *si, const char* qname, const char *interface, uint32
        {
                if (src == pp->cache) continue;
 
        {
                if (src == pp->cache) continue;
 
-               if (src->sim_srv_byname != NULL)
+               if (src->vtable->sim_srv_byname != NULL)
                {
                {
-                       list = src->sim_srv_byname(src, qname, interface, err);
+                       list = src->vtable->sim_srv_byname(src, qname, interface, err);
                        if (list != NULL) return list;
                }
        }
                        if (list != NULL) return list;
                }
        }
@@ -667,7 +690,7 @@ search_srv_byname(si_mod_t *si, const char* qname, const char *interface, uint32
        return NULL;
 }
 
        return NULL;
 }
 
-__private_extern__ int
+static int
 search_wants_addrinfo(si_mod_t *si)
 {
        int i, cat;
 search_wants_addrinfo(si_mod_t *si)
 {
        int i, cat;
@@ -685,13 +708,13 @@ search_wants_addrinfo(si_mod_t *si)
        while (NULL != (src = search_get_module(pp, cat, &i)))
        {
                if (src == pp->cache) continue;
        while (NULL != (src = search_get_module(pp, cat, &i)))
        {
                if (src == pp->cache) continue;
-               if (src->sim_addrinfo != NULL) return 1;
+               if (src->vtable->sim_addrinfo != NULL) return 1;
        }
 
        return 0;
 }
 
        }
 
        return 0;
 }
 
-__private_extern__ si_list_t *
+static si_list_t *
 search_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t protocol, uint32_t flags, const char *interface, uint32_t *err)
 {
        int i, cat;
 search_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t family, uint32_t socktype, uint32_t protocol, uint32_t flags, const char *interface, uint32_t *err)
 {
        int i, cat;
@@ -713,9 +736,9 @@ search_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t famil
        {
                if (src == pp->cache) continue;
 
        {
                if (src == pp->cache) continue;
 
-               if (src->sim_addrinfo != NULL)
+               if (src->vtable->sim_addrinfo != NULL)
                {
                {
-                       list = src->sim_addrinfo(src, node, serv, family, socktype, protocol, flags, interface, err);
+                       list = src->vtable->sim_addrinfo(src, node, serv, family, socktype, protocol, flags, interface, err);
                        if (list != NULL) return list;
                }
        }
                        if (list != NULL) return list;
                }
        }
@@ -724,7 +747,7 @@ search_addrinfo(si_mod_t *si, const void *node, const void *serv, uint32_t famil
        return NULL;
 }
 
        return NULL;
 }
 
-__private_extern__ si_item_t *
+static si_item_t *
 search_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *interface, uint32_t *err)
 {
        int i, cat;
 search_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *interface, uint32_t *err)
 {
        int i, cat;
@@ -735,7 +758,7 @@ search_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *
        if (err != NULL) *err = SI_STATUS_EAI_FAIL;
 
        if (si == NULL) return NULL;
        if (err != NULL) *err = SI_STATUS_EAI_FAIL;
 
        if (si == NULL) return NULL;
-       
+
        pp = (search_si_private_t *)si->private;
        if (pp == NULL) return NULL;
 
        pp = (search_si_private_t *)si->private;
        if (pp == NULL) return NULL;
 
@@ -757,7 +780,7 @@ search_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *
        return NULL;
 }
 
        return NULL;
 }
 
-__private_extern__ int
+static int
 search_is_valid(si_mod_t *si, si_item_t *item)
 {
        si_mod_t *src;
 search_is_valid(si_mod_t *si, si_item_t *item)
 {
        si_mod_t *src;
@@ -774,412 +797,194 @@ search_is_valid(si_mod_t *si, si_item_t *item)
        return 0;
 }
 
        return 0;
 }
 
-static si_mod_t *
-search_alloc()
+si_mod_t *
+si_module_static_search(void)
 {
 {
-       si_mod_t *out;
-       char *outname;
-       search_si_private_t *pp;
-
-       out = (si_mod_t *)calloc(1, sizeof(si_mod_t));
-       outname = strdup("search");
-       pp = (search_si_private_t *)calloc(1, sizeof(search_si_private_t));
-
-       if ((out == NULL) || (outname == NULL) || (pp == NULL))
+       static const struct si_mod_vtable_s search_vtable =
        {
        {
-               if (out != NULL) free(out);
-               if (outname != NULL) free(outname);
-               if (pp != NULL) free(pp);
+               .sim_close = &search_close,
 
 
-               errno = ENOMEM;
-               return NULL;
-       }
+               .sim_is_valid = &search_is_valid,
 
 
-       out->name = outname;
-       out->vers = 1;
-       out->refcount = 1;
-       out->private = pp;
+               .sim_user_byname = &search_user_byname,
+               .sim_user_byuid = &search_user_byuid,
+               .sim_user_all = &search_user_all,
 
 
-       out->sim_close = search_close;
+               .sim_group_byname = &search_group_byname,
+               .sim_group_bygid = &search_group_bygid,
+               .sim_group_all = &search_group_all,
 
 
-       out->sim_is_valid = search_is_valid;
+               .sim_grouplist = &search_groupist,
 
 
-       out->sim_user_byname = search_user_byname;
-       out->sim_user_byuid = search_user_byuid;
-       out->sim_user_all = search_user_all;
+               .sim_netgroup_byname = &search_netgroup_byname,
+               .sim_in_netgroup = &search_in_netgroup,
 
 
-       out->sim_group_byname = search_group_byname;
-       out->sim_group_bygid = search_group_bygid;
-       out->sim_group_all = search_group_all;
+               .sim_alias_byname = &search_alias_byname,
+               .sim_alias_all = &search_alias_all,
 
 
-       out->sim_grouplist = search_groupist;
+               .sim_host_byname = &search_host_byname,
+               .sim_host_byaddr = &search_host_byaddr,
+               .sim_host_all = &search_host_all,
 
 
-       out->sim_netgroup_byname = search_netgroup_byname;
-       out->sim_in_netgroup = search_in_netgroup;
+               .sim_network_byname = &search_network_byname,
+               .sim_network_byaddr = &search_network_byaddr,
+               .sim_network_all = &search_network_all,
 
 
-       out->sim_alias_byname = search_alias_byname;
-       out->sim_alias_all = search_alias_all;
+               .sim_service_byname = &search_service_byname,
+               .sim_service_byport = &search_service_byport,
+               .sim_service_all = &search_service_all,
 
 
-       out->sim_host_byname = search_host_byname;
-       out->sim_host_byaddr = search_host_byaddr;
-       out->sim_host_all = search_host_all;
+               .sim_protocol_byname = &search_protocol_byname,
+               .sim_protocol_bynumber = &search_protocol_bynumber,
+               .sim_protocol_all = &search_protocol_all,
 
 
-       out->sim_network_byname = search_network_byname;
-       out->sim_network_byaddr = search_network_byaddr;
-       out->sim_network_all = search_network_all;
+               .sim_rpc_byname = &search_rpc_byname,
+               .sim_rpc_bynumber = &search_rpc_bynumber,
+               .sim_rpc_all = &search_rpc_all,
 
 
-       out->sim_service_byname = search_service_byname;
-       out->sim_service_byport = search_service_byport;
-       out->sim_service_all = search_service_all;
+               .sim_fs_byspec = &search_fs_byspec,
+               .sim_fs_byfile = &search_fs_byfile,
+               .sim_fs_all = &search_fs_all,
 
 
-       out->sim_protocol_byname = search_protocol_byname;
-       out->sim_protocol_bynumber = search_protocol_bynumber;
-       out->sim_protocol_all = search_protocol_all;
+               .sim_mac_byname = &search_mac_byname,
+               .sim_mac_bymac = &search_mac_bymac,
+               .sim_mac_all = &search_mac_all,
 
 
-       out->sim_rpc_byname = search_rpc_byname;
-       out->sim_rpc_bynumber = search_rpc_bynumber;
-       out->sim_rpc_all = search_rpc_all;
+               .sim_addrinfo = &search_addrinfo,
+               .sim_wants_addrinfo = &search_wants_addrinfo,
+               .sim_nameinfo = &search_nameinfo,
 
 
-       out->sim_fs_byspec = search_fs_byspec;
-       out->sim_fs_byfile = search_fs_byfile;
-       out->sim_fs_all = search_fs_all;
+               .sim_srv_byname = &search_srv_byname,
+       };
 
 
-       out->sim_mac_byname = search_mac_byname;
-       out->sim_mac_bymac = search_mac_bymac;
-       out->sim_mac_all = search_mac_all;
-
-       out->sim_addrinfo = search_addrinfo;
-       out->sim_wants_addrinfo = search_wants_addrinfo;
-       out->sim_nameinfo = search_nameinfo;
-
-       out->sim_srv_byname = search_srv_byname;
-       
-       return out;
-}
-
-static void
-init_optional_modules(search_si_private_t *pp)
-{
-       if (pp->mdns == NULL)
+       static si_mod_t si =
        {
        {
-               pp->mdns = si_module_with_name("mdns");
-               /* allow this to fail */
-       }
+               .vers = 1,
+               .refcount = 1,
+               .flags = SI_MOD_FLAG_STATIC,
 
 
-#ifdef DS_AVAILABLE
-       if (pp->flags & SEARCH_FLAG_MAC)
-       {
-               if (pp->ds == NULL)
-               {
-                       pp->ds = si_module_with_name("ds");
-                       /* allow this to fail */
-               }
-       }
-#endif
+               .private = NULL,
+               .vtable = &search_vtable,
+       };
 
 
-       if (pp->flags & (SEARCH_FLAG_APPLETV | SEARCH_FLAG_IPHONE))
-       {
-               if (pp->dns == NULL)
-               {
-                       pp->dns = si_module_with_name("dns");
-                       /* allow this to fail */
-               }
-       }
-}
+       static dispatch_once_t once;
 
 
-__private_extern__ si_mod_t *
-si_module_static_search()
-{
-       si_mod_t *out;
-       search_si_private_t *pp;
-       FILE *conf;
-       char *line, **tokens;
-       int cat, i, j, ntokens;
+       dispatch_once(&once, ^{
+               si.name = strdup("search");
+               search_si_private_t *pp = calloc(1, sizeof(search_si_private_t));
+               si.private = pp;
 
 
-       out = search_alloc();
-       if (out == NULL) return NULL;
-
-       pp = (search_si_private_t *)out->private;
-       if (pp == NULL)
-       {
-               free(out);
-               return NULL;
-       }
+               /*
+                * Default search order:
+                * 1) cache
+                * 2) DirectoryService/OpenDirectory (where available)
+                * 3) flat file
+                * 4) mDNSResponder
+                */
 
 
-#ifdef CONFIG_MAC
-       pp->flags = SEARCH_FLAG_CACHE_ENABLED | SEARCH_FLAG_MAC;
-#endif
-#ifdef CONFIG_APPLETV
-       pp->flags = SEARCH_FLAG_CACHE_ENABLED | SEARCH_FLAG_APPLETV;
-#endif
-       
-#ifdef CONFIG_IPHONE
-       pp->flags = SEARCH_FLAG_CACHE_ENABLED | SEARCH_FLAG_IPHONE;
+               const char * const modules[] =
+               {
+                       "default", // CATEGORY_DEFAULT
+                       "cache",
+#ifdef DS_AVAILABLE
+                       "ds",
 #endif
 #endif
+                       "mdns",
+                       "file",
+               };
 
 
-       pp->cache = si_module_with_name("cache");
-       if (pp->cache == NULL) 
-       {
-               search_close(out);
-               return NULL;
-       }
-
-       pp->file = si_module_with_name("file");
-       if (pp->file == NULL)
-       {
-               search_close(out);
-               return NULL;
-       }
-
-       init_optional_modules(pp);
+               int count = sizeof(modules) / sizeof(char *);
+               si_module_config_modules_for_category(pp, CATEGORY_DEFAULT, count, modules);
+               pp->cache = pp->search_list[CATEGORY_DEFAULT].module[0];
 
 
-       conf = fopen(_PATH_SI_CONF, "r");
-       if (conf == NULL) return out;
-
-       forever
-       {
-               line = _fsi_get_line(conf);
-               if (line == NULL) break;
-
-               if (line[0] == '#') 
+               FILE *conf = fopen(_PATH_SI_CONF, "r");
+               errno = 0;
+               if (conf != NULL)
                {
                {
-                       free(line);
-                       line = NULL;
-                       continue;
-               }
+                       forever
+                       {
+                               char *line = _fsi_get_line(conf);
+                               if (line == NULL) break;
 
 
-               ntokens = 0;
-               tokens = _fsi_tokenize(line, "  : ", 0, &ntokens);
+                               si_module_config_parse_line(pp, line);
+                               free(line);
+                       }
 
 
-               if (ntokens < 2)
-               {
-                       free(tokens);
-                       tokens = NULL;
-                       free(line);
-                       line = NULL;
-                       continue;
+                       fclose(conf);
                }
                }
+       });
 
 
-               if (string_equal(tokens[0], "config"))
-               {
-                       if (string_equal(tokens[1], "mac")) pp->flags = SEARCH_FLAG_CACHE_ENABLED | SEARCH_FLAG_MAC;
-                       else if (string_equal(tokens[1], "appletv")) pp->flags = SEARCH_FLAG_CACHE_ENABLED | SEARCH_FLAG_APPLETV;
-                       else if (string_equal(tokens[1], "iphone")) pp->flags = SEARCH_FLAG_CACHE_ENABLED | SEARCH_FLAG_IPHONE;
-
-                       init_optional_modules(pp);
-
-                       free(tokens);
-                       tokens = NULL;
-                       free(line);
-                       line = NULL;
-                       continue;
-               }
+       return &si;
+}
 
 
-               if (string_equal(tokens[0], "user")) cat = CATEGORY_USER;
-               else if (string_equal(tokens[0], "group")) cat = CATEGORY_GROUP;
-               else if (string_equal(tokens[0], "grouplist")) cat = CATEGORY_GROUPLIST;
-               else if (string_equal(tokens[0], "netgroup")) cat = CATEGORY_NETGROUP;
-               else if (string_equal(tokens[0], "alias")) cat = CATEGORY_ALIAS;
-               else if (string_equal(tokens[0], "host")) cat = CATEGORY_HOST_IPV4;
-               else if (string_equal(tokens[0], "network")) cat = CATEGORY_NETWORK;
-               else if (string_equal(tokens[0], "service")) cat = CATEGORY_SERVICE;
-               else if (string_equal(tokens[0], "protocol")) cat = CATEGORY_PROTOCOL;
-               else if (string_equal(tokens[0], "rpc")) cat = CATEGORY_RPC;
-               else if (string_equal(tokens[0], "fs")) cat = CATEGORY_FS;
-               else if (string_equal(tokens[0], "mac")) cat = CATEGORY_MAC;
-               else if (string_equal(tokens[0], "addrinfo")) cat = CATEGORY_ADDRINFO;
-               else if (string_equal(tokens[0], "nameinfo")) cat = CATEGORY_NAMEINFO;
-               else
-               {
-                       free(tokens);
-                       tokens = NULL;
-                       free(line);
-                       line = NULL;
-                       continue;
-               }
+static void
+si_module_config_parse_line(search_si_private_t *pp, char *line)
+{
+       if (line == NULL || line[0] == '#') {
+               return;
+       }
 
 
-       do_ipv6:
+       int ntokens = 0;
+       char **tokens = _fsi_tokenize(line, "   : ", 0, &ntokens);
 
 
-               if (pp->search_list[cat].module != NULL)
-               {
-                       free(tokens);
-                       tokens = NULL;
-                       free(line);
-                       line = NULL;
-                       continue;
-               }
+       int cat = CATEGORY_INVALID;
 
 
-               pp->search_list[cat].count = ntokens - 1;
-               pp->search_list[cat].module = (si_mod_t **)calloc(pp->search_list[cat].count, sizeof(si_mod_t *));
-               if (pp->search_list[cat].module == NULL)
-               {
-                       search_close(out);
-                       free(tokens);
-                       tokens = NULL;
-                       free(line);
-                       line = NULL;
-                       return NULL;
-               }
+       if (string_equal(tokens[0], "default")) cat = CATEGORY_DEFAULT;
+       else if (string_equal(tokens[0], "user")) cat = CATEGORY_USER;
+       else if (string_equal(tokens[0], "group")) cat = CATEGORY_GROUP;
+       else if (string_equal(tokens[0], "grouplist")) cat = CATEGORY_GROUPLIST;
+       else if (string_equal(tokens[0], "netgroup")) cat = CATEGORY_NETGROUP;
+       else if (string_equal(tokens[0], "alias")) cat = CATEGORY_ALIAS;
+       else if (string_equal(tokens[0], "host")) cat = CATEGORY_HOST_IPV4;
+       else if (string_equal(tokens[0], "network")) cat = CATEGORY_NETWORK;
+       else if (string_equal(tokens[0], "service")) cat = CATEGORY_SERVICE;
+       else if (string_equal(tokens[0], "protocol")) cat = CATEGORY_PROTOCOL;
+       else if (string_equal(tokens[0], "rpc")) cat = CATEGORY_RPC;
+       else if (string_equal(tokens[0], "fs")) cat = CATEGORY_FS;
+       else if (string_equal(tokens[0], "mac")) cat = CATEGORY_MAC;
+       else if (string_equal(tokens[0], "addrinfo")) cat = CATEGORY_ADDRINFO;
+       else if (string_equal(tokens[0], "nameinfo")) cat = CATEGORY_NAMEINFO;
 
 
-               for (i = 1, j = 0; i < ntokens; i++, j++)
-               {
-                       if (string_equal(tokens[i], "cache"))
-                       {
-                               pp->search_list[cat].module[j] = pp->cache;
-                               pp->search_list[cat].flags = SEARCH_FLAG_CACHE_ENABLED;
-                       }
-                       else if (string_equal(tokens[i], "file"))
-                       {
-                               if (pp->file == NULL) pp->file = si_module_with_name("file");                           
-                               pp->search_list[cat].module[j] = pp->file;
-                       }
-                       else if (string_equal(tokens[i], "dns"))
-                       {
-                               if (pp->dns == NULL) pp->dns = si_module_with_name("dns");                              
-                               pp->search_list[cat].module[j] = pp->dns;
-                       }
-                       else if (string_equal(tokens[i], "mdns"))
-                       {
-                               if (pp->mdns == NULL) pp->mdns = si_module_with_name("mdns");                           
-                               pp->search_list[cat].module[j] = pp->mdns;
-                       }
-                       else if (string_equal(tokens[i], "ds"))
-                       {
-                               if (pp->ds == NULL) pp->ds = si_module_with_name("ds");                         
-                               pp->search_list[cat].module[j] = pp->ds;
-                       }
-               }
-
-               if (cat == CATEGORY_HOST_IPV4)
-               {
-                       cat = CATEGORY_HOST_IPV6;
-                       goto do_ipv6;
-               }
-
-               free(tokens);
-               tokens = NULL;
-               free(line);
-               line = NULL;
+       if (cat != CATEGORY_INVALID)
+       {
+               si_module_config_modules_for_category(pp, cat, ntokens, (const char * const *)tokens);
        }
 
        }
 
-       return out;
+       free(tokens);
 }
 
 }
 
-__private_extern__ si_mod_t *
-search_custom(int n, ...)
+static void
+si_module_config_modules_for_category(search_si_private_t *pp, int cat, int ntokens, const char * const *tokens)
 {
 {
-       va_list ap;
-       si_mod_t *out, *m;
-       search_si_private_t *pp;
-       int cat, i;
-       char *name;
-
-       if (n == 0) return si_module_static_search();
-
-       out = search_alloc();
-       if (out == NULL) return NULL;
-
-       pp = (search_si_private_t *)out->private;
-       if (pp == NULL)
+       int count = ntokens - 1;
+       pp->search_list[cat].count = count;
+       if (count == 0)
        {
        {
-               free(out);
-               return NULL;
+               return;
        }
 
        }
 
-       for (cat = 0; cat < CATEGORY_COUNT; cat++)
+       pp->search_list[cat].module = (si_mod_t **)calloc(pp->search_list[cat].count, sizeof(si_mod_t *));
+       pp->search_list[cat].module_flags = (uint32_t *)calloc(pp->search_list[cat].count, sizeof(uint32_t));
+       if ((pp->search_list[cat].module == NULL) || (pp->search_list[cat].module_flags == NULL))
        {
        {
-               pp->search_list[cat].count = n;
-               pp->search_list[cat].module = (si_mod_t **)calloc(pp->search_list[cat].count, sizeof(si_mod_t *));
-               if (pp->search_list[cat].module == NULL)
-               {
-                       search_close(out);
-                       return NULL;
-               }
-
+               free(pp->search_list[cat].module);
+               free(pp->search_list[cat].module_flags);
+               return;
        }
 
        }
 
-       va_start(ap, n);
-
-       for (i = 0; i < n; i++)
+       int i, j;
+       for (i = 1, j = 0; i < ntokens; i++)
        {
        {
-               name = va_arg(ap, char *);
-               if (name == NULL) break;
-
-               m = NULL;
-               if (string_equal(name, "cache"))
-               {
-                       if (pp->cache == NULL)
-                       {
-                               pp->cache = si_module_with_name("cache");
-                               m = pp->cache;
-                               if (pp->cache == NULL)
-                               {
-                                       search_close(out);
-                                       return NULL;
-                               }
-                       }
-               }
-               else if (string_equal(name, "file"))
-               {
-                       if (pp->file == NULL)
-                       {
-                               pp->file = si_module_with_name("file");
-                               m = pp->file;
-                               if (pp->file == NULL)
-                               {
-                                       search_close(out);
-                                       return NULL;
-                               }
-                       }
-               }
-               else if (string_equal(name, "dns"))
-               {
-                       if (pp->dns == NULL)
-                       {
-                               pp->dns = si_module_with_name("dns");
-                               m = pp->dns;
-                               if (pp->dns == NULL)
-                               {
-                                       search_close(out);
-                                       return NULL;
-                               }
-                       }
-               }
-               else if (string_equal(name, "mdns"))
-               {
-                       if (pp->mdns == NULL)
-                       {
-                               pp->mdns = si_module_with_name("mdns");
-                               m = pp->mdns;
-                               if (pp->mdns == NULL)
-                               {
-                                       search_close(out);
-                                       return NULL;
-                               }
-                       }
-               }
-               else if (string_equal(name, "ds"))
+               si_mod_t *mod = si_module_with_name(tokens[i]);
+               if (mod != NULL)
                {
                {
-                       if (pp->ds == NULL)
+                       pp->search_list[cat].module[j] = mod;
+                       j++;
+
+                       if (string_equal(tokens[i], "cache"))
                        {
                        {
-                               pp->ds = si_module_with_name("ds");
-                               m = pp->ds;
-                               if (pp->ds == NULL)
-                               {
-                                       search_close(out);
-                                       return NULL;
-                               }
+                               pp->search_list[cat].flags |= SEARCH_FLAG_CACHE_ENABLED;
                        }
                }
                        }
                }
-
-               for (cat = 0; cat < CATEGORY_COUNT; cat++)
-               {
-                       if (string_equal(name, "cache")) pp->search_list[cat].flags = SEARCH_FLAG_CACHE_ENABLED;
-                       pp->search_list[cat].module[i] = m;
-               }
        }
        }
-
-       va_end(ap);
-
-       return out;
 }
 }
index 780a13368aca539601acc6e6f2a9bc528cfe0b89..d227ad4cb10e9dcb2d41541de5931d721f689c47 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2008-2009 Apple Inc.  All rights reserved.
+ * Copyright (c) 2008-2011 Apple Inc.  All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -29,6 +29,7 @@
 #include <sys/socket.h>
 #include <net/if.h>
 #include <netinet/in.h>
 #include <sys/socket.h>
 #include <net/if.h>
 #include <netinet/in.h>
+#include <network/sa_compare.h>
 #include <arpa/inet.h>
 #include <ifaddrs.h>
 #include <net/if.h>
 #include <arpa/inet.h>
 #include <ifaddrs.h>
 #include <net/if.h>
 #define WANT_A6_PLUS_MAPPED_A4 3
 #define WANT_A6_OR_MAPPED_A4_IF_NO_A6 4
 
 #define WANT_A6_PLUS_MAPPED_A4 3
 #define WANT_A6_OR_MAPPED_A4_IF_NO_A6 4
 
-#define TEREDO_PREFIX_32 0x20010000
 #define V6TO4_PREFIX_16 0x2002
 #define V6TO4_PREFIX_16 0x2002
-#define ULA_PREFIX_8 0xfc
-
-#define NET_TYPE_UNKNOWN       0x00000000
-#define NET_TYPE_V4                    0x00000001
-#define NET_TYPE_V6                    0x00000002
-#define NET_TYPE_TEREDO                0x00000012
-#define NET_TYPE_6TO4          0x00000022
-#define NET_TYPE_LINKLOCAL     0x00000042
-#define NET_TYPE_SITELOCAL     0x00000082
-#define NET_TYPE_ULA           0x00000102
-#define NET_MASK_T6LSU         0x000001f0
-
-typedef struct
-{
-       int v4_count;
-       int v6_count;
-       int v6to4_count;
-       int teredo_count;
-       int ula_count;
-       int ll_count;
-       int sl_count;
-       int gai_v6_preferred;
-} config_stats_t;
 
 static int net_config_token = -1;
 
 static int net_config_token = -1;
-static config_stats_t config_stats_global;
+static uint32_t net_v4_count = 0;
+static uint32_t net_v6_count = 0;      // includes 6to4 addresses
 static pthread_mutex_t net_config_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 typedef struct {
 static pthread_mutex_t net_config_mutex = PTHREAD_MUTEX_INITIALIZER;
 
 typedef struct {
@@ -90,46 +68,14 @@ typedef struct {
        uint64_t ttl;
 } build_hostent_t;
 
        uint64_t ttl;
 } build_hostent_t;
 
-static int
-_si_net_addr_type(const struct sockaddr *s)
-{
-       const struct sockaddr_in6 *sa6 = (const struct sockaddr_in6 *)s;
-
-       if (s == NULL) return NET_TYPE_UNKNOWN;
-       else if (s->sa_family == AF_INET) return NET_TYPE_V4;
-       else if (s->sa_family != AF_INET6) return NET_TYPE_UNKNOWN;
-       else if (sa6->sin6_addr.__u6_addr.__u6_addr32[0] == ntohs(TEREDO_PREFIX_32)) return NET_TYPE_TEREDO;
-       else if (sa6->sin6_addr.__u6_addr.__u6_addr16[0] == ntohs(V6TO4_PREFIX_16)) return NET_TYPE_6TO4;
-       else if (IN6_IS_ADDR_LINKLOCAL(&(sa6->sin6_addr))) return NET_TYPE_LINKLOCAL;
-       else if (IN6_IS_ADDR_SITELOCAL(&(sa6->sin6_addr))) return NET_TYPE_SITELOCAL;
-       else if ((sa6->sin6_addr.__u6_addr.__u6_addr8[0] & 0xfe) == ULA_PREFIX_8) return NET_TYPE_ULA;
-
-       return NET_TYPE_V6;
-}
-
-static int
-_si_net_type_is_IPv6_globably_reachable_non_transitional(int t)
-{
-       if (t & NET_TYPE_V6)
-       {
-               if (t & NET_MASK_T6LSU) return 0;
-               return 1;
-       }
-
-       return 0;
-}
-
-static int
-_si_netconfig(config_stats_t *stats)
+__private_extern__ int
+si_inet_config(uint32_t *inet4, uint32_t *inet6)
 {
 {
-       int status, checkit, net_type;
+       int status, checkit;
        struct ifaddrs *ifa, *ifap;
 
        struct ifaddrs *ifa, *ifap;
 
-       if (stats == NULL) return 0;
-
        pthread_mutex_lock(&net_config_mutex);
 
        pthread_mutex_lock(&net_config_mutex);
 
-       status = 0;
        checkit = 1;
 
        if (net_config_token < 0)
        checkit = 1;
 
        if (net_config_token < 0)
@@ -144,6 +90,8 @@ _si_netconfig(config_stats_t *stats)
                if (status != 0) checkit = 1;
        }
 
                if (status != 0) checkit = 1;
        }
 
+       status = 0;
+
        if (checkit != 0)
        {
                if (getifaddrs(&ifa) < 0)
        if (checkit != 0)
        {
                if (getifaddrs(&ifa) < 0)
@@ -152,78 +100,36 @@ _si_netconfig(config_stats_t *stats)
                }
                else
                {
                }
                else
                {
-                       memset(&config_stats_global, 0, sizeof(config_stats_t));
+                       net_v4_count = 0;
+                       net_v6_count = 0;
 
                        for (ifap = ifa; ifap != NULL; ifap = ifap->ifa_next)
                        {
                                if (ifap->ifa_addr == NULL) continue;
                                if ((ifap->ifa_flags & IFF_UP) == 0) continue;
 
 
                        for (ifap = ifa; ifap != NULL; ifap = ifap->ifa_next)
                        {
                                if (ifap->ifa_addr == NULL) continue;
                                if ((ifap->ifa_flags & IFF_UP) == 0) continue;
 
-                               net_type = _si_net_addr_type(ifap->ifa_addr);
-               
-                               if (net_type == NET_TYPE_UNKNOWN)
-                               {
-                               }
-                               else if (net_type == NET_TYPE_V4)
+                               if (ifap->ifa_addr->sa_family == AF_INET)
                                {
                                {
-                                       config_stats_global.v4_count++;
+                                       net_v4_count++;
                                }
                                }
-                               else
+                               else if (ifap->ifa_addr->sa_family == AF_INET6)
                                {
                                {
-                                       config_stats_global.v6_count++;
-
-                                       if (net_type == NET_TYPE_LINKLOCAL)
-                                       {
-                                               config_stats_global.ll_count++;
-                                               continue;
-                                       }
-                                       else if (net_type == NET_TYPE_ULA)
-                                       {
-                                               config_stats_global.ula_count++;
-                                               if (!strncmp(ifap->ifa_name, "utun", 4)) continue;
-                                       }
-                                       if (net_type == NET_TYPE_TEREDO)
-                                       {
-                                               config_stats_global.teredo_count++;
-                                       }
-                                       else if (net_type == NET_TYPE_6TO4)
-                                       {
-                                               config_stats_global.v6to4_count++;
-                                       }
-                                       else if (net_type == NET_TYPE_SITELOCAL)
-                                       {
-                                               config_stats_global.sl_count++;
-                                       }
-
-                                       if (_si_net_type_is_IPv6_globably_reachable_non_transitional(net_type))
-                                       {
-                                               config_stats_global.gai_v6_preferred = 1;
-                                       }
+                                       net_v6_count++;
                                }
                        }
                                }
                        }
-
-                       freeifaddrs(ifa);
                }
                }
+
+               freeifaddrs(ifa);
        }
 
        }
 
-       *stats = config_stats_global;
+       if (inet4 != NULL) *inet4 = net_v4_count;
+       if (inet6 != NULL) *inet6 = net_v6_count;
 
        pthread_mutex_unlock(&net_config_mutex);
 
        return status;
 }
 
 
        pthread_mutex_unlock(&net_config_mutex);
 
        return status;
 }
 
-__private_extern__ int
-si_inet_config(uint32_t *inet4, uint32_t *inet6)
-{
-       config_stats_t x;
-
-       if (_si_netconfig(&x) < 0) return -1;
-       if (inet4 != NULL) *inet4 = x.v4_count;
-       if (inet6 != NULL) *inet6 = x.v6_count;
-       return 0;
-}
-
 void
 freeaddrinfo(struct addrinfo *a)
 {
 void
 freeaddrinfo(struct addrinfo *a)
 {
@@ -274,7 +180,7 @@ gai_strerror(int32_t err)
  * string.  If the caller specifies both NI_NUMERICHOST and NI_NUMERICSERV,
  * we inet_ntop() and printf() and return the results.
  */
  * string.  If the caller specifies both NI_NUMERICHOST and NI_NUMERICSERV,
  * we inet_ntop() and printf() and return the results.
  */
-__private_extern__ si_item_t *
+si_item_t *
 si_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *interface, uint32_t *err)
 {
        si_item_t *out = NULL;
 si_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *interface, uint32_t *err)
 {
        si_item_t *out = NULL;
@@ -316,8 +222,8 @@ si_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *inte
                memcpy(&a6, &s6->sin6_addr, sizeof(a6));
                port = s6->sin6_port;
 
                memcpy(&a6, &s6->sin6_addr, sizeof(a6));
                port = s6->sin6_port;
 
-               /* Look for link-local IPv6 scope id */
-               if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr))
+               /* Look for scope id in IPv6 Link Local, Multicast Node Local, and Multicast Link Local */
+               if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr) || IN6_IS_ADDR_MC_NODELOCAL(&s6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&s6->sin6_addr))
                {
                        ifnum = ntohs(a6.__u6_addr.__u6_addr16[1]);
                        if (ifnum == 0)
                {
                        ifnum = ntohs(a6.__u6_addr.__u6_addr16[1]);
                        if (ifnum == 0)
@@ -326,8 +232,7 @@ si_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *inte
                                a6.__u6_addr.__u6_addr16[1] = htons(ifnum);
                        }
 
                                a6.__u6_addr.__u6_addr16[1] = htons(ifnum);
                        }
 
-                       if (ifnum != s6->sin6_scope_id &&
-                           s6->sin6_scope_id != 0)
+                       if ((ifnum != s6->sin6_scope_id) && (s6->sin6_scope_id != 0))
                        {
                                if (err != NULL) *err = SI_STATUS_EAI_FAIL;
                                return NULL;
                        {
                                if (err != NULL) *err = SI_STATUS_EAI_FAIL;
                                return NULL;
@@ -359,12 +264,6 @@ si_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *inte
 
        if (do_host_lookup == 1)
        {
 
        if (do_host_lookup == 1)
        {
-#if 0
-               if ((do_serv_lookup == 1) && (si->sim_nameinfo != NULL))
-               {
-                       return si->sim_nameinfo(si, lookup_sa, flags, interface, err);
-               }
-#endif
                si_item_t *item = si_host_byaddr(si, addr, lookup_sa->sa_family, interface, NULL);
                if (item != NULL)
                {
                si_item_t *item = si_host_byaddr(si, addr, lookup_sa->sa_family, interface, NULL);
                if (item != NULL)
                {
@@ -402,7 +301,7 @@ si_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *inte
         * Return numeric host name for NI_NUMERICHOST or if lookup failed, but not
         * if NI_NAMEREQD is specified (so that we later fail with EAI_NONAME).
         */
         * Return numeric host name for NI_NUMERICHOST or if lookup failed, but not
         * if NI_NAMEREQD is specified (so that we later fail with EAI_NONAME).
         */
-       if (host == NULL && (flags & NI_NAMEREQD) == 0)
+       if ((host == NULL) && ((flags & NI_NAMEREQD) == 0))
        {
                char tmp[INET6_ADDRSTRLEN + 1 + IF_NAMESIZE + 1];
                tmp[0] = '\0';
        {
                char tmp[INET6_ADDRSTRLEN + 1 + IF_NAMESIZE + 1];
                tmp[0] = '\0';
@@ -505,7 +404,7 @@ _gai_numericserv(const char *serv, uint16_t *port)
        return numeric;
 }
 
        return numeric;
 }
 
-__private_extern__ int
+int
 _gai_serv_to_port(const char *serv, uint32_t proto, uint16_t *port)
 {
        si_item_t *item;
 _gai_serv_to_port(const char *serv, uint32_t proto, uint16_t *port)
 {
        si_item_t *item;
@@ -527,7 +426,7 @@ _gai_serv_to_port(const char *serv, uint32_t proto, uint16_t *port)
        return 0;
 }
 
        return 0;
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_addrinfo_v4(si_mod_t *si, int32_t flags, int32_t sock, int32_t proto, uint16_t port, struct in_addr *addr, uint16_t iface, const char *cname)
 {
        socket_data_t sockdata;
 si_addrinfo_v4(si_mod_t *si, int32_t flags, int32_t sock, int32_t proto, uint16_t port, struct in_addr *addr, uint16_t iface, const char *cname)
 {
        socket_data_t sockdata;
@@ -552,7 +451,33 @@ si_addrinfo_v4(si_mod_t *si, int32_t flags, int32_t sock, int32_t proto, uint16_
        return (si_item_t *)LI_ils_create("L448844444Ss", (unsigned long)si, CATEGORY_ADDRINFO, 1, unused, unused, flags, AF_INET, sock, proto, len, sockdata, cname);
 }
 
        return (si_item_t *)LI_ils_create("L448844444Ss", (unsigned long)si, CATEGORY_ADDRINFO, 1, unused, unused, flags, AF_INET, sock, proto, len, sockdata, cname);
 }
 
-__private_extern__ si_item_t *
+si_item_t *
+si_addrinfo_v4_mapped(si_mod_t *si, int32_t flags, int32_t sock, int32_t proto, uint16_t port, struct in_addr *addr, uint16_t iface, const char *cname)
+{
+       socket_data_t sockdata;
+       struct sockaddr_in6 *sa;
+       int32_t len;
+       uint64_t unused;
+
+       unused = 0;
+       len = sizeof(struct sockaddr_in6);
+       memset(&sockdata, 0, sizeof(socket_data_t));
+       sa = (struct sockaddr_in6 *)&sockdata;
+
+       sa->sin6_len = len;
+       sa->sin6_family = AF_INET6;
+       sa->sin6_port = htons(port);
+       memset(&(sa->sin6_addr.__u6_addr.__u6_addr8[10]), 0xff, 2);
+       memcpy(&(sa->sin6_addr.__u6_addr.__u6_addr8[12]), addr, sizeof(struct in_addr));
+
+       /* sin6_scope_id is in host byte order */
+       sa->sin6_scope_id = iface;
+
+       return (si_item_t *)LI_ils_create("L448844444Ss", (unsigned long)si, CATEGORY_ADDRINFO, 1, unused, unused, flags, AF_INET6, sock, proto, len, sockdata, cname);
+}
+
+
+si_item_t *
 si_addrinfo_v6(si_mod_t *si, int32_t flags, int32_t sock, int32_t proto, uint16_t port, struct in6_addr *addr, uint16_t iface, const char *cname)
 {
        socket_data_t sockdata;
 si_addrinfo_v6(si_mod_t *si, int32_t flags, int32_t sock, int32_t proto, uint16_t port, struct in6_addr *addr, uint16_t iface, const char *cname)
 {
        socket_data_t sockdata;
@@ -587,55 +512,86 @@ si_addrinfo_v6(si_mod_t *si, int32_t flags, int32_t sock, int32_t proto, uint16_
        return (si_item_t *)LI_ils_create("L448844444Ss", (unsigned long)si, CATEGORY_ADDRINFO, 1, unused, unused, flags, AF_INET6, sock, proto, len, sockdata, cname);
 }
 
        return (si_item_t *)LI_ils_create("L448844444Ss", (unsigned long)si, CATEGORY_ADDRINFO, 1, unused, unused, flags, AF_INET6, sock, proto, len, sockdata, cname);
 }
 
-__private_extern__ si_list_t *
-si_addrinfo_list(si_mod_t *si, int socktype, int proto, struct in_addr *a4, struct in6_addr *a6, int port, int scopeid, const char *cname4, const char *cname6)
+si_list_t *
+si_addrinfo_list(si_mod_t *si, uint32_t flags, int socktype, int proto, struct in_addr *a4, struct in6_addr *a6, int port, int scopeid, const char *cname4, const char *cname6)
 {
 {
+       int do_map = 0;
        si_item_t *item = NULL;
        si_list_t *out4 = NULL, *out6 = NULL;
        si_item_t *item = NULL;
        si_list_t *out4 = NULL, *out6 = NULL;
-       if (a4 != NULL)
+
+       if ((flags & AI_V4MAPPED) && ((flags & AI_ALL) || (a6 == NULL))) do_map = 1;
+
+       if (a6 != NULL)
        {
                if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_UDP))
                {
        {
                if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_UDP))
                {
-                       item = si_addrinfo_v4(si, 0, SOCK_DGRAM, IPPROTO_UDP, port, a4, 0, cname4);
-                       out4 = si_list_add(out4, item);
+                       item = si_addrinfo_v6(si, 0, SOCK_DGRAM, IPPROTO_UDP, port, a6, scopeid, cname6);
+                       out6 = si_list_add(out6, item);
                        si_item_release(item);
                }
 
                if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_TCP))
                {
                        si_item_release(item);
                }
 
                if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_TCP))
                {
-                       item = si_addrinfo_v4(si, 0, SOCK_STREAM, IPPROTO_TCP, port, a4, 0, cname4);
-                       out4 = si_list_add(out4, item);
+                       item = si_addrinfo_v6(si, 0, SOCK_STREAM, IPPROTO_TCP, port, a6, scopeid, cname6);
+                       out6 = si_list_add(out6, item);
                        si_item_release(item);
                }
 
                        si_item_release(item);
                }
 
-               if (proto == IPPROTO_ICMP)
+               if (proto == IPPROTO_ICMPV6)
                {
                {
-                       item = si_addrinfo_v4(si, 0, SOCK_RAW, IPPROTO_ICMP, port, a4, 0, cname4);
-                       out4 = si_list_add(out4, item);
+                       item = si_addrinfo_v6(si, 0, SOCK_RAW, IPPROTO_ICMPV6, port, a6, scopeid, cname6);
+                       out6 = si_list_add(out6, item);
                        si_item_release(item);
                }
        }
 
                        si_item_release(item);
                }
        }
 
-       if (a6 != NULL)
+       if (a4 != NULL)
        {
                if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_UDP))
                {
        {
                if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_UDP))
                {
-                       item = si_addrinfo_v6(si, 0, SOCK_DGRAM, IPPROTO_UDP, port, a6, scopeid, cname6);
-                       out6 = si_list_add(out6, item);
+                       if (do_map == 0)
+                       {
+                               item = si_addrinfo_v4(si, 0, SOCK_DGRAM, IPPROTO_UDP, port, a4, 0, cname4);
+                               out4 = si_list_add(out4, item);
+                       }
+                       else
+                       {
+                               item = si_addrinfo_v4_mapped(si, 0, SOCK_DGRAM, IPPROTO_UDP, port, a4, 0, cname4);
+                               out6 = si_list_add(out6, item);
+                       }
+
                        si_item_release(item);
                }
 
                if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_TCP))
                {
                        si_item_release(item);
                }
 
                if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_TCP))
                {
-                       item = si_addrinfo_v6(si, 0, SOCK_STREAM, IPPROTO_TCP, port, a6, scopeid, cname6);
-                       out6 = si_list_add(out6, item);
+                       if (do_map == 0)
+                       {
+                               item = si_addrinfo_v4(si, 0, SOCK_STREAM, IPPROTO_TCP, port, a4, 0, cname4);
+                               out4 = si_list_add(out4, item);
+                       }
+                       else
+                       {
+                               item = si_addrinfo_v4_mapped(si, 0, SOCK_STREAM, IPPROTO_TCP, port, a4, 0, cname4);
+                               out6 = si_list_add(out6, item);
+                       }
+
                        si_item_release(item);
                }
 
                        si_item_release(item);
                }
 
-               if (proto == IPPROTO_ICMPV6)
+               if (proto == IPPROTO_ICMP)
                {
                {
-                       item = si_addrinfo_v6(si, 0, SOCK_RAW, IPPROTO_ICMPV6, port, a6, scopeid, cname6);
-                       out6 = si_list_add(out6, item);
+                       if (do_map == 0)
+                       {
+                               item = si_addrinfo_v4(si, 0, SOCK_RAW, IPPROTO_ICMP, port, a4, 0, cname4);
+                               out4 = si_list_add(out4, item);
+                       }
+                       else
+                       {
+                               item = si_addrinfo_v4_mapped(si, 0, SOCK_RAW, IPPROTO_ICMP, port, a4, 0, cname4);
+                               out6 = si_list_add(out6, item);
+                       }
+
                        si_item_release(item);
                }
        }
                        si_item_release(item);
                }
        }
@@ -654,9 +610,10 @@ si_addrinfo_list(si_mod_t *si, int socktype, int proto, struct in_addr *a4, stru
  * Returns 1 if host name is numeric or 0 if not, or -1 on error.
  */
 static int
  * Returns 1 if host name is numeric or 0 if not, or -1 on error.
  */
 static int
-_gai_numerichost(const char* nodename, uint32_t *family, int flags, struct in_addr *a4, struct in6_addr *a6)
+_gai_numerichost(const char* nodename, uint32_t *family, int flags, struct in_addr *a4, struct in6_addr *a6, int *scope)
 {
        int numerichost, passive;
 {
        int numerichost, passive;
+       in_addr_t test;
 
        numerichost = 0;
 
 
        numerichost = 0;
 
@@ -665,7 +622,7 @@ _gai_numerichost(const char* nodename, uint32_t *family, int flags, struct in_ad
                /* return loopback or passive addresses */
                passive = (flags & AI_PASSIVE);
 
                /* return loopback or passive addresses */
                passive = (flags & AI_PASSIVE);
 
-               if ((*family == AF_UNSPEC) || (*family == AF_INET))
+               if (((*family == AF_UNSPEC) || (*family == AF_INET)) || ((*family == AF_INET6) && (flags & AI_V4MAPPED) && (flags & AI_ALL)))
                {
                        if (passive) a4->s_addr = 0;
                        else a4->s_addr = htonl(INADDR_LOOPBACK);
                {
                        if (passive) a4->s_addr = 0;
                        else a4->s_addr = htonl(INADDR_LOOPBACK);
@@ -681,12 +638,41 @@ _gai_numerichost(const char* nodename, uint32_t *family, int flags, struct in_ad
        }
        else
        {
        }
        else
        {
-               /* numeric IPv4 host valid for AF_UNSPEC and AF_INET */
+               /*
+                * numeric IPv4 host valid for AF_UNSPEC and AF_INET
+                * also valid for AF_INET6 with AI_V4MAPPED
+                */
                numerichost = inet_pton(AF_INET, nodename, a4);
                numerichost = inet_pton(AF_INET, nodename, a4);
+               if (numerichost == 0)
+               {
+                       test = inet_addr(nodename);
+                       if (test != (in_addr_t)-1)
+                       {
+                               a4->s_addr = test;
+                               numerichost = 1;
+                       }
+               }
+
                if (numerichost == 1)
                {
                if (numerichost == 1)
                {
-                       if (*family == AF_UNSPEC) *family = AF_INET;
-                       else if (*family == AF_INET6) numerichost = -1;
+                       if (*family == AF_UNSPEC)
+                       {
+                               *family = AF_INET;
+                       }
+                       else if (*family == AF_INET6)
+                       {
+                               if (flags & AI_V4MAPPED)
+                               {
+                                       memset(a6, 0, sizeof(struct in6_addr));
+                                       memset(&(a6->__u6_addr.__u6_addr8[10]), 0xff, 2);
+                                       memcpy(&(a6->__u6_addr.__u6_addr8[12]), a4, sizeof(struct in_addr));
+                               }
+                               else
+                               {
+                                       numerichost = -1;
+                               }
+                       }
+
                        return numerichost;
                }
 
                        return numerichost;
                }
 
@@ -694,8 +680,28 @@ _gai_numerichost(const char* nodename, uint32_t *family, int flags, struct in_ad
                numerichost = inet_pton(AF_INET6, nodename, a6);
                if (numerichost == 1)
                {
                numerichost = inet_pton(AF_INET6, nodename, a6);
                if (numerichost == 1)
                {
+                       /* check for scope/zone id */
+                       char *p = strrchr(nodename, SCOPE_DELIMITER);
+                       if (p != NULL)
+                       {
+                               int i, d;
+                               char *x;
+                               
+                               p++;
+                               d = 1;
+                               for (x = p; (*x != '\0') && (d == 1); x++)
+                               {
+                                       i = *x;
+                                       d = isdigit(i);
+                               }
+                               
+                               if (d == 1) *scope = atoi(p);
+                               else *scope = if_nametoindex(p);
+                       }
+
                        if (*family == AF_UNSPEC) *family = AF_INET6;
                        else if (*family == AF_INET) numerichost = -1;
                        if (*family == AF_UNSPEC) *family = AF_INET6;
                        else if (*family == AF_INET) numerichost = -1;
+
                        return numerichost;
                }
        }
                        return numerichost;
                }
        }
@@ -706,8 +712,8 @@ _gai_numerichost(const char* nodename, uint32_t *family, int flags, struct in_ad
 /* si_addrinfo_list_from_hostent
  * Returns an addrinfo list from IPv4 and IPv6 hostent entries
  */
 /* si_addrinfo_list_from_hostent
  * Returns an addrinfo list from IPv4 and IPv6 hostent entries
  */
-__private_extern__ si_list_t *
-si_addrinfo_list_from_hostent(si_mod_t *si, uint32_t socktype, uint32_t proto, uint16_t port, uint16_t scope, const struct hostent *h4, const struct hostent *h6)
+si_list_t *
+si_addrinfo_list_from_hostent(si_mod_t *si, uint32_t flags, uint32_t socktype, uint32_t proto, uint16_t port, uint16_t scope, const struct hostent *h4, const struct hostent *h6)
 {
        int i;
        si_list_t *out = NULL;
 {
        int i;
        si_list_t *out = NULL;
@@ -719,7 +725,7 @@ si_addrinfo_list_from_hostent(si_mod_t *si, uint32_t socktype, uint32_t proto, u
                {
                        struct in6_addr a6;
                        memcpy(&a6, h6->h_addr_list[i], h6->h_length);
                {
                        struct in6_addr a6;
                        memcpy(&a6, h6->h_addr_list[i], h6->h_length);
-                       list = si_addrinfo_list(si, socktype, proto, NULL, &a6, port, scope, NULL, h6->h_name);
+                       list = si_addrinfo_list(si, flags, socktype, proto, NULL, &a6, port, scope, NULL, h6->h_name);
                        out = si_list_concat(out, list);
                        si_list_release(list);
                }
                        out = si_list_concat(out, list);
                        si_list_release(list);
                }
@@ -731,7 +737,7 @@ si_addrinfo_list_from_hostent(si_mod_t *si, uint32_t socktype, uint32_t proto, u
                {
                        struct in_addr a4;
                        memcpy(&a4, h4->h_addr_list[i], h4->h_length);
                {
                        struct in_addr a4;
                        memcpy(&a4, h4->h_addr_list[i], h4->h_length);
-                       list = si_addrinfo_list(si, socktype, proto, &a4, NULL, port, 0, h4->h_name, NULL);
+                       list = si_addrinfo_list(si, flags, socktype, proto, &a4, NULL, port, 0, h4->h_name, NULL);
                        out = si_list_concat(out, list);
                        si_list_release(list);
                }
                        out = si_list_concat(out, list);
                        si_list_release(list);
                }
@@ -741,74 +747,107 @@ si_addrinfo_list_from_hostent(si_mod_t *si, uint32_t socktype, uint32_t proto, u
 }
 
 int
 }
 
 int
-_gai_sa_dst_compare(const struct sockaddr *a, const struct sockaddr *b, int unused)
+_gai_addr_sort(const void *a, const void *b)
 {
 {
-       int ta, tb, posn_a, posn_b;
-
-       ta = _si_net_addr_type(a);
-       tb = _si_net_addr_type(b);
-
-       posn_a = 2;
-       posn_b = 2;
-
-       if (ta & NET_TYPE_V4) posn_a = 1;
-       if (tb & NET_TYPE_V4) posn_b = 1;
-
-       if (_si_net_type_is_IPv6_globably_reachable_non_transitional(ta)) posn_a = 0;
-       if (_si_net_type_is_IPv6_globably_reachable_non_transitional(tb)) posn_b = 0;
-
-       return (posn_a - posn_b);
-}
-
-int
-_gai_addr_sort(void *thunk, const void *a, const void *b)
-{
-       si_item_t **ia, **ib;
+       si_item_t **item_a, **item_b;
        si_addrinfo_t *p, *q;
        struct sockaddr *sp, *sq;
        si_addrinfo_t *p, *q;
        struct sockaddr *sp, *sq;
-       uint32_t *v4first = (uint32_t *)thunk;
-
-       ia = (si_item_t **)a;
-       ib = (si_item_t **)b;
        
        
-       p = (si_addrinfo_t *)((uintptr_t)*ia + sizeof(si_item_t));
-       q = (si_addrinfo_t *)((uintptr_t)*ib + sizeof(si_item_t));
+       item_a = (si_item_t **)a;
+       item_b = (si_item_t **)b;
+
+       p = (si_addrinfo_t *)((uintptr_t)*item_a + sizeof(si_item_t));
+       q = (si_addrinfo_t *)((uintptr_t)*item_b + sizeof(si_item_t));
 
        sp = (struct sockaddr *)p->ai_addr.x;
        sq = (struct sockaddr *)q->ai_addr.x;
 
 
        sp = (struct sockaddr *)p->ai_addr.x;
        sq = (struct sockaddr *)q->ai_addr.x;
 
-       if (*v4first == 1)
-       {
-               if (sp->sa_family == sq->sa_family) return 0;
-               if (sp->sa_family == AF_INET) return -1;
-               return 1;
-       }
-
-       return _gai_sa_dst_compare(sp, sq, 0);
+       /*
+        * sa_dst_compare(A,B) returns -1 if A is less desirable than B,
+        * 0 if they are equally desirable, and 1 if A is more desirable.
+        * qsort() expects the inverse, so we swap sp and sq.
+        */
+       return sa_dst_compare(sq, sp, 0);
 }
 
 static si_list_t *
 }
 
 static si_list_t *
-_gai_sort_list(si_list_t *in)
+_gai_sort_list(si_list_t *in, uint32_t flags)
 {
 {
-       uint32_t v4first;
-       config_stats_t x;
+       si_list_t *out;
+       int filter_mapped;
+       uint32_t i;
+       uint32_t v4mapped_count = 0;
+       uint32_t v6_count = 0;
+       si_addrinfo_t *a;
 
        if (in == NULL) return NULL;
 
 
        if (in == NULL) return NULL;
 
-       memset(&x, 0, sizeof(config_stats_t));
-       if (_si_netconfig(&x) < 0) return in;
+       for (i = 0; i < in->count; i++)
+       {
+               a = (si_addrinfo_t *)((uintptr_t)in->entry[i] + sizeof(si_item_t));
+               if (a->ai_family == AF_INET6)
+               {
+                       struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)a->ai_addr.x;
+                       if (IN6_IS_ADDR_V4MAPPED(&(s6->sin6_addr))) v4mapped_count++;
+                       else v6_count++;
+               }
+       }
+
+       filter_mapped = 1;
+       if ((flags & AI_V4MAPPED) && ((v6_count == 0) || (flags & AI_ALL))) filter_mapped = 0;
+
+       out = in;
+
+       if ((filter_mapped == 1) && (v4mapped_count > 0))
+       {
+               i = in->count - v4mapped_count;
+               if (i == 0) return NULL;
+
+               out = (si_list_t *)calloc(1, sizeof(si_list_t));
+               if (out == NULL) return in;
+
+               out->count = i;
+               out->refcount = in->refcount;
 
 
-       v4first = 1;
-       if (x.gai_v6_preferred != 0) v4first = 0;
+               out->entry = (si_item_t **)calloc(out->count, sizeof(si_item_t *));
+               if (out->entry == NULL)
+               {
+                       free(out);
+                       return in;
+               }
+
+               out->curr = 0;
+
+               for (i = 0; i < in->count; i++)
+               {
+                       a = (si_addrinfo_t *)((uintptr_t)in->entry[i] + sizeof(si_item_t));
+                       if (a->ai_family == AF_INET6)
+                       {
+                               struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)a->ai_addr.x;
+                               if (IN6_IS_ADDR_V4MAPPED(&(s6->sin6_addr)))
+                               {
+                                       si_item_release(in->entry[i]);
+                                       continue;
+                               }
+                       }
+
+                       out->entry[out->curr++] = in->entry[i];
+               }
 
 
-       qsort_r(&in->entry[0], in->count, sizeof(si_item_t *), (void *)&v4first, _gai_addr_sort);
-       return in;
+               out->curr = 0;
+
+               free(in->entry);
+               free(in);
+       }
+
+       qsort(&out->entry[0], out->count, sizeof(si_item_t *), _gai_addr_sort);
+       return out;
 }
 
 /* _gai_simple
  * Simple lookup via gethostbyname2(3) mechanism.
  */
 }
 
 /* _gai_simple
  * Simple lookup via gethostbyname2(3) mechanism.
  */
-__private_extern__ si_list_t *
+si_list_t *
 _gai_simple(si_mod_t *si, const void *nodeptr, const void *servptr, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err)
 {
        si_item_t *h4_item = NULL, *h6_item = NULL;
 _gai_simple(si_mod_t *si, const void *nodeptr, const void *servptr, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err)
 {
        si_item_t *h4_item = NULL, *h6_item = NULL;
@@ -863,30 +902,30 @@ _gai_simple(si_mod_t *si, const void *nodeptr, const void *servptr, uint32_t fam
                h6 = (struct hostent *)((uintptr_t)h6_item + sizeof(si_item_t));
        }
 
                h6 = (struct hostent *)((uintptr_t)h6_item + sizeof(si_item_t));
        }
 
-       out = si_addrinfo_list_from_hostent(si, socktype, proto, port, 0, h4, h6);
+       out = si_addrinfo_list_from_hostent(si, flags, socktype, proto, port, 0, h4, h6);
        si_item_release(h4_item);
        si_item_release(h6_item);
 
        si_item_release(h4_item);
        si_item_release(h6_item);
 
-       return _gai_sort_list(out);
+       return _gai_sort_list(out, flags);
 }
 
 }
 
-__private_extern__ si_list_t *
+si_list_t *
 si_srv_byname(si_mod_t *si, const char *qname, const char *interface, uint32_t *err)
 {
        if (si == NULL) return 0;
 si_srv_byname(si_mod_t *si, const char *qname, const char *interface, uint32_t *err)
 {
        if (si == NULL) return 0;
-       if (si->sim_srv_byname == NULL) return 0;
+       if (si->vtable->sim_srv_byname == NULL) return 0;
 
 
-       return si->sim_srv_byname(si, qname, interface, err);
+       return si->vtable->sim_srv_byname(si, qname, interface, err);
 }
 
 }
 
-__private_extern__ int
+int
 si_wants_addrinfo(si_mod_t *si)
 {
        if (si == NULL) return 0;
 si_wants_addrinfo(si_mod_t *si)
 {
        if (si == NULL) return 0;
-       if (si->sim_addrinfo == NULL) return 0;
-       if (si->sim_wants_addrinfo == NULL) return 0;
+       if (si->vtable->sim_addrinfo == NULL) return 0;
+       if (si->vtable->sim_wants_addrinfo == NULL) return 0;
 
 
-       return si->sim_wants_addrinfo(si);
+       return si->vtable->sim_wants_addrinfo(si);
 }
 
 static si_list_t *
 }
 
 static si_list_t *
@@ -903,13 +942,13 @@ _gai_srv(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint
        /* Minimum SRV priority is zero. Start below that. */
        int lastprio = -1;
        int currprio;
        /* Minimum SRV priority is zero. Start below that. */
        int lastprio = -1;
        int currprio;
-       
+
        if (node == NULL || serv == NULL) return NULL;
        if (node == NULL || serv == NULL) return NULL;
-       
+
        asprintf(&qname, "%s.%s", serv, node);
        list = si_srv_byname(si, qname, interface, err);
        free(qname);
        asprintf(&qname, "%s.%s", serv, node);
        list = si_srv_byname(si, qname, interface, err);
        free(qname);
-       
+
        /* Iterate the SRV records starting at lowest priority and attempt to
         * lookup the target host name. Returns the first successful lookup.
         * It's an O(n^2) algorithm but data sets are small (less than 100) and
        /* Iterate the SRV records starting at lowest priority and attempt to
         * lookup the target host name. Returns the first successful lookup.
         * It's an O(n^2) algorithm but data sets are small (less than 100) and
@@ -920,12 +959,12 @@ _gai_srv(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint
                /* Find the next lowest priority level. */
                /* Maximum SRV priority is UINT16_MAX. Start above that. */
                currprio = INT_MAX;
                /* Find the next lowest priority level. */
                /* Maximum SRV priority is UINT16_MAX. Start above that. */
                currprio = INT_MAX;
-               
+
                for (i = 0; i < list->count; ++i)
                {
                        item = list->entry[i];
                        srv = (si_srv_t *)((uintptr_t)item + sizeof(si_item_t));
                for (i = 0; i < list->count; ++i)
                {
                        item = list->entry[i];
                        srv = (si_srv_t *)((uintptr_t)item + sizeof(si_item_t));
-                       
+
                        if (srv->priority > lastprio && srv->priority < currprio)
                        {
                                currprio = srv->priority;
                        if (srv->priority > lastprio && srv->priority < currprio)
                        {
                                currprio = srv->priority;
@@ -941,13 +980,13 @@ _gai_srv(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint
                {
                        lastprio = currprio;
                }
                {
                        lastprio = currprio;
                }
-               
+
                /* Lookup hosts at the current priority level. Return first match. */
                for (i = 0; i < list->count; ++i)
                {
                        item = list->entry[i];
                        srv = (si_srv_t *)((uintptr_t)item + sizeof(si_item_t));
                /* Lookup hosts at the current priority level. Return first match. */
                for (i = 0; i < list->count; ++i)
                {
                        item = list->entry[i];
                        srv = (si_srv_t *)((uintptr_t)item + sizeof(si_item_t));
-                       
+
                        if (srv->priority == currprio)
                        {
                                /* So that _gai_simple expects an integer service. */
                        if (srv->priority == currprio)
                        {
                                /* So that _gai_simple expects an integer service. */
@@ -966,14 +1005,15 @@ _gai_srv(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint
        {
                si_list_release(list);
        }
        {
                si_list_release(list);
        }
-       
+
        return result;
 }
 
        return result;
 }
 
-__private_extern__ si_list_t *
+si_list_t *
 si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err)
 {
        int numerichost, numericserv = 0;
 si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err)
 {
        int numerichost, numericserv = 0;
+       int scope = 0;
        const void *nodeptr = NULL, *servptr = NULL;
        uint16_t port;
        struct in_addr a4, *p4;
        const void *nodeptr = NULL, *servptr = NULL;
        uint16_t port;
        struct in_addr a4, *p4;
@@ -1046,6 +1086,18 @@ si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, u
                return NULL;
        }
 
                return NULL;
        }
 
+       /* check AI_V4MAPPED and AI_ALL */
+       if (family != AF_INET6)
+       {
+               /* unset AI_V4MAPPED and AI_ALL unless family is AF_INET6 */
+               flags &= ~(AI_V4MAPPED | AI_ALL);
+       }
+       else if ((flags & AI_V4MAPPED) == 0)
+       {
+               /* unset AI_ALL unless family is AF_INET6 and AI_V4MAPPED is set */
+               flags &= ~AI_ALL;
+       }
+
        memset(&a4, 0, sizeof(struct in_addr));
        memset(&a6, 0, sizeof(struct in6_addr));
 
        memset(&a4, 0, sizeof(struct in_addr));
        memset(&a6, 0, sizeof(struct in6_addr));
 
@@ -1059,7 +1111,7 @@ si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, u
        {
                /* AI_SRV SPI */
                out = _gai_srv(si, node, serv, family, socktype, proto, flags, interface, err);
        {
                /* AI_SRV SPI */
                out = _gai_srv(si, node, serv, family, socktype, proto, flags, interface, err);
-               return _gai_sort_list(out);
+               return _gai_sort_list(out, flags);
        }
        else
        {
        }
        else
        {
@@ -1074,7 +1126,7 @@ si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, u
                return NULL;
        }
 
                return NULL;
        }
 
-       if (serv != NULL)
+       if ((serv != NULL) && (strcmp(serv, "0") != 0))
        {
                if (numericserv == 1)
                {
        {
                if (numericserv == 1)
                {
@@ -1087,7 +1139,7 @@ si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, u
                }
        }
 
                }
        }
 
-       numerichost = _gai_numerichost(node, &family, flags, &a4, &a6);
+       numerichost = _gai_numerichost(node, &family, flags, &a4, &a6, &scope);
        if ((numerichost == -1) || ((flags & AI_NUMERICHOST) && (numerichost == 0)))
        {
                if (err != NULL) *err = SI_STATUS_EAI_NONAME;
        if ((numerichost == -1) || ((flags & AI_NUMERICHOST) && (numerichost == 0)))
        {
                if (err != NULL) *err = SI_STATUS_EAI_NONAME;
@@ -1137,20 +1189,23 @@ si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, u
                if (family == AF_INET6) p4 = NULL;
                if (node == NULL) cname = "localhost";
 
                if (family == AF_INET6) p4 = NULL;
                if (node == NULL) cname = "localhost";
 
+               /* allow nodename to be a mapped IPv4 address, e.g. "::ffff:10.0.0.1" */
+               if (p6 != NULL) flags |= AI_V4MAPPED;
+
                /* handle trivial questions */
                /* handle trivial questions */
-               out = si_addrinfo_list(si, socktype, proto, p4, p6, port, 0, cname, cname);
-               return _gai_sort_list(out);
+               out = si_addrinfo_list(si, flags, socktype, proto, p4, p6, port, scope, cname, cname);
+               return _gai_sort_list(out, flags);
        }
        }
-       else if ((si->sim_wants_addrinfo != NULL) && si->sim_wants_addrinfo(si))
+       else if (si_wants_addrinfo(si))
        {
                /* or let the current module handle the host lookups intelligently */
        {
                /* or let the current module handle the host lookups intelligently */
-               out = si->sim_addrinfo(si, nodeptr, servptr, family, socktype, proto, flags, interface, err);
-               return _gai_sort_list(out);
+               out = si->vtable->sim_addrinfo(si, nodeptr, servptr, family, socktype, proto, flags, interface, err);
+               return _gai_sort_list(out, flags);
        }
 
        /* fall back to a default path */
        out = _gai_simple(si, nodeptr, servptr, family, socktype, proto, flags, interface, err);
        }
 
        /* fall back to a default path */
        out = _gai_simple(si, nodeptr, servptr, family, socktype, proto, flags, interface, err);
-       return _gai_sort_list(out);
+       return _gai_sort_list(out, flags);
 }
 
 static struct addrinfo *
 }
 
 static struct addrinfo *
@@ -1194,7 +1249,7 @@ si_item_to_addrinfo(si_item_t *item)
        return out;
 }
 
        return out;
 }
 
-__private_extern__ struct addrinfo *
+struct addrinfo *
 si_list_to_addrinfo(si_list_t *list)
 {
        struct addrinfo *tail, *out;
 si_list_to_addrinfo(si_list_t *list)
 {
        struct addrinfo *tail, *out;
@@ -1369,17 +1424,17 @@ free_build_hostent(build_hostent_t *h)
        free(h);
 }
 
        free(h);
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_ipnode_byname(si_mod_t *si, const char *name, int family, int flags, const char *interface, uint32_t *err)
 {
        int i, status, want;
 si_ipnode_byname(si_mod_t *si, const char *name, int family, int flags, const char *interface, uint32_t *err)
 {
        int i, status, want;
+       uint32_t if4, if6;
        struct in_addr addr4;
        struct in6_addr addr6;
        si_item_t *item4, *item6;
        build_hostent_t *out;
        struct hostent *h;
        uint64_t unused;
        struct in_addr addr4;
        struct in6_addr addr6;
        si_item_t *item4, *item6;
        build_hostent_t *out;
        struct hostent *h;
        uint64_t unused;
-       config_stats_t ifstats;
 
        memset(&addr4, 0, sizeof(struct in_addr));
        memset(&addr6, 0, sizeof(struct in6_addr));
 
        memset(&addr4, 0, sizeof(struct in_addr));
        memset(&addr6, 0, sizeof(struct in6_addr));
@@ -1453,18 +1508,19 @@ si_ipnode_byname(si_mod_t *si, const char *name, int family, int flags, const ch
         * IF AI_ADDRCONFIG is set, we need to know what interface flavors we really have.
         */
 
         * IF AI_ADDRCONFIG is set, we need to know what interface flavors we really have.
         */
 
-       memset(&ifstats, 0, sizeof(config_stats_t));
+       if4 = 0;
+       if6 = 0;
 
        if (flags & AI_ADDRCONFIG)
        {
 
        if (flags & AI_ADDRCONFIG)
        {
-               if (_si_netconfig(&ifstats) < 0)
+               if (si_inet_config(&if4, &if6) < 0)
                {
                        if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
                        return NULL;
                }
 
                /* Bail out if there are no interfaces */
                {
                        if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
                        return NULL;
                }
 
                /* Bail out if there are no interfaces */
-               if ((ifstats.v4_count == 0) && (ifstats.v6_count == 0))
+               if ((if4 == 0) && (if6 == 0))
                {
                        if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
                        return NULL;
                {
                        if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
                        return NULL;
@@ -1479,7 +1535,7 @@ si_ipnode_byname(si_mod_t *si, const char *name, int family, int flags, const ch
 
        if (family == AF_INET)
        {
 
        if (family == AF_INET)
        {
-               if ((flags & AI_ADDRCONFIG) && (ifstats.v4_count == 0))
+               if ((flags & AI_ADDRCONFIG) && (if4 == 0))
                {
                        if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
                        return NULL;
                {
                        if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
                        return NULL;
@@ -1503,7 +1559,7 @@ si_ipnode_byname(si_mod_t *si, const char *name, int family, int flags, const ch
                }
                else
                {
                }
                else
                {
-                       if ((flags & AI_ADDRCONFIG) && (ifstats.v6_count == 0)) 
+                       if ((flags & AI_ADDRCONFIG) && (if6 == 0)) 
                        {
                                if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
                                return NULL;
                        {
                                if (err != NULL) *err = SI_STATUS_H_ERRNO_NO_RECOVERY;
                                return NULL;
index ada6b2560bc135c3617a5ec648faf98db24bb0bc..b0fc5870fc5b2e1cf5d62accce57bb520928de46 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2008-2009 Apple Inc.  All rights reserved.
+ * Copyright (c) 2008-2011 Apple Inc.  All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include <errno.h>
 #include <pthread.h>
 #include <mach/mach.h>
 #include <errno.h>
 #include <pthread.h>
 #include <mach/mach.h>
+#include <dispatch/dispatch.h>
 
 #include "si_module.h"
 
 #define PLUGIN_DIR_PATH "/usr/lib/info"
 #define PLUGIN_BUNDLE_SUFFIX "so"
 
 
 #include "si_module.h"
 
 #define PLUGIN_DIR_PATH "/usr/lib/info"
 #define PLUGIN_BUNDLE_SUFFIX "so"
 
-#define WORKUNIT_CALL_ACTIVE   0x00000001
-#define WORKUNIT_THREAD_ACTIVE 0x00000002
-#define WORKUNIT_RETURNS_LIST  0x00000004
+#define WORKUNIT_CANCELLED     0x00000001
+#define WORKUNIT_RETURNS_LIST  0x00000002
+
+#ifdef __BIG_ENDIAN__
+#define WORKUNIT_CANCELLED_BIT_ADDRESS 31
+#else
+#define WORKUNIT_CANCELLED_BIT_ADDRESS 7
+#endif
 
 typedef struct si_async_workunit_s
 {
 
 typedef struct si_async_workunit_s
 {
@@ -55,6 +61,7 @@ typedef struct si_async_workunit_s
        uint32_t err;
        /* async support below */
        uint32_t flags;
        uint32_t err;
        /* async support below */
        uint32_t flags;
+       int32_t refcount;
        void *callback;
        void *context;
        mach_port_t port;
        void *callback;
        void *context;
        mach_port_t port;
@@ -69,13 +76,13 @@ static uint32_t module_count = 0;
 static pthread_mutex_t module_mutex = PTHREAD_MUTEX_INITIALIZER;
 static si_async_workunit_t *si_async_worklist = NULL;
 
 static pthread_mutex_t module_mutex = PTHREAD_MUTEX_INITIALIZER;
 static si_async_workunit_t *si_async_worklist = NULL;
 
-__private_extern__ si_mod_t *si_module_static_search();
-__private_extern__ si_mod_t *si_module_static_file();
-__private_extern__ si_mod_t *si_module_static_cache();
-__private_extern__ si_mod_t *si_module_static_mdns();
+si_mod_t *si_module_static_search(void);
+si_mod_t *si_module_static_cache(void);
+si_mod_t *si_module_static_file(void);
 #ifdef DS_AVAILABLE
 #ifdef DS_AVAILABLE
-__private_extern__ si_mod_t *si_module_static_ds();
+si_mod_t *si_module_static_ds(void);
 #endif
 #endif
+si_mod_t *si_module_static_mdns(void);
 
 static void *
 si_mod_dlsym(void *so, const char *name, const char *sym)
 
 static void *
 si_mod_dlsym(void *so, const char *name, const char *sym)
@@ -94,22 +101,7 @@ si_mod_dlsym(void *so, const char *name, const char *sym)
        return out;
 }
 
        return out;
 }
 
-static si_mod_t *
-si_mod_static(const char *name)
-{
-       if (name == NULL) return NULL;
-
-       if (string_equal(name, "search")) return si_module_static_search();
-       if (string_equal(name, "file")) return si_module_static_file();
-       if (string_equal(name, "cache")) return si_module_static_cache();
-       if (string_equal(name, "mdns")) return si_module_static_mdns();
-#ifdef DS_AVAILABLE
-       if (string_equal(name, "ds")) return si_module_static_ds();
-#endif
-       return NULL;
-}
-
-__private_extern__ si_mod_t *
+si_mod_t *
 si_module_with_path(const char *path, const char *name)
 {
        void *so;
 si_module_with_path(const char *path, const char *name)
 {
        void *so;
@@ -149,8 +141,8 @@ si_module_with_path(const char *path, const char *name)
 
        if ((out == NULL) || (outname == NULL))
        {
 
        if ((out == NULL) || (outname == NULL))
        {
-               if (out != NULL) free(out);
-               if (outname != NULL) free(outname);
+               free(out);
+               free(outname);
                dlclose(so);
                errno = ENOMEM;
                return NULL;
                dlclose(so);
                errno = ENOMEM;
                return NULL;
@@ -158,6 +150,7 @@ si_module_with_path(const char *path, const char *name)
 
        out->name = outname;
        out->refcount = 1;
 
        out->name = outname;
        out->refcount = 1;
+       out->flags = 0;
        out->bundle = so;
 
        status = si_sym_init(out);
        out->bundle = so;
 
        status = si_sym_init(out);
@@ -176,84 +169,91 @@ si_module_with_path(const char *path, const char *name)
 si_mod_t *
 si_module_with_name(const char *name)
 {
 si_mod_t *
 si_module_with_name(const char *name)
 {
-       uint32_t i;
-       char *path;
-       si_mod_t *out;
-
-       if (name == NULL)
+       static struct
        {
        {
-               errno = EINVAL;
-               return NULL;
-       }
+               const char *name;
+               si_mod_t *(*init)(void);
+               si_mod_t *module;
+       } modules[] =
+       {
+               { "search", si_module_static_search, NULL },
+               { "cache", si_module_static_cache, NULL },
+               { "file", si_module_static_file, NULL },
+#ifdef DS_AVAILABLE
+               { "ds", si_module_static_ds, NULL },
+#endif
+               { "mdns", si_module_static_mdns, NULL },
+               { NULL, NULL },
+       };
 
 
-       pthread_mutex_lock(&module_mutex);
+       si_mod_t *si = NULL;
+       int i;
+
+       /*
+        * We don't need to worry about locking during initialization
+        * because all modules init routine returns static storage.
+        */
 
 
-       for (i = 0; i < module_count; i++)
+       /* Find the module by name */
+       for (i = 0; modules[i].name != NULL; ++i)
        {
        {
-               if (string_equal(module_list[i]->name, name))
+               if (string_equal(name, modules[i].name))
                {
                {
-                       si_module_retain(module_list[i]);
-                       pthread_mutex_unlock(&module_mutex);
-                       return module_list[i];
+                       si = modules[i].module;
+                       if (si == NULL)
+                       {
+                               si = modules[i].init();
+                               modules[i].module = si;
+                       }
+
+                       break;
                }
        }
 
                }
        }
 
-       pthread_mutex_unlock(&module_mutex);
-       out = si_mod_static(name);
-       pthread_mutex_lock(&module_mutex);
-
-       if (out == NULL)
-       {
-               path = NULL;
+       if (si != NULL) return si;
 
 
-               /* mdns lives in dns.so */
-               asprintf(&path, "%s/%s.%s", PLUGIN_DIR_PATH, name, PLUGIN_BUNDLE_SUFFIX);
-
-               if (path == NULL)
-               {
-                       errno = ENOMEM;
-                       pthread_mutex_unlock(&module_mutex);
-                       return NULL;
-               }
+       pthread_mutex_lock(&module_mutex);
+       char *path = NULL;
 
 
-               out = si_module_with_path(path, name);
-               free(path);
-       }
+       asprintf(&path, "%s/%s.%s", PLUGIN_DIR_PATH, name, PLUGIN_BUNDLE_SUFFIX);
 
 
-       if (out == NULL)
+       if (path == NULL)
        {
        {
+               errno = ENOMEM;
                pthread_mutex_unlock(&module_mutex);
                return NULL;
        }
 
                pthread_mutex_unlock(&module_mutex);
                return NULL;
        }
 
-       /* add out to module_list */
-       if (module_count == 0)
-       {
-               module_list = (si_mod_t **)calloc(1, sizeof(si_mod_t *));
-       }
-       else
+       si = si_module_with_path(path, name);
+       free(path);
+
+       if (si == NULL)
        {
        {
-               module_list = (si_mod_t **)reallocf(module_list, (module_count + 1) * sizeof(si_mod_t *));
+               pthread_mutex_unlock(&module_mutex);
+               return NULL;
        }
 
        }
 
+       /* add out to module_list */
+       module_list = (si_mod_t **)reallocf(module_list, (module_count + 1) * sizeof(si_mod_t *));
        if (module_list == NULL)
        {
                pthread_mutex_unlock(&module_mutex);
        if (module_list == NULL)
        {
                pthread_mutex_unlock(&module_mutex);
-               return out;
+               return si;
        }
 
        }
 
-       module_list[module_count] = out;
+       module_list[module_count] = si;
        module_count++;
 
        pthread_mutex_unlock(&module_mutex);
 
        module_count++;
 
        pthread_mutex_unlock(&module_mutex);
 
-       return out;
+       return si;
 }
 
 }
 
-__private_extern__ si_mod_t *
+si_mod_t *
 si_module_retain(si_mod_t *si)
 {
        if (si == NULL) return NULL;
 si_module_retain(si_mod_t *si)
 {
        if (si == NULL) return NULL;
+       if (si->flags & SI_MOD_FLAG_STATIC) return si;
 
        OSAtomicIncrement32Barrier(&si->refcount);
 
 
        OSAtomicIncrement32Barrier(&si->refcount);
 
@@ -266,6 +266,7 @@ si_module_release(si_mod_t *si)
        int32_t i;
 
        if (si == NULL) return;
        int32_t i;
 
        if (si == NULL) return;
+       if (si->flags & SI_MOD_FLAG_STATIC) return;
 
        i = OSAtomicDecrement32Barrier(&si->refcount);
        if (i > 0) return;
 
        i = OSAtomicDecrement32Barrier(&si->refcount);
        if (i > 0) return;
@@ -295,21 +296,21 @@ si_module_release(si_mod_t *si)
 
        pthread_mutex_unlock(&module_mutex);
 
 
        pthread_mutex_unlock(&module_mutex);
 
-       if (si->sim_close != NULL) si->sim_close(si);
+       if (si->vtable->sim_close != NULL) si->vtable->sim_close(si);
        if (si->bundle != NULL) dlclose(si->bundle);
        if (si->bundle != NULL) dlclose(si->bundle);
-       if (si->name != NULL) free(si->name);
+       free(si->name);
        free(si);
 }
 
        free(si);
 }
 
-__private_extern__ const char *
+const char *
 si_module_name(si_mod_t *si)
 {
        if (si == NULL) return NULL;
 
 si_module_name(si_mod_t *si)
 {
        if (si == NULL) return NULL;
 
-       return si->name;
+       return (const char *)si->name;
 }
 
 }
 
-__private_extern__ int
+int
 si_module_vers(si_mod_t *si)
 {
        if (si == NULL) return 0;
 si_module_vers(si_mod_t *si)
 {
        if (si == NULL) return 0;
@@ -317,7 +318,7 @@ si_module_vers(si_mod_t *si)
        return si->vers;
 }
 
        return si->vers;
 }
 
-__private_extern__ int
+int
 si_item_match(si_item_t *item, int cat, const void *name, uint32_t num, int which)
 {
        int i;
 si_item_match(si_item_t *item, int cat, const void *name, uint32_t num, int which)
 {
        int i;
@@ -489,7 +490,7 @@ si_item_match(si_item_t *item, int cat, const void *name, uint32_t num, int whic
        return 0;
 }
 
        return 0;
 }
 
-__private_extern__ int
+int
 si_item_is_valid(si_item_t *item)
 {
        si_mod_t *si;
 si_item_is_valid(si_item_t *item)
 {
        si_mod_t *si;
@@ -499,268 +500,268 @@ si_item_is_valid(si_item_t *item)
        si = item->src;
 
        if (si == NULL) return 0;
        si = item->src;
 
        if (si == NULL) return 0;
-       if (si->sim_is_valid == NULL) return 0;
+       if (si->vtable->sim_is_valid == NULL) return 0;
 
 
-       return si->sim_is_valid(si, item);
+       return si->vtable->sim_is_valid(si, item);
 }
 
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_user_byname(si_mod_t *si, const char *name)
 {
        if (si == NULL) return NULL;
 si_user_byname(si_mod_t *si, const char *name)
 {
        if (si == NULL) return NULL;
-       if (si->sim_user_byname == NULL) return NULL;
-       return si->sim_user_byname(si, name);
+       if (si->vtable->sim_user_byname == NULL) return NULL;
+       return si->vtable->sim_user_byname(si, name);
 }
 
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_user_byuid(si_mod_t *si, uid_t uid)
 {
        if (si == NULL) return NULL;
 si_user_byuid(si_mod_t *si, uid_t uid)
 {
        if (si == NULL) return NULL;
-       if (si->sim_user_byuid == NULL) return NULL;
-       return si->sim_user_byuid(si, uid);
+       if (si->vtable->sim_user_byuid == NULL) return NULL;
+       return si->vtable->sim_user_byuid(si, uid);
 }
 
 }
 
-__private_extern__ si_list_t *
+si_list_t *
 si_user_all(si_mod_t *si)
 {
        if (si == NULL) return NULL;
 si_user_all(si_mod_t *si)
 {
        if (si == NULL) return NULL;
-       if (si->sim_user_all == NULL) return NULL;
-       return si->sim_user_all(si);
+       if (si->vtable->sim_user_all == NULL) return NULL;
+       return si->vtable->sim_user_all(si);
 }
 
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_group_byname(si_mod_t *si, const char *name)
 {
        if (si == NULL) return NULL;
 si_group_byname(si_mod_t *si, const char *name)
 {
        if (si == NULL) return NULL;
-       if (si->sim_group_byname == NULL) return NULL;
-       return si->sim_group_byname(si, name);
+       if (si->vtable->sim_group_byname == NULL) return NULL;
+       return si->vtable->sim_group_byname(si, name);
 }
 
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_group_bygid(si_mod_t *si, gid_t gid)
 {
        if (si == NULL) return NULL;
 si_group_bygid(si_mod_t *si, gid_t gid)
 {
        if (si == NULL) return NULL;
-       if (si->sim_group_bygid == NULL) return NULL;
-       return si->sim_group_bygid(si, gid);
+       if (si->vtable->sim_group_bygid == NULL) return NULL;
+       return si->vtable->sim_group_bygid(si, gid);
 }
 
 }
 
-__private_extern__ si_list_t *
+si_list_t *
 si_group_all(si_mod_t *si)
 {
        if (si == NULL) return NULL;
 si_group_all(si_mod_t *si)
 {
        if (si == NULL) return NULL;
-       if (si->sim_group_all == NULL) return NULL;
-       return si->sim_group_all(si);
+       if (si->vtable->sim_group_all == NULL) return NULL;
+       return si->vtable->sim_group_all(si);
 }
 
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_grouplist(si_mod_t *si, const char *name)
 {
        if (si == NULL) return NULL;
 si_grouplist(si_mod_t *si, const char *name)
 {
        if (si == NULL) return NULL;
-       if (si->sim_grouplist == NULL) return NULL;
-       return si->sim_grouplist(si, name);
+       if (si->vtable->sim_grouplist == NULL) return NULL;
+       return si->vtable->sim_grouplist(si, name);
 }
 
 }
 
-__private_extern__ si_list_t *
+si_list_t *
 si_netgroup_byname(struct si_mod_s *si, const char *name)
 {
        if (si == NULL) return NULL;
 si_netgroup_byname(struct si_mod_s *si, const char *name)
 {
        if (si == NULL) return NULL;
-       if (si->sim_netgroup_byname == NULL) return NULL;
-       return si->sim_netgroup_byname(si, name);
+       if (si->vtable->sim_netgroup_byname == NULL) return NULL;
+       return si->vtable->sim_netgroup_byname(si, name);
 }
 
 }
 
-__private_extern__ int
+int
 si_in_netgroup(struct si_mod_s *si, const char *name, const char *host, const char *user, const char *domain)
 {
        if (si == NULL) return 0;
 si_in_netgroup(struct si_mod_s *si, const char *name, const char *host, const char *user, const char *domain)
 {
        if (si == NULL) return 0;
-       if (si->sim_in_netgroup == NULL) return 0;
-       return si->sim_in_netgroup(si, name, host, user, domain);
+       if (si->vtable->sim_in_netgroup == NULL) return 0;
+       return si->vtable->sim_in_netgroup(si, name, host, user, domain);
 }
 
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_alias_byname(si_mod_t *si, const char *name)
 {
        if (si == NULL) return NULL;
 si_alias_byname(si_mod_t *si, const char *name)
 {
        if (si == NULL) return NULL;
-       if (si->sim_alias_byname == NULL) return NULL;
-       return si->sim_alias_byname(si, name);
+       if (si->vtable->sim_alias_byname == NULL) return NULL;
+       return si->vtable->sim_alias_byname(si, name);
 }
 
 }
 
-__private_extern__ si_list_t *
+si_list_t *
 si_alias_all(si_mod_t *si)
 {
        if (si == NULL) return NULL;
 si_alias_all(si_mod_t *si)
 {
        if (si == NULL) return NULL;
-       if (si->sim_alias_all == NULL) return NULL;
-       return si->sim_alias_all(si);
+       if (si->vtable->sim_alias_all == NULL) return NULL;
+       return si->vtable->sim_alias_all(si);
 }
 
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_host_byname(si_mod_t *si, const char *name, int af, const char *interface, uint32_t *err)
 {
        if (si == NULL) return NULL;
 si_host_byname(si_mod_t *si, const char *name, int af, const char *interface, uint32_t *err)
 {
        if (si == NULL) return NULL;
-       if (si->sim_host_byname == NULL) return NULL;
-       return si->sim_host_byname(si, name, af, interface, err);
+       if (si->vtable->sim_host_byname == NULL) return NULL;
+       return si->vtable->sim_host_byname(si, name, af, interface, err);
 }
 
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_host_byaddr(si_mod_t *si, const void *addr, int af, const char *interface, uint32_t *err)
 {
        if (si == NULL) return NULL;
 si_host_byaddr(si_mod_t *si, const void *addr, int af, const char *interface, uint32_t *err)
 {
        if (si == NULL) return NULL;
-       if (si->sim_host_byaddr == NULL) return NULL;
-       return si->sim_host_byaddr(si, addr, af, interface, err);
+       if (si->vtable->sim_host_byaddr == NULL) return NULL;
+       return si->vtable->sim_host_byaddr(si, addr, af, interface, err);
 }
 
 }
 
-__private_extern__ si_list_t *
+si_list_t *
 si_host_all(si_mod_t *si)
 {
        if (si == NULL) return NULL;
 si_host_all(si_mod_t *si)
 {
        if (si == NULL) return NULL;
-       if (si->sim_host_all == NULL) return NULL;
-       return si->sim_host_all(si);
+       if (si->vtable->sim_host_all == NULL) return NULL;
+       return si->vtable->sim_host_all(si);
 }
 
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_mac_byname(struct si_mod_s *si, const char *name)
 {
        if (si == NULL) return NULL;
 si_mac_byname(struct si_mod_s *si, const char *name)
 {
        if (si == NULL) return NULL;
-       if (si->sim_mac_byname == NULL) return NULL;
-       return si->sim_mac_byname(si, name);
+       if (si->vtable->sim_mac_byname == NULL) return NULL;
+       return si->vtable->sim_mac_byname(si, name);
 }
 
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_mac_bymac(struct si_mod_s *si, const char *mac)
 {
        if (si == NULL) return NULL;
 si_mac_bymac(struct si_mod_s *si, const char *mac)
 {
        if (si == NULL) return NULL;
-       if (si->sim_mac_bymac == NULL) return NULL;
-       return si->sim_mac_bymac(si, mac);
+       if (si->vtable->sim_mac_bymac == NULL) return NULL;
+       return si->vtable->sim_mac_bymac(si, mac);
 }
 
 }
 
-__private_extern__ si_list_t *
+si_list_t *
 si_mac_all(si_mod_t *si)
 {
        if (si == NULL) return NULL;
 si_mac_all(si_mod_t *si)
 {
        if (si == NULL) return NULL;
-       if (si->sim_mac_all == NULL) return NULL;
-       return si->sim_mac_all(si);
+       if (si->vtable->sim_mac_all == NULL) return NULL;
+       return si->vtable->sim_mac_all(si);
 }
 
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_network_byname(si_mod_t *si, const char *name)
 {
        if (si == NULL) return NULL;
 si_network_byname(si_mod_t *si, const char *name)
 {
        if (si == NULL) return NULL;
-       if (si->sim_network_byname == NULL) return NULL;
-       return si->sim_network_byname(si, name);
+       if (si->vtable->sim_network_byname == NULL) return NULL;
+       return si->vtable->sim_network_byname(si, name);
 }
 
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_network_byaddr(si_mod_t *si, uint32_t addr)
 {
        if (si == NULL) return NULL;
 si_network_byaddr(si_mod_t *si, uint32_t addr)
 {
        if (si == NULL) return NULL;
-       if (si->sim_network_byaddr == NULL) return NULL;
-       return si->sim_network_byaddr(si, addr);
+       if (si->vtable->sim_network_byaddr == NULL) return NULL;
+       return si->vtable->sim_network_byaddr(si, addr);
 }
 
 }
 
-__private_extern__ si_list_t *
+si_list_t *
 si_network_all(si_mod_t *si)
 {
        if (si == NULL) return NULL;
 si_network_all(si_mod_t *si)
 {
        if (si == NULL) return NULL;
-       if (si->sim_network_all == NULL) return NULL;
-       return si->sim_network_all(si);
+       if (si->vtable->sim_network_all == NULL) return NULL;
+       return si->vtable->sim_network_all(si);
 }
 
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_service_byname(si_mod_t *si, const char *name, const char *proto)
 {
        if (si == NULL) return NULL;
 si_service_byname(si_mod_t *si, const char *name, const char *proto)
 {
        if (si == NULL) return NULL;
-       if (si->sim_service_byname == NULL) return NULL;
-       return si->sim_service_byname(si, name, proto);
+       if (si->vtable->sim_service_byname == NULL) return NULL;
+       return si->vtable->sim_service_byname(si, name, proto);
 }
 
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_service_byport(si_mod_t *si, int port, const char *proto)
 {
        if (si == NULL) return NULL;
 si_service_byport(si_mod_t *si, int port, const char *proto)
 {
        if (si == NULL) return NULL;
-       if (si->sim_service_byport == NULL) return NULL;
-       return si->sim_service_byport(si, port, proto);
+       if (si->vtable->sim_service_byport == NULL) return NULL;
+       return si->vtable->sim_service_byport(si, port, proto);
 }
 
 }
 
-__private_extern__ si_list_t *
+si_list_t *
 si_service_all(si_mod_t *si)
 {
        if (si == NULL) return NULL;
 si_service_all(si_mod_t *si)
 {
        if (si == NULL) return NULL;
-       if (si->sim_service_all == NULL) return NULL;
-       return si->sim_service_all(si);
+       if (si->vtable->sim_service_all == NULL) return NULL;
+       return si->vtable->sim_service_all(si);
 }
 
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_protocol_byname(si_mod_t *si, const char *name)
 {
        if (si == NULL) return NULL;
 si_protocol_byname(si_mod_t *si, const char *name)
 {
        if (si == NULL) return NULL;
-       if (si->sim_protocol_byname == NULL) return NULL;
-       return si->sim_protocol_byname(si, name);
+       if (si->vtable->sim_protocol_byname == NULL) return NULL;
+       return si->vtable->sim_protocol_byname(si, name);
 }
 
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_protocol_bynumber(si_mod_t *si, uint32_t number)
 {
        if (si == NULL) return NULL;
 si_protocol_bynumber(si_mod_t *si, uint32_t number)
 {
        if (si == NULL) return NULL;
-       if (si->sim_protocol_bynumber == NULL) return NULL;
-       return si->sim_protocol_bynumber(si, number);
+       if (si->vtable->sim_protocol_bynumber == NULL) return NULL;
+       return si->vtable->sim_protocol_bynumber(si, number);
 }
 
 }
 
-__private_extern__ si_list_t *
+si_list_t *
 si_protocol_all(si_mod_t *si)
 {
        if (si == NULL) return NULL;
 si_protocol_all(si_mod_t *si)
 {
        if (si == NULL) return NULL;
-       if (si->sim_protocol_all == NULL) return NULL;
-       return si->sim_protocol_all(si);
+       if (si->vtable->sim_protocol_all == NULL) return NULL;
+       return si->vtable->sim_protocol_all(si);
 }
 
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_rpc_byname(si_mod_t *si, const char *name)
 {
        if (si == NULL) return NULL;
 si_rpc_byname(si_mod_t *si, const char *name)
 {
        if (si == NULL) return NULL;
-       if (si->sim_rpc_byname == NULL) return NULL;
-       return si->sim_rpc_byname(si, name);
+       if (si->vtable->sim_rpc_byname == NULL) return NULL;
+       return si->vtable->sim_rpc_byname(si, name);
 }
 
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_rpc_bynumber(si_mod_t *si, int number)
 {
        if (si == NULL) return NULL;
 si_rpc_bynumber(si_mod_t *si, int number)
 {
        if (si == NULL) return NULL;
-       if (si->sim_rpc_bynumber == NULL) return NULL;
-       return si->sim_rpc_bynumber(si, number);
+       if (si->vtable->sim_rpc_bynumber == NULL) return NULL;
+       return si->vtable->sim_rpc_bynumber(si, number);
 }
 
 }
 
-__private_extern__ si_list_t *
+si_list_t *
 si_rpc_all(si_mod_t *si)
 {
        if (si == NULL) return NULL;
 si_rpc_all(si_mod_t *si)
 {
        if (si == NULL) return NULL;
-       if (si->sim_rpc_all == NULL) return NULL;
-       return si->sim_rpc_all(si);
+       if (si->vtable->sim_rpc_all == NULL) return NULL;
+       return si->vtable->sim_rpc_all(si);
 }
 
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_fs_byspec(si_mod_t *si, const char *spec)
 {
        if (si == NULL) return NULL;
 si_fs_byspec(si_mod_t *si, const char *spec)
 {
        if (si == NULL) return NULL;
-       if (si->sim_fs_byspec == NULL) return NULL;
-       return si->sim_fs_byspec(si, spec);
+       if (si->vtable->sim_fs_byspec == NULL) return NULL;
+       return si->vtable->sim_fs_byspec(si, spec);
 }
 
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_fs_byfile(si_mod_t *si, const char *file)
 {
        if (si == NULL) return NULL;
 si_fs_byfile(si_mod_t *si, const char *file)
 {
        if (si == NULL) return NULL;
-       if (si->sim_fs_byfile == NULL) return NULL;
-       return si->sim_fs_byfile(si, file);
+       if (si->vtable->sim_fs_byfile == NULL) return NULL;
+       return si->vtable->sim_fs_byfile(si, file);
 }
 
 }
 
-__private_extern__ si_list_t *
+si_list_t *
 si_fs_all(si_mod_t *si)
 {
        if (si == NULL) return NULL;
 si_fs_all(si_mod_t *si)
 {
        if (si == NULL) return NULL;
-       if (si->sim_fs_all == NULL) return NULL;
-       return si->sim_fs_all(si);
+       if (si->vtable->sim_fs_all == NULL) return NULL;
+       return si->vtable->sim_fs_all(si);
 }
 
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 si_item_call(struct si_mod_s *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t *err)
 {
        if (si == NULL) return NULL;
 si_item_call(struct si_mod_s *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t *err)
 {
        if (si == NULL) return NULL;
@@ -794,8 +795,8 @@ si_item_call(struct si_mod_s *si, int call, const char *str1, const char *str2,
                case SI_CALL_DNS_QUERY:
                case SI_CALL_DNS_SEARCH:
                {
                case SI_CALL_DNS_QUERY:
                case SI_CALL_DNS_SEARCH:
                {
-                       if (si->sim_item_call == NULL) return NULL;
-                       return si->sim_item_call(si, call, str1, str2, str3, num1, num2, err);
+                       if (si->vtable->sim_item_call == NULL) return NULL;
+                       return si->vtable->sim_item_call(si, call, str1, str2, str3, num1, num2, err);
                }
 
                default: return NULL;
                }
 
                default: return NULL;
@@ -804,7 +805,7 @@ si_item_call(struct si_mod_s *si, int call, const char *str1, const char *str2,
        return NULL;
 }
 
        return NULL;
 }
 
-__private_extern__ si_list_t *
+si_list_t *
 si_list_call(struct si_mod_s *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, uint32_t *err)
 {
        if (si == NULL) return NULL;
 si_list_call(struct si_mod_s *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, uint32_t *err)
 {
        if (si == NULL) return NULL;
@@ -951,7 +952,8 @@ si_async_workunit_create(si_mod_t *si, int call, const char *str1, const char *s
        r->num3 = num3;
        r->num4 = num4;
 
        r->num3 = num3;
        r->num4 = num4;
 
-       r->flags = WORKUNIT_CALL_ACTIVE | WORKUNIT_THREAD_ACTIVE;
+       r->refcount = 2;
+       r->flags = 0;
        if (si_call_returns_list(call)) r->flags |= WORKUNIT_RETURNS_LIST;
 
        r->callback = callback;
        if (si_call_returns_list(call)) r->flags |= WORKUNIT_RETURNS_LIST;
 
        r->callback = callback;
@@ -969,7 +971,11 @@ si_async_workunit_release(si_async_workunit_t *r)
 {
        if (r == NULL) return;
 
 {
        if (r == NULL) return;
 
-       if (r->flags & (WORKUNIT_THREAD_ACTIVE | WORKUNIT_CALL_ACTIVE)) return;
+       if (OSAtomicDecrement32Barrier(&(r->refcount)) != 0) return;
+
+#ifdef CALL_TRACE
+       fprintf(stderr, "** %s freeing worklist item %p\n", __func__, r);
+#endif
 
        si_async_worklist_remove_unit(r);
 
 
        si_async_worklist_remove_unit(r);
 
@@ -983,19 +989,46 @@ si_async_workunit_release(si_async_workunit_t *r)
        free(r);
 }
 
        free(r);
 }
 
-static void *
-si_async_launchpad(void *x)
+static void
+si_async_launchpad(si_async_workunit_t *r)
 {
 {
-       si_async_workunit_t *r;
        kern_return_t status;
        mach_msg_empty_send_t msg;
 
        kern_return_t status;
        mach_msg_empty_send_t msg;
 
-       if (x == NULL) pthread_exit(NULL);
-       r = (si_async_workunit_t *)x;
+#ifdef CALL_TRACE
+       fprintf(stderr, "** %s starting worklist item %p\n", __func__, r);
+#endif
+
+       if (r->flags & WORKUNIT_CANCELLED)
+       {
+               si_async_workunit_release(r);
+#ifdef CALL_TRACE
+               fprintf(stderr, "** %s worklist item %p was cancelled early\n", __func__, r);
+#endif
+               return;
+       }
 
        if (r->flags & WORKUNIT_RETURNS_LIST) r->reslist = si_list_call(r->si, r->call, r->str1, r->str2, r->str3, r->num1, r->num2, r->num3, r->num4, &(r->err));
        else r->resitem = si_item_call(r->si, r->call, r->str1, r->str2, r->str3, r->num1, r->num2, &(r->err));
 
 
        if (r->flags & WORKUNIT_RETURNS_LIST) r->reslist = si_list_call(r->si, r->call, r->str1, r->str2, r->str3, r->num1, r->num2, r->num3, r->num4, &(r->err));
        else r->resitem = si_item_call(r->si, r->call, r->str1, r->str2, r->str3, r->num1, r->num2, &(r->err));
 
+       /*
+        * Test and set the cancelled flag.
+        * If it was set, then this work item was cancelled.
+        * Otherwise, setting it here prevents si_async_cancel from cancelling:
+        * too late to cancel now!
+        */
+       if (OSAtomicTestAndSetBarrier(WORKUNIT_CANCELLED_BIT_ADDRESS, &(r->flags)) == 1)
+       {
+               si_async_workunit_release(r);
+#ifdef CALL_TRACE
+               fprintf(stderr, "** %s worklist item %p was cancelled in flight\n", __func__, r);
+#endif
+               return;
+       }
+#ifdef CALL_TRACE
+       else fprintf(stderr, "** %s worklist item %p flags are now 0x%08x\n", __func__, r, r->flags);
+#endif
+
        memset(&msg, 0, sizeof(mach_msg_empty_send_t));
 
        msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, MACH_MSGH_BITS_ZERO);
        memset(&msg, 0, sizeof(mach_msg_empty_send_t));
 
        msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, MACH_MSGH_BITS_ZERO);
@@ -1004,47 +1037,50 @@ si_async_launchpad(void *x)
        msg.header.msgh_size = sizeof(mach_msg_empty_send_t);
        msg.header.msgh_id = r->call;
 
        msg.header.msgh_size = sizeof(mach_msg_empty_send_t);
        msg.header.msgh_id = r->call;
 
-       OSAtomicAnd32Barrier(~WORKUNIT_THREAD_ACTIVE, &r->flags);
-
-       si_async_workunit_release(r);
-
        status = mach_msg(&(msg.header), MACH_SEND_MSG, msg.header.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
        if (status != MACH_MSG_SUCCESS)
        {
                /* receiver failed - clean up to avoid a port leak */
                mach_msg_destroy(&(msg.header));
        status = mach_msg(&(msg.header), MACH_SEND_MSG, msg.header.msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
        if (status != MACH_MSG_SUCCESS)
        {
                /* receiver failed - clean up to avoid a port leak */
                mach_msg_destroy(&(msg.header));
+#ifdef CALL_TRACE
+               fprintf(stderr, "** %s mach message send failed for worklist item %p\n", __func__, r);
+#endif
        }
 
        }
 
-       pthread_exit(NULL);
+       si_async_workunit_release(r);
 
 
-       /* UNREACHED */
-       return NULL;
+       /*
+        * The client is now responsible for calling si_async_handle_reply,
+        * which will invoke the client's callback and then release the workunit.
+        */
+
+#ifdef CALL_TRACE
+       fprintf(stderr, "** %s completed async worklist item %p\n", __func__, r);
+#endif
 }
 
 mach_port_t
 si_async_call(struct si_mod_s *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context)
 {
        si_async_workunit_t *req;
 }
 
 mach_port_t
 si_async_call(struct si_mod_s *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context)
 {
        si_async_workunit_t *req;
-       pthread_attr_t attr;
-       pthread_t t;
 
        if (si == NULL) return MACH_PORT_NULL;
        if (callback == NULL) return MACH_PORT_NULL;
 
        /* if module does async on it's own, hand off the call */
 
        if (si == NULL) return MACH_PORT_NULL;
        if (callback == NULL) return MACH_PORT_NULL;
 
        /* if module does async on it's own, hand off the call */
-       if (si->sim_async_call != NULL)
+       if (si->vtable->sim_async_call != NULL)
        {
        {
-               return si->sim_async_call(si, call, str1, str2, str3, num1, num2, num3, num4, callback, context);
+               return si->vtable->sim_async_call(si, call, str1, str2, str3, num1, num2, num3, num4, callback, context);
        }
 
        req = si_async_workunit_create(si, call, str1, str2, str3, num1, num2, num3, num4, callback, context);
        if (req == NULL) return MACH_PORT_NULL;
 
        }
 
        req = si_async_workunit_create(si, call, str1, str2, str3, num1, num2, num3, num4, callback, context);
        if (req == NULL) return MACH_PORT_NULL;
 
-       /* start a new thread to do the work */
-       pthread_attr_init(&attr);
-       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
-       pthread_create(&t, &attr, si_async_launchpad, req);
-       pthread_attr_destroy(&attr);
+       /* queue the work on the global low-priority dispatch queue */
+#ifdef CALL_TRACE
+       fprintf(stderr, "** %s dispatching worklist item %p\n", __func__, req);
+#endif
+       dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, DISPATCH_QUEUE_OVERCOMMIT), ^{ si_async_launchpad(req); });
 
        return req->port;
 }
 
        return req->port;
 }
@@ -1055,9 +1091,30 @@ si_async_cancel(mach_port_t p)
        si_async_workunit_t *r;
 
        r = si_async_worklist_find_unit(p);
        si_async_workunit_t *r;
 
        r = si_async_worklist_find_unit(p);
-       if (r == NULL) return;
+       if (r == NULL)
+       {
+#ifdef CALL_TRACE
+               fprintf(stderr, "** %s can't find worklist item\n", __func__);
+#endif
+               return;
+       }
 
 
-       OSAtomicAnd32Barrier(~WORKUNIT_CALL_ACTIVE, &r->flags);
+       /*
+        * Test and set the WORKUNIT_CANCELLED flag.
+        * If it was already set, this work item has been executed - too late to cancel.
+        */
+       if (OSAtomicTestAndSetBarrier(WORKUNIT_CANCELLED_BIT_ADDRESS, &(r->flags)) == 1)
+       {
+               /* already executed */
+#ifdef CALL_TRACE
+               fprintf(stderr, "** %s worklist item %p has executed\n", __func__, r);
+#endif
+               return;
+       }
+
+#ifdef CALL_TRACE
+       fprintf(stderr, "** %s calling worklist item %p callback SI_STATUS_CALL_CANCELLED\n", __func__, r);
+#endif
 
        if (r->callback != NULL)
        {
 
        if (r->callback != NULL)
        {
@@ -1085,7 +1142,10 @@ si_async_handle_reply(mach_msg_header_t *msg)
                return;
        }
 
                return;
        }
 
-       if (r->flags & WORKUNIT_THREAD_ACTIVE)
+#ifdef CALL_TRACE
+       fprintf(stderr, "** %s worklist item %p flags are 0x%08x\n", __func__, r, r->flags);
+#endif
+       if ((r->flags & WORKUNIT_CANCELLED) == 0)
        {
 #ifdef CALL_TRACE
                fprintf(stderr, "** %s workunit thread is still active\n", __func__);
        {
 #ifdef CALL_TRACE
                fprintf(stderr, "** %s workunit thread is still active\n", __func__);
@@ -1108,20 +1168,18 @@ si_async_handle_reply(mach_msg_header_t *msg)
 #endif
        }
 
 #endif
        }
 
-       OSAtomicAnd32Barrier(~WORKUNIT_CALL_ACTIVE, &r->flags);
-
        si_async_workunit_release(r);
 
        mach_port_mod_refs(mach_task_self(), reply, MACH_PORT_RIGHT_RECEIVE, -1);
 }
 
        si_async_workunit_release(r);
 
        mach_port_mod_refs(mach_task_self(), reply, MACH_PORT_RIGHT_RECEIVE, -1);
 }
 
-__private_extern__ char *
-si_canonical_mac_address(const char *addr)
+char *
+si_standardize_mac_address(const char *addr)
 {
        char e[6][3];
        char *out;
        struct ether_addr *ether;
 {
        char e[6][3];
        char *out;
        struct ether_addr *ether;
-       int i, bit;
+       int i;
 
        if (addr == NULL) return NULL;
 
 
        if (addr == NULL) return NULL;
 
@@ -1135,9 +1193,9 @@ si_canonical_mac_address(const char *addr)
                return NULL;
        }
 
                return NULL;
        }
 
-       for (i = 0, bit = 1; i < 6; i++, bit *= 2)
+       for (i = 0; i < 6; i++)
        {
        {
-               if ((i & bit) && (ether->ether_addr_octet[i] <= 15))
+               if (ether->ether_addr_octet[i] <= 15)
                {
                        sprintf(e[i], "0%x", ether->ether_addr_octet[i]);
                }
                {
                        sprintf(e[i], "0%x", ether->ether_addr_octet[i]);
                }
index 676c1f9d8cd9b0364cc3b60534e13f72545e7835..37635c097de3a66dd097906bda2946d5856233be 100644 (file)
 #define si_call_str1_is_buffer(A) \
 ((A==SI_CALL_HOST_BYADDR)||(A==SI_CALL_NAMEINFO))
 
 #define si_call_str1_is_buffer(A) \
 ((A==SI_CALL_HOST_BYADDR)||(A==SI_CALL_NAMEINFO))
 
-#define CATEGORY_USER       0
-#define CATEGORY_GROUP      1
-#define CATEGORY_GROUPLIST  2
-#define CATEGORY_NETGROUP   3
-#define CATEGORY_ALIAS      4
-#define CATEGORY_HOST_IPV4  5
-#define CATEGORY_HOST_IPV6  6
-#define CATEGORY_NETWORK    7
-#define CATEGORY_SERVICE    8
-#define CATEGORY_PROTOCOL   9
-#define CATEGORY_RPC       10
-#define CATEGORY_FS        11
-#define CATEGORY_MAC       12
-#define CATEGORY_NAMEINFO  13
-#define CATEGORY_ADDRINFO  14
-#define CATEGORY_DNSPACKET 15
-#define CATEGORY_SRV       16
-#define CATEGORY_COUNT     17
+#define CATEGORY_INVALID  (-1)
+#define CATEGORY_DEFAULT    0
+#define CATEGORY_USER       1
+#define CATEGORY_GROUP      2
+#define CATEGORY_GROUPLIST  3
+#define CATEGORY_NETGROUP   4
+#define CATEGORY_ALIAS      5
+#define CATEGORY_HOST_IPV4  6
+#define CATEGORY_HOST_IPV6  7
+#define CATEGORY_NETWORK    8
+#define CATEGORY_SERVICE    9
+#define CATEGORY_PROTOCOL  10
+#define CATEGORY_RPC       11
+#define CATEGORY_FS        12
+#define CATEGORY_MAC       13
+#define CATEGORY_NAMEINFO  14
+#define CATEGORY_ADDRINFO  15
+#define CATEGORY_DNSPACKET 16
+#define CATEGORY_SRV       17
+#define CATEGORY_COUNT     18
 
 /* convenience */
 #define CATEGORY_HOST CATEGORY_HOST_IPV4
 
 /* convenience */
 #define CATEGORY_HOST CATEGORY_HOST_IPV4
@@ -199,15 +201,10 @@ typedef struct si_srv_s
        char *target;
 } si_srv_t;
 
        char *target;
 } si_srv_t;
 
-typedef struct si_mod_s
-{
-       char *name;
-       uint32_t vers;
-       int32_t refcount;
-
-       void *bundle;
-       void *private;
+struct si_mod_s;
 
 
+struct si_mod_vtable_s
+{
        void (*sim_close)(struct si_mod_s *si);
 
        int (*sim_is_valid)(struct si_mod_s *si, si_item_t *item);
        void (*sim_close)(struct si_mod_s *si);
 
        int (*sim_is_valid)(struct si_mod_s *si, si_item_t *item);
@@ -269,86 +266,102 @@ typedef struct si_mod_s
        mach_port_t (*sim_async_call)(struct si_mod_s *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context);
        void (*sim_async_cancel)(mach_port_t p);
        void (*sim_async_handle_reply)(mach_msg_header_t *msg);
        mach_port_t (*sim_async_call)(struct si_mod_s *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context);
        void (*sim_async_cancel)(mach_port_t p);
        void (*sim_async_handle_reply)(mach_msg_header_t *msg);
+};
+
+#define SI_MOD_FLAG_STATIC 0x00000001
+
+typedef struct si_mod_s
+{
+       char *name;
+       uint32_t vers;
+       int32_t refcount;
+       uint32_t flags;
+
+       void *bundle;
+       void *private;
+       
+       const struct si_mod_vtable_s *vtable;
 } si_mod_t;
 
 si_mod_t *si_module_with_name(const char *name);
 } si_mod_t;
 
 si_mod_t *si_module_with_name(const char *name);
-__private_extern__ si_mod_t *si_module_with_path(const char *path, const char *name);
-__private_extern__ si_mod_t *si_module_retain(si_mod_t *si);
+si_mod_t *si_module_retain(si_mod_t *si);
 void si_module_release(si_mod_t *si);
 void si_module_release(si_mod_t *si);
-__private_extern__ const char *si_module_name(si_mod_t *si);
-__private_extern__ int si_module_vers(si_mod_t *si);
+const char *si_module_name(si_mod_t *si);
+int si_module_vers(si_mod_t *si);
 
 si_mod_t *si_search(void);
 
 
 si_mod_t *si_search(void);
 
-__private_extern__ int si_item_match(si_item_t *item, int cat, const void *name, uint32_t num, int which);
-__private_extern__ int si_item_is_valid(si_item_t *item);
+int si_item_match(si_item_t *item, int cat, const void *name, uint32_t num, int which);
+int si_item_is_valid(si_item_t *item);
 
 
-__private_extern__ si_item_t *si_user_byname(si_mod_t *si, const char *name);
-__private_extern__ si_item_t *si_user_byuid(si_mod_t *si, uid_t uid);
-__private_extern__ si_list_t *si_user_all(si_mod_t *si);
+si_item_t *si_user_byname(si_mod_t *si, const char *name);
+si_item_t *si_user_byuid(si_mod_t *si, uid_t uid);
+si_list_t *si_user_all(si_mod_t *si);
 
 
-__private_extern__ si_item_t *si_group_byname(si_mod_t *si, const char *name);
-__private_extern__ si_item_t *si_group_bygid(si_mod_t *si, gid_t gid);
-__private_extern__ si_list_t *si_group_all(si_mod_t *si);
+si_item_t *si_group_byname(si_mod_t *si, const char *name);
+si_item_t *si_group_bygid(si_mod_t *si, gid_t gid);
+si_list_t *si_group_all(si_mod_t *si);
 
 
-__private_extern__ si_item_t *si_grouplist(si_mod_t *si, const char *name);
+si_item_t *si_grouplist(si_mod_t *si, const char *name);
 
 
-__private_extern__ int si_in_netgroup(struct si_mod_s *si, const char *name, const char *host, const char *user, const char *domain);
-__private_extern__ si_list_t *si_netgroup_byname(struct si_mod_s *si, const char *name);
+int si_in_netgroup(struct si_mod_s *si, const char *name, const char *host, const char *user, const char *domain);
+si_list_t *si_netgroup_byname(struct si_mod_s *si, const char *name);
 
 
-__private_extern__ si_item_t *si_alias_byname(struct si_mod_s *si, const char *name);
-__private_extern__ si_list_t *si_alias_all(struct si_mod_s *si);
+si_item_t *si_alias_byname(struct si_mod_s *si, const char *name);
+si_list_t *si_alias_all(struct si_mod_s *si);
 
 
-__private_extern__ si_item_t *si_host_byname(si_mod_t *si, const char *name, int af, const char *interface, uint32_t *err);
-__private_extern__ si_item_t *si_host_byaddr(si_mod_t *si, const void *addr, int af, const char *interface, uint32_t *err);
-__private_extern__ si_list_t *si_host_all(si_mod_t *si);
+si_item_t *si_host_byname(si_mod_t *si, const char *name, int af, const char *interface, uint32_t *err);
+si_item_t *si_host_byaddr(si_mod_t *si, const void *addr, int af, const char *interface, uint32_t *err);
+si_list_t *si_host_all(si_mod_t *si);
 
 
-__private_extern__ si_item_t *si_mac_byname(struct si_mod_s *si, const char *name);
-__private_extern__ si_item_t *si_mac_bymac(struct si_mod_s *si, const char *mac);
-__private_extern__ si_list_t *si_mac_all(struct si_mod_s *si);
+si_item_t *si_mac_byname(struct si_mod_s *si, const char *name);
+si_item_t *si_mac_bymac(struct si_mod_s *si, const char *mac);
+si_list_t *si_mac_all(struct si_mod_s *si);
 
 
-__private_extern__ si_item_t *si_network_byname(si_mod_t *si, const char *name);
-__private_extern__ si_item_t *si_network_byaddr(si_mod_t *si, uint32_t addr);
-__private_extern__ si_list_t *si_network_all(si_mod_t *si);
+si_item_t *si_network_byname(si_mod_t *si, const char *name);
+si_item_t *si_network_byaddr(si_mod_t *si, uint32_t addr);
+si_list_t *si_network_all(si_mod_t *si);
 
 
-__private_extern__ si_item_t *si_service_byname(si_mod_t *si, const char *name, const char *proto);
-__private_extern__ si_item_t *si_service_byport(si_mod_t *si, int port, const char *proto);
-__private_extern__ si_list_t *si_service_all(si_mod_t *si);
+si_item_t *si_service_byname(si_mod_t *si, const char *name, const char *proto);
+si_item_t *si_service_byport(si_mod_t *si, int port, const char *proto);
+si_list_t *si_service_all(si_mod_t *si);
 
 
-__private_extern__ si_item_t *si_protocol_byname(si_mod_t *si, const char *name);
-__private_extern__ si_item_t *si_protocol_bynumber(si_mod_t *si, uint32_t number);
-__private_extern__ si_list_t *si_protocol_all(si_mod_t *si);
+si_item_t *si_protocol_byname(si_mod_t *si, const char *name);
+si_item_t *si_protocol_bynumber(si_mod_t *si, uint32_t number);
+si_list_t *si_protocol_all(si_mod_t *si);
 
 
-__private_extern__ si_item_t *si_rpc_byname(si_mod_t *si, const char *name);
-__private_extern__ si_item_t *si_rpc_bynumber(si_mod_t *si, int number);
-__private_extern__ si_list_t *si_rpc_all(si_mod_t *si);
+si_item_t *si_rpc_byname(si_mod_t *si, const char *name);
+si_item_t *si_rpc_bynumber(si_mod_t *si, int number);
+si_list_t *si_rpc_all(si_mod_t *si);
 
 
-__private_extern__ si_item_t *si_fs_byspec(si_mod_t *si, const char *spec);
-__private_extern__ si_item_t *si_fs_byfile(si_mod_t *si, const char *file);
-__private_extern__ si_list_t *si_fs_all(si_mod_t *si);
+si_item_t *si_fs_byspec(si_mod_t *si, const char *spec);
+si_item_t *si_fs_byfile(si_mod_t *si, const char *file);
+si_list_t *si_fs_all(si_mod_t *si);
 
 
-__private_extern__ int si_wants_addrinfo(si_mod_t *s);
-__private_extern__ si_list_t *si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint32_t socktype, uint32_t protocol, uint32_t flags, const char *interface, uint32_t *err);
+int si_wants_addrinfo(si_mod_t *s);
+si_list_t *si_addrinfo(si_mod_t *si, const char *node, const char *serv, uint32_t family, uint32_t socktype, uint32_t protocol, uint32_t flags, const char *interface, uint32_t *err);
 
 
-__private_extern__ si_item_t *si_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *interface, uint32_t *err);
-__private_extern__ si_item_t *si_ipnode_byname(si_mod_t *si, const char *name, int family, int flags, const char *interface, uint32_t *err);
+si_item_t *si_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *interface, uint32_t *err);
+si_item_t *si_ipnode_byname(si_mod_t *si, const char *name, int family, int flags, const char *interface, uint32_t *err);
 
 
-__private_extern__ si_list_t *si_srv_byname(si_mod_t *si, const char *qname, const char *interface, uint32_t *err);
+si_list_t *si_srv_byname(si_mod_t *si, const char *qname, const char *interface, uint32_t *err);
 
 
-__private_extern__ si_item_t *si_item_call(si_mod_t *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t *err);
-__private_extern__ si_list_t *si_list_call(si_mod_t *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, uint32_t *err);
+si_item_t *si_item_call(si_mod_t *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t *err);
+si_list_t *si_list_call(si_mod_t *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, uint32_t *err);
 
 extern mach_port_t si_async_call(si_mod_t *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context);
 extern void si_async_cancel(mach_port_t p);
 extern void si_async_handle_reply(mach_msg_header_t *msg);
 
 
 extern mach_port_t si_async_call(si_mod_t *si, int call, const char *str1, const char *str2, const char *str3, uint32_t num1, uint32_t num2, uint32_t num3, uint32_t num4, void *callback, void *context);
 extern void si_async_cancel(mach_port_t p);
 extern void si_async_handle_reply(mach_msg_header_t *msg);
 
-char *si_canonical_mac_address(const char *addr);
+char *si_standardize_mac_address(const char *addr);
 si_item_t *si_addrinfo_v4(si_mod_t *si, int32_t flags, int32_t sock, int32_t proto, uint16_t port, struct in_addr *addr, uint16_t iface, const char *cname);
 si_item_t *si_addrinfo_v6(si_mod_t *si, int32_t flags, int32_t sock, int32_t proto, uint16_t port, struct in6_addr *addr, uint16_t iface, const char *cname);
 si_item_t *si_addrinfo_v4(si_mod_t *si, int32_t flags, int32_t sock, int32_t proto, uint16_t port, struct in_addr *addr, uint16_t iface, const char *cname);
 si_item_t *si_addrinfo_v6(si_mod_t *si, int32_t flags, int32_t sock, int32_t proto, uint16_t port, struct in6_addr *addr, uint16_t iface, const char *cname);
-si_list_t *si_addrinfo_list(si_mod_t *si, int socktype, int proto, struct in_addr *a4, struct in6_addr *a6, int port, int scopeid, const char *cname4, const char *cname6);
-si_list_t *si_addrinfo_list_from_hostent(si_mod_t *si, uint32_t socktype, uint32_t proto, uint16_t port, uint16_t scope, const struct hostent *h4, const struct hostent *h6);
+si_item_t *si_addrinfo_v4_mapped(si_mod_t *si, int32_t flags, int32_t sock, int32_t proto, uint16_t port, struct in_addr *addr, uint16_t iface, const char *cname);
+si_list_t *si_addrinfo_list(si_mod_t *si, uint32_t flags, int socktype, int proto, struct in_addr *a4, struct in6_addr *a6, int port, int scopeid, const char *cname4, const char *cname6);
+si_list_t *si_addrinfo_list_from_hostent(si_mod_t *si, uint32_t flags, uint32_t socktype, uint32_t proto, uint16_t port, uint16_t scope, const struct hostent *h4, const struct hostent *h6);
 
 int _gai_serv_to_port(const char *serv, uint32_t proto, uint16_t *port);
 si_list_t *_gai_simple(si_mod_t *si, const void *nodeptr, const void *servptr, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err);
 
 int _gai_serv_to_port(const char *serv, uint32_t proto, uint16_t *port);
 si_list_t *_gai_simple(si_mod_t *si, const void *nodeptr, const void *servptr, uint32_t family, uint32_t socktype, uint32_t proto, uint32_t flags, const char *interface, uint32_t *err);
+int si_inet_config(uint32_t *inet4, uint32_t *inet6);
 
 #endif /* ! __SI_MODULE_H__ */
 
 #endif /* ! __SI_MODULE_H__ */
index c29ce543f1001946b88b63119026dc6561259439..d7aa02afd6495b5421b3ce167e1719c3bf225b1b 100644 (file)
@@ -162,7 +162,7 @@ LI_get_thread_info(uint32_t key)
        return tdata;
 }
 
        return tdata;
 }
 
-__private_extern__ si_item_t *
+si_item_t *
 LI_get_thread_item(uint32_t key)
 {
        li_thread_data_t *tdata;
 LI_get_thread_item(uint32_t key)
 {
        li_thread_data_t *tdata;
@@ -173,7 +173,7 @@ LI_get_thread_item(uint32_t key)
        return tdata->thread_item;
 }
 
        return tdata->thread_item;
 }
 
-__private_extern__ si_list_t *
+si_list_t *
 LI_get_thread_list(uint32_t key)
 {
        li_thread_data_t *tdata;
 LI_get_thread_list(uint32_t key)
 {
        li_thread_data_t *tdata;
@@ -184,7 +184,7 @@ LI_get_thread_list(uint32_t key)
        return tdata->thread_list;
 }
 
        return tdata->thread_list;
 }
 
-__private_extern__ void
+void
 LI_set_thread_item(uint32_t key, si_item_t *item)
 {
        li_thread_data_t *tdata;
 LI_set_thread_item(uint32_t key, si_item_t *item)
 {
        li_thread_data_t *tdata;
@@ -196,7 +196,7 @@ LI_set_thread_item(uint32_t key, si_item_t *item)
        tdata->thread_item = item;
 }
 
        tdata->thread_item = item;
 }
 
-__private_extern__ void
+void
 LI_set_thread_list(uint32_t key, si_list_t *list)
 {
        li_thread_data_t *tdata;
 LI_set_thread_list(uint32_t key, si_list_t *list)
 {
        li_thread_data_t *tdata;
index 08dd0224d1cb7101e05a53fa32e718d767e3985c..357ec223f9c71a454ef120aedd24030d1b1255bd 100644 (file)
@@ -26,9 +26,9 @@
 
 #include <si_data.h>
 
 
 #include <si_data.h>
 
-__private_extern__ si_item_t *LI_get_thread_item(uint32_t key);
-__private_extern__ si_list_t *LI_get_thread_list(uint32_t key);
-__private_extern__ void LI_set_thread_item(uint32_t key, si_item_t *item);
-__private_extern__ void LI_set_thread_list(uint32_t key, si_list_t *list);
+si_item_t *LI_get_thread_item(uint32_t key);
+si_list_t *LI_get_thread_list(uint32_t key);
+void LI_set_thread_item(uint32_t key, si_item_t *item);
+void LI_set_thread_list(uint32_t key, si_list_t *list);
 
 #endif /* ! __THREAD_DATA_H__ */
 
 #endif /* ! __THREAD_DATA_H__ */
diff --git a/membership.subproj/Makefile b/membership.subproj/Makefile
deleted file mode 100644 (file)
index 20b6836..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-Project = membership
-ProductType = staticlib
-Install_Dir = /scratch
-BuildDebug = YES
-BuildProfile = YES
-
-PRODUCT = $(shell tconf --product)
-
-HFILES = membership.h membershipPriv.h ntsid.h
-
-CFILES = membership.c
-
-MANPAGES = mbr_check_membership.3 mbr_uid_to_uuid.3
-
-ifeq ($(PRODUCT),MacOSX)
-USERDEFS = /usr/local/include/DSmemberdMIG.defs
-endif
-
-Install_Headers = membership.h ntsid.h 
-Install_Private_Headers = membershipPriv.h
-
-Extra_CC_Flags = -Wall -fno-common \
-       -D__MigTypeCheck=1 -D__DARWIN_NON_CANCELABLE=1
-ifeq ($(PRODUCT),MacOSX)
-Extra_CC_Flags += -DDS_AVAILABLE
-endif
-
-include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
-
-after_install:
-       @for LINK in mbr_gid_to_uuid.3 mbr_sid_to_uuid.3 mbr_uuid_to_id.3 \
-               mbr_uuid_to_sid.3 ; do \
-               $(LN) -f "$(DSTROOT)/usr/share/man/man3/mbr_uid_to_uuid.3" \
-                       "$(DSTROOT)/usr/share/man/man3/$${LINK}" ; \
-       done
-
index 96d8ae69028bedaa75b355f83a5fd97448343edc..a778aeade6fbb7ff5a2b4aa439028d4f9ac0e04b 100644 (file)
@@ -1,4 +1,4 @@
-.\" Copyright (c) 2005-2007 Apple Inc
+.\" Copyright (c) 2005-2010 Apple Inc
 .\" All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
 .\" All rights reserved.
 .\"
 .\" Redistribution and use in source and binary forms, with or without
@@ -26,7 +26,7 @@
 .\" SUCH DAMAGE.
 .\"
 .\"
 .\" SUCH DAMAGE.
 .\"
 .\"
-.Dd February 3, 2005
+.Dd August 25, 2010
 .Dt MBR_UID_TO_UUID 3
 .Os "Mac OS X"
 .Sh NAME
 .Dt MBR_UID_TO_UUID 3
 .Os "Mac OS X"
 .Sh NAME
 .Fn mbr_sid_to_uuid "const nt_sid_t *sid" "uuid_t uu"
 .Ft int
 .Fn mbr_uuid_to_sid "const uuid_t uu" "nt_sid_t *sid"
 .Fn mbr_sid_to_uuid "const nt_sid_t *sid" "uuid_t uu"
 .Ft int
 .Fn mbr_uuid_to_sid "const uuid_t uu" "nt_sid_t *sid"
+.Ft int
+.Fn mbr_sid_to_string "const nt_sid_t *sid" "char *string"
+.Ft int
+.Fn mbr_string_to_sid "const char *string" "nt_sid_t *sid"
 .Sh DESCRIPTION
 Users and groups can be referred to in multiple ways.
 In addition to the traditional uid and gid, 
 .Sh DESCRIPTION
 Users and groups can be referred to in multiple ways.
 In addition to the traditional uid and gid, 
@@ -88,13 +92,22 @@ or
 .Pp
 .Fn mbr_sid_to_uuid
 takes a sid and returns the associated uuid.
 .Pp
 .Fn mbr_sid_to_uuid
 takes a sid and returns the associated uuid.
-Like
-.Fn mbr_uuid_to_id ,
-.Fn mbr_sid_to_uuid
-always returns a uuid for the sid, even if the sid can not be found.
 .Pp
 .Fn mbr_uuid_to_sid
 returns a sid for the associated uuid.
 .Pp
 .Fn mbr_uuid_to_sid
 returns a sid for the associated uuid.
+.Pp
+Two additional utility functions are available to convert between sids and a string representation.
+String representations may be required, for example, when text files or XML files are used to save sid values.
+.Pp
+.Fn mbr_sid_to_string
+converts a sid into a string representation.
+The 
+.Fa string
+parameter must be a buffer of at least 194 characters.
+The converted string is terminated with a nul character.
+.Pp
+.Fn mbr_string_to_sid
+converts an external string representation into a sid.
 .Sh RETURN VALUES
 These functions return 0 on success, or EIO if communications with the
 .Xr DirectoryService 8
 .Sh RETURN VALUES
 These functions return 0 on success, or EIO if communications with the
 .Xr DirectoryService 8
@@ -105,6 +118,12 @@ ENOENT is returned if the mapping can not be performed.
 and
 .Fn mbr_uid_to_uuid
 return 0 (success), even if the user/group does not exist.
 and
 .Fn mbr_uid_to_uuid
 return 0 (success), even if the user/group does not exist.
+.Pp
+The 
+.Fn mbr_sid_to_string
+and 
+.Fn mbr_string_to_sid
+functions return 0 on success, or an errno value on failure.
 .Sh SEE ALSO
 .Xr getpwuid 3 ,
 .Xr getgrgid 3 ,
 .Sh SEE ALSO
 .Xr getpwuid 3 ,
 .Xr getgrgid 3 ,
index 4d9edb92db52e93c22e975cb8b3cf24d7bacb9b4..b2c980cece19f1c0bf2cd071d1eb3e73d841c8e5 100644 (file)
@@ -1,5 +1,5 @@
 /*
 /*
- * Copyright (c) 2004-2007 Apple Inc. All rights reserved.
+ * Copyright (c) 2004-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 #include <servers/bootstrap.h>
 #include <libkern/OSByteOrder.h>
 #ifdef DS_AVAILABLE
 #include <servers/bootstrap.h>
 #include <libkern/OSByteOrder.h>
 #ifdef DS_AVAILABLE
-#include <DSmemberdMIG.h>
-#include <DSmemberdMIG_types.h>
+#include "DSmemberdMIG.h"
 #endif
 
 #ifdef DS_AVAILABLE
 extern mach_port_t _mbr_port;
 extern int _ds_running(void);
 
 #endif
 
 #ifdef DS_AVAILABLE
 extern mach_port_t _mbr_port;
 extern int _ds_running(void);
 
-static const uint8_t _mbr_root_uuid[] = {0xff, 0xff, 0xee, 0xee, 0xdd, 0xdd, 0xcc, 0xcc, 0xbb, 0xbb, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00};
+static const uuid_t _user_compat_prefix = {0xff, 0xff, 0xee, 0xee, 0xdd, 0xdd, 0xcc, 0xcc, 0xbb, 0xbb, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00};
+static const uuid_t _group_compat_prefix = {0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef, 0xab, 0xcd, 0xef, 0x00, 0x00, 0x00, 0x00};
+
+#define COMPAT_PREFIX_LEN      (sizeof(uuid_t) - sizeof(id_t))
 
 #define MAX_LOOKUP_ATTEMPTS 10
 #endif
 
 
 #define MAX_LOOKUP_ATTEMPTS 10
 #endif
 
-__private_extern__ uid_t
+uid_t
 audit_token_uid(audit_token_t a)
 {
        /*
 audit_token_uid(audit_token_t a)
 {
        /*
@@ -59,7 +61,8 @@ _mbr_MembershipCall(struct kauth_identity_extlookup *req)
        kern_return_t status;
        uint32_t i;
 
        kern_return_t status;
        uint32_t i;
 
-       if (_ds_running() == 0) return EIO;
+       /* call _ds_running() to look up _mbr_port */
+       _ds_running();
        if (_mbr_port == MACH_PORT_NULL) return EIO;
 
        memset(&token, 0, sizeof(audit_token_t));
        if (_mbr_port == MACH_PORT_NULL) return EIO;
 
        memset(&token, 0, sizeof(audit_token_t));
@@ -95,7 +98,8 @@ _mbr_MapName(char *name, int type, guid_t *uu)
        if (name == NULL) return EINVAL;
        if (strlen(name) > 255) return EINVAL;
 
        if (name == NULL) return EINVAL;
        if (strlen(name) > 255) return EINVAL;
 
-       if (_ds_running() == 0) return EIO;
+       /* call _ds_running() to look up _mbr_port */
+       _ds_running();
        if (_mbr_port == MACH_PORT_NULL) return EIO;
 
        memset(&token, 0, sizeof(audit_token_t));
        if (_mbr_port == MACH_PORT_NULL) return EIO;
 
        memset(&token, 0, sizeof(audit_token_t));
@@ -129,7 +133,8 @@ _mbr_ClearCache()
        kern_return_t status;
        uint32_t i;
 
        kern_return_t status;
        uint32_t i;
 
-       if (_ds_running() == 0) return EIO;
+       /* call _ds_running() to look up _mbr_port */
+       _ds_running();
        if (_mbr_port == MACH_PORT_NULL) return EIO;
 
        status = MIG_SERVER_DIED;
        if (_mbr_port == MACH_PORT_NULL) return EIO;
 
        status = MIG_SERVER_DIED;
@@ -151,55 +156,46 @@ _mbr_ClearCache()
 }
 #endif
 
 }
 #endif
 
-int
-mbr_uid_to_uuid(uid_t id, uuid_t uu)
-{
 #ifdef DS_AVAILABLE
 #ifdef DS_AVAILABLE
-       struct kauth_identity_extlookup request;
-       int status;
-
-       if (id == 0)
+static int
+_mbr_SetIdentifierTTL(int idType, const void *identifier, size_t identifier_size, unsigned int seconds)
+{
+       kern_return_t status;
+       uint32_t i;
+       
+       /* call _ds_running() to look up _mbr_port */
+       _ds_running();
+       if (_mbr_port == MACH_PORT_NULL) return EIO;
+       
+       status = MIG_SERVER_DIED;
+       for (i = 0; (_mbr_port != MACH_PORT_NULL) && (status == MIG_SERVER_DIED) && (i < MAX_LOOKUP_ATTEMPTS); i++)
        {
        {
-               memcpy(uu, _mbr_root_uuid, sizeof(uuid_t));
-               return 0;
+               status = memberdDSmig_SetIdentifierTTL(_mbr_port, idType, (identifier_data_t)identifier, identifier_size, seconds);
+               if (status == MACH_SEND_INVALID_DEST)
+               {
+                       mach_port_mod_refs(mach_task_self(), _mbr_port, MACH_PORT_RIGHT_SEND, -1);
+                       _mbr_port = MACH_PORT_NULL;
+                       _ds_running();
+                       status = MIG_SERVER_DIED;
+               }
        }
        }
-
-       /* used as a byte order field */
-       request.el_seqno = 1;
-       request.el_flags = KAUTH_EXTLOOKUP_VALID_UID | KAUTH_EXTLOOKUP_WANT_UGUID;
-       request.el_uid = id;
-
-       status = _mbr_MembershipCall(&request);
-       if (status != 0) return status;
-       if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_UGUID) == 0) return ENOENT;
-
-       memcpy(uu, &request.el_uguid, sizeof(guid_t));
+       
+       if (status != KERN_SUCCESS) return EIO;
+       
        return 0;
        return 0;
-#else
-       return EIO;
+}
 #endif
 #endif
+
+int
+mbr_uid_to_uuid(uid_t id, uuid_t uu)
+{
+       return mbr_identifier_to_uuid(ID_TYPE_UID, &id, sizeof(id), uu);
 }
 
 int
 mbr_gid_to_uuid(gid_t id, uuid_t uu)
 {
 }
 
 int
 mbr_gid_to_uuid(gid_t id, uuid_t uu)
 {
-#ifdef DS_AVAILABLE
-       struct kauth_identity_extlookup request;
-       int status;
-
-       request.el_seqno = 1;
-       request.el_flags = KAUTH_EXTLOOKUP_VALID_GID | KAUTH_EXTLOOKUP_WANT_GGUID;
-       request.el_gid = id;
-
-       status = _mbr_MembershipCall(&request);
-       if (status != 0) return status;
-       if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_GGUID) == 0) return ENOENT;
-
-       memcpy(uu, &request.el_gguid, sizeof(guid_t));
-       return 0;
-#else
-       return EIO;
-#endif
+       return mbr_identifier_to_uuid(ID_TYPE_GID, &id, sizeof(id), uu);
 }
 
 int
 }
 
 int
@@ -208,16 +204,25 @@ mbr_uuid_to_id(const uuid_t uu, uid_t *id, int *id_type)
 #ifdef DS_AVAILABLE
        struct kauth_identity_extlookup request;
        int status;
 #ifdef DS_AVAILABLE
        struct kauth_identity_extlookup request;
        int status;
+       id_t tempID;
 
        if (id == NULL) return EIO;
        if (id_type == NULL) return EIO;
 
 
        if (id == NULL) return EIO;
        if (id_type == NULL) return EIO;
 
-       if (!memcmp(uu, _mbr_root_uuid, sizeof(uuid_t)))
+       if (!memcmp(uu, _user_compat_prefix, COMPAT_PREFIX_LEN))
        {
        {
-               *id = 0;
+               memcpy(&tempID, &uu[COMPAT_PREFIX_LEN], sizeof(tempID));
+               *id = ntohl(tempID);
                *id_type = ID_TYPE_UID;
                return 0;
        }
                *id_type = ID_TYPE_UID;
                return 0;
        }
+       else if (!memcmp(uu, _group_compat_prefix, COMPAT_PREFIX_LEN))
+       {
+               memcpy(&tempID, &uu[COMPAT_PREFIX_LEN], sizeof(tempID));
+               *id = ntohl(tempID);
+               *id_type = ID_TYPE_GID;
+               return 0;
+       }
 
        request.el_seqno = 1;
        request.el_flags = KAUTH_EXTLOOKUP_VALID_UGUID | KAUTH_EXTLOOKUP_VALID_GGUID | KAUTH_EXTLOOKUP_WANT_UID | KAUTH_EXTLOOKUP_WANT_GID;
 
        request.el_seqno = 1;
        request.el_flags = KAUTH_EXTLOOKUP_VALID_UGUID | KAUTH_EXTLOOKUP_VALID_GGUID | KAUTH_EXTLOOKUP_WANT_UID | KAUTH_EXTLOOKUP_WANT_GID;
@@ -284,17 +289,52 @@ mbr_identifier_to_uuid(int id_type, const void *identifier, size_t identifier_si
        vm_offset_t ool = 0;
        mach_msg_type_number_t oolCnt = 0;
        uint32_t i;
        vm_offset_t ool = 0;
        mach_msg_type_number_t oolCnt = 0;
        uint32_t i;
+       id_t tempID;
 #if __BIG_ENDIAN__
        id_t newID;
 #endif
 #if __BIG_ENDIAN__
        id_t newID;
 #endif
-       
+
        if (identifier == NULL) return EINVAL;
        if (identifier_size == 0) return EINVAL;
        else if (identifier_size == -1) identifier_size = strlen((char*) identifier) + 1;
        if (identifier == NULL) return EINVAL;
        if (identifier_size == 0) return EINVAL;
        else if (identifier_size == -1) identifier_size = strlen((char*) identifier) + 1;
-       
-       if (_ds_running() == 0) return EIO;
+
+       /* call _ds_running() to look up _mbr_port */
+       _ds_running();
+
+       /* if this is a UID or GID translation, we shortcut UID/GID 0 */
+       /* if no DS, we return compatibility UUIDs */
+       switch (id_type)
+       {
+               case ID_TYPE_UID:
+               {
+                       if (identifier_size != sizeof(tempID)) return EINVAL;
+
+                       tempID = *((id_t *) identifier);
+                       if ((tempID == 0) || (_mbr_port == MACH_PORT_NULL))
+                       {
+                               uuid_copy(uu, _user_compat_prefix);
+                               *((id_t *) &uu[COMPAT_PREFIX_LEN]) = htonl(tempID);
+                               return 0;
+                       }
+                       break;
+               }
+               case ID_TYPE_GID:
+               {
+                       if (identifier_size != sizeof(tempID)) return EINVAL;
+
+                       tempID = *((id_t *) identifier);
+                       if ((tempID == 0) || (_mbr_port == MACH_PORT_NULL))
+                       {
+                               uuid_copy(uu, _group_compat_prefix);
+                               *((id_t *) &uu[COMPAT_PREFIX_LEN]) = htonl(tempID);
+                               return 0;
+                       }
+                       break;
+               }
+       }
+
        if (_mbr_port == MACH_PORT_NULL) return EIO;
        if (_mbr_port == MACH_PORT_NULL) return EIO;
-       
+
        memset(&token, 0, sizeof(audit_token_t));
 
 #if __BIG_ENDIAN__
        memset(&token, 0, sizeof(audit_token_t));
 
 #if __BIG_ENDIAN__
@@ -308,20 +348,20 @@ mbr_identifier_to_uuid(int id_type, const void *identifier, size_t identifier_si
                        break;
        }
 #endif
                        break;
        }
 #endif
-       
+
        if (identifier_size > MAX_MIG_INLINE_DATA)
        {
                if (vm_read(mach_task_self(), (vm_offset_t) identifier, identifier_size, &ool, &oolCnt) != 0) return ENOMEM;
                identifier = NULL;
                identifier_size = 0;
        }
        if (identifier_size > MAX_MIG_INLINE_DATA)
        {
                if (vm_read(mach_task_self(), (vm_offset_t) identifier, identifier_size, &ool, &oolCnt) != 0) return ENOMEM;
                identifier = NULL;
                identifier_size = 0;
        }
-       
+
        status = MIG_SERVER_DIED;
        for (i = 0; (_mbr_port != MACH_PORT_NULL) && (status == MIG_SERVER_DIED) && (i < MAX_LOOKUP_ATTEMPTS); i++)
        {
        status = MIG_SERVER_DIED;
        for (i = 0; (_mbr_port != MACH_PORT_NULL) && (status == MIG_SERVER_DIED) && (i < MAX_LOOKUP_ATTEMPTS); i++)
        {
-               status = memberdDSmig_MapIdentifier(_mbr_port, id_type, (vm_offset_t)identifier, identifier_size, ool, oolCnt, uu, &token);
+               status = memberdDSmig_MapIdentifier(_mbr_port, id_type, (identifier_data_t) identifier, identifier_size, ool, oolCnt, (guid_t *)uu, &token);
                if (status == KERN_FAILURE) return ENOENT;
                if (status == KERN_FAILURE) return ENOENT;
-               
+
                if (status == MACH_SEND_INVALID_DEST)
                {
                        if (ool != 0) vm_deallocate(mach_task_self(), ool, oolCnt);
                if (status == MACH_SEND_INVALID_DEST)
                {
                        if (ool != 0) vm_deallocate(mach_task_self(), ool, oolCnt);
@@ -332,10 +372,10 @@ mbr_identifier_to_uuid(int id_type, const void *identifier, size_t identifier_si
                        status = MIG_SERVER_DIED;
                }
        }
                        status = MIG_SERVER_DIED;
                }
        }
-       
+
        if (status != KERN_SUCCESS) return EIO;
        if (audit_token_uid(token) != 0) return EAUTH;
        if (status != KERN_SUCCESS) return EIO;
        if (audit_token_uid(token) != 0) return EAUTH;
-       
+
        return 0;
 #else
        return EIO;
        return 0;
 #else
        return EIO;
@@ -396,7 +436,7 @@ mbr_uuid_to_sid(const uuid_t uu, nt_sid_t *sid)
 }
 
 int
 }
 
 int
-mbr_check_membership(uuid_t user, uuid_t group, int *ismember)
+mbr_check_membership(const uuid_t user, const uuid_t group, int *ismember)
 {
 #ifdef DS_AVAILABLE
        struct kauth_identity_extlookup request;
 {
 #ifdef DS_AVAILABLE
        struct kauth_identity_extlookup request;
@@ -502,7 +542,7 @@ mbr_check_service_membership(const uuid_t user, const char *servicename, int *is
        char *all_services = "com.apple.access_all_services";
        char groupName[256];
        uuid_t group_uu;
        char *all_services = "com.apple.access_all_services";
        char groupName[256];
        uuid_t group_uu;
-       int result, dummy;
+       int result;
 
        if (servicename == NULL) return EINVAL;
        if (strlen(servicename) > 255 - strlen(prefix)) return EINVAL;
 
        if (servicename == NULL) return EINVAL;
        if (strlen(servicename) > 255 - strlen(prefix)) return EINVAL;
@@ -522,17 +562,8 @@ mbr_check_service_membership(const uuid_t user, const char *servicename, int *is
 
        if (result == 0)
        {
 
        if (result == 0)
        {
-               result = mbr_check_membership_refresh(user, group_uu, ismember);
-       }
-       else if (result == EAUTH)
-       {
-               return result;
-       }
-       else
-       {
-               /* just force cache update with bogus membership check */
-               memset(group_uu, 0, sizeof(group_uu));
-               mbr_check_membership_refresh(user, group_uu, &dummy);
+               /* refreshes are driven at a higher level, just check membership */
+               result = mbr_check_membership(user, group_uu, ismember);
        }
 
        return result;
        }
 
        return result;
@@ -625,7 +656,11 @@ mbr_string_to_sid(const char *string, nt_sid_t *sid)
        while (*current != '\0' && count < NTSID_MAX_AUTHORITIES)
        {
                current++;
        while (*current != '\0' && count < NTSID_MAX_AUTHORITIES)
        {
                current++;
+               errno = 0;
                sid->sid_authorities[count] = (u_int32_t)strtoll(current, &current, 10);
                sid->sid_authorities[count] = (u_int32_t)strtoll(current, &current, 10);
+               if ((sid->sid_authorities[count] == 0) && (errno == EINVAL)) {
+                       return EINVAL;
+               }
                count++;
        }
 
                count++;
        }
 
@@ -741,3 +776,13 @@ mbr_string_to_uuid(const char *string, uuid_t uu)
 #endif
 }
 
 #endif
 }
 
+int 
+mbr_set_identifier_ttl(int id_type, const void *identifier, size_t identifier_size, unsigned int seconds)
+{
+#ifdef DS_AVAILABLE
+       _mbr_SetIdentifierTTL(id_type, identifier, identifier_size, seconds);
+       return 0;
+#else
+       return EIO;
+#endif
+}
index 32c8a8ac97ebd03188181aa2c0f63860c79e7289..ea724474f43625fb66fc8ac30ec45676872dfdca 100644 (file)
@@ -175,6 +175,27 @@ int mbr_uuid_to_id(const uuid_t uu, id_t* uid_or_gid, int* id_type);
 */
 int mbr_uuid_to_sid(const uuid_t uu, nt_sid_t* sid);
 
 */
 int mbr_uuid_to_sid(const uuid_t uu, nt_sid_t* sid);
 
+/*!
+       @function       mbr_sid_to_string
+       @abstract       convert a SID to a corresponding character string representation
+       @discussion for use in situations where an external representation of a SID is required.
+       @param          sid is the SID to be converted
+       @param          string is a buffer that will be filled in with a nul-terminated string
+                               representation of the SID.  The buffer must be at least 194 characters in length.
+       @result    returns 0 on success or appropriate errno code.
+ */
+int mbr_sid_to_string(const nt_sid_t *sid, char *string);
+
+/*!
+       @function       mbr_string_to_sid
+       @abstract       convert a character string representation of a sid to an nt_sid_t value
+       @discussion for converting an external representation of a sid.
+       @param          string is a buffer containing a nul-terminated string representation of a SID
+       @param          sid is the target of the conversion
+       @result    returns 0 on success or appropriate errno code.
+ */
+int mbr_string_to_sid(const char *string, nt_sid_t *sid);
+
 /*!
        @function       mbr_check_membership
        @abstract       checks if a user is a member of a group
 /*!
        @function       mbr_check_membership
        @abstract       checks if a user is a member of a group
@@ -186,7 +207,7 @@ int mbr_uuid_to_sid(const uuid_t uu, nt_sid_t* sid);
                                otherwise 0 is returned
        @result         returns 0 on success or appropriate errno code.
 */
                                otherwise 0 is returned
        @result         returns 0 on success or appropriate errno code.
 */
-int mbr_check_membership(uuid_t user, uuid_t group, int* ismember);
+int mbr_check_membership(const uuid_t user, const uuid_t group, int* ismember);
 
 /*!
        @function       mbr_check_service_membership
 
 /*!
        @function       mbr_check_service_membership
index a98854e8f15ec68c39958583b5e4eda1bdd66a7b..83abd35b699c8b8b6fa3ee4e3ec3a4d688a8f27c 100644 (file)
@@ -41,9 +41,8 @@ int mbr_check_membership_by_id(uuid_t user, gid_t group, int *ismember);
 int mbr_check_membership_refresh(const uuid_t user, uuid_t group, int *ismember);
 int mbr_uuid_to_string(const uuid_t uu, char *string);
 int mbr_string_to_uuid(const char *string, uuid_t uu);
 int mbr_check_membership_refresh(const uuid_t user, uuid_t group, int *ismember);
 int mbr_uuid_to_string(const uuid_t uu, char *string);
 int mbr_string_to_uuid(const char *string, uuid_t uu);
-int mbr_sid_to_string(const nt_sid_t *sid, char *string);
-int mbr_string_to_sid(const char *string, nt_sid_t *sid);
 int mbr_uuid_to_sid_type(const uuid_t uu, nt_sid_t *sid, int *id_type);
 int mbr_uuid_to_sid_type(const uuid_t uu, nt_sid_t *sid, int *id_type);
+int mbr_set_identifier_ttl(int id_type, const void *identifier, size_t identifier_size, unsigned int seconds);
 
 __END_DECLS
 
 
 __END_DECLS
 
index 5fe28bd3f1f4350c5f362dbd825a7a1f0fcca350..06a6b80829890c91bb0b0e554835cc73f663174c 100644 (file)
@@ -32,6 +32,6 @@ typedef struct {
        u_int8_t                sid_authcount;
        u_int8_t                sid_authority[6];
        u_int32_t               sid_authorities[NTSID_MAX_AUTHORITIES];
        u_int8_t                sid_authcount;
        u_int8_t                sid_authority[6];
        u_int32_t               sid_authorities[NTSID_MAX_AUTHORITIES];
-} nt_sid_t __attribute__ ((packed));
+} nt_sid_t;
 
 #endif /* !_NTSID_H_ */
 
 #endif /* !_NTSID_H_ */
diff --git a/netinfo.subproj/Makefile b/netinfo.subproj/Makefile
deleted file mode 100644 (file)
index 41f5577..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-Project = netinfo
-ProductType = staticlib
-Install_Dir = /scratch
-BuildDebug = YES
-BuildProfile = YES
-
-CFILES = ni_stub.c
-
-Extra_CC_Flags = -Wall -fno-common \
-       -D__DARWIN_NON_CANCELABLE=1
-
-include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
diff --git a/nis.subproj/Makefile b/nis.subproj/Makefile
deleted file mode 100644 (file)
index 8859ee9..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-Project = nis
-ProductType = staticlib
-Install_Dir = /scratch
-BuildDebug = YES
-BuildProfile = YES
-
-HFILES = ypclnt.h ypinternal.h yp_prot.h
-
-CFILES = getdomainname.c getnetgrent.c innetgr.c setdomainname.c\
-         xdr_domainname.c xdr_keydat.c xdr_mapname.c xdr_peername.c\
-         xdr_valdat.c xdr_ypbind_binding.c xdr_ypbind_resp.c\
-         xdr_ypbind_resptype.c xdr_ypbind_setdom.c xdr_ypmaplist.c\
-         xdr_ypreq_key.c xdr_ypreq_nokey.c xdr_ypresp_all.c\
-         xdr_ypresp_key_val.c xdr_ypresp_maplist.c xdr_ypresp_master.c\
-         xdr_ypresp_order.c xdr_ypresp_val.c xdr_ypstat.c\
-         yperr_string.c ypmatch_cache.c yppasswdd_xdr.c ypprot_err.c\
-         yp_all.c yp_bind.c yp_first.c yp_get_default_domain.c\
-         yp_maplist.c yp_master.c yp_order.c
-
-MANPAGES = yp_all.3 yp_bind.3 yp_first.3\
-            yp_get_default_domain.3 yp_master.3 yp_match.3 yp_next.3\
-            yp_order.3 yp_unbind.3 ypclnt.3 yperr_string.3 ypprot_err.3\
-            yp.8
-
-Install_Headers = ypclnt.h yp_prot.h
-Install_Headers_Directory =  /usr/include/rpcsvc
-
-Extra_CC_Flags = -Wall -fno-common -I. \
-       -I../gen.subproj -I../lookup.subproj \
-       -D__DARWIN_NON_CANCELABLE=1
-
-include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
index 531017cc15ee585d507283621fb64ca746278e43..94c75886f155e906472df31f46f69d26f4215fd6 100644 (file)
@@ -1,28 +1,5 @@
 /*
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@fsa.ca>
+ * Copyright (c) 1992/3 Theo de Raadt <deraadt@fsa.ca>
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by Theo de Raadt.
- * 4. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
+ * 3. The name of the author may not be used to endorse or promote
+ *    products derived from this software without specific prior written
+ *    permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
@@ -50,6 +25,8 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
+ *
+ * $FreeBSD: src/include/rpcsvc/yp_prot.h,v 1.13 2005/12/06 02:01:06 peter Exp $
  */
 
 #ifndef _RPCSVC_YP_PROT_H_
  */
 
 #ifndef _RPCSVC_YP_PROT_H_
@@ -57,9 +34,9 @@
 
 /*
  * YPSERV PROTOCOL:
 
 /*
  * YPSERV PROTOCOL:
- * 
+ *
  * ypserv supports the following procedures:
  * ypserv supports the following procedures:
- * 
+ *
  * YPPROC_NULL         takes (void), returns (void).
  *                     called to check if server is alive.
  * YPPROC_DOMAIN       takes (char *), returns (bool_t).
  * YPPROC_NULL         takes (void), returns (void).
  *                     called to check if server is alive.
  * YPPROC_DOMAIN       takes (char *), returns (bool_t).
  * YPPROC_MAPLIST      takes (char *), returns (struct ypmaplist *).
  */
 
  * YPPROC_MAPLIST      takes (char *), returns (struct ypmaplist *).
  */
 
-#ifndef BOOL_DEFINED
-typedef unsigned int bool;
-#define BOOL_DEFINED
-#endif
-
-
 /* Program and version symbols, magic numbers */
 /* Program and version symbols, magic numbers */
-#define YPPROG         ((unsigned long)100004)
-#define YPVERS         ((unsigned long)2)
-#define YPVERS_ORIG    ((unsigned long)1)
-#define YPMAXRECORD    ((unsigned long)1024)
-#define YPMAXDOMAIN    ((unsigned long)64)
-#define YPMAXMAP       ((unsigned long)64)
-#define YPMAXPEER      ((unsigned long)256)
+
+#define YPPROG         ((u_long)100004)
+#define YPVERS         ((u_long)2)
+#define YPVERS_ORIG    ((u_long)1)
+#define YPMAXRECORD    ((u_long)1024)
+#define YPMAXDOMAIN    ((u_long)64)
+#define YPMAXMAP       ((u_long)64)
+#define YPMAXPEER      ((u_long)256)
 
 /*
  * I don't know if anything of sun's depends on this, or if they
 
 /*
  * I don't know if anything of sun's depends on this, or if they
@@ -114,35 +86,35 @@ typedef unsigned int bool;
 
 #ifndef DATUM
 typedef struct {
 
 #ifndef DATUM
 typedef struct {
-       const char      *dptr;
-       int              dsize;
+       char    *dptr;
+       int     dsize;
 } datum;
 #define DATUM
 #endif
 
 struct ypmap_parms {
 } datum;
 #define DATUM
 #endif
 
 struct ypmap_parms {
-       const char *domain;
-       const char *map;
-       unsigned long ordernum;
+       char *domain;
+       char *map;
+       u_int ordernum;
        char *owner;
 };
 
 struct ypreq_key {
        char *owner;
 };
 
 struct ypreq_key {
-       const char *domain;
-       const char *map;
+       char *domain;
+       char *map;
        datum keydat;
 };
 
 struct ypreq_nokey {
        datum keydat;
 };
 
 struct ypreq_nokey {
-       const char *domain;
-       const char *map;
+       char *domain;
+       char *map;
 };
 
 struct ypreq_xfr {
        struct ypmap_parms map_parms;
 };
 
 struct ypreq_xfr {
        struct ypmap_parms map_parms;
-       unsigned long transid;
-       unsigned long proto;
-       unsigned short port;
+       u_int transid;
+       u_int proto;
+       u_int port;
 };
 #define ypxfr_domain   map_parms.domain
 #define ypxfr_map      map_parms.map
 };
 #define ypxfr_domain   map_parms.domain
 #define ypxfr_map      map_parms.map
@@ -150,24 +122,24 @@ struct ypreq_xfr {
 #define ypxfr_owner    map_parms.owner
 
 struct ypresp_val {
 #define ypxfr_owner    map_parms.owner
 
 struct ypresp_val {
-       unsigned long status;
+       u_int status;
        datum valdat;
 };
 
 struct ypresp_key_val {
        datum valdat;
 };
 
 struct ypresp_key_val {
-       unsigned long status;
+       u_int status;
        datum keydat;
        datum valdat;
 };
 
 struct ypresp_master {
        datum keydat;
        datum valdat;
 };
 
 struct ypresp_master {
-       unsigned long status;
+       u_int status;
        char *master;
 };
 
 struct ypresp_order {
        char *master;
 };
 
 struct ypresp_order {
-       unsigned long status;
-       unsigned long ordernum;
+       u_int status;
+       u_int ordernum;
 };
 
 struct ypresp_all {
 };
 
 struct ypresp_all {
@@ -178,28 +150,28 @@ struct ypresp_all {
 };
 
 struct ypmaplist {
 };
 
 struct ypmaplist {
-       char ypml_name[YPMAXMAP + 1];
+       char *ypml_name;
        struct ypmaplist *ypml_next;
 };
 
 struct ypresp_maplist {
        struct ypmaplist *ypml_next;
 };
 
 struct ypresp_maplist {
-       unsigned long status;
+       u_int status;
        struct ypmaplist *list;
 };
 
 /* ypserv procedure numbers */
        struct ypmaplist *list;
 };
 
 /* ypserv procedure numbers */
-#define YPPROC_NULL            ((unsigned long)0)
-#define YPPROC_DOMAIN          ((unsigned long)1)
-#define YPPROC_DOMAIN_NONACK   ((unsigned long)2)
-#define YPPROC_MATCH           ((unsigned long)3)
-#define YPPROC_FIRST           ((unsigned long)4)
-#define YPPROC_NEXT            ((unsigned long)5)
-#define YPPROC_XFR             ((unsigned long)6)
-#define YPPROC_CLEAR           ((unsigned long)7)
-#define YPPROC_ALL             ((unsigned long)8)
-#define YPPROC_MASTER          ((unsigned long)9)
-#define YPPROC_ORDER           ((unsigned long)10)
-#define YPPROC_MAPLIST         ((unsigned long)11)
+#define YPPROC_NULL            ((u_long)0)
+#define YPPROC_DOMAIN          ((u_long)1)
+#define YPPROC_DOMAIN_NONACK   ((u_long)2)
+#define YPPROC_MATCH           ((u_long)3)
+#define YPPROC_FIRST           ((u_long)4)
+#define YPPROC_NEXT            ((u_long)5)
+#define YPPROC_XFR             ((u_long)6)
+#define YPPROC_CLEAR           ((u_long)7)
+#define YPPROC_ALL             ((u_long)8)
+#define YPPROC_MASTER          ((u_long)9)
+#define YPPROC_ORDER           ((u_long)10)
+#define YPPROC_MAPLIST         ((u_long)11)
 
 /* ypserv procedure return status values */
 #define YP_TRUE                ((long)1)       /* general purpose success code */
 
 /* ypserv procedure return status values */
 #define YP_TRUE                ((long)1)       /* general purpose success code */
@@ -220,7 +192,7 @@ struct ypresp_maplist {
  * Users of the ypclnt package (or of this protocol) don't HAVE to know about
  * it, but it must be available to users because _yp_dobind is a public
  * interface."
  * Users of the ypclnt package (or of this protocol) don't HAVE to know about
  * it, but it must be available to users because _yp_dobind is a public
  * interface."
- * 
+ *
  * This is totally bogus! Nowhere else does Sun state that _yp_dobind() is
  * a public interface, and I don't know any reason anyone would want to call
  * it. But, just in case anyone does actually expect it to be available..
  * This is totally bogus! Nowhere else does Sun state that _yp_dobind() is
  * a public interface, and I don't know any reason anyone would want to call
  * it. But, just in case anyone does actually expect it to be available..
@@ -230,16 +202,16 @@ struct dom_binding {
        struct dom_binding *dom_pnext;
        char dom_domain[YPMAXDOMAIN + 1];
        struct sockaddr_in dom_server_addr;
        struct dom_binding *dom_pnext;
        char dom_domain[YPMAXDOMAIN + 1];
        struct sockaddr_in dom_server_addr;
-       unsigned short dom_server_port;
+       u_short dom_server_port;
        int dom_socket;
        CLIENT *dom_client;
        int dom_socket;
        CLIENT *dom_client;
-       unsigned short dom_local_port;
+       u_short dom_local_port;
        long dom_vers;
 };
 
 /*
  * YPBIND PROTOCOL:
        long dom_vers;
 };
 
 /*
  * YPBIND PROTOCOL:
- * 
+ *
  * ypbind supports the following procedures:
  *
  * YPBINDPROC_NULL     takes (void), returns (void).
  * ypbind supports the following procedures:
  *
  * YPBINDPROC_NULL     takes (void), returns (void).
@@ -250,15 +222,15 @@ struct dom_binding {
  * YPBINDPROC_SETDOM   takes (struct ypbind_setdom), returns (void).
  *                     used by ypset.
  */
  * YPBINDPROC_SETDOM   takes (struct ypbind_setdom), returns (void).
  *                     used by ypset.
  */
-#define YPBINDPROG             ((unsigned long)100007)
-#define YPBINDVERS             ((unsigned long)2)
-#define YPBINDVERS_ORIG                ((unsigned long)1)
+
+#define YPBINDPROG             ((u_long)100007)
+#define YPBINDVERS             ((u_long)2)
+#define YPBINDVERS_ORIG                ((u_long)1)
 
 /* ypbind procedure numbers */
 
 /* ypbind procedure numbers */
-#define YPBINDPROC_NULL                ((unsigned long)0)
-#define YPBINDPROC_DOMAIN      ((unsigned long)1)
-#define YPBINDPROC_SETDOM      ((unsigned long)2)
+#define YPBINDPROC_NULL                ((u_long)0)
+#define YPBINDPROC_DOMAIN      ((u_long)1)
+#define YPBINDPROC_SETDOM      ((u_long)2)
 
 /* error code in ypbind_resp.ypbind_status */
 enum ypbind_resptype {
 
 /* error code in ypbind_resp.ypbind_status */
 enum ypbind_resptype {
@@ -269,13 +241,13 @@ enum ypbind_resptype {
 /* network order, of course */
 struct ypbind_binding {
        struct in_addr  ypbind_binding_addr;
 /* network order, of course */
 struct ypbind_binding {
        struct in_addr  ypbind_binding_addr;
-       unsigned short          ypbind_binding_port;
+       u_short         ypbind_binding_port;
 };
 
 struct ypbind_resp {
        enum ypbind_resptype    ypbind_status;
        union {
 };
 
 struct ypbind_resp {
        enum ypbind_resptype    ypbind_status;
        union {
-               unsigned long                   ypbind_error;
+               u_int                   ypbind_error;
                struct ypbind_binding   ypbind_bindinfo;
        } ypbind_respbody;
 };
                struct ypbind_binding   ypbind_bindinfo;
        } ypbind_respbody;
 };
@@ -291,33 +263,33 @@ struct ypbind_resp {
 struct ypbind_setdom {
        char ypsetdom_domain[YPMAXDOMAIN + 1];
        struct ypbind_binding ypsetdom_binding;
 struct ypbind_setdom {
        char ypsetdom_domain[YPMAXDOMAIN + 1];
        struct ypbind_binding ypsetdom_binding;
-       unsigned short ypsetdom_vers;
+       u_int ypsetdom_vers;
 };
 #define ypsetdom_addr ypsetdom_binding.ypbind_binding_addr
 #define ypsetdom_port ypsetdom_binding.ypbind_binding_port
 
 /*
  * YPPUSH PROTOCOL:
 };
 #define ypsetdom_addr ypsetdom_binding.ypbind_binding_addr
 #define ypsetdom_port ypsetdom_binding.ypbind_binding_port
 
 /*
  * YPPUSH PROTOCOL:
- * 
+ *
  * Sun says:
  * "Protocol between clients (ypxfr, only) and yppush
  *  yppush speaks a protocol in the transient range, which
  *  is supplied to ypxfr as a command-line parameter when it
  *  is activated by ypserv."
  * Sun says:
  * "Protocol between clients (ypxfr, only) and yppush
  *  yppush speaks a protocol in the transient range, which
  *  is supplied to ypxfr as a command-line parameter when it
  *  is activated by ypserv."
- * 
- * This protocol is not implimented, naturally, because this YP
- * implimentation only does the client side.
+ *
+ * This protocol is not implemented, naturally, because this YP
+ * implementation only does the client side.
  */
  */
-#define YPPUSHVERS             ((unsigned long)1)
-#define YPPUSHVERS_ORIG                ((unsigned long)1)
+#define YPPUSHVERS             ((u_long)1)
+#define YPPUSHVERS_ORIG                ((u_long)1)
 
 /* yppush procedure numbers */
 
 /* yppush procedure numbers */
-#define YPPUSHPROC_NULL                ((unsigned long)0)
-#define YPPUSHPROC_XFRRESP     ((unsigned long)1)
+#define YPPUSHPROC_NULL                ((u_long)0)
+#define YPPUSHPROC_XFRRESP     ((u_long)1)
 
 struct yppushresp_xfr {
 
 struct yppushresp_xfr {
-       unsigned long   transid;
-       unsigned long   status;
+       u_int   transid;
+       u_int   status;
 };
 
 /* yppush status value in yppushresp_xfr.status */
 };
 
 /* yppush status value in yppushresp_xfr.status */
@@ -325,7 +297,7 @@ struct yppushresp_xfr {
 #define YPPUSH_AGE     ((long)2)       /* Master's version not newer */
 #define YPPUSH_NOMAP   ((long)-1)      /* Can't find server for map */
 #define YPPUSH_NODOM   ((long)-2)      /* Domain not supported */
 #define YPPUSH_AGE     ((long)2)       /* Master's version not newer */
 #define YPPUSH_NOMAP   ((long)-1)      /* Can't find server for map */
 #define YPPUSH_NODOM   ((long)-2)      /* Domain not supported */
-#define YPPUSH_RSRC    ((long)-3)      /* Local resouce alloc failure */
+#define YPPUSH_RSRC    ((long)-3)      /* Local resource alloc failure */
 #define YPPUSH_RPC     ((long)-4)      /* RPC failure talking to server */
 #define YPPUSH_MADDR   ((long)-5)      /* Can't get master address */
 #define YPPUSH_YPERR   ((long)-6)      /* YP server/map db error */
 #define YPPUSH_RPC     ((long)-4)      /* RPC failure talking to server */
 #define YPPUSH_MADDR   ((long)-5)      /* Can't get master address */
 #define YPPUSH_YPERR   ((long)-6)      /* YP server/map db error */
diff --git a/rpc.subproj/Makefile b/rpc.subproj/Makefile
deleted file mode 100644 (file)
index 1aeaab7..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-Project = rpc
-ProductType = staticlib
-Install_Dir = /scratch
-BuildDebug = YES
-BuildProfile = YES
-
-HFILES = auth.h auth_unix.h clnt.h pmap_clnt.h pmap_prot.h pmap_rmt.h\
-         rpc.h rpc_msg.h svc.h svc_auth.h types.h xdr.h pmap_wakeup.h
-
-CFILES = auth_none.c auth_unix.c authunix_prot.c bindresvport.c\
-         clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c\
-         clnt_tcp.c clnt_udp.c get_myaddress.c pmap_clnt.c\
-         pmap_getmaps.c pmap_getport.c pmap_prot.c pmap_prot2.c\
-         pmap_rmt.c rpc_callmsg.c rpc_commondata.c rpc_dtablesize.c\
-         rpc_prot.c svc.c svc_auth.c svc_auth_unix.c svc_raw.c\
-         svc_run.c svc_simple.c svc_tcp.c getrpcent.c svc_udp.c xdr.c\
-         xdr_array.c xdr_float.c xdr_mem.c xdr_rec.c xdr_reference.c\
-         xdr_sizeof.c xdr_stdio.c getrpcport.c pmap_wakeup.c
-
-MANPAGES = bindresvport.3 getrpcent.3 getrpcport.3 rpc.3 xdr.3
-
-Install_Headers_Directory = /usr/include/rpc
-Install_Headers = auth.h auth_unix.h clnt.h pmap_clnt.h pmap_prot.h\
-                 pmap_rmt.h rpc.h rpc_msg.h svc.h svc_auth.h types.h\
-                 xdr.h
-
-Extra_CC_Flags = -Wall -fno-common \
-       -I../gen.subproj -I../lookup.subproj \
-       -D__DARWIN_NON_CANCELABLE=1
-
-include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
-
-after_install:
-       @for LINK in getrpcbyname.3 getrpcbynumber.3 \
-               endrpcent.3 setrpcent.3 ; do \
-               $(LN) -f "$(DSTROOT)/usr/share/man/man3/getrpcent.3" \
-                       "$(DSTROOT)/usr/share/man/man3/$${LINK}" ; \
-       done 
-       @for LINK in auth_destroy.3 authnone_create.3 authunix_create.3 \
-               authunix_create_default.3 callrpc.3 clnt_broadcast.3 \
-               clnt_call.3 clnt_control.3 clnt_create.3 clnt_destroy.3 \
-               clnt_freeres.3 clnt_geterr.3 clnt_pcreateerror.3 \
-               clnt_perrno.3 clnt_perror.3 clnt_spcreateerror.3 \
-               clnt_sperrno.3 clnt_sperror.3 clntraw_create.3 \
-               clnttcp_create.3 clntudp_bufcreate.3 clntudp_create.3 \
-               get_myaddress.3 pmap_getmaps.3 pmap_getport.3 pmap_rmtcall.3 \
-               pmap_set.3 pmap_unset.3 regsterrpc.3 rpc_createerr.3 \
-               svc_destroy.3 svc_fds.3 svc_fdset.3 svc_getargs.3 \
-               svc_getcaller.3 svc_getreg.3 svc_getregset.3 svc_register.3 \
-               svc_run.3 svc_sendreply.3 svc_unregister.3 svcerr_auth.3 \
-               svcerr_decode.3 svcerr_noproc.3 svcerr_noprog.3 \
-               svcerr_progvers.3 svcerr_systemerr.3 svcerr_weakauth.3 \
-               svcfd_create.3 svcraw_create.3 svctcp_create.3 \
-               svcudp_bufcreate.3 xdr_accepted_reply.3 xdr_authunix_parms.3 \
-               xdr_callhdr.3 xdr_callmsg.3 xdr_opaque_auth.3 xdr_pmap.3 \
-               xdr_pmaplist.3 xdr_rejected_reply.3 xdr_replymsg.3 \
-               xprt_register.3 xprt_unregister.3 ; do \
-               $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" \
-                       "$(DSTROOT)/usr/share/man/man3/$${LINK}" ; \
-       done
-       @for LINK in xdr_array.3 xdr_bool.3 xdr_bytes.3 xdr_char.3 \
-               xdr_destroy.3 xdr_double.3 xdr_enum.3 xdr_float.3 xdr_free.3 \
-               xdr_getpos.3 xdr_inline.3 xdr_int.3 xdr_long.3 \
-               xdrmem_create.3 xdr_opaque.3 xdr_pointer.3 xdrrec_create.3 \
-               xdrrec_endofrecord.3 xdrrec_eof.3 xdrrec_skiprecord.3 \
-               xdr_reference.3 xdr_setpos.3 xdr_short.3 xdrstdio_create.3 \
-               xdr_string.3 xdr_u_char.3 xdr_u_long.3 xdr_u_short.3 \
-               xdr_union.3 xdr_vector.3 xdr_void.3 xdr_wrapstring.3 ; do \
-               $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" \
-                       "$(DSTROOT)/usr/share/man/man3/$${LINK}" ; \
-       done
index e5d2da1bed72a092e51f883b0cfd7d0653f2c673..b00bc1911b3c904ebd69a560ec2f143e77b7fc02 100644 (file)
@@ -80,6 +80,9 @@ static struct callrpc_private {
 
 int
 callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
 
 int
 callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
+       int prognum;
+       int versnum;
+       int procnum;
        char *host;
        xdrproc_t inproc, outproc;
        char *in, *out;
        char *host;
        xdrproc_t inproc, outproc;
        char *in, *out;
@@ -121,10 +124,12 @@ callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
                server_addr.sin_family = AF_INET;
                server_addr.sin_port =  0;
 #ifdef __LP64__
                server_addr.sin_family = AF_INET;
                server_addr.sin_port =  0;
 #ifdef __LP64__
-               if ((crp->client = clntudp_create(&server_addr, (uint32_t)prognum, (uint32_t)versnum, timeout, &crp->socket)) == NULL)
+               if ((crp->client = clntudp_create(&server_addr, (uint32_t)prognum,
+                       (uint32_t)versnum, timeout, &crp->socket)) == NULL)
                        return ((int) rpc_createerr.cf_stat);
 #else
                        return ((int) rpc_createerr.cf_stat);
 #else
-               if ((crp->client = clntudp_create(&server_addr, (u_long)prognum, (u_long)versnum, timeout, &crp->socket)) == NULL)
+               if ((crp->client = clntudp_create(&server_addr, (u_long)prognum,
+                       (u_long)versnum, timeout, &crp->socket)) == NULL)
                        return ((int) rpc_createerr.cf_stat);
 #endif
                crp->valid = 1;
                        return ((int) rpc_createerr.cf_stat);
 #endif
                crp->valid = 1;
index 20934f6ca08d7285a161d98e256b140eb19610e2..4c1ebbb8e0022f2b6b570b6d9aada31e2a9fe42d 100644 (file)
@@ -93,7 +93,7 @@ extern int errno;
 extern int     bindresvport();
 extern bool_t  xdr_opaque_auth();
 
 extern int     bindresvport();
 extern bool_t  xdr_opaque_auth();
 
-__private_extern__ u_short pmap_getport_timeout(struct sockaddr_in *address, uint32_t program, uint32_t version, uint32_t protocol, struct timeval *timeout, struct timeval *totaltimeout);
+extern u_short pmap_getport_timeout(struct sockaddr_in *address, uint32_t program, uint32_t version, uint32_t protocol, struct timeval *timeout, struct timeval *totaltimeout);
 
 static int     readtcp();
 static int     writetcp();
 
 static int     readtcp();
 static int     writetcp();
index ea76ba1e8bcebea7a55c4bae3bc1e30a41dff043..e7a1e9f19036c2b654ad2323723cf4b8dced1285 100644 (file)
@@ -77,7 +77,7 @@ static char *rcsid = "$Id: clnt_udp.c,v 1.4 2002/03/15 22:07:49 majka Exp $";
 extern int     bindresvport();
 extern bool_t  xdr_opaque_auth();
 
 extern int     bindresvport();
 extern bool_t  xdr_opaque_auth();
 
-__private_extern__ u_short pmap_getport_timeout(struct sockaddr_in *address, uint32_t program, uint32_t version, uint32_t protocol, struct timeval *timeout, struct timeval *totaltimeout);
+extern u_short pmap_getport_timeout(struct sockaddr_in *address, uint32_t program, uint32_t version, uint32_t protocol, struct timeval *timeout, struct timeval *totaltimeout);
 
 extern int errno;
 
 
 extern int errno;
 
@@ -135,7 +135,7 @@ struct cu_data {
  * sendsz and recvsz are the maximum allowable packet sizes that can be
  * sent and received.
  */
  * sendsz and recvsz are the maximum allowable packet sizes that can be
  * sent and received.
  */
-__private_extern__ CLIENT *
+CLIENT *
 clntudp_bufcreate_timeout(struct sockaddr_in *raddr, uint32_t program, uint32_t version, int *sockp, uint32_t sendsz, uint32_t recvsz, struct timeval *retry_timeout, struct timeval *total_timeout)
 {
        CLIENT *cl;
 clntudp_bufcreate_timeout(struct sockaddr_in *raddr, uint32_t program, uint32_t version, int *sockp, uint32_t sendsz, uint32_t recvsz, struct timeval *retry_timeout, struct timeval *total_timeout)
 {
        CLIENT *cl;
index f7c51af2d159d7dab3f67b09bebf3d4f40ee9d9d..dadcfa41980c6010e9d8535105cbd11c472b57fe 100644 (file)
@@ -70,6 +70,9 @@ static char *rcsid = "$Id: getrpcport.c,v 1.3 2002/02/19 20:36:23 epeyton Exp $"
 int
 getrpcport(host, prognum, versnum, proto)
        char *host;
 int
 getrpcport(host, prognum, versnum, proto)
        char *host;
+       int prognum;
+       int versnum;
+       int proto;
 {
        struct sockaddr_in addr;
        struct hostent *hp;
 {
        struct sockaddr_in addr;
        struct hostent *hp;
index 9cb337b37a8f84b82fd9fcd37f29780dd626aa2c..5ddfd00a473601becb1b502774246044e32b823b 100644 (file)
@@ -76,7 +76,7 @@ static char *rcsid = "$Id: pmap_clnt.c,v 1.5 2004/12/19 22:45:44 zarzycki Exp $"
 
 #include "pmap_wakeup.h"
 
 
 #include "pmap_wakeup.h"
 
-__private_extern__ CLIENT *clntudp_bufcreate_timeout(struct sockaddr_in *raddr, uint32_t program, uint32_t version, int *sockp, uint32_t sendsz, uint32_t recvsz, struct timeval *timeout, struct timeval *totaltimeout);
+extern CLIENT *clntudp_bufcreate_timeout(struct sockaddr_in *raddr, uint32_t program, uint32_t version, int *sockp, uint32_t sendsz, uint32_t recvsz, struct timeval *timeout, struct timeval *totaltimeout);
 
 static struct timeval set_retry_timeout = { 5, 0 };
 static struct timeval set_total_timeout = { 60, 0 };
 
 static struct timeval set_retry_timeout = { 5, 0 };
 static struct timeval set_total_timeout = { 60, 0 };
index 318df959d7c08325ae129697c0ec59b78616616e..fd7e6e38cc3898e8c08cdfa4908a45d3217f3e00 100644 (file)
@@ -77,7 +77,7 @@ static struct timeval default_timeout = { 5, 0 };
  * Calls the pmap service remotely to do the lookup.
  * Returns 0 if no map exists.
  */
  * Calls the pmap service remotely to do the lookup.
  * Returns 0 if no map exists.
  */
-__private_extern__ u_short
+u_short
 pmap_getport_timeout(struct sockaddr_in *address, uint32_t program, uint32_t version, uint32_t protocol, struct timeval *timeout, struct timeval *totaltimeout)
 {
        u_short port;
 pmap_getport_timeout(struct sockaddr_in *address, uint32_t program, uint32_t version, uint32_t protocol, struct timeval *timeout, struct timeval *totaltimeout)
 {
        u_short port;
diff --git a/util.subproj/Makefile b/util.subproj/Makefile
deleted file mode 100644 (file)
index ee01d36..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-Project = util
-ProductType = staticlib
-Install_Dir = /scratch
-BuildDebug = YES
-BuildProfile = YES
-
-CFILES = hton.c putpwpasswd.c rcmd.c rcmdsh.c
-MANPAGES = rcmd.3 hosts.equiv.5
-
-Extra_CC_Flags = -Wall -fno-common -I. \
-       -I../dns.subproj -I../gen.subproj -I../lookup.subproj \
-       -D__DARWIN_NON_CANCELABLE=1 -DINET6=1
-
-include $(MAKEFILEPATH)/CoreOS/ReleaseControl/BSDCommon.make
-
-after_install:
-       @for LINK in iruserok.3 iruserok_sa.3 rcmd_af.3 rresvport.3 \
-               rresvport_af.3 ruserok.3 ; do \
-                       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rcmd.3" \
-                       "$(DSTROOT)/usr/share/man/man3/$${LINK}" ; \
-       done
-       $(LN) -f "$(DSTROOT)/usr/share/man/man5//hosts.equiv.5" \
-               "$(DSTROOT)/usr/share/man/man5/.rhosts.5"
diff --git a/xcodescripts/install_files.sh b/xcodescripts/install_files.sh
new file mode 100755 (executable)
index 0000000..4157e3f
--- /dev/null
@@ -0,0 +1,248 @@
+# exit immediately on failure
+set -e -x
+
+# check if we're building for the simulator
+if [ "${RC_ProjectName%_Sim}" != "${RC_ProjectName}" ] ; then
+       if [ -d ${DSTROOT}${SDKROOT}/usr/lib/system ] ; then
+               for lib in ${DSTROOT}${SDKROOT}/usr/lib/system/*.dylib ; do
+                       install_name_tool -id "${lib#${DSTROOT}${SDKROOT}}" "${lib}"
+               done
+       fi
+
+       DSTROOT="${DSTROOT}${SDKROOT}"
+fi
+
+function InstallHeaders() {
+       DESTDIR="$DSTROOT/$1"
+       shift
+       install -d -o "$INSTALL_OWNER" -g "$INSTALL_GROUP" -m 0755 "$DESTDIR"
+       install -o "$INSTALL_OWNER" -g "$INSTALL_GROUP" -m 0444 "$@" "$DESTDIR"
+}
+
+InstallHeaders /usr/include \
+       gen.subproj/ifaddrs.h \
+       lookup.subproj/aliasdb.h \
+       lookup.subproj/bootparams.h \
+       lookup.subproj/netdb.h \
+       lookup.subproj/printerdb.h \
+       membership.subproj/membership.h \
+       membership.subproj/ntsid.h
+
+# lookup.subproj is not installed for the simulator, but its API is provided
+# by Interposition_Sim.  To be cautious, we only want to provide headers for
+# the SPI *used* by other simulator projects.  We should work to keep this
+# SPI as backwards-compatible as possible and use Interposition_Sim to
+# translate where that cannot be achieved.
+if [ "${RC_ProjectName%_Sim}" == "${RC_ProjectName}" ] ; then
+       InstallHeaders /usr/local/include \
+               lookup.subproj/ils.h \
+               lookup.subproj/kvbuf.h \
+               lookup.subproj/libinfo.h \
+               lookup.subproj/si_data.h \
+               lookup.subproj/si_module.h \
+               lookup.subproj/thread_data.h
+fi
+
+InstallHeaders /usr/local/include \
+       lookup.subproj/netdb_async.h \
+       membership.subproj/membershipPriv.h
+
+InstallHeaders /usr/include/arpa \
+       dns.subproj/inet.h
+
+InstallHeaders /usr/include/rpc \
+       rpc.subproj/auth.h \
+       rpc.subproj/auth_unix.h \
+       rpc.subproj/clnt.h \
+       rpc.subproj/pmap_clnt.h \
+       rpc.subproj/pmap_prot.h \
+       rpc.subproj/pmap_rmt.h \
+       rpc.subproj/rpc.h \
+       rpc.subproj/rpc_msg.h \
+       rpc.subproj/svc.h \
+       rpc.subproj/svc_auth.h \
+       rpc.subproj/types.h \
+       rpc.subproj/xdr.h
+
+InstallHeaders /usr/include/rpcsvc \
+       nis.subproj/yp_prot.h \
+       nis.subproj/ypclnt.h
+
+# Don't install man pages for installhdrs nor simulator builds
+if [ "$ACTION" == "installhdrs" -o \
+     "${RC_ProjectName%_Sim}" != "${RC_ProjectName}" ] ; then
+       exit 0
+fi
+
+function InstallManPages() {
+       for MANPAGE in "$@"; do
+               SECTION=`basename "${MANPAGE/*./}"`
+               MANDIR="$DSTROOT"/usr/share/man/man"$SECTION"
+               install -d -o "$INSTALL_OWNER" -g "$INSTALL_GROUP" -m 0755 "$MANDIR"
+               install -o "$INSTALL_OWNER" -g "$INSTALL_GROUP" -m 0444 "$MANPAGE" "$MANDIR"
+       done
+}
+
+function LinkManPages() {
+       MANPAGE=`basename "$1"`
+       SECTION=`basename "${MANPAGE/*./}"`
+       MANDIR="$DSTROOT"/usr/share/man/man"$SECTION"
+       shift
+       for LINK in "$@"; do
+               ln -hf "$MANDIR/$MANPAGE" "$MANDIR/$LINK"
+       done
+}
+
+InstallManPages \
+       gen.subproj/getifaddrs.3 \
+       gen.subproj/getifmaddrs.3 \
+       gen.subproj/gethostbyname.3 \
+       gen.subproj/getipnodebyname.3 \
+       gen.subproj/getnetent.3 \
+       gen.subproj/getprotoent.3 \
+       gen.subproj/getservent.3 \
+       gen.subproj/if_indextoname.3 \
+       gen.subproj/inet6_rth_space.3 \
+       gen.subproj/inet6_rthdr_space.3 \
+       gen.subproj/inet6_option_space.3 \
+       gen.subproj/inet6_opt_init.3
+
+InstallManPages \
+       lookup.subproj/bootparams.5 \
+       lookup.subproj/gai_strerror.3 \
+       lookup.subproj/getaddrinfo.3 \
+       lookup.subproj/getfsent.3 \
+       lookup.subproj/getgrent.3 \
+       lookup.subproj/getgrouplist.3 \
+       lookup.subproj/getnameinfo.3 \
+       lookup.subproj/getnetgrent.3 \
+       lookup.subproj/getpwent.3 \
+       lookup.subproj/initgroups.3
+
+InstallManPages \
+       membership.subproj/mbr_check_membership.3 \
+       membership.subproj/mbr_uid_to_uuid.3
+
+InstallManPages \
+       nis.subproj/yp_all.3 \
+       nis.subproj/yp_bind.3 \
+       nis.subproj/yp_first.3 \
+       nis.subproj/yp_get_default_domain.3 \
+       nis.subproj/yp_master.3 \
+       nis.subproj/yp_match.3 \
+       nis.subproj/yp_next.3 \
+       nis.subproj/yp_order.3 \
+       nis.subproj/yp_unbind.3 \
+       nis.subproj/ypclnt.3 \
+       nis.subproj/yperr_string.3 \
+       nis.subproj/ypprot_err.3 \
+       nis.subproj/yp.8
+
+InstallManPages \
+       rpc.subproj/bindresvport.3 \
+       rpc.subproj/getrpcent.3 \
+       rpc.subproj/getrpcport.3 \
+       rpc.subproj/rpc.3 \
+       rpc.subproj/xdr.3
+
+InstallManPages \
+       util.subproj/rcmd.3 \
+       util.subproj/hosts.equiv.5
+
+LinkManPages gethostbyname.3 \
+       endhostent.3 gethostbyaddr.3 gethostbyname2.3 \
+       gethostent.3 herror.3 hstrerror.3 sethostent.3
+
+LinkManPages getifaddrs.3 \
+       freeifaddrs.3
+
+LinkManPages getipnodebyname.3 \
+       freehostent.3 getipnodebyaddr.3
+
+LinkManPages getnetent.3 \
+       endnetent.3 getnetbyaddr.3 getnetbyname.3 setnetent.3
+
+LinkManPages getprotoent.3 \
+       endprotoent.3 getprotobyname.3 getprotobynumber.3 setprotoent.3
+
+LinkManPages getservent.3 \
+       endservent.3 getservbyname.3 getservbyport.3 setservent.3
+
+LinkManPages if_indextoname.3 \
+       if_freenameindex.3 if_nameindex.3 if_nametoindex.3
+
+LinkManPages inet6_option_space.3 \
+       inet6_option_alloc.3 inet6_option_append.3 \
+       inet6_option_find.3 inet6_option_init.3 inet6_option_next.3
+
+LinkManPages inet6_rthdr_space.3 \
+       inet6_rthdr_add.3 inet6_rthdr_getaddr.3 \
+       inet6_rthdr_getflags.3 inet6_rthdr_init.3 \
+       inet6_rthdr_lasthop.3 inet6_rthdr_reverse.3 \
+       inet6_rthdr_segments.3
+
+LinkManPages inet6_opt_init.3 \
+       inet6_opt_append.3 inet6_opt_finish.3 inet6_opt_set_val.3 \
+       inet6_opt_next.3 inet6_opt_find.3 inet6_opt_get_val.3
+
+LinkManPages getaddrinfo.3 \
+       freeaddrinfo.3
+
+LinkManPages getfsent.3 \
+       endfsent.3 getfsfile.3 getfsspec.3 getfstype.3 setfsent.3
+
+LinkManPages getgrent.3 \
+       endgrent.3 getgrgid.3 getgrgid_r.3 getgrnam.3 \
+       getgrnam_r.3 setgrent.3 setgroupent.3
+
+LinkManPages getnetgrent.3 \
+       endnetgrent.3 innetgr.3 setnetgrent.3
+
+LinkManPages getpwent.3 \
+       endpwent.3 getpwnam.3 getpwnam_r.3 getpwuid.3 \
+       getpwuid_r.3 setpassent.3 setpwent.3 setpwfile.3
+
+LinkManPages mbr_uid_to_uuid.3 \
+       mbr_gid_to_uuid.3 mbr_sid_to_uuid.3 mbr_uuid_to_id.3 mbr_uuid_to_sid.3 \
+       mbr_sid_to_string.3 mbr_string_to_sid.3
+
+LinkManPages getrpcent.3 \
+       getrpcbyname.3 getrpcbynumber.3 endrpcent.3 setrpcent.3
+
+LinkManPages rpc.3 \
+       auth_destroy.3 authnone_create.3 authunix_create.3 \
+       authunix_create_default.3 callrpc.3 clnt_broadcast.3 \
+       clnt_call.3 clnt_control.3 clnt_create.3 clnt_destroy.3 \
+       clnt_freeres.3 clnt_geterr.3 clnt_pcreateerror.3 \
+       clnt_perrno.3 clnt_perror.3 clnt_spcreateerror.3 \
+       clnt_sperrno.3 clnt_sperror.3 clntraw_create.3 \
+       clnttcp_create.3 clntudp_bufcreate.3 clntudp_create.3 \
+       get_myaddress.3 pmap_getmaps.3 pmap_getport.3 pmap_rmtcall.3 \
+       pmap_set.3 pmap_unset.3 regsterrpc.3 rpc_createerr.3 \
+       svc_destroy.3 svc_fds.3 svc_fdset.3 svc_getargs.3 \
+       svc_getcaller.3 svc_getreg.3 svc_getregset.3 svc_register.3 \
+       svc_run.3 svc_sendreply.3 svc_unregister.3 svcerr_auth.3 \
+       svcerr_decode.3 svcerr_noproc.3 svcerr_noprog.3 \
+       svcerr_progvers.3 svcerr_systemerr.3 svcerr_weakauth.3 \
+       svcfd_create.3 svcraw_create.3 svctcp_create.3 \
+       svcudp_bufcreate.3 xdr_accepted_reply.3 xdr_authunix_parms.3 \
+       xdr_callhdr.3 xdr_callmsg.3 xdr_opaque_auth.3 xdr_pmap.3 \
+       xdr_pmaplist.3 xdr_rejected_reply.3 xdr_replymsg.3 \
+       xprt_register.3 xprt_unregister.3
+
+LinkManPages xdr.3 \
+       xdr_array.3 xdr_bool.3 xdr_bytes.3 xdr_char.3 \
+       xdr_destroy.3 xdr_double.3 xdr_enum.3 xdr_float.3 xdr_free.3 \
+       xdr_getpos.3 xdr_inline.3 xdr_int.3 xdr_long.3 \
+       xdrmem_create.3 xdr_opaque.3 xdr_pointer.3 xdrrec_create.3 \
+       xdrrec_endofrecord.3 xdrrec_eof.3 xdrrec_skiprecord.3 \
+       xdr_reference.3 xdr_setpos.3 xdr_short.3 xdrstdio_create.3 \
+       xdr_string.3 xdr_u_char.3 xdr_u_long.3 xdr_u_short.3 \
+       xdr_union.3 xdr_vector.3 xdr_void.3 xdr_wrapstring.3
+
+LinkManPages rcmd.3 \
+       iruserok.3 iruserok_sa.3 rcmd_af.3 rresvport.3 rresvport_af.3 ruserok.3
+
+LinkManPages hosts.equiv.5 \
+       .rhosts.5
+