From 03fb6eb005e0e1ca66f0422cb7821f0a2ad2d381 Mon Sep 17 00:00:00 2001 From: Apple Date: Wed, 11 Apr 2001 00:34:00 +0000 Subject: [PATCH 1/1] Libinfo-78.tar.gz --- Makefile | 56 + Makefile.postamble | 4 + Makefile.preamble | 4 + PB.project | 39 + dns.subproj/Makefile | 55 + dns.subproj/Makefile.postamble | 7 + dns.subproj/Makefile.preamble | 24 + dns.subproj/PB.project | 41 + dns.subproj/gethnamaddr.c | 810 +++++++++++++ dns.subproj/getnetbyaddr.c | 80 ++ dns.subproj/getnetbyname.c | 87 ++ dns.subproj/getnetent.c | 187 +++ dns.subproj/getnetnamadr.c | 328 +++++ dns.subproj/herror.c | 145 +++ dns.subproj/inet.h | 111 ++ dns.subproj/nameser.h | 368 ++++++ dns.subproj/options.h | 189 +++ dns.subproj/portability.h | 570 +++++++++ dns.subproj/res_comp.c | 452 +++++++ dns.subproj/res_data.c | 46 + dns.subproj/res_debug.c | 857 +++++++++++++ dns.subproj/res_init.c | 675 +++++++++++ dns.subproj/res_mkquery.c | 272 +++++ dns.subproj/res_query.c | 417 +++++++ dns.subproj/res_send.c | 784 ++++++++++++ dns.subproj/resolv.h | 263 ++++ dns.subproj/sethostent.c | 85 ++ gen.subproj/Makefile | 47 + gen.subproj/Makefile.preamble | 31 + gen.subproj/PB.project | 37 + gen.subproj/aliasdb.c | 54 + gen.subproj/ether_addr.c | 188 +++ gen.subproj/fstab.c | 330 +++++ gen.subproj/getaddrinfo.c | 1608 +++++++++++++++++++++++++ gen.subproj/getgrent.c | 204 ++++ gen.subproj/getproto.c | 78 ++ gen.subproj/getprotoent.c | 142 +++ gen.subproj/getprotoname.c | 85 ++ gen.subproj/getpwent.c | 370 ++++++ gen.subproj/getservbyname.c | 88 ++ gen.subproj/getservbyport.c | 83 ++ gen.subproj/getservent.c | 144 +++ gen.subproj/initgroups.c | 81 ++ gen.subproj/printerdb.c | 286 +++++ lookup.subproj/Makefile | 54 + lookup.subproj/Makefile.postamble | 8 + lookup.subproj/Makefile.preamble | 8 + lookup.subproj/PB.project | 48 + lookup.subproj/_lu_types.x | 247 ++++ lookup.subproj/aliasdb.h | 48 + lookup.subproj/bootparams.h | 52 + lookup.subproj/lookup.defs | 71 ++ lookup.subproj/lookup_types.h | 47 + lookup.subproj/lu_alias.c | 249 ++++ lookup.subproj/lu_bootp.c | 145 +++ lookup.subproj/lu_bootparam.c | 246 ++++ lookup.subproj/lu_fstab.c | 296 +++++ lookup.subproj/lu_group.c | 396 ++++++ lookup.subproj/lu_host.c | 378 ++++++ lookup.subproj/lu_netgroup.c | 257 ++++ lookup.subproj/lu_network.c | 334 ++++++ lookup.subproj/lu_overrides.h | 106 ++ lookup.subproj/lu_printer.c | 268 +++++ lookup.subproj/lu_protocol.c | 299 +++++ lookup.subproj/lu_rpc.c | 301 +++++ lookup.subproj/lu_service.c | 323 +++++ lookup.subproj/lu_user.c | 380 ++++++ lookup.subproj/lu_utils.c | 332 ++++++ lookup.subproj/lu_utils.h | 130 ++ lookup.subproj/netgr.h | 47 + lookup.subproj/printerdb.h | 54 + netinfo.subproj/Makefile | 51 + netinfo.subproj/Makefile.postamble | 5 + netinfo.subproj/Makefile.preamble | 6 + netinfo.subproj/PB.project | 23 + netinfo.subproj/clib.h | 34 + netinfo.subproj/mm.h | 57 + netinfo.subproj/multi_call.c | 352 ++++++ netinfo.subproj/ni.h | 124 ++ netinfo.subproj/ni_error.c | 77 ++ netinfo.subproj/ni_glue.c | 2251 +++++++++++++++++++++++++++++++++++ netinfo.subproj/ni_prot.x | 502 ++++++++ netinfo.subproj/ni_pwdomain.c | 345 ++++++ netinfo.subproj/ni_useful.c | 745 ++++++++++++ netinfo.subproj/ni_util.c | 527 ++++++++ netinfo.subproj/ni_util.h | 98 ++ netinfo.subproj/nibind_prot.x | 116 ++ nis.subproj/Makefile | 58 + nis.subproj/Makefile.preamble | 1 + nis.subproj/PB.project | 58 + nis.subproj/getdomainname.c | 39 + nis.subproj/getnetgrent.c | 236 ++++ nis.subproj/innetgr.c | 337 ++++++ nis.subproj/setdomainname.c | 39 + nis.subproj/xdr_domainname.c | 77 ++ nis.subproj/xdr_keydat.c | 78 ++ nis.subproj/xdr_mapname.c | 77 ++ nis.subproj/xdr_peername.c | 77 ++ nis.subproj/xdr_valdat.c | 78 ++ nis.subproj/xdr_ypbind_binding.c | 80 ++ nis.subproj/xdr_ypbind_resp.c | 91 ++ nis.subproj/xdr_ypbind_resptype.c | 77 ++ nis.subproj/xdr_ypbind_setdom.c | 83 ++ nis.subproj/xdr_ypmaplist.c | 81 ++ nis.subproj/xdr_ypreq_key.c | 83 ++ nis.subproj/xdr_ypreq_nokey.c | 80 ++ nis.subproj/xdr_ypresp_all.c | 88 ++ nis.subproj/xdr_ypresp_key_val.c | 83 ++ nis.subproj/xdr_ypresp_maplist.c | 81 ++ nis.subproj/xdr_ypresp_master.c | 80 ++ nis.subproj/xdr_ypresp_order.c | 80 ++ nis.subproj/xdr_ypresp_val.c | 80 ++ nis.subproj/xdr_ypstat.c | 77 ++ nis.subproj/yp_all.c | 193 +++ nis.subproj/yp_bind.c | 315 +++++ nis.subproj/yp_first.c | 136 +++ nis.subproj/yp_get_default_domain.c | 87 ++ nis.subproj/yp_maplist.c | 106 ++ nis.subproj/yp_master.c | 119 ++ nis.subproj/yp_order.c | 125 ++ nis.subproj/yp_prot.h | 365 ++++++ nis.subproj/ypclnt.h | 111 ++ nis.subproj/yperr_string.c | 118 ++ nis.subproj/ypinternal.h | 100 ++ nis.subproj/ypmatch_cache.c | 324 +++++ nis.subproj/yppasswdd_xdr.c | 105 ++ nis.subproj/ypprot_err.c | 103 ++ rpc.subproj/Makefile | 60 + rpc.subproj/Makefile.preamble | 8 + rpc.subproj/PB.project | 88 ++ rpc.subproj/auth.h | 201 ++++ rpc.subproj/auth_none.c | 158 +++ rpc.subproj/auth_unix.c | 364 ++++++ rpc.subproj/auth_unix.h | 102 ++ rpc.subproj/authunix_prot.c | 92 ++ rpc.subproj/bindresvport.c | 107 ++ rpc.subproj/clnt.h | 387 ++++++ rpc.subproj/clnt_generic.c | 131 ++ rpc.subproj/clnt_perror.c | 326 +++++ rpc.subproj/clnt_raw.c | 263 ++++ rpc.subproj/clnt_simple.c | 139 +++ rpc.subproj/clnt_tcp.c | 482 ++++++++ rpc.subproj/clnt_udp.c | 458 +++++++ rpc.subproj/get_myaddress.c | 139 +++ rpc.subproj/getrpcent.c | 231 ++++ rpc.subproj/getrpcport.c | 81 ++ rpc.subproj/pmap_clnt.c | 152 +++ rpc.subproj/pmap_clnt.h | 107 ++ rpc.subproj/pmap_getmaps.c | 109 ++ rpc.subproj/pmap_getport.c | 112 ++ rpc.subproj/pmap_prot.c | 82 ++ rpc.subproj/pmap_prot.h | 127 ++ rpc.subproj/pmap_prot2.c | 141 +++ rpc.subproj/pmap_rmt.c | 411 +++++++ rpc.subproj/pmap_rmt.h | 86 ++ rpc.subproj/rpc.h | 93 ++ rpc.subproj/rpc_callmsg.c | 215 ++++ rpc.subproj/rpc_commondata.c | 73 ++ rpc.subproj/rpc_dtablesize.c | 78 ++ rpc.subproj/rpc_msg.h | 218 ++++ rpc.subproj/rpc_prot.c | 316 +++++ rpc.subproj/svc.c | 475 ++++++++ rpc.subproj/svc.h | 325 +++++ rpc.subproj/svc_auth.c | 140 +++ rpc.subproj/svc_auth.h | 73 ++ rpc.subproj/svc_auth_unix.c | 160 +++ rpc.subproj/svc_raw.c | 191 +++ rpc.subproj/svc_run.c | 90 ++ rpc.subproj/svc_simple.c | 168 +++ rpc.subproj/svc_tcp.c | 435 +++++++ rpc.subproj/svc_udp.c | 503 ++++++++ rpc.subproj/types.h | 85 ++ rpc.subproj/xdr.c | 605 ++++++++++ rpc.subproj/xdr.h | 318 +++++ rpc.subproj/xdr_array.c | 178 +++ rpc.subproj/xdr_float.c | 306 +++++ rpc.subproj/xdr_mem.c | 213 ++++ rpc.subproj/xdr_rec.c | 607 ++++++++++ rpc.subproj/xdr_reference.c | 157 +++ rpc.subproj/xdr_stdio.c | 214 ++++ util.subproj/Makefile | 46 + util.subproj/PB.project | 21 + util.subproj/getgrouplist.c | 112 ++ util.subproj/glob.c | 845 +++++++++++++ util.subproj/hton.c | 52 + util.subproj/putpwpasswd.c | 137 +++ util.subproj/pwcache.c | 111 ++ util.subproj/rcmd.c | 637 ++++++++++ util.subproj/rcmdsh.c | 146 +++ 189 files changed, 39342 insertions(+) create mode 100644 Makefile create mode 100644 Makefile.postamble create mode 100644 Makefile.preamble create mode 100644 PB.project create mode 100644 dns.subproj/Makefile create mode 100644 dns.subproj/Makefile.postamble create mode 100644 dns.subproj/Makefile.preamble create mode 100644 dns.subproj/PB.project create mode 100644 dns.subproj/gethnamaddr.c create mode 100644 dns.subproj/getnetbyaddr.c create mode 100644 dns.subproj/getnetbyname.c create mode 100644 dns.subproj/getnetent.c create mode 100644 dns.subproj/getnetnamadr.c create mode 100644 dns.subproj/herror.c create mode 100644 dns.subproj/inet.h create mode 100644 dns.subproj/nameser.h create mode 100644 dns.subproj/options.h create mode 100644 dns.subproj/portability.h create mode 100644 dns.subproj/res_comp.c create mode 100644 dns.subproj/res_data.c create mode 100644 dns.subproj/res_debug.c create mode 100644 dns.subproj/res_init.c create mode 100644 dns.subproj/res_mkquery.c create mode 100644 dns.subproj/res_query.c create mode 100644 dns.subproj/res_send.c create mode 100644 dns.subproj/resolv.h create mode 100644 dns.subproj/sethostent.c create mode 100644 gen.subproj/Makefile create mode 100644 gen.subproj/Makefile.preamble create mode 100644 gen.subproj/PB.project create mode 100644 gen.subproj/aliasdb.c create mode 100644 gen.subproj/ether_addr.c create mode 100644 gen.subproj/fstab.c create mode 100644 gen.subproj/getaddrinfo.c create mode 100644 gen.subproj/getgrent.c create mode 100644 gen.subproj/getproto.c create mode 100644 gen.subproj/getprotoent.c create mode 100644 gen.subproj/getprotoname.c create mode 100644 gen.subproj/getpwent.c create mode 100644 gen.subproj/getservbyname.c create mode 100644 gen.subproj/getservbyport.c create mode 100644 gen.subproj/getservent.c create mode 100644 gen.subproj/initgroups.c create mode 100644 gen.subproj/printerdb.c create mode 100644 lookup.subproj/Makefile create mode 100644 lookup.subproj/Makefile.postamble create mode 100644 lookup.subproj/Makefile.preamble create mode 100644 lookup.subproj/PB.project create mode 100644 lookup.subproj/_lu_types.x create mode 100644 lookup.subproj/aliasdb.h create mode 100644 lookup.subproj/bootparams.h create mode 100644 lookup.subproj/lookup.defs create mode 100644 lookup.subproj/lookup_types.h create mode 100644 lookup.subproj/lu_alias.c create mode 100644 lookup.subproj/lu_bootp.c create mode 100644 lookup.subproj/lu_bootparam.c create mode 100644 lookup.subproj/lu_fstab.c create mode 100644 lookup.subproj/lu_group.c create mode 100644 lookup.subproj/lu_host.c create mode 100644 lookup.subproj/lu_netgroup.c create mode 100644 lookup.subproj/lu_network.c create mode 100644 lookup.subproj/lu_overrides.h create mode 100644 lookup.subproj/lu_printer.c create mode 100644 lookup.subproj/lu_protocol.c create mode 100644 lookup.subproj/lu_rpc.c create mode 100644 lookup.subproj/lu_service.c create mode 100644 lookup.subproj/lu_user.c create mode 100644 lookup.subproj/lu_utils.c create mode 100644 lookup.subproj/lu_utils.h create mode 100644 lookup.subproj/netgr.h create mode 100644 lookup.subproj/printerdb.h create mode 100644 netinfo.subproj/Makefile create mode 100644 netinfo.subproj/Makefile.postamble create mode 100644 netinfo.subproj/Makefile.preamble create mode 100644 netinfo.subproj/PB.project create mode 100644 netinfo.subproj/clib.h create mode 100644 netinfo.subproj/mm.h create mode 100644 netinfo.subproj/multi_call.c create mode 100644 netinfo.subproj/ni.h create mode 100644 netinfo.subproj/ni_error.c create mode 100644 netinfo.subproj/ni_glue.c create mode 100644 netinfo.subproj/ni_prot.x create mode 100644 netinfo.subproj/ni_pwdomain.c create mode 100644 netinfo.subproj/ni_useful.c create mode 100644 netinfo.subproj/ni_util.c create mode 100644 netinfo.subproj/ni_util.h create mode 100644 netinfo.subproj/nibind_prot.x create mode 100644 nis.subproj/Makefile create mode 100644 nis.subproj/Makefile.preamble create mode 100644 nis.subproj/PB.project create mode 100644 nis.subproj/getdomainname.c create mode 100644 nis.subproj/getnetgrent.c create mode 100644 nis.subproj/innetgr.c create mode 100644 nis.subproj/setdomainname.c create mode 100644 nis.subproj/xdr_domainname.c create mode 100644 nis.subproj/xdr_keydat.c create mode 100644 nis.subproj/xdr_mapname.c create mode 100644 nis.subproj/xdr_peername.c create mode 100644 nis.subproj/xdr_valdat.c create mode 100644 nis.subproj/xdr_ypbind_binding.c create mode 100644 nis.subproj/xdr_ypbind_resp.c create mode 100644 nis.subproj/xdr_ypbind_resptype.c create mode 100644 nis.subproj/xdr_ypbind_setdom.c create mode 100644 nis.subproj/xdr_ypmaplist.c create mode 100644 nis.subproj/xdr_ypreq_key.c create mode 100644 nis.subproj/xdr_ypreq_nokey.c create mode 100644 nis.subproj/xdr_ypresp_all.c create mode 100644 nis.subproj/xdr_ypresp_key_val.c create mode 100644 nis.subproj/xdr_ypresp_maplist.c create mode 100644 nis.subproj/xdr_ypresp_master.c create mode 100644 nis.subproj/xdr_ypresp_order.c create mode 100644 nis.subproj/xdr_ypresp_val.c create mode 100644 nis.subproj/xdr_ypstat.c create mode 100644 nis.subproj/yp_all.c create mode 100644 nis.subproj/yp_bind.c create mode 100644 nis.subproj/yp_first.c create mode 100644 nis.subproj/yp_get_default_domain.c create mode 100644 nis.subproj/yp_maplist.c create mode 100644 nis.subproj/yp_master.c create mode 100644 nis.subproj/yp_order.c create mode 100644 nis.subproj/yp_prot.h create mode 100644 nis.subproj/ypclnt.h create mode 100644 nis.subproj/yperr_string.c create mode 100644 nis.subproj/ypinternal.h create mode 100644 nis.subproj/ypmatch_cache.c create mode 100644 nis.subproj/yppasswdd_xdr.c create mode 100644 nis.subproj/ypprot_err.c create mode 100644 rpc.subproj/Makefile create mode 100644 rpc.subproj/Makefile.preamble create mode 100644 rpc.subproj/PB.project create mode 100644 rpc.subproj/auth.h create mode 100644 rpc.subproj/auth_none.c create mode 100644 rpc.subproj/auth_unix.c create mode 100644 rpc.subproj/auth_unix.h create mode 100644 rpc.subproj/authunix_prot.c create mode 100644 rpc.subproj/bindresvport.c create mode 100644 rpc.subproj/clnt.h create mode 100644 rpc.subproj/clnt_generic.c create mode 100644 rpc.subproj/clnt_perror.c create mode 100644 rpc.subproj/clnt_raw.c create mode 100644 rpc.subproj/clnt_simple.c create mode 100644 rpc.subproj/clnt_tcp.c create mode 100644 rpc.subproj/clnt_udp.c create mode 100644 rpc.subproj/get_myaddress.c create mode 100644 rpc.subproj/getrpcent.c create mode 100644 rpc.subproj/getrpcport.c create mode 100644 rpc.subproj/pmap_clnt.c create mode 100644 rpc.subproj/pmap_clnt.h create mode 100644 rpc.subproj/pmap_getmaps.c create mode 100644 rpc.subproj/pmap_getport.c create mode 100644 rpc.subproj/pmap_prot.c create mode 100644 rpc.subproj/pmap_prot.h create mode 100644 rpc.subproj/pmap_prot2.c create mode 100644 rpc.subproj/pmap_rmt.c create mode 100644 rpc.subproj/pmap_rmt.h create mode 100644 rpc.subproj/rpc.h create mode 100644 rpc.subproj/rpc_callmsg.c create mode 100644 rpc.subproj/rpc_commondata.c create mode 100644 rpc.subproj/rpc_dtablesize.c create mode 100644 rpc.subproj/rpc_msg.h create mode 100644 rpc.subproj/rpc_prot.c create mode 100644 rpc.subproj/svc.c create mode 100644 rpc.subproj/svc.h create mode 100644 rpc.subproj/svc_auth.c create mode 100644 rpc.subproj/svc_auth.h create mode 100644 rpc.subproj/svc_auth_unix.c create mode 100644 rpc.subproj/svc_raw.c create mode 100644 rpc.subproj/svc_run.c create mode 100644 rpc.subproj/svc_simple.c create mode 100644 rpc.subproj/svc_tcp.c create mode 100644 rpc.subproj/svc_udp.c create mode 100644 rpc.subproj/types.h create mode 100644 rpc.subproj/xdr.c create mode 100644 rpc.subproj/xdr.h create mode 100644 rpc.subproj/xdr_array.c create mode 100644 rpc.subproj/xdr_float.c create mode 100644 rpc.subproj/xdr_mem.c create mode 100644 rpc.subproj/xdr_rec.c create mode 100644 rpc.subproj/xdr_reference.c create mode 100644 rpc.subproj/xdr_stdio.c create mode 100644 util.subproj/Makefile create mode 100644 util.subproj/PB.project create mode 100644 util.subproj/getgrouplist.c create mode 100644 util.subproj/glob.c create mode 100644 util.subproj/hton.c create mode 100644 util.subproj/putpwpasswd.c create mode 100644 util.subproj/pwcache.c create mode 100644 util.subproj/rcmd.c create mode 100644 util.subproj/rcmdsh.c diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5784600 --- /dev/null +++ b/Makefile @@ -0,0 +1,56 @@ +# +# Generated by the NeXT Project Builder. +# +# NOTE: Do NOT change this file -- Project Builder maintains it. +# +# Put all of your customizations in files called Makefile.preamble +# and Makefile.postamble (both optional), and Makefile will include them. +# + +NAME = info + +PROJECTVERSION = 2.8 +PROJECT_TYPE = Library + +SUBPROJECTS = dns.subproj gen.subproj lookup.subproj netinfo.subproj\ + nis.subproj rpc.subproj util.subproj + +OTHERSRCS = Makefile.preamble Makefile Makefile.postamble + +MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles +CURRENTLY_ACTIVE_VERSION = YES +DEPLOY_WITH_VERSION_NAME = A +CODE_GEN_STYLE = DYNAMIC +MAKEFILE = library.make +NEXTSTEP_INSTALLDIR = /usr/local/lib/system +WINDOWS_INSTALLDIR = /Developer/Libraries +PDO_UNIX_INSTALLDIR = /lib +LIBS = +DEBUG_LIBS = $(LIBS) +PROF_LIBS = $(LIBS) + + + + +NEXTSTEP_PUBLIC_HEADERS_DIR = /usr/include + +WINDOWS_PUBLIC_HEADERS_DIR = /Developer/Headers/$(NAME) + +PDO_UNIX_PUBLIC_HEADERS_DIR = /Developer/Headers/$(NAME) + +NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc +WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc +PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc +NEXTSTEP_JAVA_COMPILER = /usr/bin/javac +WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe +PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac + +include $(MAKEFILEDIR)/platform.make + +-include Makefile.preamble + +include $(MAKEFILEDIR)/$(MAKEFILE) + +-include Makefile.postamble + +-include Makefile.dependencies diff --git a/Makefile.postamble b/Makefile.postamble new file mode 100644 index 0000000..0e9365d --- /dev/null +++ b/Makefile.postamble @@ -0,0 +1,4 @@ +override DEBUG_SUFFIX = _debug +PRODUCTS += $(LIBRARY_PREFIX)$(NAME)$(DEBUG_SUFFIX)$(LIBRARY_EXT) +PRODUCTS += $(LIBRARY_PREFIX)$(NAME)$(PROFILE_SUFFIX)$(LIBRARY_EXT) +RECURSIVE_FLAGS += "LINK_SUBPROJECTS = NO" diff --git a/Makefile.preamble b/Makefile.preamble new file mode 100644 index 0000000..4e19fe6 --- /dev/null +++ b/Makefile.preamble @@ -0,0 +1,4 @@ +LIBRARY_STYLE = STATIC +STRIP_ON_INSTALL = NO +BEFORE_INSTALL += debug profile +override LINK_SUBPROJECTS = NO diff --git a/PB.project b/PB.project new file mode 100644 index 0000000..5ebc657 --- /dev/null +++ b/PB.project @@ -0,0 +1,39 @@ +{ + CURRENTLY_ACTIVE_VERSION = YES; + DEPLOY_WITH_VERSION_NAME = A; + DYNAMIC_CODE_GEN = YES; + FILESTABLE = { + FRAMEWORKS = (); + H_FILES = (); + OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble); + SUBPROJECTS = ( + dns.subproj, + gen.subproj, + lookup.subproj, + netinfo.subproj, + nis.subproj, + rpc.subproj, + util.subproj + ); + }; + LANGUAGE = English; + MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; + NEXTSTEP_BUILDTOOL = /bin/gnumake; + NEXTSTEP_INSTALLDIR = /usr/local/lib/system; + NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; + NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; + NEXTSTEP_PUBLICHEADERSDIR = /usr/include; + PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; + PDO_UNIX_INSTALLDIR = /lib; + PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; + PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; + PDO_UNIX_PUBLICHEADERSDIR = "/Developer/Headers/$(NAME)"; + PROJECTNAME = info; + PROJECTTYPE = Library; + PROJECTVERSION = 2.8; + WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; + WINDOWS_INSTALLDIR = /Developer/Libraries; + WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; + WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; + WINDOWS_PUBLICHEADERSDIR = "/Developer/Headers/$(NAME)"; +} diff --git a/dns.subproj/Makefile b/dns.subproj/Makefile new file mode 100644 index 0000000..7097677 --- /dev/null +++ b/dns.subproj/Makefile @@ -0,0 +1,55 @@ +# +# Generated by the NeXT Project Builder. +# +# NOTE: Do NOT change this file -- Project Builder maintains it. +# +# Put all of your customizations in files called Makefile.preamble +# and Makefile.postamble (both optional), and Makefile will include them. +# + +NAME = dns + +PROJECTVERSION = 2.8 +PROJECT_TYPE = Component + +HFILES = inet.h nameser.h options.h portability.h resolv.h + +CFILES = gethnamaddr.c getnetbyaddr.c getnetbyname.c getnetent.c\ + getnetnamadr.c herror.c res_comp.c res_data.c res_debug.c\ + res_init.c res_mkquery.c res_query.c res_send.c sethostent.c + +OTHERSRCS = Makefile.preamble Makefile Makefile.postamble + + +MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles +CODE_GEN_STYLE = DYNAMIC +MAKEFILE = subproj.make +NEXTSTEP_INSTALLDIR = /Local/Developer/System +LIBS = +DEBUG_LIBS = $(LIBS) +PROF_LIBS = $(LIBS) + + +NEXTSTEP_PB_CFLAGS = -DUSE_OPTIONS_H +PUBLIC_HEADERS = resolv.h nameser.h + + + +NEXTSTEP_PUBLIC_HEADERS_DIR = /usr/include + +NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc +WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc +PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc +NEXTSTEP_JAVA_COMPILER = /usr/bin/javac +WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe +PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac + +include $(MAKEFILEDIR)/platform.make + +-include Makefile.preamble + +include $(MAKEFILEDIR)/$(MAKEFILE) + +-include Makefile.postamble + +-include Makefile.dependencies diff --git a/dns.subproj/Makefile.postamble b/dns.subproj/Makefile.postamble new file mode 100644 index 0000000..e0bdfec --- /dev/null +++ b/dns.subproj/Makefile.postamble @@ -0,0 +1,7 @@ +arpa_headers: $(DSTROOT)$(PUBLIC_HDR_INSTALLDIR)$(ARPA_HEADER_DIR_SUFFIX) + $(RM) -f $(foreach header, $(ARPA_SYMLINKED_HEADERS), $(DSTROOT)$(PUBLIC_HDR_INSTALLDIR)$(ARPA_HEADER_DIR_SUFFIX)/$(header)) + $(LN) -s $(foreach header, $(ARPA_SYMLINKED_HEADERS), ../$(header)) $(DSTROOT)$(PUBLIC_HDR_INSTALLDIR)$(ARPA_HEADER_DIR_SUFFIX) + $(SILENT) $(FASTCP) $(ARPA_HEADERS) $(DSTROOT)$(PUBLIC_HDR_INSTALLDIR)$(ARPA_HEADER_DIR_SUFFIX) + +$(DSTROOT)$(PUBLIC_HDR_INSTALLDIR)$(ARPA_HEADER_DIR_SUFFIX): + $(MKDIRS) $@ diff --git a/dns.subproj/Makefile.preamble b/dns.subproj/Makefile.preamble new file mode 100644 index 0000000..89f0837 --- /dev/null +++ b/dns.subproj/Makefile.preamble @@ -0,0 +1,24 @@ +OTHER_CFLAGS = \ + -Dsethostent=_res_sethostent \ + -Dgethostent=_res_gethostent \ + -Dendhostent=_res_endhostent \ + -Dgethostbyname=_res_gethostbyname \ + -Dgethostbyaddr=_res_gethostbyaddr \ + -Dsetnetent=_old_setnetent \ + -Dgetnetent=_old_getnetent \ + -Dendnetent=_old_endnetent \ + -Dgetnetbyname=_res_getnetbyname \ + -Dgetnetbyaddr=_res_getnetbyaddr \ + -D_sethtent=_old_sethostent \ + -D_gethtent=_old_gethostent \ + -D_endhtent=_old_endhostent \ + -D_gethtbyname=_old_gethostbyname \ + -D_gethtbyaddr=_old_gethostbyaddr \ + -D_getnetbyname=_old_getnetbyname \ + -D_getnetbyaddr=_old_getnetbyaddr + +PUBLIC_HEADER_DIR_SUFFIX = +ARPA_HEADER_DIR_SUFFIX = /arpa +ARPA_HEADERS = inet.h +ARPA_SYMLINKED_HEADERS = nameser.h +AFTER_INSTALLHDRS += arpa_headers diff --git a/dns.subproj/PB.project b/dns.subproj/PB.project new file mode 100644 index 0000000..32107f8 --- /dev/null +++ b/dns.subproj/PB.project @@ -0,0 +1,41 @@ +{ + DYNAMIC_CODE_GEN = YES; + FILESTABLE = { + H_FILES = (inet.h, nameser.h, options.h, portability.h, resolv.h); + OTHER_LINKED = ( + gethnamaddr.c, + getnetbyaddr.c, + getnetbyname.c, + getnetent.c, + getnetnamadr.c, + herror.c, + res_comp.c, + res_data.c, + res_debug.c, + res_init.c, + res_mkquery.c, + res_query.c, + res_send.c, + sethostent.c + ); + OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble); + PUBLIC_HEADERS = (resolv.h, nameser.h); + }; + LANGUAGE = English; + MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; + NEXTSTEP_BUILDTOOL = /bin/gnumake; + NEXTSTEP_COMPILEROPTIONS = "-DUSE_OPTIONS_H"; + NEXTSTEP_INSTALLDIR = /Local/Developer/System; + NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; + NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; + NEXTSTEP_PUBLICHEADERSDIR = /usr/include; + PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; + PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; + PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; + PROJECTNAME = dns; + PROJECTTYPE = Component; + PROJECTVERSION = 2.8; + WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; + WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; + WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; +} diff --git a/dns.subproj/gethnamaddr.c b/dns.subproj/gethnamaddr.c new file mode 100644 index 0000000..1d6aba5 --- /dev/null +++ b/dns.subproj/gethnamaddr.c @@ -0,0 +1,810 @@ +/* + * 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++ 1985, 1988, 1993 + * - + * Copyright (c) 1985, 1988, 1993 + * 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-- + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$Id: gethnamaddr.c,v 1.2 1999/10/14 21:56:44 wsanchez Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifndef LOG_AUTH +# define LOG_AUTH 0 +#endif + +#define MULTI_PTRS_ARE_ALIASES 1 /* XXX - experimental */ + +#if defined(BSD) && (BSD >= 199103) +# include +#else +# include "portability.h" +#endif +#if defined(USE_OPTIONS_H) +# include "options.h" +#endif + +#define MAXALIASES 35 +#define MAXADDRS 35 + +static const char AskedForGot[] = + "gethostby*.getanswer: asked for \"%s\", got \"%s\""; + +static char *h_addr_ptrs[MAXADDRS + 1]; +static struct hostent *gethostbyname_ipv4 __P((const char *)); + +static struct hostent host; +static char *host_aliases[MAXALIASES]; +static char hostbuf[8*1024]; +static struct in_addr host_addr; +static FILE *hostf = NULL; +static int stayopen = 0; + +#ifdef RESOLVSORT +static void addrsort __P((char **, int)); +#endif + +#if PACKETSZ > 1024 +#define MAXPACKET PACKETSZ +#else +#define MAXPACKET 1024 +#endif + +typedef union { + HEADER hdr; + u_char buf[MAXPACKET]; +} querybuf; + +typedef union { + int32_t al; + char ac; +} align; + +extern int h_errno; + +#ifdef DEBUG +static void +dprintf(msg, num) + char *msg; + int num; +{ + if (_res.options & RES_DEBUG) { + int save = errno; + + printf(msg, num); + errno = save; + } +} +#else +# define dprintf(msg, num) /*nada*/ +#endif + +static struct hostent * +getanswer(answer, anslen, qname, qclass, qtype) + const querybuf *answer; + int anslen; + const char *qname; + int qclass, qtype; +{ + register const HEADER *hp; + register const u_char *cp; + register int n; + const u_char *eom; + char *bp, **ap, **hap; + int type, class, buflen, ancount, qdcount; + int haveanswer, had_error; + int toobig = 0; + char tbuf[MAXDNAME+1]; + const char *tname; + + tname = qname; + host.h_name = NULL; + eom = answer->buf + anslen; + /* + * find first satisfactory answer + */ + hp = &answer->hdr; + ancount = ntohs(hp->ancount); + qdcount = ntohs(hp->qdcount); + bp = hostbuf; + buflen = sizeof hostbuf; + cp = answer->buf + HFIXEDSZ; + if (qdcount != 1) { + h_errno = NO_RECOVERY; + return (NULL); + } + if ((n = dn_expand(answer->buf, eom, cp, bp, buflen)) < 0) { + h_errno = NO_RECOVERY; + return (NULL); + } + cp += n + QFIXEDSZ; + if (qtype == T_A) { + /* res_send() has already verified that the query name is the + * same as the one we sent; this just gets the expanded name + * (i.e., with the succeeding search-domain tacked on). + */ + n = strlen(bp) + 1; /* for the \0 */ + host.h_name = bp; + bp += n; + buflen -= n; + /* The qname can be abbreviated, but h_name is now absolute. */ + qname = host.h_name; + } + ap = host_aliases; + *ap = NULL; + host.h_aliases = host_aliases; + hap = h_addr_ptrs; + *hap = NULL; +#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */ + host.h_addr_list = h_addr_ptrs; +#endif + haveanswer = 0; + had_error = 0; + while (ancount-- > 0 && cp < eom && !had_error) { + n = dn_expand(answer->buf, eom, cp, bp, buflen); + if (n < 0) { + had_error++; + continue; + } + cp += n; /* name */ + type = _getshort(cp); + cp += INT16SZ; /* type */ + class = _getshort(cp); + cp += INT16SZ + INT32SZ; /* class, TTL */ + n = _getshort(cp); + cp += INT16SZ; /* len */ + if (class != qclass) { + /* XXX - debug? syslog? */ + cp += n; + continue; /* XXX - had_error++ ? */ + } + if (qtype == T_A && type == T_CNAME) { + if (ap >= &host_aliases[MAXALIASES-1]) + continue; + n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); + if (n < 0) { + had_error++; + continue; + } + cp += n; + if (host.h_name && strcasecmp(host.h_name, bp) != 0) { + syslog(LOG_NOTICE|LOG_AUTH, + "gethostby*.getanswer: asked for \"%s\", got CNAME for \"%s\"", + host.h_name, bp); + continue; /* XXX - had_error++ ? */ + } + /* Store alias. */ + *ap++ = bp; + n = strlen(bp) + 1; /* for the \0 */ + bp += n; + buflen -= n; + /* Get canonical name. */ + n = strlen(tbuf) + 1; /* for the \0 */ + if (n > buflen) { + had_error++; + continue; + } + strcpy(bp, tbuf); + host.h_name = bp; + bp += n; + buflen -= n; + continue; + } + if (qtype == T_PTR && type == T_CNAME) { + n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); + if (n < 0) { + had_error++; + continue; + } + cp += n; + /* Get canonical name. */ + n = strlen(tbuf) + 1; /* for the \0 */ + if (n > buflen) { + had_error++; + continue; + } + strcpy(bp, tbuf); + tname = bp; + bp += n; + buflen -= n; + continue; + } + if (type != qtype) { + syslog(LOG_NOTICE|LOG_AUTH, + "gethostby*.getanswer: asked for \"%s %s %s\", got type \"%s\"", + qname, p_class(qclass), p_type(qtype), + p_type(type)); + cp += n; + continue; /* XXX - had_error++ ? */ + } + switch (type) { + case T_PTR: + if (strcasecmp(tname, bp) != 0) { + syslog(LOG_NOTICE|LOG_AUTH, + AskedForGot, qname, bp); + cp += n; + continue; /* XXX - had_error++ ? */ + } + n = dn_expand(answer->buf, eom, cp, bp, buflen); + if (n < 0) { + had_error++; + break; + } +#if MULTI_PTRS_ARE_ALIASES + cp += n; + if (!haveanswer) + host.h_name = bp; + else if (ap < &host_aliases[MAXALIASES-1]) + *ap++ = bp; + else + n = -1; + if (n != -1) { + n = strlen(bp) + 1; /* for the \0 */ + bp += n; + buflen -= n; + } + break; +#else + host.h_name = bp; + h_errno = NETDB_SUCCESS; + return (&host); +#endif + case T_A: + if (strcasecmp(host.h_name, bp) != 0) { + syslog(LOG_NOTICE|LOG_AUTH, + AskedForGot, host.h_name, bp); + cp += n; + continue; /* XXX - had_error++ ? */ + } + if (haveanswer) { + if (n != host.h_length) { + cp += n; + continue; + } + } else { + register int nn; + + host.h_length = n; + host.h_addrtype = (class == C_IN) + ? AF_INET + : AF_UNSPEC; + host.h_name = bp; + nn = strlen(bp) + 1; /* for the \0 */ + bp += nn; + buflen -= nn; + } + + bp += sizeof(align) - ((u_long)bp % sizeof(align)); + + if (bp + n >= &hostbuf[sizeof hostbuf]) { + dprintf("size (%d) too big\n", n); + had_error++; + continue; + } + if (hap >= &h_addr_ptrs[MAXADDRS-1]) { + if (!toobig++) + dprintf("Too many addresses (%d)\n", + MAXADDRS); + cp += n; + continue; + } + bcopy(cp, *hap++ = bp, n); + bp += n; + cp += n; + break; + default: + dprintf("Impossible condition (type=%d)\n", type); + h_errno = NO_RECOVERY; + return (NULL); + } /*switch*/ + if (!had_error) + haveanswer++; + } /*while*/ + if (haveanswer) { + *ap = NULL; + *hap = NULL; +# if defined(RESOLVSORT) + /* + * Note: we sort even if host can take only one address + * in its return structures - should give it the "best" + * address in that case, not some random one + */ + if (_res.nsort && haveanswer > 1 && + qclass == C_IN && qtype == T_A) + addrsort(h_addr_ptrs, haveanswer); +# endif /*RESOLVSORT*/ +#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */ + /* nothing */ +#else + host.h_addr = h_addr_ptrs[0]; +#endif /*BSD*/ + if (!host.h_name) { + n = strlen(qname) + 1; /* for the \0 */ + strcpy(bp, qname); + host.h_name = bp; + } + h_errno = NETDB_SUCCESS; + return (&host); + } else { + h_errno = TRY_AGAIN; + return (NULL); + } +} + +struct hostent * +gethostbyname(name) + const char *name; +{ +#if defined(AF_INET6) && defined(RES_TRY_INET6) + struct hostent *hp; + + if (_res.options & RES_TRY_INET6) { + hp = gethostbyname2(name, AF_INET6); + if (hp) + return (hp); + } +#endif + return (gethostbyname2(name, AF_INET)); +} + +struct hostent * +gethostbyname2(name, af) + const char *name; + int af; +{ + switch (af) { + case AF_INET: + return (gethostbyname_ipv4(name)); + } + errno = EAFNOSUPPORT; + h_errno = NETDB_INTERNAL; + return (NULL); +} + +static struct hostent * +gethostbyname_ipv4(name) + const char *name; +{ + querybuf buf; + register const char *cp; + int n; +#if !defined(__APPLE__) + extern struct hostent *_gethtbyname(); +#endif /* !NeXT */ + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; + return (NULL); + } + + /* + * if there aren't any dots, it could be a user-level alias. + * this is also done in res_query() since we are not the only + * function that looks up host names. + */ + if (!strchr(name, '.') && (cp = __hostalias(name))) + name = cp; + + /* + * disallow names consisting only of digits/dots, unless + * they end in a dot. + */ + if (isdigit(name[0])) + for (cp = name;; ++cp) { + if (!*cp) { + if (*--cp == '.') + break; + /* + * All-numeric, no dot at the end. + * Fake up a hostent as if we'd actually + * done a lookup. + */ + if (!inet_aton(name, &host_addr)) { + h_errno = HOST_NOT_FOUND; + return (NULL); + } + strncpy(hostbuf, name, MAXDNAME); + hostbuf[MAXDNAME] = '\0'; + host.h_name = hostbuf; + host.h_aliases = host_aliases; + host_aliases[0] = NULL; + host.h_addrtype = AF_INET; + host.h_length = INT32SZ; + h_addr_ptrs[0] = (char *)&host_addr; + h_addr_ptrs[1] = NULL; +#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */ + host.h_addr_list = h_addr_ptrs; +#else + host.h_addr = h_addr_ptrs[0]; +#endif + h_errno = NETDB_SUCCESS; + return (&host); + } + if (!isdigit(*cp) && *cp != '.') + break; + } + + if ((n = res_search(name, C_IN, T_A, buf.buf, sizeof(buf))) < 0) { + dprintf("res_search failed (%d)\n", n); +#if !defined(__APPLE__) + if (errno == ECONNREFUSED) + return (_gethtbyname(name)); +#endif + return (NULL); + } + return (getanswer(&buf, n, name, C_IN, T_A)); +} + +struct hostent * +gethostbyaddr(addr, len, type) + const char *addr; + int len, type; +{ + int n; + querybuf buf; + register struct hostent *hp; + char qbuf[MAXDNAME+1]; +#ifdef SUNSECURITY + register struct hostent *rhp; + char **haddr; + u_long old_options; + char hname2[MAXDNAME+1]; +#endif /*SUNSECURITY*/ +#if !defined(__APPLE__) + extern struct hostent *_gethtbyaddr(); +#endif /* !NeXT */ + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; + return (NULL); + } + if (type != AF_INET) { + errno = EAFNOSUPPORT; + h_errno = NETDB_INTERNAL; + return (NULL); + } + (void)sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", + ((unsigned)addr[3] & 0xff), + ((unsigned)addr[2] & 0xff), + ((unsigned)addr[1] & 0xff), + ((unsigned)addr[0] & 0xff)); + n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf); + if (n < 0) { + dprintf("res_query failed (%d)\n", n); +#if !defined(__APPLE__) + if (errno == ECONNREFUSED) + return (_gethtbyaddr(addr, len, type)); +#endif + return (NULL); + } + if (!(hp = getanswer(&buf, n, qbuf, C_IN, T_PTR))) + return (NULL); /* h_errno was set by getanswer() */ +#ifdef SUNSECURITY + /* + * turn off search as the name should be absolute, + * 'localhost' should be matched by defnames + */ + strncpy(hname2, hp->h_name, MAXDNAME); + hname2[MAXDNAME] = '\0'; + old_options = _res.options; + _res.options &= ~RES_DNSRCH; + _res.options |= RES_DEFNAMES; + if (!(rhp = gethostbyname(hname2))) { + syslog(LOG_NOTICE|LOG_AUTH, + "gethostbyaddr: No A record for %s (verifying [%s])", + hname2, inet_ntoa(*((struct in_addr *)addr))); + _res.options = old_options; + h_errno = HOST_NOT_FOUND; + return (NULL); + } + _res.options = old_options; + for (haddr = rhp->h_addr_list; *haddr; haddr++) + if (!memcmp(*haddr, addr, INADDRSZ)) + break; + if (!*haddr) { + syslog(LOG_NOTICE|LOG_AUTH, + "gethostbyaddr: A record of %s != PTR record [%s]", + hname2, inet_ntoa(*((struct in_addr *)addr))); + h_errno = HOST_NOT_FOUND; + return (NULL); + } +#endif /*SUNSECURITY*/ + hp->h_addrtype = type; + hp->h_length = len; + h_addr_ptrs[0] = (char *)&host_addr; + h_addr_ptrs[1] = NULL; + host_addr = *(struct in_addr *)addr; + h_errno = NETDB_SUCCESS; + return (hp); +} + +void +_sethtent(f) + int f; +{ + if (!hostf) + hostf = fopen(_PATH_HOSTS, "r" ); + else + rewind(hostf); + stayopen = f; +} + +void +_endhtent() +{ + if (hostf && !stayopen) { + (void) fclose(hostf); + hostf = NULL; + } +} + +struct hostent * +_gethtent() +{ + char *p; + register char *cp, **q; + + if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) { + h_errno = NETDB_INTERNAL; + return (NULL); + } +again: + if (!(p = fgets(hostbuf, sizeof hostbuf, hostf))) { + h_errno = HOST_NOT_FOUND; + return (NULL); + } + if (*p == '#') + goto again; + if (!(cp = strpbrk(p, "#\n"))) + goto again; + *cp = '\0'; + if (!(cp = strpbrk(p, " \t"))) + goto again; + *cp++ = '\0'; + /* THIS STUFF IS INTERNET SPECIFIC */ + if (!inet_aton(p, &host_addr)) + goto again; + h_addr_ptrs[0] = (char *)&host_addr; + h_addr_ptrs[1] = NULL; +#if BSD >= 43 || defined(h_addr) /* new-style hostent structure */ + host.h_addr_list = h_addr_ptrs; +#else + host.h_addr = h_addr_ptrs[0]; +#endif + host.h_length = INT32SZ; + host.h_addrtype = AF_INET; + while (*cp == ' ' || *cp == '\t') + cp++; + host.h_name = cp; + q = host.h_aliases = host_aliases; + if (cp = strpbrk(cp, " \t")) + *cp++ = '\0'; + while (cp && *cp) { + if (*cp == ' ' || *cp == '\t') { + cp++; + continue; + } + if (q < &host_aliases[MAXALIASES - 1]) + *q++ = cp; + if (cp = strpbrk(cp, " \t")) + *cp++ = '\0'; + } + *q = NULL; + h_errno = NETDB_SUCCESS; + return (&host); +} + +struct hostent * +_gethtbyname(name) + char *name; +{ + register struct hostent *p; + register char **cp; + + _sethtent(0); + while (p = _gethtent()) { + if (strcasecmp(p->h_name, name) == 0) + break; + for (cp = p->h_aliases; *cp != 0; cp++) + if (strcasecmp(*cp, name) == 0) + goto found; + } +found: + _endhtent(); + return (p); +} + +struct hostent * +_gethtbyaddr(addr, len, type) + const char *addr; + int len, type; +{ + register struct hostent *p; + + _sethtent(0); + while (p = _gethtent()) + if (p->h_addrtype == type && !bcmp(p->h_addr, addr, len)) + break; + _endhtent(); + return (p); +} + +#ifdef RESOLVSORT +static void +addrsort(ap, num) + char **ap; + int num; +{ + int i, j; + char **p; + short aval[MAXADDRS]; + int needsort = 0; + + p = ap; + for (i = 0; i < num; i++, p++) { + for (j = 0 ; (unsigned)j < _res.nsort; j++) + if (_res.sort_list[j].addr.s_addr == + (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask)) + break; + aval[i] = j; + if (needsort == 0 && i > 0 && j < aval[i-1]) + needsort = i; + } + if (!needsort) + return; + + while (needsort < num) { + for (j = needsort - 1; j >= 0; j--) { + if (aval[j] > aval[j+1]) { + char *hp; + + i = aval[j]; + aval[j] = aval[j+1]; + aval[j+1] = i; + + hp = ap[j]; + ap[j] = ap[j+1]; + ap[j+1] = hp; + + } else + break; + } + needsort++; + } +} +#endif + +#if defined(BSD43_BSD43_NFS) || defined(sun) +/* some libc's out there are bound internally to these names (UMIPS) */ +void +ht_sethostent(stayopen) + int stayopen; +{ + _sethtent(stayopen); +} + +void +ht_endhostent() +{ + _endhtent(); +} + +struct hostent * +ht_gethostbyname(name) + char *name; +{ + return (_gethtbyname(name)); +} + +struct hostent * +ht_gethostbyaddr(addr, len, type) + const char *addr; + int len, type; +{ + return (_gethtbyaddr(addr, len, type)); +} + +struct hostent * +gethostent() +{ + return (_gethtent()); +} + +void +dns_service() +{ + return; +} + +#undef dn_skipname +dn_skipname(comp_dn, eom) + const u_char *comp_dn, *eom; +{ + return (__dn_skipname(comp_dn, eom)); +} +#endif /*old-style libc with yp junk in it*/ diff --git a/dns.subproj/getnetbyaddr.c b/dns.subproj/getnetbyaddr.c new file mode 100644 index 0000000..415aa1b --- /dev/null +++ b/dns.subproj/getnetbyaddr.c @@ -0,0 +1,80 @@ +/* + * 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) 1983 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getnetbyaddr.c 1.1 (Coimbra) 93/06/02"; +static char rcsid[] = "$Id: getnetbyaddr.c,v 1.2 1999/10/14 21:56:44 wsanchez Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include + +extern int _net_stayopen; + +struct netent * +_getnetbyaddr(net, type) + register long net; + register int type; +{ + register struct netent *p; + + setnetent(_net_stayopen); + while (p = getnetent()) + if (p->n_addrtype == type && p->n_net == net) + break; + if (!_net_stayopen) + endnetent(); + return (p); +} diff --git a/dns.subproj/getnetbyname.c b/dns.subproj/getnetbyname.c new file mode 100644 index 0000000..fe5ac4d --- /dev/null +++ b/dns.subproj/getnetbyname.c @@ -0,0 +1,87 @@ +/* + * 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) 1983, 1993 + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getnetbyname.c 8.1 (Berkeley) 6/4/93"; +static char sccsid_[] = "from getnetbyname.c 1.1 (Coimbra) 93/06/02"; +static char rcsid[] = "$Id: getnetbyname.c,v 1.2 1999/10/14 21:56:44 wsanchez Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +extern int _net_stayopen; + +struct netent * +_getnetbyname(name) + register const char *name; +{ + register struct netent *p; + register char **cp; + + setnetent(_net_stayopen); + while (p = getnetent()) { + if (strcasecmp(p->n_name, name) == 0) + break; + for (cp = p->n_aliases; *cp != 0; cp++) + if (strcasecmp(*cp, name) == 0) + goto found; + } +found: + if (!_net_stayopen) + endnetent(); + return (p); +} diff --git a/dns.subproj/getnetent.c b/dns.subproj/getnetent.c new file mode 100644 index 0000000..00f9d6e --- /dev/null +++ b/dns.subproj/getnetent.c @@ -0,0 +1,187 @@ +/* + * 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) 1983 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 Carlos Leandro and Rui Salgueiro + * Dep. Matematica Universidade de Coimbra, Portugal, Europe + * + * 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. + * + * from getnetent.c 1.1 (Coimbra) 93/06/02 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getnetent.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$Id: getnetent.c,v 1.2 1999/10/14 21:56:44 wsanchez Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifndef _PATH_NETWORKS +#define _PATH_NETWORKS "/etc/networks" +#endif + +#define MAXALIASES 35 + +static FILE *netf; +static char line[BUFSIZ+1]; +static struct netent net; +static char *net_aliases[MAXALIASES]; +#if defined(__APPLE__) +extern +#endif +int _net_stayopen; + +void _setnetent __P((int)); +void _endnetent __P((void)); + +void +setnetent(stayopen) + int stayopen; +{ + + sethostent(stayopen); + _setnetent(stayopen); +} + +void +endnetent() +{ + + endhostent(); + _endnetent(); +} + +void +_setnetent(f) + int f; +{ + + if (netf == NULL) + netf = fopen(_PATH_NETWORKS, "r" ); + else + rewind(netf); + _net_stayopen |= f; +} + +void +_endnetent() +{ + + if (netf) { + fclose(netf); + netf = NULL; + } + _net_stayopen = 0; +} + +struct netent * +getnetent() +{ + char *p; + register char *cp, **q; + + if (netf == NULL && (netf = fopen(_PATH_NETWORKS, "r" )) == NULL) + return (NULL); +again: + p = fgets(line, BUFSIZ, netf); + if (p == NULL) + return (NULL); + if (*p == '#') + goto again; + cp = strpbrk(p, "#\n"); + if (cp == NULL) + goto again; + *cp = '\0'; + net.n_name = p; + cp = strpbrk(p, " \t"); + if (cp == NULL) + goto again; + *cp++ = '\0'; + while (*cp == ' ' || *cp == '\t') + cp++; + p = strpbrk(cp, " \t"); + if (p != NULL) + *p++ = '\0'; + net.n_net = inet_network(cp); + net.n_addrtype = AF_INET; + q = net.n_aliases = net_aliases; + if (p != NULL) + cp = p; + while (cp && *cp) { + if (*cp == ' ' || *cp == '\t') { + cp++; + continue; + } + if (q < &net_aliases[MAXALIASES - 1]) + *q++ = cp; + cp = strpbrk(cp, " \t"); + if (cp != NULL) + *cp++ = '\0'; + } + *q = NULL; + return (&net); +} diff --git a/dns.subproj/getnetnamadr.c b/dns.subproj/getnetnamadr.c new file mode 100644 index 0000000..f3d3265 --- /dev/null +++ b/dns.subproj/getnetnamadr.c @@ -0,0 +1,328 @@ +/* + * 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) 1993 Carlos Leandro and Rui Salgueiro + * Dep. Matematica Universidade de Coimbra, Portugal, Europe + * + * 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. + */ +/* + * Copyright (c) 1983, 1993 + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getnetbyaddr.c 8.1 (Berkeley) 6/4/93"; +static char sccsid_[] = "from getnetnamadr.c 1.4 (Coimbra) 93/06/03"; +static char rcsid[] = "$Id: getnetnamadr.c,v 1.2 1999/10/14 21:56:44 wsanchez Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +extern int h_errno; + +#if defined(mips) && defined(SYSTYPE_BSD43) +extern int errno; +#endif + +struct netent *_getnetbyaddr __P((long net, int type)); +struct netent *_getnetbyname __P((const char *name)); + +#define BYADDR 0 +#define BYNAME 1 +#define MAXALIASES 35 + +#if PACKETSZ > 1024 +#define MAXPACKET PACKETSZ +#else +#define MAXPACKET 1024 +#endif + +typedef union { + HEADER hdr; + u_char buf[MAXPACKET]; +} querybuf; + +typedef union { + long al; + char ac; +} align; + +static struct netent * +getnetanswer(answer, anslen, net_i) + querybuf *answer; + int anslen; + int net_i; +{ + + register HEADER *hp; + register u_char *cp; + register int n; + u_char *eom; + int type, class, buflen, ancount, qdcount, haveanswer, i, nchar; + char aux1[30], aux2[30], ans[30], *in, *st, *pauxt, *bp, **ap, + *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0; +static struct netent net_entry; +static char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1]; + + /* + * find first satisfactory answer + * + * answer --> +------------+ ( MESSAGE ) + * | Header | + * +------------+ + * | Question | the question for the name server + * +------------+ + * | Answer | RRs answering the question + * +------------+ + * | Authority | RRs pointing toward an authority + * | Additional | RRs holding additional information + * +------------+ + */ + eom = answer->buf + anslen; + hp = &answer->hdr; + ancount = ntohs(hp->ancount); /* #/records in the answer section */ + qdcount = ntohs(hp->qdcount); /* #/entries in the question section */ + bp = netbuf; + buflen = sizeof(netbuf); + cp = answer->buf + HFIXEDSZ; + if (!qdcount) { + if (hp->aa) + h_errno = HOST_NOT_FOUND; + else + h_errno = TRY_AGAIN; + return (NULL); + } + while (qdcount-- > 0) + cp += __dn_skipname(cp, eom) + QFIXEDSZ; + ap = net_aliases; + *ap = NULL; + net_entry.n_aliases = net_aliases; + haveanswer = 0; + while (--ancount >= 0 && cp < eom) { + n = dn_expand(answer->buf, eom, cp, bp, buflen); + if (n < 0) + break; + cp += n; + ans[0] = '\0'; + (void)strcpy(&ans[0], bp); + GETSHORT(type, cp); + GETSHORT(class, cp); + cp += INT32SZ; /* TTL */ + GETSHORT(n, cp); + if (class == C_IN && type == T_PTR) { + n = dn_expand(answer->buf, eom, cp, bp, buflen); + if (n < 0) { + cp += n; + return (NULL); + } + cp += n; + *ap++ = bp; + bp += strlen(bp) + 1; + net_entry.n_addrtype = + (class == C_IN) ? AF_INET : AF_UNSPEC; + haveanswer++; + } + } + if (haveanswer) { + *ap = NULL; + switch (net_i) { + case BYADDR: + net_entry.n_name = *net_entry.n_aliases; + net_entry.n_net = 0L; + break; + case BYNAME: + in = *net_entry.n_aliases; + net_entry.n_name = &ans[0]; + aux2[0] = '\0'; + for (i = 0; i < 4; i++) { + for (st = in, nchar = 0; + *st != '.'; + st++, nchar++) + ; + if (nchar != 1 || *in != '0' || flag) { + flag = 1; + (void)strncpy(paux1, + (i==0) ? in : in-1, + (i==0) ?nchar : nchar+1); + paux1[(i==0) ? nchar : nchar+1] = '\0'; + pauxt = paux2; + paux2 = strcat(paux1, paux2); + paux1 = pauxt; + } + in = ++st; + } + net_entry.n_net = inet_network(paux2); + break; + } + net_entry.n_aliases++; + return (&net_entry); + } + h_errno = TRY_AGAIN; + return (NULL); +} + +struct netent * +getnetbyaddr(net, net_type) + register long net; + register int net_type; +{ + unsigned int netbr[4]; + int nn, anslen; + querybuf buf; + char qbuf[MAXDNAME]; + unsigned long net2; + struct netent *net_entry; + + if (net_type != AF_INET) +#if defined(__APPLE__) + return NULL; +#else + return (_getnetbyaddr(net, net_type)); +#endif /* !NeXT */ + + for (nn = 4, net2 = net; net2; net2 >>= 8) + netbr[--nn] = net2 & 0xff; + switch (nn) { + case 3: /* Class A */ + sprintf(qbuf, "0.0.0.%u.in-addr.arpa", netbr[3]); + break; + case 2: /* Class B */ + sprintf(qbuf, "0.0.%u.%u.in-addr.arpa", netbr[3], netbr[2]); + break; + case 1: /* Class C */ + sprintf(qbuf, "0.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2], + netbr[1]); + break; + case 0: /* Class D - E */ + sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2], + netbr[1], netbr[0]); + break; + } + anslen = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf)); + if (anslen < 0) { +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf("res_query failed\n"); +#endif +#if !defined(__APPLE__) + if (errno == ECONNREFUSED) + return (_getnetbyaddr(net, net_type)); +#endif /* !NeXT */ + return (NULL); + } + net_entry = getnetanswer(&buf, anslen, BYADDR); + if (net_entry) { + unsigned u_net = net; /* maybe net should be unsigned ? */ + + /* Strip trailing zeros */ + while ((u_net & 0xff) == 0 && u_net != 0) + u_net >>= 8; + net_entry->n_net = u_net; + return (net_entry); + } +#if defined(__APPLE__) + return NULL; +#else + return (_getnetbyaddr(net, net_type)); +#endif /* !NeXT */ +} + +struct netent * +getnetbyname(net) + register const char *net; +{ + int anslen; + querybuf buf; + char qbuf[MAXDNAME]; + struct netent *net_entry; + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; + return (NULL); + } + strcpy(&qbuf[0], net); + anslen = res_search(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf)); + if (anslen < 0) { +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf("res_query failed\n"); +#endif +#if defined(__APPLE__) + return NULL; +#else + if (errno == ECONNREFUSED) + return (_getnetbyname(net)); + return (_getnetbyname(net)); +#endif /* !NeXT */ + } + net_entry = getnetanswer(&buf, anslen, BYNAME); + if (net_entry) + return (net_entry); +#if defined(__APPLE__) + return NULL; +#else + return (_getnetbyname(net)); +#endif /* !NeXT */ +} diff --git a/dns.subproj/herror.c b/dns.subproj/herror.c new file mode 100644 index 0000000..dcfe656 --- /dev/null +++ b/dns.subproj/herror.c @@ -0,0 +1,145 @@ +/* + * 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++ 1987, 1993 + * - + * Copyright (c) 1987, 1993 + * 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-- + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$Id: herror.c,v 1.2 1999/10/14 21:56:44 wsanchez Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#if defined(BSD) && (BSD >= 199103) +# include +# include +#else +# include "portability.h" +#endif + +const char *h_errlist[] = { + "Resolver Error 0 (no error)", + "Unknown host", /* 1 HOST_NOT_FOUND */ + "Host name lookup failure", /* 2 TRY_AGAIN */ + "Unknown server error", /* 3 NO_RECOVERY */ + "No address associated with name", /* 4 NO_ADDRESS */ +}; +int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] }; + +#if defined(__APPLE__) +int h_errno = 0; +#else +extern int h_errno; +#endif /* !NeXT */ + +/* + * herror -- + * print the error indicated by the h_errno value. + */ +void +herror(s) + const char *s; +{ + struct iovec iov[4]; + register struct iovec *v = iov; + + if (s && *s) { + v->iov_base = (char *)s; + v->iov_len = strlen(s); + v++; + v->iov_base = ": "; + v->iov_len = 2; + v++; + } + v->iov_base = (char *)hstrerror(h_errno); + v->iov_len = strlen(v->iov_base); + v++; + v->iov_base = "\n"; + v->iov_len = 1; + writev(STDERR_FILENO, iov, (v - iov) + 1); +} + +char * +hstrerror(err) + int err; +{ + if (err < 0) + return ("Resolver internal error"); + else if (err < h_nerr) + return (h_errlist[err]); + return ("Unknown resolver error"); +} diff --git a/dns.subproj/inet.h b/dns.subproj/inet.h new file mode 100644 index 0000000..ae203b2 --- /dev/null +++ b/dns.subproj/inet.h @@ -0,0 +1,111 @@ +/* + * 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++ 1983, 1993 + * - + * Copyright (c) 1983, 1993 + * 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-- + */ + +/* + * @(#)inet.h 8.1 (Berkeley) 6/2/93 + * $Id: inet.h,v 1.2 1999/10/14 21:56:45 wsanchez Exp $ + */ + +#ifndef _INET_H_ +#define _INET_H_ + +/* External definitions for functions in inet(3) */ + +#include +#if (!defined(BSD)) || (BSD < 199306) +# include +#else +# include +#endif +#include + +__BEGIN_DECLS +unsigned long inet_addr __P((const char *)); +int inet_aton __P((const char *, struct in_addr *)); +unsigned long inet_lnaof __P((struct in_addr)); +struct in_addr inet_makeaddr __P((u_long , u_long)); +unsigned long inet_netof __P((struct in_addr)); +unsigned long inet_network __P((const char *)); +char *inet_ntoa __P((struct in_addr)); + +u_int inet_nsap_addr __P((const char *, u_char *, int maxlen)); +char *inet_nsap_ntoa __P((int, const u_char *, char *ascii)); + +__END_DECLS + +#endif /* !_INET_H_ */ diff --git a/dns.subproj/nameser.h b/dns.subproj/nameser.h new file mode 100644 index 0000000..b3874e4 --- /dev/null +++ b/dns.subproj/nameser.h @@ -0,0 +1,368 @@ +/* + * 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++ 1983, 1989, 1993 + * - + * Copyright (c) 1983, 1989, 1993 + * 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-- + */ + +/* + * @(#)nameser.h 8.1 (Berkeley) 6/2/93 + * $Id: nameser.h,v 1.2 1999/10/14 21:56:45 wsanchez Exp $ + */ + +#ifndef _NAMESER_H_ +#define _NAMESER_H_ + +#include +#if (!defined(BSD)) || (BSD < 199306) +# include +#else +# include +#endif +#include + +#ifdef _AUX_SOURCE +#include /* ech for A/UX */ +#define res_send ucb_res_send /* already def'd in libc */ +#define _res_close _ucb_res_close /* removing res_send.o from the library */ +#endif /* gives an undefined symbol... */ + +/* + * revision information. this is the release date in YYYYMMDD format. + * it can change every day so the right thing to do with it is use it + * in preprocessor commands such as "#if (__BIND > 19931104)". do not + * compare for equality; rather, use it to determine whether your resolver + * is new enough to contain a certain feature. + */ + +#define __BIND 19950621 /* interface version stamp */ + +/* + * Define constants based on rfc883 + */ +#define PACKETSZ 512 /* maximum packet size */ +#define MAXDNAME 256 /* maximum domain name */ +#define MAXCDNAME 255 /* maximum compressed domain name */ +#define MAXLABEL 63 /* maximum length of domain label */ +#define HFIXEDSZ 12 /* #/bytes of fixed data in header */ +#define QFIXEDSZ 4 /* #/bytes of fixed data in query */ +#define RRFIXEDSZ 10 /* #/bytes of fixed data in r record */ +#define INT32SZ 4 /* for systems without 32-bit ints */ +#define INT16SZ 2 /* for systems without 16-bit ints */ +#define INADDRSZ 4 /* for sizeof(struct inaddr) != 4 */ + +/* + * Internet nameserver port number + */ +#define NAMESERVER_PORT 53 + +/* + * Currently defined opcodes + */ +#define QUERY 0x0 /* standard query */ +#define IQUERY 0x1 /* inverse query */ +#define STATUS 0x2 /* nameserver status query */ +/*#define xxx 0x3*/ /* 0x3 reserved */ +#define NS_NOTIFY_OP 0x4 /* notify secondary of SOA change */ +#ifdef ALLOW_UPDATES + /* non standard - supports ALLOW_UPDATES stuff from Mike Schwartz */ +# define UPDATEA 0x9 /* add resource record */ +# define UPDATED 0xa /* delete a specific resource record */ +# define UPDATEDA 0xb /* delete all named resource record */ +# define UPDATEM 0xc /* modify a specific resource record */ +# define UPDATEMA 0xd /* modify all named resource record */ +# define ZONEINIT 0xe /* initial zone transfer */ +# define ZONEREF 0xf /* incremental zone referesh */ +#endif + +/* + * Currently defined response codes + */ +#define NOERROR 0 /* no error */ +#define FORMERR 1 /* format error */ +#define SERVFAIL 2 /* server failure */ +#define NXDOMAIN 3 /* non existent domain */ +#define NOTIMP 4 /* not implemented */ +#define REFUSED 5 /* query refused */ +#ifdef ALLOW_UPDATES + /* non standard */ +# define NOCHANGE 0xf /* update failed to change db */ +#endif + +/* + * Type values for resources and queries + */ +#define T_A 1 /* host address */ +#define T_NS 2 /* authoritative server */ +#define T_MD 3 /* mail destination */ +#define T_MF 4 /* mail forwarder */ +#define T_CNAME 5 /* canonical name */ +#define T_SOA 6 /* start of authority zone */ +#define T_MB 7 /* mailbox domain name */ +#define T_MG 8 /* mail group member */ +#define T_MR 9 /* mail rename name */ +#define T_NULL 10 /* null resource record */ +#define T_WKS 11 /* well known service */ +#define T_PTR 12 /* domain name pointer */ +#define T_HINFO 13 /* host information */ +#define T_MINFO 14 /* mailbox information */ +#define T_MX 15 /* mail routing information */ +#define T_TXT 16 /* text strings */ +#define T_RP 17 /* responsible person */ +#define T_AFSDB 18 /* AFS cell database */ +#define T_X25 19 /* X_25 calling address */ +#define T_ISDN 20 /* ISDN calling address */ +#define T_RT 21 /* router */ +#define T_NSAP 22 /* NSAP address */ +#define T_NSAP_PTR 23 /* reverse NSAP lookup (deprecated) */ +#define T_SIG 24 /* security signature */ +#define T_KEY 25 /* security key */ +#define T_PX 26 /* X.400 mail mapping */ +#define T_GPOS 27 /* geographical position (withdrawn) */ +#define T_AAAA 28 /* IP6 Address */ +#define T_LOC 29 /* Location Information */ + /* non standard */ +#define T_UINFO 100 /* user (finger) information */ +#define T_UID 101 /* user ID */ +#define T_GID 102 /* group ID */ +#define T_UNSPEC 103 /* Unspecified format (binary data) */ + /* Query type values which do not appear in resource records */ +#define T_AXFR 252 /* transfer zone of authority */ +#define T_MAILB 253 /* transfer mailbox records */ +#define T_MAILA 254 /* transfer mail agent records */ +#define T_ANY 255 /* wildcard match */ + +/* + * Values for class field + */ + +#define C_IN 1 /* the arpa internet */ +#define C_CHAOS 3 /* for chaos net (MIT) */ +#define C_HS 4 /* for Hesiod name server (MIT) (XXX) */ + /* Query class values which do not appear in resource records */ +#define C_ANY 255 /* wildcard match */ + +/* + * Status return codes for T_UNSPEC conversion routines + */ +#define CONV_SUCCESS 0 +#define CONV_OVERFLOW (-1) +#define CONV_BADFMT (-2) +#define CONV_BADCKSUM (-3) +#define CONV_BADBUFLEN (-4) + +#ifndef BYTE_ORDER +#if (BSD >= 199103) +# include +#else +#ifdef linux +# include +#else +#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax, pc) */ +#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */ +#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp)*/ + +#if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \ + defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \ + defined(__alpha__) || defined(__alpha) +#define BYTE_ORDER LITTLE_ENDIAN +#endif + +#if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \ + defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \ + defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\ + defined(apollo) || defined(__convex__) || defined(_CRAY) || \ + defined(__hppa) || defined(__hp9000) || \ + defined(__hp9000s300) || defined(__hp9000s700) || \ + defined (BIT_ZERO_ON_LEFT) || defined(m68k) +#define BYTE_ORDER BIG_ENDIAN +#endif +#endif /* linux */ +#endif /* BSD */ +#endif /* BYTE_ORDER */ + +#if !defined(BYTE_ORDER) || \ + (BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN && \ + BYTE_ORDER != PDP_ENDIAN) + /* you must determine what the correct bit order is for + * your compiler - the next line is an intentional error + * which will force your compiles to bomb until you fix + * the above macros. + */ + error "Undefined or invalid BYTE_ORDER"; +#endif + +/* + * Structure for query header. The order of the fields is machine- and + * compiler-dependent, depending on the byte/bit order and the layout + * of bit fields. We use bit fields only in int variables, as this + * is all ANSI requires. This requires a somewhat confusing rearrangement. + */ + +typedef struct { + unsigned id :16; /* query identification number */ +#if BYTE_ORDER == BIG_ENDIAN + /* fields in third byte */ + unsigned qr: 1; /* response flag */ + unsigned opcode: 4; /* purpose of message */ + unsigned aa: 1; /* authoritive answer */ + unsigned tc: 1; /* truncated message */ + unsigned rd: 1; /* recursion desired */ + /* fields in fourth byte */ + unsigned ra: 1; /* recursion available */ + unsigned unused :3; /* unused bits (MBZ as of 4.9.3a3) */ + unsigned rcode :4; /* response code */ +#endif +#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN + /* fields in third byte */ + unsigned rd :1; /* recursion desired */ + unsigned tc :1; /* truncated message */ + unsigned aa :1; /* authoritive answer */ + unsigned opcode :4; /* purpose of message */ + unsigned qr :1; /* response flag */ + /* fields in fourth byte */ + unsigned rcode :4; /* response code */ + unsigned unused :3; /* unused bits (MBZ as of 4.9.3a3) */ + unsigned ra :1; /* recursion available */ +#endif + /* remaining bytes */ + unsigned qdcount :16; /* number of question entries */ + unsigned ancount :16; /* number of answer entries */ + unsigned nscount :16; /* number of authority entries */ + unsigned arcount :16; /* number of resource entries */ +} HEADER; + +/* + * Defines for handling compressed domain names + */ +#define INDIR_MASK 0xc0 + +/* + * Structure for passing resource records around. + */ +struct rrec { + int16_t r_zone; /* zone number */ + int16_t r_class; /* class number */ + int16_t r_type; /* type number */ + u_int32_t r_ttl; /* time to live */ + int r_size; /* size of data area */ + char *r_data; /* pointer to data */ +}; + +extern u_int16_t _getshort __P((const u_char *)); +extern u_int32_t _getlong __P((const u_char *)); + +/* + * Inline versions of get/put short/long. Pointer is advanced. + * + * These macros demonstrate the property of C whereby it can be + * portable or it can be elegant but rarely both. + */ +#define GETSHORT(s, cp) { \ + register u_char *t_cp = (u_char *)(cp); \ + (s) = ((u_int16_t)t_cp[0] << 8) \ + | ((u_int16_t)t_cp[1]) \ + ; \ + (cp) += INT16SZ; \ +} + +#define GETLONG(l, cp) { \ + register u_char *t_cp = (u_char *)(cp); \ + (l) = ((u_int32_t)t_cp[0] << 24) \ + | ((u_int32_t)t_cp[1] << 16) \ + | ((u_int32_t)t_cp[2] << 8) \ + | ((u_int32_t)t_cp[3]) \ + ; \ + (cp) += INT32SZ; \ +} + +#define PUTSHORT(s, cp) { \ + register u_int16_t t_s = (u_int16_t)(s); \ + register u_char *t_cp = (u_char *)(cp); \ + *t_cp++ = t_s >> 8; \ + *t_cp = t_s; \ + (cp) += INT16SZ; \ +} + +#define PUTLONG(l, cp) { \ + register u_int32_t t_l = (u_int32_t)(l); \ + register u_char *t_cp = (u_char *)(cp); \ + *t_cp++ = t_l >> 24; \ + *t_cp++ = t_l >> 16; \ + *t_cp++ = t_l >> 8; \ + *t_cp = t_l; \ + (cp) += INT32SZ; \ +} + +#endif /* !_NAMESER_H_ */ diff --git a/dns.subproj/options.h b/dns.subproj/options.h new file mode 100644 index 0000000..6a79326 --- /dev/null +++ b/dns.subproj/options.h @@ -0,0 +1,189 @@ +/* + * 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@ + */ +/* options.h - specify the conditionally-compiled features + * vix 28mar92 [moved out of the Makefile because they were getting too big] + * + * $Id: options.h,v 1.2 1999/10/14 21:56:45 wsanchez Exp $ + */ + +/* + * ++Copyright++ + * - + * Copyright (c) + * 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-- + */ + +/* Key: + * ucb = U C Berkeley 4.8.3 release + * vix = Paul Vixie of Digital + * del = Don Lewis of Harris + * mcsun = Piet Beertema of EUNet + * asp = Andrew Partan of UUNet + * pma = Paul Albitz of Hewlett Packard + * bb = Bryan Beecher of UMich + * mpa = Mark Andrews of CSIRO - DMS + * rossc = Ross Cartlidge of The Univeritsy of Sydney + * mtr = Marshall Rose of TPC.INT + * bg = Benoit Grange of INRIA + * ckd = Christopher Davis of Kapor Enterprises + * gns = Greg Shapiro of WPI + */ + +#define DEBUG /* enable -d flag and SIGUSR[12] support (ucb) */ +/*#define ALLOW_T_UNSPEC enable the "unspec" RR type for old athena (ucb) */ +/*#define INVQ enable inverse queries (nslookup) (ucb/vix) */ +/*#define DSTORAGE debug malloc overruns using storage.o (ucb/vix) */ +/*#define DMALLOC trace malloc orphans using dmalloc.o (vix) */ +#define XFRNETS /* enable "xfrnets" command in named.boot (vix) */ +#define PID_FIX /* be careful about overwriting named.pid file (del) */ +#define FWD_LOOP /* try to break out of forwarding loops (del) */ +#define NO_GLUE /* don't accept or send out-of-zone glue (del) */ +#define BOGUSNS /* detect bogus nameservers (mcsun) */ +#define QRYLOG /* enable SIGWINCH for query logging (bb) */ +/*#define YPKLUDGE deal effectively with broken "ypserv -i" (mcsun) */ +#define TRACEROOT /* trace bogus root servers and ignore them (pma,bb) */ +/*#define LOCALDOM permit "domain" directive in named.boot (ucb) */ +#define FORCED_RELOAD /* refresh secondary zones on SIGHUP (pma) */ +#define SLAVE_FORWARD /* use sensible timeouts on slave forwarders (pma) */ +#define WANT_PIDFILE /* if you want the named.pid file (ucb/arc) */ +#define DOTTED_SERIAL /* if you want to be able to specify dotted serial#s */ +/*#define SENSIBLE_DOTS if you want dotted serial#s to make numeric sense */ +#define NCACHE /* negative caching (anant@isi.edu) */ +/*#define VALIDATE validation procedure (anant@isi.edu) (DO NOT USE!)*/ +/*#define SHORT_FNAMES file names used in named-xfer need to be short */ +#define RESOLVSORT /* allow sorting of addresses in gethostbyname (mpa) */ +#define STUBS /* allow transfers of NS only for a zone (mpa) */ +#ifndef LOGFAC +#define LOGFAC LOG_DAEMON /* what syslog facility should named use? */ +#endif +#define SECURE_ZONES /* if you want to inhibit world access to zones (gns)*/ +#define ROUND_ROBIN /* rotate databuf list after each access (mtr) */ +#define ADDAUTH /* return NS and glue w/ authorative answers (mpa) */ +#define RFC1535 /* use RFC 1535 default for "search" list (vix) */ +#define GEN_AXFR /* distinct zones within each class */ +#define DATUMREFCNT /* use reference counts on datums (mpa) */ +#define LAME_DELEGATION /* lame delegations (original-del,reworked-bb&del)*/ +#define LAME_LOGGING LOG_WARNING /* log lame delegations, set log level */ +#define GETSER_LOGGING LOG_INFO /* log errors/timeouts getting serial number */ +/*#define RETURNSOA good code that the world isn't ready for yet */ +#define CLEANCACHE /* useful and necessary in the face of NCACHE */ +#define PURGE_ZONE /* remove all traces of a zone when reloading (mpa) */ +#define STATS /* keep nameserver statistics; uses more memory */ +#define RENICE /* named-xfer should run at normal priority */ +#define XSTATS /* extended statistics, syslogged periodically (bg) */ +/*#define BIND_NOTIFY experimental - do not enable in customer products */ +/*#define LOC_RR support for (draft) LOC record parsing (ckd) */ + +/*--------------------------------------------* + * no user-servicable parts beyond this point * + *--------------------------------------------*/ + +/* if DSTORAGE is defined, we need to disable DMALLOC and remap + * malloc and free to storage.o's exported names. storage.o also + * includes a calloc and a realloc, but once we drag in its malloc + * and free we'll get the others automatically and so will never + * pull in those routines from libc.a. + */ +#ifdef DSTORAGE +# ifdef DMALLOC +# undef DMALLOC +# endif /*DMALLOC*/ +# define malloc rt_malloc +# define free rt_free +#endif /*DSTORAGE*/ + +/* if DMALLOC is defined, grab the header file which will remap + * all the malloc-style names to those exported by dmalloc.o. note + * that DMALLOC also changes the function signatures of several + * functions in private named source modules, and that this file + * (options.h) must be included before any other private *.h files + * since those *.h files have some conditional remapping to do. + */ +#ifdef DMALLOC +# include "dmalloc.h" +#endif + +/* systems with killall(1M) don't need this + */ +#ifdef __sgi +# ifdef WANT_PIDFILE +# undef WANT_PIDFILE +# endif +#endif + +#ifdef LAME_LOGGING +# define LAME_DELEGATION +#endif + +#if defined(XSTATS) && !defined(STATS) +# define STATS +#endif diff --git a/dns.subproj/portability.h b/dns.subproj/portability.h new file mode 100644 index 0000000..55ed578 --- /dev/null +++ b/dns.subproj/portability.h @@ -0,0 +1,570 @@ +/* + * 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@ + */ +/* portability.h - include or define things that aren't present on all systems + * vixie@decwrl 26dec92 [new] + * + * $Id: portability.h,v 1.2 1999/10/14 21:56:45 wsanchez Exp $ + */ + +/* + * ++Copyright++ + * - + * Copyright (c) + * 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-- + */ + +/* XXX: this file has become a hopeless morass, and will be redone someday. */ + +#include +#include +#include +#ifndef TIME_H_INCLUDED +# include +# define TIME_H_INCLUDED +#endif + +#ifdef ISC +# ifndef _POSIX_SOURCE +# define _POSIX_SOURCE +# endif +# define SYSV +# define SVR3 +# define _SYSV3 +# define NEED_STRTOUL +# define NEED_FTRUNCATE +# define USE_POSIX +# include +# include +# include +# include +#endif + +#if defined(__convex__) +# if !defined(_POSIX_SOURCE) +# define _POSIX_SOURCE +# endif +# define USE_UTIME +# define NEED_PUTENV +#endif + +#if defined(_CRAY) +# if !defined(_POSIX_SOURCE) +# define _POSIX_SOURCE +# endif +# define writev(a,b,c) __writev(a,b,c) +# define setitimer(a,b,c) __setitimer(a,b,c) +#endif + +/* This is defined in the Makefile for ISC compiles. */ +#if defined(ISC) +# define ftruncate(a,b) __ftruncate(a,b) +# define USE_MEMCPY +# define USE_UTIME +# define HAVE_FCHMOD 0 +#endif + +/* SCO UNIX defines only this unique symbol, apparently. */ +#if defined(M_UNIX) +/* XXX - why is this POSIX_SOURCE instead of _POSIX_SOURCE? */ +# undef POSIX_SOURCE +# define POSIX_SIGNALS +# define HAVE_FCHMOD 0 +# define writev(a,b,c) __writev(a,b,c) +# define ftruncate(a,b) __ftruncate(a,b) +#endif + +#if defined(__APPLE__) && BSD < 199506 +# define NEED_PUTENV +# define NEED_SETENV +#endif + +#if defined(__sgi) +# define BSD 43 +# define vfork fork +#endif + +#if defined(SUNOS4) +# define BSD 43 +#endif + +#if defined(_AUX_SOURCE) +# define vfork fork +# define NEED_STRERROR +# define NEED_STRTOUL +# define SIG_FN void +# define USE_MEMCPY +#endif + + +#if defined(SVR4) && !defined(SYSV) +# define SYSV +#endif + +#if defined(_POSIX_SOURCE) || defined(__sgi) || defined(__ultrix) || \ + defined(__hpux) || (defined(BSD) && (BSD >= 199103)) || \ + (defined(sun) && defined(SYSV)) +# define USE_POSIX +#endif + +#if defined(__ultrix) && !defined(BSD) +# define BSD 42 +#endif + +#if defined(host_mips) && defined(SYSTYPE_BSD43) +# define RISCOS_BSD +#endif + +#if defined(SYSV) || defined(__ultrix) || defined(__osf__) \ + || (defined(BSD) && BSD >= 199306) || defined(linux) +# define USE_UTIME +# define HAVE_SETVBUF +#endif + +#if defined(SYSV) && !defined(SVR4) +# define vfork fork +#endif + +#if defined(sun) || defined(SVR4) +# define NETREAD_BROKEN +#endif + +#if defined(BSD) && BSD >= 199006 && !defined(i386) && !defined(RISCOS_BSD) +# define HAVE_DAEMON +#endif + +#if !defined(BSD) || (BSD <= 199006) +# if !defined(__APPLE__) +# define NEED_INETADDR +# endif +# define NEED_INETATON +#endif + +#if defined(__hpux) +# if defined(__STDC__) +# define select(a,b,c,d,e) select(a, (int *)b, (int *)c, (int *)d, e) +# define ctime(x) ctime((const time_t *)x) +# endif /*__STDC__*/ +# if !defined(SYSV) +# define USE_UTIME +# define setlinebuf(x) setvbuf(x, NULL, _IOLBF, BUFSIZ) +# if !defined(SIGWINCH) /*pre 9.0*/ +# define SIGWINCH SIGWINDOW +# endif +# endif /*SYSV*/ +/* XXX: better autodetection of the need for "struct linger" would be nice */ +# if 0 +struct linger { + int l_onoff; /* option on/off */ + int l_linger; /* linger time */ +}; +# endif +#endif /*__hpux*/ + +#if defined(_SEQUENT_) +# include +# define USE_UTIME +# define USE_POSIX +# define NEED_GETTIMEOFDAY +# define _TIMEZONE timezoneBSD +struct timezoneBSD { + int tz_minuteswest; + int tz_dsttime; +}; +#endif + +#ifndef __P +# if defined(__STDC__) || defined(__GNUC__) +# define __P(x) x +# else +# define __P(x) () +# endif +#endif + +#ifndef _TIMEZONE +# define _TIMEZONE timezone +#endif + +#if defined(USE_POSIX) +# include +# include +# include + +#else + +# define NEED_STRTOUL + +# define STDIN_FILENO 0 +# define STDOUT_FILENO 1 +# define STDERR_FILENO 2 +# ifndef __APPLE__ +extern char *getenv __P((char *)); +# else +extern char *getenv __P((const char *)); +# endif +extern int errno; + +# if !defined(DMALLOC) && !defined(__APPLE__) +extern char *malloc(), *realloc(), *calloc(); +# if defined(sun) +extern int free(); +# else +extern void free(); +# endif +# endif + +extern int getdtablesize __P((void)); +# ifdef SHORT_FNAMES +extern long pathconf __P((const char *path, int name)); +# endif + +#endif /*USE_POSIX*/ + +#ifndef UINT_MAX +# ifdef __STDC__ +# define UINT_MAX 4294967295u /* max value of an "u_int" */ +# else +# define UINT_MAX ((unsigned)4294967295) /* max value of an "u_int" */ +# endif +# define ULONG_MAX UINT_MAX /* max decimal value of a "u_long" */ +#endif + +#ifndef INT_MAX +# define INT_MAX 2147483647 /* max decimal value of an "int" */ +#endif + +#ifndef RAND_MAX +# define RAND_MAX 0x7fffffff +#endif + +#ifndef IN_LOOPBACKNET +# define IN_LOOPBACKNET 127 +#endif + +#ifndef INADDR_NONE +# define INADDR_NONE 0xffffffff +#endif + +#if defined(apollo) + /* Defined in /usr/include/netinet/in.h but doesn't work */ +#undef IP_OPTIONS +#endif + +#if !defined(__STDC__) && !defined(const) +# define const /*constant*/ +#endif + +#if !defined(__convex__) && (!defined(BSD) || (BSD < 199103)) +int strcasecmp __P((const char *, const char *)); +#endif + +/* is USE_POSIX the right thing to use here? */ +#if (!defined(BSD) || (BSD <= 43)) && \ + !defined(NeXT) && \ + !defined(__convex__) && \ + !defined(USE_POSIX) +# if !defined(NCR) +extern void syslog(); +# endif +extern char *ctime __P((const time_t *clock)); +extern int close(), setitimer(), recv(), sendto(), sigsetmask(), + atoi(), getpid(), fork(), read(), ioctl(), + setsockopt(), socket(), bind(); +#endif + +#if !defined(bcopy) /* some machines have their own macros for this */ +# if defined(USE_POSIX) || \ + (defined(__STDC__) && !defined(sun) && !defined(sequent)) +/* use ANSI C3.159-1989 (``ANSI C'') functions if possible; + * ideally we would change the code to use them and then + * define them in terms of bcopy et al if !defined(__STDC__) + * but that's more work. + */ +#if defined(USE_MEMCPY) +# define bcopy(a,b,c) memcpy(b,a,c) +#else +# define bcopy(a,b,c) memmove(b,a,c) +#endif +# define bzero(a,b) memset(a,0,b) +# define bcmp(a,b,c) memcmp(a,b,c) +# else +extern void bcopy(); +extern void bzero(); +extern int bcmp(); +# endif /* BSD */ +#endif /* bcopy */ + +#if (!defined(BSD) || (BSD < 43) || defined(RISCOS_BSD)) \ + && !defined(USE_POSIX) && !defined(apollo) && !defined(sequent) \ + && !defined(M_UNIX) +# define NEED_STRERROR +#if !defined(ultrix) && !defined(NCR) +# define NEED_PUTENV +#endif +#endif + +#if defined(SUNOS4) +# define NEED_STRERROR +# if defined(sun386) +# define pid_t int +# define NEED_STRCASECMP +# endif +#endif + +#if (!defined(BSD) || (BSD < 43)) +# define NEED_MKSTEMP +# if !defined(__ultrix) && !defined(apollo) +# define NEED_STRCASECMP +# define NEED_MKTEMP +# if !defined(SVR4) +# define NEED_STRPBRK +# endif +# endif +#endif + +#if defined(USE_POSIX) +# define POSIX_SIGNALS +#endif + +/* + * Attempt to configure for type of function returned by signal-catching + * functions (which signal and sigvec.sv_handler take a pointer to). + * This can guess for BSD; otherwise, define SIG_FN externally. + */ +#ifndef SIG_FN +# ifdef BSD +# if (BSD >= 199006) || defined(__APPLE__) || defined(__osf__) || defined(sun) \ + || defined(__ultrix) || defined(apollo) || defined(POSIX_SIGNALS) +# define SIG_FN void /* signal-catching functions return void */ +# else +# define SIG_FN int /* signal-catching functions return int */ +# endif +# else /*BSD*/ +# define SIG_FN void /* signal-catching functions return void */ +# endif /*BSD*/ +#endif + +#if !defined(ntohl) && !defined(htonl) && defined(BSD) && (BSD <= 43) +/* if these aren't null macros in netinet/in.h, extern them here. */ +extern u_short htons(), ntohs(); +extern u_long htonl(), ntohl(); +#endif + +#if defined(USE_POSIX) && !defined(sun) && !defined(__sgi) \ + && !defined(__convex__) && !defined(__ultrix) && !defined(_AUX_SOURCE) +# define PORT_NONBLOCK O_NONBLOCK +# define PORT_WOULDBLK EAGAIN +#else +# define PORT_NONBLOCK O_NDELAY +# define PORT_WOULDBLK EWOULDBLOCK +#endif + +#if defined(USE_POSIX) +# define USE_SETSID +#endif + +#if defined(USE_POSIX) || !defined(SYSV) +#define USE_WAITPID +#endif + +#if !defined(USE_POSIX) +#define waitpid(x,y,z) (wait3(y,z,(struct rusage *)NULL)) +#endif + +#if defined(__APPLE__) || defined(_AIX) || defined(sun386) +# undef WIFEXITED +# undef WEXITSTATUS +# undef WIFSIGNALED +# undef WTERMSIG +#endif /* NeXT */ + +#if defined(sequent) +#define WEXITSTATUS(x) ((x).w_retcode) +#define WTERMSIG(x) ((x).w_termsig) +#endif /* sequent */ + +#if !defined(WIFEXITED) +# define WIFEXITED(x) (!(x & 0177)) +#endif +#if !defined(WEXITSTATUS) +# define WEXITSTATUS(x) (x >> 8) +#endif +#if !defined(WIFSIGNALED) +# define WIFSIGNALED(x) ((x & 0177) && ((x & 0377) != 0177)) +#endif +#if !defined(WTERMSIG) +# define WTERMSIG(x) (x & 0177) +#endif + +#ifndef S_ISDIR +# ifndef S_IFMT +# define S_IFMT 0170000 +# endif +# ifndef S_IFDIR +# define S_IFDIR 0040000 +# endif +# define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR) +#endif + +#ifndef S_ISREG +# ifndef S_IFMT +# define S_IFMT 0170000 +# endif +# ifndef S_IFREG +# define S_IFREG 0100000 +# endif +# define S_ISREG(m) ((m & S_IFMT) == S_IFREG) +#endif + +#ifndef S_ISFIFO +# ifndef S_IFMT +# define S_IFMT 0170000 +# endif +# ifndef S_IFIFO +# define S_IFIFO 0010000 +# endif +# define S_ISFIFO(m) ((m & S_IFMT) == S_IFIFO) +#endif + +#if defined(NEED_STRTOUL) && \ + (defined(__ultrix) || defined(__osf__) || defined(NeXT)) +# undef NEED_STRTOUL +#endif + +#if defined(__ultrix) || defined(__osf__) +# define MAYBE_HESIOD +#endif + +#ifndef FD_SET +#define NFDBITS 32 +#define FD_SETSIZE 32 +#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) +#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) +#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS))) +#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p))) +#endif + +#ifndef MIN +# define MIN(x, y) ((x > y) ?y :x) +#endif +#ifndef MAX +# define MAX(x, y) ((x > y) ?x :y) +#endif + +#if !defined(PATH_MAX) +# if defined(_POSIX_PATH_MAX) +# define PATH_MAX _POSIX_PATH_MAX +# else +# if defined(MAXPATHLEN) +# define PATH_MAX MAXPATHLEN +# endif +# endif +#endif + +#if defined(BSD) || defined(__osf__) || defined(__convex__) +# define HAVE_GETRUSAGE +#endif + +/* May be set in the Makefile. */ +#if defined(HAVE_GETRUSAGE) +# include +#endif + +/* + * Because Convex has true library function feof() which is + * patently wrong (it test bit _IOREAD) we need feof() as + * a macro. + */ +#if defined(__convex__) && !defined(feof) +# define feof(p) ((p)->_flag&_IOEOF) +#endif + +#if defined(M_UNIX) || defined(linux) +# define SPURIOUS_ECONNREFUSED +#endif + +/* + * Assume that a system has fchmod() unless something above says otherwise. + */ +#if !defined(HAVE_FCHMOD) +# define HAVE_FCHMOD 1 +#endif + +/* + * Prototype the functions we'll be supplying. + */ +#ifdef NEED_PUTENV +extern int putenv __P((char *)); +#endif + +#ifdef NEED_GETTIMEOFDAY +extern int gettimeofday __P((struct timeval *, struct _TIMEZONE *)); +#endif diff --git a/dns.subproj/res_comp.c b/dns.subproj/res_comp.c new file mode 100644 index 0000000..7c07818 --- /dev/null +++ b/dns.subproj/res_comp.c @@ -0,0 +1,452 @@ +/* + * 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++ 1985, 1993 + * - + * Copyright (c) 1985, 1993 + * 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-- + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$Id: res_comp.c,v 1.2 1999/10/14 21:56:45 wsanchez Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include + +#include +#include +#include + +#if defined(BSD) && (BSD >= 199103) +# include +# include +#else +# include "portability.h" +#endif + +static int dn_find __P((u_char *exp_dn, u_char *msg, + u_char **dnptrs, u_char **lastdnptr)); + +/* + * Expand compressed domain name 'comp_dn' to full domain name. + * 'msg' is a pointer to the begining of the message, + * 'eomorig' points to the first location after the message, + * 'exp_dn' is a pointer to a buffer of size 'length' for the result. + * Return size of compressed name or -1 if there was an error. + */ +int +dn_expand(msg, eomorig, comp_dn, exp_dn, length) + const u_char *msg, *eomorig, *comp_dn; + char *exp_dn; + int length; +{ + register const u_char *cp; + register char *dn; + register int n, c; + char *eom; + int len = -1, checked = 0; + + dn = exp_dn; + cp = comp_dn; + eom = exp_dn + length; + /* + * fetch next label in domain name + */ + while (n = *cp++) { + /* + * Check for indirection + */ + switch (n & INDIR_MASK) { + case 0: + if (dn != exp_dn) { + if (dn >= eom) + return (-1); + *dn++ = '.'; + } + if (dn+n >= eom) + return (-1); + checked += n + 1; + while (--n >= 0) { + if ((c = *cp++) == '.') { + if (dn + n + 2 >= eom) + return (-1); + *dn++ = '\\'; + } + *dn++ = c; + if (cp >= eomorig) /* out of range */ + return (-1); + } + break; + + case INDIR_MASK: + if (len < 0) + len = cp - comp_dn + 1; + cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff)); + if (cp < msg || cp >= eomorig) /* out of range */ + return (-1); + checked += 2; + /* + * Check for loops in the compressed name; + * if we've looked at the whole message, + * there must be a loop. + */ + if (checked >= eomorig - msg) + return (-1); + break; + + default: + return (-1); /* flag error */ + } + } + *dn = '\0'; + for (dn = exp_dn; (c = *dn) != '\0'; dn++) + if (isascii(c) && isspace(c)) + return (-1); + if (len < 0) + len = cp - comp_dn; + return (len); +} + +/* + * Compress domain name 'exp_dn' into 'comp_dn'. + * Return the size of the compressed name or -1. + * 'length' is the size of the array pointed to by 'comp_dn'. + * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0] + * is a pointer to the beginning of the message. The list ends with NULL. + * 'lastdnptr' is a pointer to the end of the arrary pointed to + * by 'dnptrs'. Side effect is to update the list of pointers for + * labels inserted into the message as we compress the name. + * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr' + * is NULL, we don't update the list. + */ +int +dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr) + const char *exp_dn; + u_char *comp_dn, **dnptrs, **lastdnptr; + int length; +{ + register u_char *cp, *dn; + register int c, l; + u_char **cpp, **lpp, *sp, *eob; + u_char *msg; + + dn = (u_char *)exp_dn; + cp = comp_dn; + eob = cp + length; + lpp = cpp = NULL; + if (dnptrs != NULL) { + if ((msg = *dnptrs++) != NULL) { + for (cpp = dnptrs; *cpp != NULL; cpp++) + ; + lpp = cpp; /* end of list to search */ + } + } else + msg = NULL; + for (c = *dn++; c != '\0'; ) { + /* look to see if we can use pointers */ + if (msg != NULL) { + if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) { + if (cp+1 >= eob) + return (-1); + *cp++ = (l >> 8) | INDIR_MASK; + *cp++ = l % 256; + return (cp - comp_dn); + } + /* not found, save it */ + if (lastdnptr != NULL && cpp < lastdnptr-1) { + *cpp++ = cp; + *cpp = NULL; + } + } + sp = cp++; /* save ptr to length byte */ + do { + if (c == '.') { + c = *dn++; + break; + } + if (c == '\\') { + if ((c = *dn++) == '\0') + break; + } + if (cp >= eob) { + if (msg != NULL) + *lpp = NULL; + return (-1); + } + *cp++ = c; + } while ((c = *dn++) != '\0'); + /* catch trailing '.'s but not '..' */ + if ((l = cp - sp - 1) == 0 && c == '\0') { + cp--; + break; + } + if (l <= 0 || l > MAXLABEL) { + if (msg != NULL) + *lpp = NULL; + return (-1); + } + *sp = l; + } + if (cp >= eob) { + if (msg != NULL) + *lpp = NULL; + return (-1); + } + *cp++ = '\0'; + return (cp - comp_dn); +} + +/* + * Skip over a compressed domain name. Return the size or -1. + */ +int +__dn_skipname(comp_dn, eom) + const u_char *comp_dn, *eom; +{ + register const u_char *cp; + register int n; + + cp = comp_dn; + while (cp < eom && (n = *cp++)) { + /* + * check for indirection + */ + switch (n & INDIR_MASK) { + case 0: /* normal case, n == len */ + cp += n; + continue; + case INDIR_MASK: /* indirection */ + cp++; + break; + default: /* illegal type */ + return (-1); + } + break; + } + if (cp > eom) + return (-1); + return (cp - comp_dn); +} + +static int +mklower(ch) + register int ch; +{ + if (isascii(ch) && isupper(ch)) + return (tolower(ch)); + return (ch); +} + +/* + * Search for expanded name from a list of previously compressed names. + * Return the offset from msg if found or -1. + * dnptrs is the pointer to the first name on the list, + * not the pointer to the start of the message. + */ +static int +dn_find(exp_dn, msg, dnptrs, lastdnptr) + u_char *exp_dn, *msg; + u_char **dnptrs, **lastdnptr; +{ + register u_char *dn, *cp, **cpp; + register int n; + u_char *sp; + + for (cpp = dnptrs; cpp < lastdnptr; cpp++) { + dn = exp_dn; + sp = cp = *cpp; + while (n = *cp++) { + /* + * check for indirection + */ + switch (n & INDIR_MASK) { + case 0: /* normal case, n == len */ + while (--n >= 0) { + if (*dn == '.') + goto next; + if (*dn == '\\') + dn++; + if (mklower(*dn++) != mklower(*cp++)) + goto next; + } + if ((n = *dn++) == '\0' && *cp == '\0') + return (sp - msg); + if (n == '.') + continue; + goto next; + + case INDIR_MASK: /* indirection */ + cp = msg + (((n & 0x3f) << 8) | *cp); + break; + + default: /* illegal type */ + return (-1); + } + } + if (*dn == '\0') + return (sp - msg); + next: ; + } + return (-1); +} + +/* + * Routines to insert/extract short/long's. + */ + +u_int16_t +_getshort(msgp) + register const u_char *msgp; +{ + register u_int16_t u; + + GETSHORT(u, msgp); + return (u); +} + +#if defined(__APPLE__) +/* + * nExt machines have some funky library conventions, which we must maintain. + */ +u_int16_t +res_getshort(msgp) + register const u_char *msgp; +{ + return (_getshort(msgp)); +} +#endif + +u_int32_t +_getlong(msgp) + register const u_char *msgp; +{ + register u_int32_t u; + + GETLONG(u, msgp); + return (u); +} + +void +#if defined(__STDC__) || defined(__cplusplus) +__putshort(register u_int16_t s, register u_char *msgp) /* must match proto */ +#else +__putshort(s, msgp) + register u_int16_t s; + register u_char *msgp; +#endif +{ + PUTSHORT(s, msgp); +} + +void +__putlong(l, msgp) + register u_int32_t l; + register u_char *msgp; +{ + PUTLONG(l, msgp); +} + +#ifdef ultrix +/* ultrix 4.0 had some icky packaging in its libc.a. alias for it here. + * there is more gunk of this kind over in res_debug.c. + */ +#undef putshort +void +#if defined(__STDC__) || defined(__cplusplus) +putshort(register u_short s, register u_char *msgp) +#else +putshort(s, msgp) + register u_short s; + register u_char *msgp; +#endif +{ + __putshort(s, msgp); +} +#undef putlong +void +putlong(l, msgp) + register u_int32_t l; + register u_char *msgp; +{ + __putlong(l, msgp); +} + +#undef dn_skipname +dn_skipname(comp_dn, eom) + const u_char *comp_dn, *eom; +{ + return (__dn_skipname(comp_dn, eom)); +} +#endif /* Ultrix 4.0 hackery */ diff --git a/dns.subproj/res_data.c b/dns.subproj/res_data.c new file mode 100644 index 0000000..93d648d --- /dev/null +++ b/dns.subproj/res_data.c @@ -0,0 +1,46 @@ +/* + * 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@ + */ +/* + * This file contains global data but it is a `private_extern' in the + * shared library so that its address and size can change. + */ + +#if defined(__APPLE__) + +#include +#include +#include +#include +#include +#include + +/* From res_init.c */ + +struct __res_state _res = {0}; + +/* From getnetent.c */ + +int _net_stayopen = 0; + +#endif /* NeXT */ diff --git a/dns.subproj/res_debug.c b/dns.subproj/res_debug.c new file mode 100644 index 0000000..519104a --- /dev/null +++ b/dns.subproj/res_debug.c @@ -0,0 +1,857 @@ +/* + * 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++ 1985, 1990, 1993 + * - + * Copyright (c) 1985, 1990, 1993 + * 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-- + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$Id: res_debug.c,v 1.2 1999/10/14 21:56:45 wsanchez Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include + +#include +#include +#include +#if defined(BSD) && (BSD >= 199103) +# include +#else +# include "portability.h" +#endif + +#if defined(USE_OPTIONS_H) +# include "options.h" +#endif + +const char *_res_opcodes[] = { + "QUERY", + "IQUERY", + "CQUERYM", + "CQUERYU", /* experimental */ + "NOTIFY", /* experimental */ + "5", + "6", + "7", + "8", + "UPDATEA", + "UPDATED", + "UPDATEDA", + "UPDATEM", + "UPDATEMA", + "ZONEINIT", + "ZONEREF", +}; + +const char *_res_resultcodes[] = { + "NOERROR", + "FORMERR", + "SERVFAIL", + "NXDOMAIN", + "NOTIMP", + "REFUSED", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13", + "14", + "NOCHANGE", +}; + +/* XXX: we should use getservbyport() instead. */ +static const char * +dewks(wks) + int wks; +{ + static char nbuf[20]; + + switch (wks) { + case 5: return "rje"; + case 7: return "echo"; + case 9: return "discard"; + case 11: return "systat"; + case 13: return "daytime"; + case 15: return "netstat"; + case 17: return "qotd"; + case 19: return "chargen"; + case 20: return "ftp-data"; + case 21: return "ftp"; + case 23: return "telnet"; + case 25: return "smtp"; + case 37: return "time"; + case 39: return "rlp"; + case 42: return "name"; + case 43: return "whois"; + case 53: return "domain"; + case 57: return "apts"; + case 59: return "apfs"; + case 67: return "bootps"; + case 68: return "bootpc"; + case 69: return "tftp"; + case 77: return "rje"; + case 79: return "finger"; + case 87: return "link"; + case 95: return "supdup"; + case 100: return "newacct"; + case 101: return "hostnames"; + case 102: return "iso-tsap"; + case 103: return "x400"; + case 104: return "x400-snd"; + case 105: return "csnet-ns"; + case 109: return "pop-2"; + case 111: return "sunrpc"; + case 113: return "auth"; + case 115: return "sftp"; + case 117: return "uucp-path"; + case 119: return "nntp"; + case 121: return "erpc"; + case 123: return "ntp"; + case 133: return "statsrv"; + case 136: return "profile"; + case 144: return "NeWS"; + case 161: return "snmp"; + case 162: return "snmp-trap"; + case 170: return "print-srv"; + default: (void) sprintf(nbuf, "%d", wks); return (nbuf); + } +} + +/* XXX: we should use getprotobynumber() instead. */ +static const char * +deproto(protonum) + int protonum; +{ + static char nbuf[20]; + + switch (protonum) { + case 1: return "icmp"; + case 2: return "igmp"; + case 3: return "ggp"; + case 5: return "st"; + case 6: return "tcp"; + case 7: return "ucl"; + case 8: return "egp"; + case 9: return "igp"; + case 11: return "nvp-II"; + case 12: return "pup"; + case 16: return "chaos"; + case 17: return "udp"; + default: (void) sprintf(nbuf, "%d", protonum); return (nbuf); + } +} + +static const u_char * +do_rrset(msg, len, cp, cnt, pflag, file, hs) + int cnt, pflag, len; + const u_char *cp, *msg; + const char *hs; + FILE *file; +{ + int n; + int sflag; + + /* + * Print answer records. + */ + sflag = (_res.pfcode & pflag); + if (n = ntohs(cnt)) { + if ((!_res.pfcode) || + ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) + fprintf(file, hs); + while (--n >= 0) { + if ((!_res.pfcode) || sflag) { + cp = p_rr(cp, msg, file); + } else { + unsigned int dlen; + cp += __dn_skipname(cp, cp + MAXCDNAME); + cp += INT16SZ; + cp += INT16SZ; + cp += INT32SZ; + dlen = _getshort((u_char*)cp); + cp += INT16SZ; + cp += dlen; + } + if ((cp - msg) > len) + return (NULL); + } + if ((!_res.pfcode) || + ((sflag) && (_res.pfcode & RES_PRF_HEAD1))) + putc('\n', file); + } + return (cp); +} + +void +__p_query(msg) + const u_char *msg; +{ + __fp_query(msg, stdout); +} + +#ifdef ultrix +/* ultrix 4.0's packaging has some icky packaging. alias for it here. + * there is more junk of this kind over in res_comp.c. + */ +void +p_query(msg) + const u_char *msg; +{ + __p_query(msg); +} +#endif + +/* + * Print the current options. + * This is intended to be primarily a debugging routine. + */ +void +__fp_resstat(statp, file) + struct __res_state *statp; + FILE *file; +{ + register u_long mask; + + fprintf(file, ";; res options:"); + if (!statp) + statp = &_res; + for (mask = 1; mask != 0; mask <<= 1) + if (statp->options & mask) + fprintf(file, " %s", p_option(mask)); + putc('\n', file); +} + +/* + * Print the contents of a query. + * This is intended to be primarily a debugging routine. + */ +void +__fp_nquery(msg, len, file) + const u_char *msg; + int len; + FILE *file; +{ + register const u_char *cp, *endMark; + register const HEADER *hp; + register int n; + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) + return; + +#define TruncTest(x) if (x >= endMark) goto trunc +#define ErrorTest(x) if (x == NULL) goto error + + /* + * Print header fields. + */ + hp = (HEADER *)msg; + cp = msg + HFIXEDSZ; + endMark = cp + len; + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || hp->rcode) { + fprintf(file, ";; ->>HEADER<<- opcode: %s, status: %s, id: %d", + _res_opcodes[hp->opcode], + _res_resultcodes[hp->rcode], + ntohs(hp->id)); + putc('\n', file); + } + putc(';', file); + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) { + fprintf(file, "; flags:"); + if (hp->qr) + fprintf(file, " qr"); + if (hp->aa) + fprintf(file, " aa"); + if (hp->tc) + fprintf(file, " tc"); + if (hp->rd) + fprintf(file, " rd"); + if (hp->ra) + fprintf(file, " ra"); + } + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) { + fprintf(file, "; Ques: %d", ntohs(hp->qdcount)); + fprintf(file, ", Ans: %d", ntohs(hp->ancount)); + fprintf(file, ", Auth: %d", ntohs(hp->nscount)); + fprintf(file, ", Addit: %d", ntohs(hp->arcount)); + } + if ((!_res.pfcode) || (_res.pfcode & + (RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) { + putc('\n',file); + } + /* + * Print question records. + */ + if (n = ntohs(hp->qdcount)) { + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) + fprintf(file, ";; QUESTIONS:\n"); + while (--n >= 0) { + fprintf(file, ";;\t"); + TruncTest(cp); + cp = p_cdnname(cp, msg, len, file); + ErrorTest(cp); + TruncTest(cp); + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) + fprintf(file, ", type = %s", + __p_type(_getshort((u_char*)cp))); + cp += INT16SZ; + TruncTest(cp); + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_QUES)) + fprintf(file, ", class = %s\n", + __p_class(_getshort((u_char*)cp))); + cp += INT16SZ; + putc('\n', file); + } + } + /* + * Print authoritative answer records + */ + TruncTest(cp); + cp = do_rrset(msg, len, cp, hp->ancount, RES_PRF_ANS, file, + ";; ANSWERS:\n"); + ErrorTest(cp); + + /* + * print name server records + */ + TruncTest(cp); + cp = do_rrset(msg, len, cp, hp->nscount, RES_PRF_AUTH, file, + ";; AUTHORITY RECORDS:\n"); + ErrorTest(cp); + + TruncTest(cp); + /* + * print additional records + */ + cp = do_rrset(msg, len, cp, hp->arcount, RES_PRF_ADD, file, + ";; ADDITIONAL RECORDS:\n"); + ErrorTest(cp); + return; + trunc: + fprintf(file, "\n;; ...truncated\n"); + return; + error: + fprintf(file, "\n;; ...malformed\n"); +} + +void +__fp_query(msg, file) + const u_char *msg; + FILE *file; +{ + fp_nquery(msg, PACKETSZ, file); +} + +const u_char * +__p_cdnname(cp, msg, len, file) + const u_char *cp, *msg; + int len; + FILE *file; +{ + char name[MAXDNAME]; + int n; + + if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0) + return (NULL); + if (name[0] == '\0') + putc('.', file); + else + fputs(name, file); + return (cp + n); +} + +const u_char * +__p_cdname(cp, msg, file) + const u_char *cp, *msg; + FILE *file; +{ + return (p_cdnname(cp, msg, PACKETSZ, file)); +} + +/* XXX: the rest of these functions need to become length-limited, too. (vix) + */ + +const u_char * +__p_fqname(cp, msg, file) + const u_char *cp, *msg; + FILE *file; +{ + char name[MAXDNAME]; + int n; + + if ((n = dn_expand(msg, cp + MAXCDNAME, cp, name, sizeof name)) < 0) + return (NULL); + if (name[0] == '\0') { + putc('.', file); + } else { + fputs(name, file); + if (name[strlen(name) - 1] != '.') + putc('.', file); + } + return (cp + n); +} + +/* + * Print resource record fields in human readable form. + */ +const u_char * +__p_rr(cp, msg, file) + const u_char *cp, *msg; + FILE *file; +{ + int type, class, dlen, n, c; + struct in_addr inaddr; + const u_char *cp1, *cp2; + u_int32_t tmpttl, t; + int lcnt; + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; + return (NULL); + } + if ((cp = p_fqname(cp, msg, file)) == NULL) + return (NULL); /* compression error */ + type = _getshort((u_char*)cp); + cp += INT16SZ; + class = _getshort((u_char*)cp); + cp += INT16SZ; + tmpttl = _getlong((u_char*)cp); + cp += INT32SZ; + dlen = _getshort((u_char*)cp); + cp += INT16SZ; + cp1 = cp; + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_TTLID)) + fprintf(file, "\t%lu", (u_long)tmpttl); + if ((!_res.pfcode) || (_res.pfcode & RES_PRF_CLASS)) + fprintf(file, "\t%s", __p_class(class)); + fprintf(file, "\t%s", __p_type(type)); + /* + * Print type specific data, if appropriate + */ + switch (type) { + case T_A: + switch (class) { + case C_IN: + case C_HS: + bcopy(cp, (char *)&inaddr, INADDRSZ); + if (dlen == 4) { + fprintf(file, "\t%s", inet_ntoa(inaddr)); + cp += dlen; + } else if (dlen == 7) { + char *address; + u_char protocol; + u_short port; + + address = inet_ntoa(inaddr); + cp += INADDRSZ; + protocol = *(u_char*)cp; + cp += sizeof(u_char); + port = _getshort((u_char*)cp); + cp += INT16SZ; + fprintf(file, "\t%s\t; proto %d, port %d", + address, protocol, port); + } + break; + default: + cp += dlen; + } + break; + case T_CNAME: + case T_MB: + case T_MG: + case T_MR: + case T_NS: + case T_PTR: + putc('\t', file); + if ((cp = p_fqname(cp, msg, file)) == NULL) + return (NULL); + break; + + case T_HINFO: + case T_ISDN: + cp2 = cp + dlen; + if (n = *cp++) { + fprintf(file, "\t%.*s", n, cp); + cp += n; + } + if ((cp < cp2) && (n = *cp++)) { + fprintf(file, "\t%.*s", n, cp); + cp += n; + } else if (type == T_HINFO) + fprintf(file, "\n;; *** Warning *** OS-type missing"); + break; + + case T_SOA: + putc('\t', file); + if ((cp = p_fqname(cp, msg, file)) == NULL) + return (NULL); + putc(' ', file); + if ((cp = p_fqname(cp, msg, file)) == NULL) + return (NULL); + fputs(" (\n", file); + t = _getlong((u_char*)cp); cp += INT32SZ; + fprintf(file, "\t\t\t%lu\t; serial\n", (u_long)t); + t = _getlong((u_char*)cp); cp += INT32SZ; + fprintf(file, "\t\t\t%lu\t; refresh (%s)\n", + (u_long)t, __p_time(t)); + t = _getlong((u_char*)cp); cp += INT32SZ; + fprintf(file, "\t\t\t%lu\t; retry (%s)\n", + (u_long)t, __p_time(t)); + t = _getlong((u_char*)cp); cp += INT32SZ; + fprintf(file, "\t\t\t%lu\t; expire (%s)\n", + (u_long)t, __p_time(t)); + t = _getlong((u_char*)cp); cp += INT32SZ; + fprintf(file, "\t\t\t%lu )\t; minimum (%s)", + (u_long)t, __p_time(t)); + break; + + case T_MX: + case T_AFSDB: + case T_RT: + fprintf(file, "\t%d ", _getshort((u_char*)cp)); + cp += INT16SZ; + if ((cp = p_fqname(cp, msg, file)) == NULL) + return (NULL); + break; + + case T_PX: + fprintf(file, "\t%d ", _getshort((u_char*)cp)); + cp += INT16SZ; + if ((cp = p_fqname(cp, msg, file)) == NULL) + return (NULL); + putc(' ', file); + if ((cp = p_fqname(cp, msg, file)) == NULL) + return (NULL); + break; + + case T_TXT: + case T_X25: + (void) fputs("\t\"", file); + cp2 = cp1 + dlen; + while (cp < cp2) { + if (n = (unsigned char) *cp++) { + for (c = n; c > 0 && cp < cp2; c--) + if ((*cp == '\n') || (*cp == '"')) { + (void) putc('\\', file); + (void) putc(*cp++, file); + } else + (void) putc(*cp++, file); + } + } + putc('"', file); + break; + + case T_NSAP: + (void) fprintf(file, "\t%s", inet_nsap_ntoa(dlen, cp, NULL)); + cp += dlen; + break; + + case T_MINFO: + case T_RP: + putc('\t', file); + if ((cp = p_fqname(cp, msg, file)) == NULL) + return (NULL); + putc(' ', file); + if ((cp = p_fqname(cp, msg, file)) == NULL) + return (NULL); + break; + + case T_UINFO: + putc('\t', file); + fputs((char *)cp, file); + cp += dlen; + break; + + case T_UID: + case T_GID: + if (dlen == 4) { + fprintf(file, "\t%u", _getlong((u_char*)cp)); + cp += INT32SZ; + } + break; + + case T_WKS: + if (dlen < INT32SZ + 1) + break; + bcopy(cp, (char *)&inaddr, INADDRSZ); + cp += INT32SZ; + fprintf(file, "\t%s %s ( ", + inet_ntoa(inaddr), + deproto((int) *cp)); + cp += sizeof(u_char); + n = 0; + lcnt = 0; + while (cp < cp1 + dlen) { + c = *cp++; + do { + if (c & 0200) { + if (lcnt == 0) { + fputs("\n\t\t\t", file); + lcnt = 5; + } + fputs(dewks(n), file); + putc(' ', file); + lcnt--; + } + c <<= 1; + } while (++n & 07); + } + putc(')', file); + break; + +#ifdef ALLOW_T_UNSPEC + case T_UNSPEC: + { + int NumBytes = 8; + u_char *DataPtr; + int i; + + if (dlen < NumBytes) NumBytes = dlen; + fprintf(file, "\tFirst %d bytes of hex data:", + NumBytes); + for (i = 0, DataPtr = cp; i < NumBytes; i++, DataPtr++) + fprintf(file, " %x", *DataPtr); + cp += dlen; + } + break; +#endif /* ALLOW_T_UNSPEC */ + + default: + fprintf(file, "\t?%d?", type); + cp += dlen; + } +#if 0 + fprintf(file, "\t; dlen=%d, ttl %s\n", dlen, __p_time(tmpttl)); +#else + putc('\n', file); +#endif + if (cp - cp1 != dlen) { + fprintf(file, ";; packet size error (found %d, dlen was %d)\n", + cp - cp1, dlen); + cp = NULL; + } + return (cp); +} + +/* + * Return a string for the type + */ +const char * +__p_type(type) + int type; +{ + static char nbuf[20]; + + switch (type) { + case T_A: return "A"; + case T_NS: return "NS"; + case T_CNAME: return "CNAME"; + case T_SOA: return "SOA"; + case T_MB: return "MB"; + case T_MG: return "MG"; + case T_MR: return "MR"; + case T_NULL: return "NULL"; + case T_WKS: return "WKS"; + case T_PTR: return "PTR"; + case T_HINFO: return "HINFO"; + case T_MINFO: return "MINFO"; + case T_MX: return "MX"; + case T_TXT: return "TXT"; + case T_RP: return "RP"; + case T_AFSDB: return "AFSDB"; + case T_X25: return "X25"; + case T_ISDN: return "ISDN"; + case T_RT: return "RT"; + case T_NSAP: return "NSAP"; + case T_NSAP_PTR: return "NSAP_PTR"; + case T_SIG: return "SIG"; + case T_KEY: return "KEY"; + case T_PX: return "PX"; + case T_GPOS: return "GPOS"; + case T_AAAA: return "AAAA"; + case T_LOC: return "LOC"; + case T_AXFR: return "AXFR"; + case T_MAILB: return "MAILB"; + case T_MAILA: return "MAILA"; + case T_ANY: return "ANY"; + case T_UINFO: return "UINFO"; + case T_UID: return "UID"; + case T_GID: return "GID"; +#ifdef ALLOW_T_UNSPEC + case T_UNSPEC: return "UNSPEC"; +#endif /* ALLOW_T_UNSPEC */ + default: (void)sprintf(nbuf, "%d", type); return (nbuf); + } +} + +/* + * Return a mnemonic for class + */ +const char * +__p_class(class) + int class; +{ + static char nbuf[20]; + + switch (class) { + case C_IN: return "IN"; + case C_HS: return "HS"; + case C_ANY: return "ANY"; + default: (void)sprintf(nbuf, "%d", class); return (nbuf); + } +} + +/* + * Return a mnemonic for an option + */ +const char * +__p_option(option) + u_long option; +{ + static char nbuf[40]; + + switch (option) { + case RES_INIT: return "init"; + case RES_DEBUG: return "debug"; + case RES_AAONLY: return "aaonly(unimpl)"; + case RES_USEVC: return "usevc"; + case RES_PRIMARY: return "primry(unimpl)"; + case RES_IGNTC: return "igntc"; + case RES_RECURSE: return "recurs"; + case RES_DEFNAMES: return "defnam"; + case RES_STAYOPEN: return "styopn"; + case RES_DNSRCH: return "dnsrch"; + case RES_INSECURE1: return "insecure1"; + case RES_INSECURE2: return "insecure2"; + default: sprintf(nbuf, "?0x%lx?", (u_long)option); + return (nbuf); + } +} + +/* + * Return a mnemonic for a time to live + */ +char * +__p_time(value) + u_int32_t value; +{ + static char nbuf[40]; + int secs, mins, hours, days; + register char *p; + + if (value == 0) { + strcpy(nbuf, "0 secs"); + return (nbuf); + } + + secs = value % 60; + value /= 60; + mins = value % 60; + value /= 60; + hours = value % 24; + value /= 24; + days = value; + value = 0; + +#define PLURALIZE(x) x, (x == 1) ? "" : "s" + p = nbuf; + if (days) { + (void)sprintf(p, "%d day%s", PLURALIZE(days)); + while (*++p); + } + if (hours) { + if (days) + *p++ = ' '; + (void)sprintf(p, "%d hour%s", PLURALIZE(hours)); + while (*++p); + } + if (mins) { + if (days || hours) + *p++ = ' '; + (void)sprintf(p, "%d min%s", PLURALIZE(mins)); + while (*++p); + } + if (secs || ! (days || hours || mins)) { + if (days || hours || mins) + *p++ = ' '; + (void)sprintf(p, "%d sec%s", PLURALIZE(secs)); + } + return (nbuf); +} diff --git a/dns.subproj/res_init.c b/dns.subproj/res_init.c new file mode 100644 index 0000000..5eb64dd --- /dev/null +++ b/dns.subproj/res_init.c @@ -0,0 +1,675 @@ +/* + * 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++ 1985, 1989, 1993 + * - + * Copyright (c) 1985, 1989, 1993 + * 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-- + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93"; +static char rcsid[] = "$Id: res_init.c,v 1.3 2000/08/01 23:12:13 lindak Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#if defined(BSD) && (BSD >= 199103) +# include +# include +# include +#else +# include "portability.h" +#endif + +/*-------------------------------------- info about "sortlist" -------------- + * Marc Majka 1994/04/16 + * Allan Nathanson 1994/10/29 (BIND 4.9.3.x) + * + * NetInfo resolver configuration directory support. + * + * Allow a NetInfo directory to be created in the hierarchy which + * contains the same information as the resolver configuration file. + * + * - The local domain name is stored as the value of the "domain" property. + * - The Internet address(es) of the name server(s) are stored as values + * of the "nameserver" property. + * - The name server addresses are stored as values of the "nameserver" + * property. + * - The search list for host-name lookup is stored as values of the + * "search" property. + * - The sortlist comprised of IP address netmask pairs are stored as + * values of the "sortlist" property. The IP address and optional netmask + * should be seperated by a slash (/) or ampersand (&) character. + * - Internal resolver variables can be set from the value of the "options" + * property. + */ +#if defined(__APPLE__) +# include +# define NI_PATH_RESCONF "/locations/resolver" +# define NI_TIMEOUT 10 +static int netinfo_res_init __P((int *haveenv, int *havesearch)); +#endif + +#if defined(USE_OPTIONS_H) +# include "options.h" +#endif + +static void res_setoptions __P((char *, char *)); + +#ifdef RESOLVSORT +static const char sort_mask[] = "/&"; +#define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL) +static u_int32_t net_mask __P((struct in_addr)); +#endif + +#if !defined(isascii) /* XXX - could be a function */ +# define isascii(c) (!(c & 0200)) +#endif + +/* + * Resolver state default settings. + */ + +#if defined(__APPLE__) +extern +#endif /* NeXT */ +struct __res_state _res; + +/* + * Set up default settings. If the configuration file exist, the values + * there will have precedence. Otherwise, the server address is set to + * INADDR_ANY and the default domain name comes from the gethostname(). + * + * An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1 + * rather than INADDR_ANY ("0.0.0.0") as the default name server address + * since it was noted that INADDR_ANY actually meant ``the first interface + * you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface, + * it had to be "up" in order for you to reach your own name server. It + * was later decided that since the recommended practice is to always + * install local static routes through 127.0.0.1 for all your network + * interfaces, that we could solve this problem without a code change. + * + * The configuration file should always be used, since it is the only way + * to specify a default domain. If you are running a server on your local + * machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1" + * in the configuration file. + * + * Return 0 if completes successfully, -1 on error + */ +int +res_init() +{ + register FILE *fp; + register char *cp, **pp; + register int n; + char buf[BUFSIZ]; + int nserv = 0; /* number of nameserver records read from file */ + int haveenv = 0; + int havesearch = 0; +#ifdef RESOLVSORT + int nsort = 0; + char *net; +#endif +#ifndef RFC1535 + int dots; +#endif + + /* + * These three fields used to be statically initialized. This made + * it hard to use this code in a shared library. It is necessary, + * now that we're doing dynamic initialization here, that we preserve + * the old semantics: if an application modifies one of these three + * fields of _res before res_init() is called, res_init() will not + * alter them. Of course, if an application is setting them to + * _zero_ before calling res_init(), hoping to override what used + * to be the static default, we can't detect it and unexpected results + * will follow. Zero for any of these fields would make no sense, + * so one can safely assume that the applications were already getting + * unexpected results. + * + * _res.options is tricky since some apps were known to diddle the bits + * before res_init() was first called. We can't replicate that semantic + * with dynamic initialization (they may have turned bits off that are + * set in RES_DEFAULT). Our solution is to declare such applications + * "broken". They could fool us by setting RES_INIT but none do (yet). + */ + if (!_res.retrans) + _res.retrans = RES_TIMEOUT; + if (!_res.retry) + _res.retry = 4; + if (!(_res.options & RES_INIT)) + _res.options = RES_DEFAULT; + + /* + * This one used to initialize implicitly to zero, so unless the app + * has set it to something in particular, we can randomize it now. + */ + if (!_res.id) + _res.id = res_randomid(); + +#ifdef USELOOPBACK + _res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1); +#else + _res.nsaddr.sin_addr.s_addr = INADDR_ANY; +#endif + _res.nsaddr.sin_family = AF_INET; + _res.nsaddr.sin_port = htons(NAMESERVER_PORT); + _res.nscount = 1; + _res.ndots = 1; + _res.pfcode = 0; + + /* Allow user to override the local domain definition */ + if ((cp = getenv("LOCALDOMAIN")) != NULL) { + (void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); + haveenv++; + + /* + * Set search list to be blank-separated strings + * from rest of env value. Permits users of LOCALDOMAIN + * to still have a search list, and anyone to set the + * one that they want to use as an individual (even more + * important now that the rfc1535 stuff restricts searches) + */ + cp = _res.defdname; + pp = _res.dnsrch; + *pp++ = cp; + for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) { + if (*cp == '\n') /* silly backwards compat */ + break; + else if (*cp == ' ' || *cp == '\t') { + *cp = 0; + n = 1; + } else if (n) { + *pp++ = cp; + n = 0; + havesearch = 1; + } + } + /* null terminate last domain if there are excess */ + while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n') + cp++; + *cp = '\0'; + *pp++ = 0; + } + +#define MATCH(line, name) \ + (!strncmp(line, name, sizeof(name) - 1) && \ + (line[sizeof(name) - 1] == ' ' || \ + line[sizeof(name) - 1] == '\t')) + + if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) { + /* read the config file */ + while (fgets(buf, sizeof(buf), fp) != NULL) { + /* skip comments */ + if (*buf == ';' || *buf == '#') + continue; + /* read default domain name */ + if (MATCH(buf, "domain")) { + if (haveenv) /* skip if have from environ */ + continue; + cp = buf + sizeof("domain") - 1; + while (*cp == ' ' || *cp == '\t') + cp++; + if ((*cp == '\0') || (*cp == '\n')) + continue; + strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); + if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL) + *cp = '\0'; + havesearch = 0; + continue; + } + /* set search list */ + if (MATCH(buf, "search")) { + if (haveenv) /* skip if have from environ */ + continue; + cp = buf + sizeof("search") - 1; + while (*cp == ' ' || *cp == '\t') + cp++; + if ((*cp == '\0') || (*cp == '\n')) + continue; + strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1); + if ((cp = strchr(_res.defdname, '\n')) != NULL) + *cp = '\0'; + /* + * Set search list to be blank-separated strings + * on rest of line. + */ + cp = _res.defdname; + pp = _res.dnsrch; + *pp++ = cp; + for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) { + if (*cp == ' ' || *cp == '\t') { + *cp = 0; + n = 1; + } else if (n) { + *pp++ = cp; + n = 0; + } + } + /* null terminate last domain if there are excess */ + while (*cp != '\0' && *cp != ' ' && *cp != '\t') + cp++; + *cp = '\0'; + *pp++ = 0; + havesearch = 1; + continue; + } + /* read nameservers to query */ + if (MATCH(buf, "nameserver") && nserv < MAXNS) { + struct in_addr a; + + cp = buf + sizeof("nameserver") - 1; + while (*cp == ' ' || *cp == '\t') + cp++; + if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) { + _res.nsaddr_list[nserv].sin_addr = a; + _res.nsaddr_list[nserv].sin_family = AF_INET; + _res.nsaddr_list[nserv].sin_port = + htons(NAMESERVER_PORT); + nserv++; + } + continue; + } +#ifdef RESOLVSORT + if (MATCH(buf, "sortlist")) { + struct in_addr a; + + cp = buf + sizeof("sortlist") - 1; + while (nsort < MAXRESOLVSORT) { + while (*cp == ' ' || *cp == '\t') + cp++; + if (*cp == '\0' || *cp == '\n' || *cp == ';') + break; + net = cp; + while (*cp && !ISSORTMASK(*cp) && *cp != ';' && + isascii(*cp) && !isspace(*cp)) + cp++; + n = *cp; + *cp = 0; + if (inet_aton(net, &a)) { + _res.sort_list[nsort].addr = a; + if (ISSORTMASK(n)) { + *cp++ = n; + net = cp; + while (*cp && *cp != ';' && + isascii(*cp) && !isspace(*cp)) + cp++; + n = *cp; + *cp = 0; + if (inet_aton(net, &a)) { + _res.sort_list[nsort].mask = a.s_addr; + } else { + _res.sort_list[nsort].mask = + net_mask(_res.sort_list[nsort].addr); + } + } else { + _res.sort_list[nsort].mask = + net_mask(_res.sort_list[nsort].addr); + } + nsort++; + } + *cp = n; + } + continue; + } +#endif + if (MATCH(buf, "options")) { + res_setoptions(buf + sizeof("options") - 1, "conf"); + continue; + } + } + if (nserv > 1) + _res.nscount = nserv; +#ifdef RESOLVSORT + _res.nsort = nsort; +#endif + (void) fclose(fp); + } +#ifdef __APPLE__ + else netinfo_res_init(&haveenv, &havesearch); +#endif + + if (_res.defdname[0] == 0 && + gethostname(buf, sizeof(_res.defdname) - 1) == 0 && + (cp = strchr(buf, '.')) != NULL) + strcpy(_res.defdname, cp + 1); + + /* find components of local domain that might be searched */ + if (havesearch == 0) { + pp = _res.dnsrch; + *pp++ = _res.defdname; + *pp = NULL; + +#ifndef RFC1535 + dots = 0; + for (cp = _res.defdname; *cp; cp++) + dots += (*cp == '.'); + + cp = _res.defdname; + while (pp < _res.dnsrch + MAXDFLSRCH) { + if (dots < LOCALDOMAINPARTS) + break; + cp = strchr(cp, '.') + 1; /* we know there is one */ + *pp++ = cp; + dots--; + } + *pp = NULL; +#ifdef DEBUG + if (_res.options & RES_DEBUG) { + printf(";; res_init()... default dnsrch list:\n"); + for (pp = _res.dnsrch; *pp; pp++) + printf(";;\t%s\n", *pp); + printf(";;\t..END..\n"); + } +#endif /* DEBUG */ +#endif /* !RFC1535 */ + } + + if ((cp = getenv("RES_OPTIONS")) != NULL) + res_setoptions(cp, "env"); + _res.options |= RES_INIT; + return (0); +} + +static void +res_setoptions(options, source) + char *options, *source; +{ + char *cp = options; + int i; + +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf(";; res_setoptions(\"%s\", \"%s\")...\n", + options, source); +#endif + while (*cp) { + /* skip leading and inner runs of spaces */ + while (*cp == ' ' || *cp == '\t') + cp++; + /* search for and process individual options */ + if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) { + i = atoi(cp + sizeof("ndots:") - 1); + if (i <= RES_MAXNDOTS) + _res.ndots = i; + else + _res.ndots = RES_MAXNDOTS; +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf(";;\tndots=%d\n", _res.ndots); +#endif + } else if (!strncmp(cp, "debug", sizeof("debug") - 1)) { +#ifdef DEBUG + if (!(_res.options & RES_DEBUG)) { + printf(";; res_setoptions(\"%s\", \"%s\")..\n", + options, source); + _res.options |= RES_DEBUG; + } + printf(";;\tdebug\n"); +#endif + } else { + /* XXX - print a warning here? */ + } + /* skip to next run of spaces */ + while (*cp && *cp != ' ' && *cp != '\t') + cp++; + } +} + +#ifdef RESOLVSORT +/* XXX - should really support CIDR which means explicit masks always. */ +static u_int32_t +net_mask(in) /* XXX - should really use system's version of this */ + struct in_addr in; +{ + register u_int32_t i = ntohl(in.s_addr); + + if (IN_CLASSA(i)) + return (htonl(IN_CLASSA_NET)); + else if (IN_CLASSB(i)) + return (htonl(IN_CLASSB_NET)); + return (htonl(IN_CLASSC_NET)); +} +#endif + +#ifdef __APPLE__ +static int +netinfo_res_init(haveenv, havesearch) + int *haveenv; + int *havesearch; +{ + register int n; + void *domain, *parent; + ni_id dir; + ni_status status; + ni_namelist nl; + int nserv = 0; +#ifdef RESOLVSORT + int nsort = 0; +#endif + + status = ni_open(NULL, ".", &domain); + if (status == NI_OK) { + ni_setreadtimeout(domain, NI_TIMEOUT); + ni_setabort(domain, 1); + + /* climb the NetInfo hierarchy to find a resolver directory */ + while (status == NI_OK) { + status = ni_pathsearch(domain, &dir, NI_PATH_RESCONF); + if (status == NI_OK) { + /* found a resolver directory */ + + if (*haveenv == 0) { + /* get the default domain name */ + status = ni_lookupprop(domain, &dir, "domain", &nl); + if (status == NI_OK && nl.ni_namelist_len > 0) { + (void)strncpy(_res.defdname, + nl.ni_namelist_val[0], + sizeof(_res.defdname) - 1); + _res.defdname[sizeof(_res.defdname) - 1] = '\0'; + ni_namelist_free(&nl); + *havesearch = 0; + } + + /* get search list */ + status = ni_lookupprop(domain, &dir, "search", &nl); + if (status == NI_OK && nl.ni_namelist_len > 0) { + (void)strncpy(_res.defdname, + nl.ni_namelist_val[0], + sizeof(_res.defdname) - 1); + _res.defdname[sizeof(_res.defdname) - 1] = '\0'; + /* copy */ + for (n = 0; + n < nl.ni_namelist_len && n < MAXDNSRCH; + n++) { + /* duplicate up to MAXDNSRCH servers */ + char *cp = nl.ni_namelist_val[n]; + _res.dnsrch[n] = + strcpy((char *)malloc(strlen(cp) + 1), cp); + } + ni_namelist_free(&nl); + *havesearch = 1; + } + } + + /* get list of nameservers */ + status = ni_lookupprop(domain, &dir, "nameserver", &nl); + if (status == NI_OK && nl.ni_namelist_len > 0) { + /* copy up to MAXNS servers */ + for (n = 0; + n < nl.ni_namelist_len && nserv < MAXNS; + n++) { + struct in_addr a; + + if (inet_aton(nl.ni_namelist_val[n], &a)) { + _res.nsaddr_list[nserv].sin_addr = a; + _res.nsaddr_list[nserv].sin_family = AF_INET; + _res.nsaddr_list[nserv].sin_port = + htons(NAMESERVER_PORT); + nserv++; + } + } + ni_namelist_free(&nl); + } + + if (nserv > 1) + _res.nscount = nserv; + +#ifdef RESOLVSORT + /* get sort order */ + status = ni_lookupprop(domain, &dir, "sortlist", &nl); + if (status == NI_OK && nl.ni_namelist_len > 0) { + + /* copy up to MAXRESOLVSORT address/netmask pairs */ + for (n = 0; + n < nl.ni_namelist_len && nsort < MAXRESOLVSORT; + n++) { + char ch; + char *cp; + const char *sp; + struct in_addr a; + + cp = NULL; + for (sp = sort_mask; *sp; sp++) { + char *cp1; + cp1 = strchr(nl.ni_namelist_val[n], *sp); + if (cp && cp1) + cp = (cp < cp1)? cp : cp1; + else if (cp1) + cp = cp1; + } + if (cp != NULL) { + ch = *cp; + *cp = '\0'; + break; + } + if (inet_aton(nl.ni_namelist_val[n], &a)) { + _res.sort_list[nsort].addr = a; + if (*cp && ISSORTMASK(ch)) { + *cp++ = ch; + if (inet_aton(cp, &a)) { + _res.sort_list[nsort].mask = a.s_addr; + } else { + _res.sort_list[nsort].mask = + net_mask(_res.sort_list[nsort].addr); + } + } else { + _res.sort_list[nsort].mask = + net_mask(_res.sort_list[nsort].addr); + } + nsort++; + } + } + ni_namelist_free(&nl); + } + + _res.nsort = nsort; +#endif + + /* get resolver options */ + status = ni_lookupprop(domain, &dir, "options", &nl); + if (status == NI_OK && nl.ni_namelist_len > 0) { + res_setoptions(nl.ni_namelist_val[0], "conf"); + ni_namelist_free(&nl); + } + + ni_free(domain); + return(1); /* using DNS configuration from NetInfo */ + } + + status = ni_open(domain, "..", &parent); + ni_free(domain); + if (status == NI_OK) + domain = parent; + } + } + return(0); /* if not using DNS configuration from NetInfo */ +} +#endif /* __APPLE__ */ + +u_int16_t +res_randomid() +{ + struct timeval now; + + gettimeofday(&now, NULL); + return (0xffff & (now.tv_sec ^ now.tv_usec ^ getpid())); +} diff --git a/dns.subproj/res_mkquery.c b/dns.subproj/res_mkquery.c new file mode 100644 index 0000000..deda02f --- /dev/null +++ b/dns.subproj/res_mkquery.c @@ -0,0 +1,272 @@ +/* + * 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++ 1985, 1993 + * - + * Copyright (c) 1985, 1993 + * 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-- + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$Id: res_mkquery.c,v 1.2 1999/10/14 21:56:45 wsanchez Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include + +#include +#include +#include +#if defined(BSD) && (BSD >= 199103) +# include +#else +# include "portability.h" +#endif + +#if defined(USE_OPTIONS_H) +# include "options.h" +#endif + +/* + * Form all types of queries. + * Returns the size of the result or -1. + */ +int +res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen) + int op; /* opcode of query */ + const char *dname; /* domain name */ + int class, type; /* class and type of query */ + const u_char *data; /* resource record data */ + int datalen; /* length of data */ + const u_char *newrr_in; /* new rr for modify or append */ + u_char *buf; /* buffer to put query */ + int buflen; /* size of buffer */ +{ + register HEADER *hp; + register u_char *cp; + register int n; +#ifdef ALLOW_UPDATES + struct rrec *newrr = (struct rrec *) newrr_in; +#endif + u_char *dnptrs[20], **dpp, **lastdnptr; + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; + return (-1); + } +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf(";; res_mkquery(%d, %s, %d, %d)\n", + op, dname, class, type); +#endif + /* + * Initialize header fields. + */ + if ((buf == NULL) || (buflen < HFIXEDSZ)) + return (-1); + bzero(buf, HFIXEDSZ); + hp = (HEADER *) buf; + hp->id = htons(++_res.id); + hp->opcode = op; + hp->rd = (_res.options & RES_RECURSE) != 0; + hp->rcode = NOERROR; + cp = buf + HFIXEDSZ; + buflen -= HFIXEDSZ; + dpp = dnptrs; + *dpp++ = buf; + *dpp++ = NULL; + lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0]; + /* + * perform opcode specific processing + */ + switch (op) { + case QUERY: /*FALLTHROUGH*/ + case NS_NOTIFY_OP: + if ((buflen -= QFIXEDSZ) < 0) + return (-1); + if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) + return (-1); + cp += n; + buflen -= n; + __putshort(type, cp); + cp += INT16SZ; + __putshort(class, cp); + cp += INT16SZ; + hp->qdcount = htons(1); + if (op == QUERY || data == NULL) + break; + /* + * Make an additional record for completion domain. + */ + buflen -= RRFIXEDSZ; + n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr); + if (n < 0) + return (-1); + cp += n; + buflen -= n; + __putshort(T_NULL, cp); + cp += INT16SZ; + __putshort(class, cp); + cp += INT16SZ; + __putlong(0, cp); + cp += INT32SZ; + __putshort(0, cp); + cp += INT16SZ; + hp->arcount = htons(1); + break; + + case IQUERY: + /* + * Initialize answer section + */ + if (buflen < 1 + RRFIXEDSZ + datalen) + return (-1); + *cp++ = '\0'; /* no domain name */ + __putshort(type, cp); + cp += INT16SZ; + __putshort(class, cp); + cp += INT16SZ; + __putlong(0, cp); + cp += INT32SZ; + __putshort(datalen, cp); + cp += INT16SZ; + if (datalen) { + bcopy(data, cp, datalen); + cp += datalen; + } + hp->ancount = htons(1); + break; + +#ifdef ALLOW_UPDATES + /* + * For UPDATEM/UPDATEMA, do UPDATED/UPDATEDA followed by UPDATEA + * (Record to be modified is followed by its replacement in msg.) + */ + case UPDATEM: + case UPDATEMA: + + case UPDATED: + /* + * The res code for UPDATED and UPDATEDA is the same; user + * calls them differently: specifies data for UPDATED; server + * ignores data if specified for UPDATEDA. + */ + case UPDATEDA: + buflen -= RRFIXEDSZ + datalen; + if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) + return (-1); + cp += n; + __putshort(type, cp); + cp += INT16SZ; + __putshort(class, cp); + cp += INT16SZ; + __putlong(0, cp); + cp += INT32SZ; + __putshort(datalen, cp); + cp += INT16SZ; + if (datalen) { + bcopy(data, cp, datalen); + cp += datalen; + } + if ( (op == UPDATED) || (op == UPDATEDA) ) { + hp->ancount = htons(0); + break; + } + /* Else UPDATEM/UPDATEMA, so drop into code for UPDATEA */ + + case UPDATEA: /* Add new resource record */ + buflen -= RRFIXEDSZ + datalen; + if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0) + return (-1); + cp += n; + __putshort(newrr->r_type, cp); + cp += INT16SZ; + __putshort(newrr->r_class, cp); + cp += INT16SZ; + __putlong(0, cp); + cp += INT32SZ; + __putshort(newrr->r_size, cp); + cp += INT16SZ; + if (newrr->r_size) { + bcopy(newrr->r_data, cp, newrr->r_size); + cp += newrr->r_size; + } + hp->ancount = htons(0); + break; +#endif /* ALLOW_UPDATES */ + default: + return (-1); + } + return (cp - buf); +} diff --git a/dns.subproj/res_query.c b/dns.subproj/res_query.c new file mode 100644 index 0000000..85b705a --- /dev/null +++ b/dns.subproj/res_query.c @@ -0,0 +1,417 @@ +/* + * 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++ 1988, 1993 + * - + * Copyright (c) 1988, 1993 + * 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-- + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$Id: res_query.c,v 1.2 1999/10/14 21:56:45 wsanchez Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#if defined(BSD) && (BSD >= 199306) +# include +# include +#else +# include "portability.h" +#endif + +#if defined(USE_OPTIONS_H) +# include "options.h" +#endif + +#if PACKETSZ > 1024 +#define MAXPACKET PACKETSZ +#else +#define MAXPACKET 1024 +#endif + +char *__hostalias __P((const char *)); +#if defined(__APPLE__) +extern +#endif +int h_errno; + +/* + * Formulate a normal query, send, and await answer. + * Returned answer is placed in supplied buffer "answer". + * Perform preliminary check of answer, returning success only + * if no error is indicated and the answer count is nonzero. + * Return the size of the response on success, -1 on error. + * Error number is left in h_errno. + * + * Caller must parse answer and determine whether it answers the question. + */ +int +res_query(name, class, type, answer, anslen) + const char *name; /* domain name */ + int class, type; /* class and type of query */ + u_char *answer; /* buffer to put answer */ + int anslen; /* size of answer buffer */ +{ + u_char buf[MAXPACKET]; + register HEADER *hp = (HEADER *) answer; + int n; + + hp->rcode = NOERROR; /* default */ + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; + return (-1); + } +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf(";; res_query(%s, %d, %d)\n", name, class, type); +#endif + + n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL, + buf, sizeof(buf)); + if (n <= 0) { +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf(";; res_query: mkquery failed\n"); +#endif + h_errno = NO_RECOVERY; + return (n); + } + n = res_send(buf, n, answer, anslen); + if (n < 0) { +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf(";; res_query: send error\n"); +#endif + h_errno = TRY_AGAIN; + return (n); + } + + if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) { +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf(";; rcode = %d, ancount=%d\n", hp->rcode, + ntohs(hp->ancount)); +#endif + switch (hp->rcode) { + case NXDOMAIN: + h_errno = HOST_NOT_FOUND; + break; + case SERVFAIL: + h_errno = TRY_AGAIN; + break; + case NOERROR: + h_errno = NO_DATA; + break; + case FORMERR: + case NOTIMP: + case REFUSED: + default: + h_errno = NO_RECOVERY; + break; + } + return (-1); + } + return (n); +} + +/* + * Formulate a normal query, send, and retrieve answer in supplied buffer. + * Return the size of the response on success, -1 on error. + * If enabled, implement search rules until answer or unrecoverable failure + * is detected. Error code, if any, is left in h_errno. + */ +int +res_search(name, class, type, answer, anslen) + const char *name; /* domain name */ + int class, type; /* class and type of query */ + u_char *answer; /* buffer to put answer */ + int anslen; /* size of answer */ +{ + register const char *cp, * const *domain; + HEADER *hp = (HEADER *) answer; + u_int dots; + int trailing_dot, ret, saved_herrno; + int got_nodata = 0, got_servfail = 0, tried_as_is = 0; + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; + return (-1); + } + errno = 0; + h_errno = HOST_NOT_FOUND; /* default, if we never query */ + dots = 0; + for (cp = name; *cp; cp++) + dots += (*cp == '.'); + trailing_dot = 0; + if (cp > name && *--cp == '.') + trailing_dot++; + + /* + * if there aren't any dots, it could be a user-level alias + */ + if (!dots && (cp = __hostalias(name)) != NULL) + return (res_query(cp, class, type, answer, anslen)); + + /* + * If there are dots in the name already, let's just give it a try + * 'as is'. The threshold can be set with the "ndots" option. + */ + saved_herrno = -1; + if (dots >= _res.ndots) { + ret = res_querydomain(name, NULL, class, type, answer, anslen); + if (ret > 0) + return (ret); + saved_herrno = h_errno; + tried_as_is++; + } + + /* + * We do at least one level of search if + * - there is no dot and RES_DEFNAME is set, or + * - there is at least one dot, there is no trailing dot, + * and RES_DNSRCH is set. + */ + if ((!dots && (_res.options & RES_DEFNAMES)) || + (dots && !trailing_dot && (_res.options & RES_DNSRCH))) { + int done = 0; + + for (domain = (const char * const *)_res.dnsrch; + *domain && !done; + domain++) { + + ret = res_querydomain(name, *domain, class, type, + answer, anslen); + if (ret > 0) + return (ret); + + /* + * If no server present, give up. + * If name isn't found in this domain, + * keep trying higher domains in the search list + * (if that's enabled). + * On a NO_DATA error, keep trying, otherwise + * a wildcard entry of another type could keep us + * from finding this entry higher in the domain. + * If we get some other error (negative answer or + * server failure), then stop searching up, + * but try the input name below in case it's + * fully-qualified. + */ + if (errno == ECONNREFUSED) { + h_errno = TRY_AGAIN; + return (-1); + } + + switch (h_errno) { + case NO_DATA: + got_nodata++; + /* FALLTHROUGH */ + case HOST_NOT_FOUND: + /* keep trying */ + break; + case TRY_AGAIN: + if (hp->rcode == SERVFAIL) { + /* try next search element, if any */ + got_servfail++; + break; + } + /* FALLTHROUGH */ + default: + /* anything else implies that we're done */ + done++; + } + + /* if we got here for some reason other than DNSRCH, + * we only wanted one iteration of the loop, so stop. + */ + if (!(_res.options & RES_DNSRCH)) + done++; + } + } + + /* if we have not already tried the name "as is", do that now. + * note that we do this regardless of how many dots were in the + * name or whether it ends with a dot. + */ + if (!tried_as_is) { + ret = res_querydomain(name, NULL, class, type, answer, anslen); + if (ret > 0) + return (ret); + } + + /* if we got here, we didn't satisfy the search. + * if we did an initial full query, return that query's h_errno + * (note that we wouldn't be here if that query had succeeded). + * else if we ever got a nodata, send that back as the reason. + * else send back meaningless h_errno, that being the one from + * the last DNSRCH we did. + */ + if (saved_herrno != -1) + h_errno = saved_herrno; + else if (got_nodata) + h_errno = NO_DATA; + else if (got_servfail) + h_errno = TRY_AGAIN; + return (-1); +} + +/* + * Perform a call on res_query on the concatenation of name and domain, + * removing a trailing dot from name if domain is NULL. + */ +int +res_querydomain(name, domain, class, type, answer, anslen) + const char *name, *domain; + int class, type; /* class and type of query */ + u_char *answer; /* buffer to put answer */ + int anslen; /* size of answer */ +{ + char nbuf[2*MAXDNAME+2]; + const char *longname = nbuf; + int n; + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + h_errno = NETDB_INTERNAL; + return (-1); + } +#ifdef DEBUG + if (_res.options & RES_DEBUG) + printf(";; res_querydomain(%s, %s, %d, %d)\n", + name, domain?domain:"", class, type); +#endif + if (domain == NULL) { + /* + * Check for trailing '.'; + * copy without '.' if present. + */ + n = strlen(name) - 1; + if (n != (0 - 1) && name[n] == '.' && n < sizeof(nbuf) - 1) { + bcopy(name, nbuf, n); + nbuf[n] = '\0'; + } else + longname = name; + } else + sprintf(nbuf, "%.*s.%.*s", MAXDNAME, name, MAXDNAME, domain); + + return (res_query(longname, class, type, answer, anslen)); +} + +char * +__hostalias(name) + register const char *name; +{ + register char *cp1, *cp2; + FILE *fp; + char *file; + char buf[BUFSIZ]; + static char abuf[MAXDNAME]; + + if (_res.options & RES_NOALIASES) + return (NULL); + file = getenv("HOSTALIASES"); + if (file == NULL || (fp = fopen(file, "r")) == NULL) + return (NULL); + setbuf(fp, NULL); + buf[sizeof(buf) - 1] = '\0'; + while (fgets(buf, sizeof(buf), fp)) { + for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1) + ; + if (!*cp1) + break; + *cp1 = '\0'; + if (!strcasecmp(buf, name)) { + while (isspace(*++cp1)) + ; + if (!*cp1) + break; + for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2) + ; + abuf[sizeof(abuf) - 1] = *cp2 = '\0'; + strncpy(abuf, cp1, sizeof(abuf) - 1); + fclose(fp); + return (abuf); + } + } + fclose(fp); + return (NULL); +} diff --git a/dns.subproj/res_send.c b/dns.subproj/res_send.c new file mode 100644 index 0000000..b1c3a08 --- /dev/null +++ b/dns.subproj/res_send.c @@ -0,0 +1,784 @@ +/* + * 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++ 1985, 1989, 1993 + * - + * Copyright (c) 1985, 1989, 1993 + * 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-- + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$Id: res_send.c,v 1.2 1999/10/14 21:56:45 wsanchez Exp $"; +#endif /* LIBC_SCCS and not lint */ + + /* change this to "0" + * if you talk to a lot + * of multi-homed SunOS + * ("broken") name servers. + */ +#define CHECK_SRVR_ADDR 1 /* XXX - should be in options.h */ + +/* + * Send query to name server and wait for reply. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#if defined(BSD) && (BSD >= 199306) +# include +# include +# include +#else +# include "portability.h" +#endif + +#if defined(USE_OPTIONS_H) +# include "options.h" +#endif + +void _res_close __P((void)); + +static int s = -1; /* socket used for communications */ +static int connected = 0; /* is the socket connected */ +static int vc = 0; /* is the socket a virtual ciruit? */ + +#ifndef FD_SET +/* XXX - should be in portability.h */ +#define NFDBITS 32 +#define FD_SETSIZE 32 +#define FD_SET(n, p) ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS))) +#define FD_CLR(n, p) ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS))) +#define FD_ISSET(n, p) ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS))) +#define FD_ZERO(p) bzero((char *)(p), sizeof(*(p))) +#endif + +/* XXX - this should be done in portability.h */ +#if (defined(BSD) && (BSD >= 199103)) || defined(linux) +# define CAN_RECONNECT 1 +#else +# define CAN_RECONNECT 0 +#endif + +#ifndef DEBUG +# define Dprint(cond, args) /*empty*/ +# define DprintQ(cond, args, query, size) /*empty*/ +# define Aerror(file, string, error, address) /*empty*/ +# define Perror(file, string, error) /*empty*/ +#else +# define Dprint(cond, args) if (cond) {fprintf args;} else {} +# define DprintQ(cond, args, query, size) if (cond) {\ + fprintf args;\ + __fp_nquery(query, size, stdout);\ + } else {} + static void + Aerror(file, string, error, address) + FILE *file; + char *string; + int error; + struct sockaddr_in address; + { + int save = errno; + + if (_res.options & RES_DEBUG) { + fprintf(file, "res_send: %s ([%s].%u): %s\n", + string, + inet_ntoa(address.sin_addr), + ntohs(address.sin_port), + strerror(error)); + } + errno = save; + } + static void + Perror(file, string, error) + FILE *file; + char *string; + int error; + { + int save = errno; + + if (_res.options & RES_DEBUG) { + fprintf(file, "res_send: %s: %s\n", + string, strerror(error)); + } + errno = save; + } +#endif + +static res_send_qhook Qhook = NULL; +static res_send_rhook Rhook = NULL; + +void +res_send_setqhook(hook) + res_send_qhook hook; +{ + + Qhook = hook; +} + +void +res_send_setrhook(hook) + res_send_rhook hook; +{ + + Rhook = hook; +} + +/* int + * res_isourserver(ina) + * looks up "ina" in _res.ns_addr_list[] + * returns: + * 0 : not found + * >0 : found + * author: + * paul vixie, 29may94 + */ +int +res_isourserver(inp) + const struct sockaddr_in *inp; +{ + struct sockaddr_in ina; + register int ns, ret; + + ina = *inp; + ret = 0; + for (ns = 0; ns < _res.nscount; ns++) { + register const struct sockaddr_in *srv = &_res.nsaddr_list[ns]; + + if (srv->sin_family == ina.sin_family && + srv->sin_port == ina.sin_port && + (srv->sin_addr.s_addr == INADDR_ANY || + srv->sin_addr.s_addr == ina.sin_addr.s_addr)) { + ret++; + break; + } + } + return (ret); +} + +/* int + * res_nameinquery(name, type, class, buf, eom) + * look for (name,type,class) in the query section of packet (buf,eom) + * returns: + * -1 : format error + * 0 : not found + * >0 : found + * author: + * paul vixie, 29may94 + */ +int +res_nameinquery(name, type, class, buf, eom) + const char *name; + register int type, class; + const u_char *buf, *eom; +{ + register const u_char *cp = buf + HFIXEDSZ; + int qdcount = ntohs(((HEADER*)buf)->qdcount); + + while (qdcount-- > 0) { + char tname[MAXDNAME+1]; + register int n, ttype, tclass; + + n = dn_expand(buf, eom, cp, tname, sizeof tname); + if (n < 0) + return (-1); + cp += n; + ttype = _getshort(cp); cp += INT16SZ; + tclass = _getshort(cp); cp += INT16SZ; + if (ttype == type && + tclass == class && + strcasecmp(tname, name) == 0) + return (1); + } + return (0); +} + +/* int + * res_queriesmatch(buf1, eom1, buf2, eom2) + * is there a 1:1 mapping of (name,type,class) + * in (buf1,eom1) and (buf2,eom2)? + * returns: + * -1 : format error + * 0 : not a 1:1 mapping + * >0 : is a 1:1 mapping + * author: + * paul vixie, 29may94 + */ +int +res_queriesmatch(buf1, eom1, buf2, eom2) + const u_char *buf1, *eom1; + const u_char *buf2, *eom2; +{ + register const u_char *cp = buf1 + HFIXEDSZ; + int qdcount = ntohs(((HEADER*)buf1)->qdcount); + + if (qdcount != ntohs(((HEADER*)buf2)->qdcount)) + return (0); + while (qdcount-- > 0) { + char tname[MAXDNAME+1]; + register int n, ttype, tclass; + + n = dn_expand(buf1, eom1, cp, tname, sizeof tname); + if (n < 0) + return (-1); + cp += n; + ttype = _getshort(cp); cp += INT16SZ; + tclass = _getshort(cp); cp += INT16SZ; + if (!res_nameinquery(tname, ttype, tclass, buf2, eom2)) + return (0); + } + return (1); +} + +int +res_send(buf, buflen, ans, anssiz) + const u_char *buf; + int buflen; + u_char *ans; + int anssiz; +{ + HEADER *hp = (HEADER *) buf; + HEADER *anhp = (HEADER *) ans; + int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns; + register int n; + u_int badns; /* XXX NSMAX can't exceed #/bits in this var */ + + if ((_res.options & RES_INIT) == 0 && res_init() == -1) { + /* errno should have been set by res_init() in this case. */ + return (-1); + } + DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY), + (stdout, ";; res_send()\n"), buf, buflen); + v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ; + gotsomewhere = 0; + connreset = 0; + terrno = ETIMEDOUT; + badns = 0; + + /* + * Send request, RETRY times, or until successful + */ + for (try = 0; try < _res.retry; try++) { + for (ns = 0; ns < _res.nscount; ns++) { + struct sockaddr_in *nsap = &_res.nsaddr_list[ns]; + same_ns: + if (badns & (1 << ns)) { + _res_close(); + goto next_ns; + } + + if (Qhook) { + int done = 0, loops = 0; + + do { + res_sendhookact act; + + act = (*Qhook)(&nsap, &buf, &buflen, + ans, anssiz, &resplen); + switch (act) { + case res_goahead: + done = 1; + break; + case res_nextns: + _res_close(); + goto next_ns; + case res_done: + return (resplen); + case res_modified: + /* give the hook another try */ + if (++loops < 42) /*doug adams*/ + break; + /*FALLTHROUGH*/ + case res_error: + /*FALLTHROUGH*/ + default: + return (-1); + } + } while (!done); + } + + Dprint(_res.options & RES_DEBUG, + (stdout, ";; Querying server (# %d) address = %s\n", + ns + 1, inet_ntoa(nsap->sin_addr))); + + if (v_circuit) { + int truncated; + struct iovec iov[2]; + u_short len; + u_char *cp; + + /* + * Use virtual circuit; + * at most one attempt per server. + */ + try = _res.retry; + truncated = 0; + if ((s < 0) || (!vc)) { + if (s >= 0) + _res_close(); + + s = socket(PF_INET, SOCK_STREAM, 0); + if (s < 0) { + terrno = errno; + Perror(stderr, "socket(vc)", errno); + return (-1); + } + errno = 0; + if (connect(s, (struct sockaddr *)nsap, + sizeof(struct sockaddr)) < 0) { + terrno = errno; + Aerror(stderr, "connect/vc", + errno, *nsap); + badns |= (1 << ns); + _res_close(); + goto next_ns; + } + vc = 1; + } + /* + * Send length & message + */ + putshort((u_short)buflen, (u_char*)&len); + iov[0].iov_base = (caddr_t)&len; + iov[0].iov_len = INT16SZ; + iov[1].iov_base = (caddr_t)buf; + iov[1].iov_len = buflen; + if (writev(s, iov, 2) != (INT16SZ + buflen)) { + terrno = errno; + Perror(stderr, "write failed", errno); + badns |= (1 << ns); + _res_close(); + goto next_ns; + } + /* + * Receive length & response + */ + cp = ans; + len = INT16SZ; + while ((n = read(s, (char *)cp, (int)len)) > 0) { + cp += n; + if ((len -= n) <= 0) + break; + } + if (n <= 0) { + terrno = errno; + Perror(stderr, "read failed", errno); + _res_close(); + /* + * A long running process might get its TCP + * connection reset if the remote server was + * restarted. Requery the server instead of + * trying a new one. When there is only one + * server, this means that a query might work + * instead of failing. We only allow one reset + * per query to prevent looping. + */ + if (terrno == ECONNRESET && !connreset) { + connreset = 1; + _res_close(); + goto same_ns; + } + _res_close(); + goto next_ns; + } + resplen = _getshort(ans); + if (resplen > anssiz) { + Dprint(_res.options & RES_DEBUG, + (stdout, ";; response truncated\n") + ); + truncated = 1; + len = anssiz; + } else + len = resplen; + cp = ans; + while (len != 0 && + (n = read(s, (char *)cp, (int)len)) > 0) { + cp += n; + len -= n; + } + if (n <= 0) { + terrno = errno; + Perror(stderr, "read(vc)", errno); + _res_close(); + goto next_ns; + } + if (truncated) { + /* + * Flush rest of answer + * so connection stays in synch. + */ + anhp->tc = 1; + len = resplen - anssiz; + while (len != 0) { + char junk[PACKETSZ]; + + n = (len > sizeof(junk) + ? sizeof(junk) + : len); + if ((n = read(s, junk, n)) > 0) + len -= n; + else + break; + } + } + } else { + /* + * Use datagrams. + */ + struct timeval timeout; + fd_set dsmask; + struct sockaddr_in from; + int fromlen; + + if ((s < 0) || vc) { + if (vc) + _res_close(); + s = socket(PF_INET, SOCK_DGRAM, 0); + if (s < 0) { +#if !CAN_RECONNECT + bad_dg_sock: +#endif + terrno = errno; + Perror(stderr, "socket(dg)", errno); + return (-1); + } + connected = 0; + } + /* + * On a 4.3BSD+ machine (client and server, + * actually), sending to a nameserver datagram + * port with no nameserver will cause an + * ICMP port unreachable message to be returned. + * If our datagram socket is "connected" to the + * server, we get an ECONNREFUSED error on the next + * socket operation, and select returns if the + * error message is received. We can thus detect + * the absence of a nameserver without timing out. + * If we have sent queries to at least two servers, + * however, we don't want to remain connected, + * as we wish to receive answers from the first + * server to respond. + */ + if (_res.nscount == 1 || (try == 0 && ns == 0)) { + /* + * Connect only if we are sure we won't + * receive a response from another server. + */ + if (!connected) { + if (connect(s, (struct sockaddr *)nsap, + sizeof(struct sockaddr) + ) < 0) { + Aerror(stderr, + "connect(dg)", + errno, *nsap); + badns |= (1 << ns); + _res_close(); + goto next_ns; + } + connected = 1; + } + if (send(s, (char*)buf, buflen, 0) != buflen) { + Perror(stderr, "send", errno); + badns |= (1 << ns); + _res_close(); + goto next_ns; + } + } else { + /* + * Disconnect if we want to listen + * for responses from more than one server. + */ + if (connected) { +#if CAN_RECONNECT + struct sockaddr_in no_addr; + + no_addr.sin_family = AF_INET; + no_addr.sin_addr.s_addr = INADDR_ANY; + no_addr.sin_port = 0; + (void) connect(s, + (struct sockaddr *) + &no_addr, + sizeof(no_addr)); +#else + int s1 = socket(PF_INET, SOCK_DGRAM,0); + if (s1 < 0) + goto bad_dg_sock; + (void) dup2(s1, s); + (void) close(s1); + Dprint(_res.options & RES_DEBUG, + (stdout, ";; new DG socket\n")) +#endif + connected = 0; + errno = 0; + } + if (sendto(s, (char*)buf, buflen, 0, + (struct sockaddr *)nsap, + sizeof(struct sockaddr)) + != buflen) { + Aerror(stderr, "sendto", errno, *nsap); + badns |= (1 << ns); + _res_close(); + goto next_ns; + } + } + + /* + * Wait for reply + */ + timeout.tv_sec = (_res.retrans << try); + if (try > 0) + timeout.tv_sec /= _res.nscount; + if ((long) timeout.tv_sec <= 0) + timeout.tv_sec = 1; + timeout.tv_usec = 0; + wait: + FD_ZERO(&dsmask); + FD_SET(s, &dsmask); + n = select(s+1, &dsmask, (fd_set *)NULL, + (fd_set *)NULL, &timeout); + if (n < 0) { + Perror(stderr, "select", errno); + _res_close(); + goto next_ns; + } + if (n == 0) { + /* + * timeout + */ + Dprint(_res.options & RES_DEBUG, + (stdout, ";; timeout\n")); + gotsomewhere = 1; + _res_close(); + goto next_ns; + } + errno = 0; + fromlen = sizeof(struct sockaddr_in); + resplen = recvfrom(s, (char*)ans, anssiz, 0, + (struct sockaddr *)&from, &fromlen); + if (resplen <= 0) { + Perror(stderr, "recvfrom", errno); + _res_close(); + goto next_ns; + } + gotsomewhere = 1; + if (hp->id != anhp->id) { + /* + * response from old query, ignore it. + * XXX - potential security hazard could + * be detected here. + */ + DprintQ((_res.options & RES_DEBUG) || + (_res.pfcode & RES_PRF_REPLY), + (stdout, ";; old answer:\n"), + ans, resplen); + goto wait; + } +#if CHECK_SRVR_ADDR + if (!(_res.options & RES_INSECURE1) && + !res_isourserver(&from)) { + /* + * response from wrong server? ignore it. + * XXX - potential security hazard could + * be detected here. + */ + DprintQ((_res.options & RES_DEBUG) || + (_res.pfcode & RES_PRF_REPLY), + (stdout, ";; not our server:\n"), + ans, resplen); + goto wait; + } +#endif + if (!(_res.options & RES_INSECURE2) && + !res_queriesmatch(buf, buf + buflen, + ans, ans + anssiz)) { + /* + * response contains wrong query? ignore it. + * XXX - potential security hazard could + * be detected here. + */ + DprintQ((_res.options & RES_DEBUG) || + (_res.pfcode & RES_PRF_REPLY), + (stdout, ";; wrong query name:\n"), + ans, resplen); + goto wait; + } + if (anhp->rcode == SERVFAIL || + anhp->rcode == NOTIMP || + anhp->rcode == REFUSED) { + DprintQ(_res.options & RES_DEBUG, + (stdout, "server rejected query:\n"), + ans, resplen); + badns |= (1 << ns); + _res_close(); + /* don't retry if called from dig */ + if (!_res.pfcode) + goto next_ns; + } + if (!(_res.options & RES_IGNTC) && anhp->tc) { + /* + * get rest of answer; + * use TCP with same server. + */ + Dprint(_res.options & RES_DEBUG, + (stdout, ";; truncated answer\n")); + v_circuit = 1; + _res_close(); + goto same_ns; + } + } /*if vc/dg*/ + DprintQ((_res.options & RES_DEBUG) || + (_res.pfcode & RES_PRF_REPLY), + (stdout, ";; got answer:\n"), + ans, resplen); + /* + * If using virtual circuits, we assume that the first server + * is preferred over the rest (i.e. it is on the local + * machine) and only keep that one open. + * If we have temporarily opened a virtual circuit, + * or if we haven't been asked to keep a socket open, + * close the socket. + */ + if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) || + !(_res.options & RES_STAYOPEN)) { + _res_close(); + } + if (Rhook) { + int done = 0, loops = 0; + + do { + res_sendhookact act; + + act = (*Rhook)(nsap, buf, buflen, + ans, anssiz, &resplen); + switch (act) { + case res_goahead: + case res_done: + done = 1; + break; + case res_nextns: + _res_close(); + goto next_ns; + case res_modified: + /* give the hook another try */ + if (++loops < 42) /*doug adams*/ + break; + /*FALLTHROUGH*/ + case res_error: + /*FALLTHROUGH*/ + default: + return (-1); + } + } while (!done); + + } + return (resplen); + next_ns: ; + } /*foreach ns*/ + } /*foreach retry*/ + _res_close(); + if (!v_circuit) + if (!gotsomewhere) + errno = ECONNREFUSED; /* no nameservers found */ + else + errno = ETIMEDOUT; /* no answer obtained */ + else + errno = terrno; + return (-1); +} + +/* + * This routine is for closing the socket if a virtual circuit is used and + * the program wants to close it. This provides support for endhostent() + * which expects to close the socket. + * + * This routine is not expected to be user visible. + */ +void +_res_close() +{ + if (s >= 0) { + (void) close(s); + s = -1; + connected = 0; + vc = 0; + } +} diff --git a/dns.subproj/resolv.h b/dns.subproj/resolv.h new file mode 100644 index 0000000..12302ac --- /dev/null +++ b/dns.subproj/resolv.h @@ -0,0 +1,263 @@ +/* + * 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++ 1983, 1987, 1989, 1993 + * - + * Copyright (c) 1983, 1987, 1989, 1993 + * 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-- + */ + +/* + * @(#)resolv.h 8.1 (Berkeley) 6/2/93 + * $Id: resolv.h,v 1.2 1999/10/14 21:56:45 wsanchez Exp $ + */ + +#ifndef _RESOLV_H_ +#define _RESOLV_H_ + +#include +#if (!defined(BSD)) || (BSD < 199306) +# include +#else +# include +#endif +#include +#include + +/* + * revision information. this is the release date in YYYYMMDD format. + * it can change every day so the right thing to do with it is use it + * in preprocessor commands such as "#if (__RES > 19931104)". do not + * compare for equality; rather, use it to determine whether your resolver + * is new enough to contain a certain feature. + */ + +#define __RES 19950621 + +/* + * Resolver configuration file. + * Normally not present, but may contain the address of the + * inital name server(s) to query and the domain search list. + */ + +#ifndef _PATH_RESCONF +#define _PATH_RESCONF "/etc/resolv.conf" +#endif + +/* + * Global defines and variables for resolver stub. + */ +#define MAXNS 3 /* max # name servers we'll track */ +#define MAXDFLSRCH 3 /* # default domain levels to try */ +#define MAXDNSRCH 6 /* max # domains in search path */ +#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */ + +#define RES_TIMEOUT 5 /* min. seconds between retries */ +#define MAXRESOLVSORT 10 /* number of net to sort on */ +#define RES_MAXNDOTS 15 /* should reflect bit field size */ + +struct __res_state { + int retrans; /* retransmition time interval */ + int retry; /* number of times to retransmit */ + u_long options; /* option flags - see below. */ + int nscount; /* number of name servers */ + struct sockaddr_in + nsaddr_list[MAXNS]; /* address of name server */ +#define nsaddr nsaddr_list[0] /* for backward compatibility */ + u_short id; /* current packet id */ + char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */ + char defdname[MAXDNAME]; /* default domain */ + u_long pfcode; /* RES_PRF_ flags - see below. */ + unsigned ndots:4; /* threshold for initial abs. query */ + unsigned nsort:4; /* number of elements in sort_list[] */ + char unused[3]; + struct { + struct in_addr addr; + u_int32_t mask; + } sort_list[MAXRESOLVSORT]; +}; + +/* + * Resolver options (keep these in synch with res_debug.c, please) + */ +#define RES_INIT 0x00000001 /* address initialized */ +#define RES_DEBUG 0x00000002 /* print debug messages */ +#define RES_AAONLY 0x00000004 /* authoritative answers only (!IMPL)*/ +#define RES_USEVC 0x00000008 /* use virtual circuit */ +#define RES_PRIMARY 0x00000010 /* query primary server only (!IMPL) */ +#define RES_IGNTC 0x00000020 /* ignore trucation errors */ +#define RES_RECURSE 0x00000040 /* recursion desired */ +#define RES_DEFNAMES 0x00000080 /* use default domain name */ +#define RES_STAYOPEN 0x00000100 /* Keep TCP socket open */ +#define RES_DNSRCH 0x00000200 /* search up local domain tree */ +#define RES_INSECURE1 0x00000400 /* type 1 security disabled */ +#define RES_INSECURE2 0x00000800 /* type 2 security disabled */ +#define RES_NOALIASES 0x00001000 /* shuts off HOSTALIASES feature */ + +#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH) + +/* + * Resolver "pfcode" values. Used by dig. + */ +#define RES_PRF_STATS 0x00000001 +/* 0x00000002 */ +#define RES_PRF_CLASS 0x00000004 +#define RES_PRF_CMD 0x00000008 +#define RES_PRF_QUES 0x00000010 +#define RES_PRF_ANS 0x00000020 +#define RES_PRF_AUTH 0x00000040 +#define RES_PRF_ADD 0x00000080 +#define RES_PRF_HEAD1 0x00000100 +#define RES_PRF_HEAD2 0x00000200 +#define RES_PRF_TTLID 0x00000400 +#define RES_PRF_HEADX 0x00000800 +#define RES_PRF_QUERY 0x00001000 +#define RES_PRF_REPLY 0x00002000 +#define RES_PRF_INIT 0x00004000 +/* 0x00008000 */ + +/* hooks are still experimental as of 4.9.2 */ +typedef enum { res_goahead, res_nextns, res_modified, res_done, res_error } + res_sendhookact; + +typedef res_sendhookact (*res_send_qhook)__P((struct sockaddr_in * const *ns, + const u_char **query, + int *querylen, + u_char *ans, + int anssiz, + int *resplen)); + +typedef res_sendhookact (*res_send_rhook)__P((const struct sockaddr_in *ns, + const u_char *query, + int querylen, + u_char *ans, + int anssiz, + int *resplen)); + +extern struct __res_state _res; + +/* Private routines shared between libc/net, named, nslookup and others. */ +#define dn_skipname __dn_skipname +#define fp_query __fp_query +#define fp_nquery __fp_nquery +#define hostalias __hostalias +#define putlong __putlong +#define putshort __putshort +#define p_class __p_class +#define p_time __p_time +#define p_type __p_type +#define p_cdnname __p_cdnname +#define p_cdname __p_cdname +#define p_fqname __p_fqname +#define p_rr __p_rr +#define p_option __p_option +#define res_randomid __res_randomid +#define res_isourserver __res_isourserver +#define res_nameinquery __res_nameinquery +#define res_queriesmatch __res_queriesmatch +__BEGIN_DECLS +int __dn_skipname __P((const u_char *, const u_char *)); +void __fp_resstat __P((struct __res_state *, FILE *)); +void __fp_query __P((const u_char *, FILE *)); +void __fp_nquery __P((const u_char *, int, FILE *)); +char *__hostalias __P((const char *)); +void __putlong __P((u_int32_t, u_char *)); +void __putshort __P((u_int16_t, u_char *)); +char *__p_time __P((u_int32_t)); +void __p_query __P((const u_char *)); +const u_char *__p_cdnname __P((const u_char *, const u_char *, int, FILE *)); +const u_char *__p_cdname __P((const u_char *, const u_char *, FILE *)); +const u_char *__p_fqname __P((const u_char *, const u_char *, FILE *)); +const u_char *__p_rr __P((const u_char *, const u_char *, FILE *)); +const char *__p_type __P((int)); +const char *__p_class __P((int)); +const char *__p_option __P((u_long option)); +int dn_comp __P((const char *, u_char *, int, u_char **, u_char **)); +int dn_expand __P((const u_char *, const u_char *, const u_char *, + char *, int)); +int res_init __P((void)); +u_int16_t res_randomid __P((void)); +int res_query __P((const char *, int, int, u_char *, int)); +int res_search __P((const char *, int, int, u_char *, int)); +int res_querydomain __P((const char *, const char *, int, int, + u_char *, int)); +int res_mkquery __P((int, const char *, int, int, const u_char *, int, + const u_char *, u_char *, int)); +int res_send __P((const u_char *, int, u_char *, int)); +int res_isourserver __P((const struct sockaddr_in *)); +int res_nameinquery __P((const char *, int, int, + const u_char *, const u_char *)); +int res_queriesmatch __P((const u_char *, const u_char *, + const u_char *, const u_char *)); +__END_DECLS + +#endif /* !_RESOLV_H_ */ diff --git a/dns.subproj/sethostent.c b/dns.subproj/sethostent.c new file mode 100644 index 0000000..3070283 --- /dev/null +++ b/dns.subproj/sethostent.c @@ -0,0 +1,85 @@ +/* + * 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) 1985, 1993 + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)sethostent.c 8.1 (Berkeley) 6/4/93"; +static char rcsid[] = "$Id: sethostent.c,v 1.2 1999/10/14 21:56:45 wsanchez Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include + +void _res_close __P((void)); + +void +sethostent(stayopen) + int stayopen; +{ + if ((_res.options & RES_INIT) == 0 && res_init() == -1) + return; + if (stayopen) + _res.options |= RES_STAYOPEN | RES_USEVC; +} + +void +endhostent() +{ + _res.options &= ~(RES_STAYOPEN | RES_USEVC); + _res_close(); +} diff --git a/gen.subproj/Makefile b/gen.subproj/Makefile new file mode 100644 index 0000000..3e59457 --- /dev/null +++ b/gen.subproj/Makefile @@ -0,0 +1,47 @@ +# +# Generated by the NeXT Project Builder. +# +# NOTE: Do NOT change this file -- Project Builder maintains it. +# +# Put all of your customizations in files called Makefile.preamble +# and Makefile.postamble (both optional), and Makefile will include them. +# + +NAME = gen + +PROJECTVERSION = 2.8 +PROJECT_TYPE = Component + +CFILES = aliasdb.c ether_addr.c fstab.c getaddrinfo.c getgrent.c getproto.c\ + getprotoent.c getprotoname.c getpwent.c getservbyname.c\ + getservbyport.c getservent.c initgroups.c printerdb.c + +OTHERSRCS = Makefile.preamble Makefile + + +MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles +CODE_GEN_STYLE = DYNAMIC +MAKEFILE = subproj.make +LIBS = +DEBUG_LIBS = $(LIBS) +PROF_LIBS = $(LIBS) + + + + +NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc +WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc +PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc +NEXTSTEP_JAVA_COMPILER = /usr/bin/javac +WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe +PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac + +include $(MAKEFILEDIR)/platform.make + +-include Makefile.preamble + +include $(MAKEFILEDIR)/$(MAKEFILE) + +-include Makefile.postamble + +-include Makefile.dependencies diff --git a/gen.subproj/Makefile.preamble b/gen.subproj/Makefile.preamble new file mode 100644 index 0000000..8bcebdc --- /dev/null +++ b/gen.subproj/Makefile.preamble @@ -0,0 +1,31 @@ +OTHER_CFLAGS = \ + -Dsetservent=_old_setservent \ + -Dgetservent=_old_getservent \ + -Dendservent=_old_endservent \ + -Dgetservbyname=_old_getservbyname \ + -Dgetservbyport=_old_getservbyport \ + -Dsetprotoent=_old_setprotoent \ + -Dgetprotoent=_old_getprotoent \ + -Dendprotoent=_old_endprotoent \ + -Dgetprotobyname=_old_getprotobyname \ + -Dgetprotobynumber=_old_getprotobynumber \ + -Dsetnetgrent=_old_setnetgrent \ + -Dgetnetgrent=_old_getnetgrent \ + -Dendnetgrent=_old_endnetgrent \ + -Dsetpwent=_old_setpwent \ + -Dgetpwent=_old_getpwent \ + -Dendpwent=_old_endpwent \ + -Dgetpwnam=_old_getpwnam \ + -Dgetpwuid=_old_getpwuid \ + -Dsetgrent=_old_setgrent \ + -Dgetgrent=_old_getgrent \ + -Dendgrent=_old_endgrent \ + -Dgetgrnam=_old_getgrnam \ + -Dgetgrgid=_old_getgrgid \ + -Dsetfsent=_old_setfsent \ + -Dendfsent=_old_endfsent \ + -Dgetfsent=_old_getfsent \ + -Dgetfsfile=_old_getfsfile \ + -Dgetfsspec=_old_getfsspec \ + -Dinitgroups=_old_initgroups \ + -I../lookup.subproj diff --git a/gen.subproj/PB.project b/gen.subproj/PB.project new file mode 100644 index 0000000..5e70c18 --- /dev/null +++ b/gen.subproj/PB.project @@ -0,0 +1,37 @@ +{ + DYNAMIC_CODE_GEN = YES; + FILESTABLE = { + H_FILES = (); + OTHER_LINKED = ( + aliasdb.c, + ether_addr.c, + fstab.c, + getaddrinfo.c, + getgrent.c, + getproto.c, + getprotoent.c, + getprotoname.c, + getpwent.c, + getservbyname.c, + getservbyport.c, + getservent.c, + initgroups.c, + printerdb.c + ); + OTHER_SOURCES = (Makefile.preamble, Makefile); + }; + LANGUAGE = English; + MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; + NEXTSTEP_BUILDTOOL = /bin/gnumake; + NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; + NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; + PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; + PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; + PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; + PROJECTNAME = gen; + PROJECTTYPE = Component; + PROJECTVERSION = 2.8; + WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; + WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; + WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; +} diff --git a/gen.subproj/aliasdb.c b/gen.subproj/aliasdb.c new file mode 100644 index 0000000..ad0bd4f --- /dev/null +++ b/gen.subproj/aliasdb.c @@ -0,0 +1,54 @@ +/* + * 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@ + */ +/* + * Unimplemented backward-compatible alias lookup routines. + * These are only called if NetInfo is not running or if YP + * has been turned on, in which case NetInfo will be tried first. + * This is the standard NeXT policy for all lookup routines. + */ + +#include +#include + +void +_old_alias_setent(void) +{ +} + +struct aliasent * +_old_alias_getent(void) +{ + return (NULL); +} + +void +_old_alias_endent(void) +{ +} + +struct aliasent * +_old_alias_getbyname(char *name) +{ + return (NULL); +} diff --git a/gen.subproj/ether_addr.c b/gen.subproj/ether_addr.c new file mode 100644 index 0000000..d3d1aea --- /dev/null +++ b/gen.subproj/ether_addr.c @@ -0,0 +1,188 @@ +/* + * 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@ + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)ether_addr.c 1.2 88/05/10 4.0NFSSRC; from 1.9 88/02/08 Copyr 1985 Sun Micro"; +#endif + +/* + * Copyright (c) 1985 by Sun Microsystems, Inc. + * + * All routines necessary to deal with the file /etc/ethers. The file + * contains mappings from 48 bit ethernet addresses to their corresponding + * hosts name. The addresses have an ascii representation of the form + * "x:x:x:x:x:x" where x is a hex number between 0x00 and 0xff; the + * bytes are always in network order. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static const char ethers[] = "/etc/ethers"; + +/* + * Parses a line from /etc/ethers into its components. The line has the form + * 8:0:20:1:17:c8 krypton + * where the first part is a 48 bit ethernet addrerss and the second is + * the corresponding hosts name. + * Returns zero if successful, non-zero otherwise. + */ +int ether_line(s, e, hostname) + char *s; /* the string to be parsed */ + struct ether_addr *e; /* ethernet address struct to be filled in */ + char *hostname; /* hosts name to be set */ +{ + register int i; + unsigned int t[6]; + + i = sscanf(s, " %x:%x:%x:%x:%x:%x %s", + &t[0], &t[1], &t[2], &t[3], &t[4], &t[5], hostname); + if (i != 7) { + return (7 - i); + } + for (i = 0; i < 6; i++) + e->ether_addr_octet[i] = t[i]; + return (0); +} + +/* + * Converts a 48 bit ethernet number to its string representation. + */ +#define EI(i) (unsigned int)(e->ether_addr_octet[(i)]) +char * +ether_ntoa(e) + struct ether_addr *e; +{ + static char *s; + + if (s == 0) { + s = (char *)malloc(18); + if (s == 0) + return (0); + } + s[0] = 0; + sprintf(s, "%x:%x:%x:%x:%x:%x", + EI(0), EI(1), EI(2), EI(3), EI(4), EI(5)); + return (s); +} + +/* + * Converts a ethernet address representation back into its 48 bits. + */ +struct ether_addr * +ether_aton(s) + char *s; +{ + static struct ether_addr *ep; + register int i; + unsigned int t[6]; + + if (ep == 0) { + ep = (struct ether_addr *)calloc(1, sizeof (struct ether_addr)); + if (ep == 0) + return (0); + } + i = sscanf(s, " %x:%x:%x:%x:%x:%x", + &t[0], &t[1], &t[2], &t[3], &t[4], &t[5]); + if (i != 6) + return ((struct ether_addr *)NULL); + for (i = 0; i < 6; i++) + ep->ether_addr_octet[i] = t[i]; + return (ep); +} + +/* + * Given a host's name, this routine returns its 48 bit ethernet address. + * Returns zero if successful, non-zero otherwise. + */ +/* XXX need to override in netinfo */ +int ether_hostton(host, e) + char *host; /* function input */ + struct ether_addr *e; /* function output */ +{ + char currenthost[256]; + char buf[512]; + char *val = buf; + register int reason; + FILE *f; + + if ((f = fopen(ethers, "r")) == NULL) + { + return (-1); + } + + reason = -1; + while (fscanf(f, "%[^\n] ", val) == 1) + { + if ((ether_line(val, e, currenthost) == 0) && + (strcmp(currenthost, host) == 0)) + { + reason = 0; + break; + } + } + + fclose(f); + return (reason); +} + +/* + * Given a 48 bit ethernet address, this routine return its host name. + * Returns zero if successful, non-zero otherwise. + */ +/* XXX need to override in netinfo */ +int ether_ntohost(host, e) + char *host; /* function output */ + struct ether_addr *e; /* function input */ +{ + struct ether_addr currente; + char buf[512]; + char *val = buf; + register int reason; + FILE *f; + + if ((f = fopen(ethers, "r")) == NULL) + { + return (-1); + } + + reason = -1; + while (fscanf(f, "%[^\n] ", val) == 1) + { + if ((ether_line(val, ¤te, host) == 0) && + (bcmp(e, ¤te, sizeof(currente)) == 0)) + { + reason = 0; + break; + } + } + + fclose(f); + return (reason); +} diff --git a/gen.subproj/fstab.c b/gen.subproj/fstab.c new file mode 100644 index 0000000..09a2f7b --- /dev/null +++ b/gen.subproj/fstab.c @@ -0,0 +1,330 @@ +/* + * 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) 1995 NeXT Computer, Inc. All Rights Reserved + * + * Copyright (c) 1980, 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * The NEXTSTEP Software License Agreement specifies the terms + * and conditions for redistribution. + * + * @(#)fstab.c 8.1 (Berkeley) 6/4/93 + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static FILE *_fs_fp; +static struct fstab _fs_fstab; +static struct fstab _root_fstab; +static char _root_fstype[MFSNAMELEN]; +static int firstTime = 1; +static int returnedRoot = 0; +static void error __P((int)); +static fstabscan __P((void)); +static char *getRootDev(void); +static const char *slash = "/"; +static const char *remountedroot = "/root"; + +/* We don't want to depend on fstab for the root filesystem entry, +** since that can change when disks are added or removed from the system. +** So, we stat "/" and find the _PATH_DEV entry that matches. The devname() +** function can be used as a shortcut if _PATH_DEVDB exists. This returns a +** string like "sd1a", so we need to prepend _PATH_DEV to it. +*/ + +static char *getDevPath(dev_t target_dev) { + static char dev[MAXPATHLEN]; + char *name; + + strcpy(dev, _PATH_DEV); + + /* The root device in fstab should always be a block special device */ + name = devname(target_dev, S_IFBLK); + if (name == NULL) { + /* No _PATH_DEVDB. We have to search for it the slow way */ + DIR *dirp; + struct dirent *ent; + dirp = opendir(_PATH_DEV); + if (dirp == NULL) { + perror("opendir"); + return NULL; + } + while ((ent = readdir(dirp)) != NULL) { + /* Look for a block special device */ + if (ent->d_type == DT_BLK) { + struct stat devst; + strcat(dev, ent->d_name); + if (stat(dev, &devst) >= 0) { + if (devst.st_rdev == target_dev) { + return dev; + } + } + } + /* set dev to _PATH_DEV and try again */ + dev[sizeof(_PATH_DEV) - 1] = '\0'; + } + } else { + /* We found the _PATH_DEVDB entry */ + strcat(dev, name); + return dev; + } + return NULL; +} + +static int initrootentry(struct fstab *rootentry) +{ + char *rootpath = slash; + struct stat rootstat; + struct statfs rootfsinfo; + char *rootdevname; + + if (stat(rootpath, &rootstat) < 0) { + perror("stat"); + return -1; + }; + if (statfs(rootpath, &rootfsinfo) < 0) { + perror("statfs"); + return -1; + }; + + /* Check to make sure we're not looking at a synthetic root: */ + if (strcmp(rootfsinfo.f_fstypename, "synthfs") == 0) { + rootpath = remountedroot; + if (stat(rootpath, &rootstat) < 0) { + perror("stat"); + return -1; + }; + if (statfs(rootpath, &rootfsinfo) < 0) { + perror("statfs"); + return -1; + }; + }; + + /* Copy the type name before returning a pointer a pointer to it */ + strncpy(_root_fstype, rootfsinfo.f_fstypename, MFSNAMELEN); + + rootentry->fs_spec = getDevPath(rootstat.st_dev); + rootentry->fs_file = rootpath; + rootentry->fs_vfstype = _root_fstype; + rootentry->fs_mntops = FSTAB_RW; + rootentry->fs_type = FSTAB_RW; + rootentry->fs_freq = 0; + rootentry->fs_passno = 1; + + return 0; +} + +static int fstabscan() +{ + register char *cp; +#define MAXLINELENGTH 1024 + static char line[MAXLINELENGTH]; + char subline[MAXLINELENGTH]; + int typexx; + + if (!returnedRoot) { + returnedRoot = 1; + if (firstTime) { + firstTime = 0; + if (initrootentry(&_root_fstab) != 0) { + return 0; + }; + } + _fs_fstab = _root_fstab; + return 1; + } + if (!_fs_fp) { + return(0); + } + for (;;) { + if (!(cp = fgets(line, sizeof(line), _fs_fp))) + return(0); +/* OLD_STYLE_FSTAB */ + if (!strpbrk(cp, " \t")) { + _fs_fstab.fs_spec = strtok(cp, ":\n"); +#if defined(__APPLE__) + if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#') + continue; +#endif + _fs_fstab.fs_file = strtok((char *)NULL, ":\n"); + /* Only list the root filesystem once */ + if (!(strcmp(_fs_fstab.fs_file, "/"))) { + continue; + } + _fs_fstab.fs_type = strtok((char *)NULL, ":\n"); + if (_fs_fstab.fs_type) { + if (!strcmp(_fs_fstab.fs_type, FSTAB_XX)) + continue; + _fs_fstab.fs_mntops = _fs_fstab.fs_type; + _fs_fstab.fs_vfstype = + strcmp(_fs_fstab.fs_type, FSTAB_SW) ? + "ufs" : "swap"; + if ((cp = strtok((char *)NULL, ":\n"))) { + _fs_fstab.fs_freq = atoi(cp); + if ((cp = strtok((char *)NULL, ":\n"))) { + _fs_fstab.fs_passno = atoi(cp); + return(1); + } + } + } + goto bad; + } +/* OLD_STYLE_FSTAB */ + _fs_fstab.fs_spec = strtok(cp, " \t\n"); + if (!_fs_fstab.fs_spec || *_fs_fstab.fs_spec == '#') + continue; + _fs_fstab.fs_file = strtok((char *)NULL, " \t\n"); + /* Only list the root filesystem once */ + if (!(strcmp(_fs_fstab.fs_file, "/"))) { + continue; + } + _fs_fstab.fs_vfstype = strtok((char *)NULL, " \t\n"); + _fs_fstab.fs_mntops = strtok((char *)NULL, " \t\n"); + if (_fs_fstab.fs_mntops == NULL) + goto bad; + _fs_fstab.fs_freq = 0; + _fs_fstab.fs_passno = 0; + if ((cp = strtok((char *)NULL, " \t\n")) != NULL) { + _fs_fstab.fs_freq = atoi(cp); + if ((cp = strtok((char *)NULL, " \t\n")) != NULL) + _fs_fstab.fs_passno = atoi(cp); + } + strcpy(subline, _fs_fstab.fs_mntops); + for (typexx = 0, cp = strtok(subline, ","); cp; + cp = strtok((char *)NULL, ",")) { + if (strlen(cp) != 2) + continue; + if (!strcmp(cp, FSTAB_RW)) { + _fs_fstab.fs_type = FSTAB_RW; + break; + } + if (!strcmp(cp, FSTAB_RQ)) { + _fs_fstab.fs_type = FSTAB_RQ; + break; + } + if (!strcmp(cp, FSTAB_RO)) { + _fs_fstab.fs_type = FSTAB_RO; + break; + } + if (!strcmp(cp, FSTAB_SW)) { + _fs_fstab.fs_type = FSTAB_SW; + break; + } + if (!strcmp(cp, FSTAB_XX)) { + _fs_fstab.fs_type = FSTAB_XX; + typexx++; + break; + } + } + if (typexx) + continue; + if (cp != NULL) + return(1); + +bad: /* no way to distinguish between EOF and syntax error */ + error(EFTYPE); + } + /* NOTREACHED */ +} + +struct fstab * +getfsent() +{ + if (!returnedRoot) { + setfsent(); + } + if (!fstabscan()) { + return((struct fstab *)NULL); + } + return(&_fs_fstab); +} + +struct fstab * +getfsspec(name) + register const char *name; +{ + if (setfsent()) + while (fstabscan()) + if (!strcmp(_fs_fstab.fs_spec, name)) + return(&_fs_fstab); + return((struct fstab *)NULL); +} + +struct fstab * +getfsfile(name) + register const char *name; +{ + if (setfsent()) + while (fstabscan()) + if (!strcmp(_fs_fstab.fs_file, name)) + return(&_fs_fstab); + return((struct fstab *)NULL); +} + +int +setfsent() +{ + returnedRoot = 0; + if (_fs_fp) { + rewind(_fs_fp); + } else { + _fs_fp = fopen(_PATH_FSTAB, "r"); + } + return(1); +} + +void +endfsent() +{ + returnedRoot = 0; + if (_fs_fp) { + (void)fclose(_fs_fp); + _fs_fp = NULL; + } +} + +static void error(err) + int err; +{ + char *p; + + (void)write(STDERR_FILENO, "fstab: ", 7); + (void)write(STDERR_FILENO, _PATH_FSTAB, sizeof(_PATH_FSTAB) - 1); + (void)write(STDERR_FILENO, ": ", 1); + p = strerror(err); + (void)write(STDERR_FILENO, p, strlen(p)); + (void)write(STDERR_FILENO, "\n", 1); +} diff --git a/gen.subproj/getaddrinfo.c b/gen.subproj/getaddrinfo.c new file mode 100644 index 0000000..bce133f --- /dev/null +++ b/gen.subproj/getaddrinfo.c @@ -0,0 +1,1608 @@ +/* + * 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@ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SOCK_UNSPEC 0 +#define IPPROTO_UNSPEC 0 + +#define LONG_STRING_LENGTH 8192 +#define _LU_MAXLUSTRLEN 256 + +static char *LOOKUPD_NAME = "lookup daemon"; + +extern int _lookup_link(); +extern int _lookup_one(); +extern int _lookup_all(); + +struct lu_dict +{ + int count; + char *type; + char *name; + char *cname; + char *mx; + char *ipv4; + char *ipv6; + char *service; + char *port; + char *protocol; + char *target; + char *priority; + char *weight; + struct lu_dict *lu_next; +}; + +#define LU_NAME 1 +#define LU_CNAME 2 +#define LU_MX 3 +#define LU_IPV4 4 +#define LU_IPV6 5 +#define LU_PORT 6 +#define LU_TARGET 7 +#define LU_PRIORITY 8 +#define LU_WEIGHT 9 + +static int supported_family[] = +{ + PF_UNSPEC, + PF_INET, + PF_INET6 +}; +static int supported_family_count = 3; + +static int supported_socket[] = +{ + SOCK_UNSPEC, + SOCK_DGRAM, + SOCK_STREAM +}; +static int supported_socket_count = 3; + +static int supported_protocol[] = +{ + IPPROTO_UNSPEC, + IPPROTO_UDP, + IPPROTO_TCP +}; +static int supported_protocol_count = 3; + +static int supported_socket_protocol_pair[] = +{ + SOCK_UNSPEC, IPPROTO_UNSPEC, + SOCK_UNSPEC, IPPROTO_UDP, + SOCK_UNSPEC, IPPROTO_TCP, + SOCK_DGRAM, IPPROTO_UNSPEC, + SOCK_DGRAM, IPPROTO_UDP, + SOCK_STREAM, IPPROTO_UNSPEC, + SOCK_STREAM, IPPROTO_TCP +}; +static int supported_socket_protocol_pair_count = 7; + +static int +gai_family_type_check(int f) +{ + int i; + + for (i = 0; i < supported_family_count; i++) + { + if (f == supported_family[i]) return 0; + } + + return 1; +} + +static int +gai_socket_type_check(int s) +{ + int i; + + for (i = 0; i < supported_socket_count; i++) + { + if (s == supported_socket[i]) return 0; + } + + return 1; +} + +static int +gai_protocol_type_check(int p) +{ + int i; + + for (i = 0; i < supported_protocol_count; i++) + { + if (p == supported_protocol[i]) return 0; + } + + return 1; +} + +static int +gai_socket_protocol_type_check(int s, int p) +{ + int i, j, ss, sp; + + for (i = 0, j = 0; i < supported_socket_protocol_pair_count; i++, j+=2) + { + ss = supported_socket_protocol_pair[j]; + sp = supported_socket_protocol_pair[j+1]; + if ((s == ss) && (p == sp)) return 0; + } + + return 1; +} + +static int +gai_inet_pton(const char *s, struct in6_addr *a6) +{ + int run, ncolon; + unsigned short x[8]; + char *p, buf[4]; + + if (s == NULL) return 0; + if (a6 == NULL) return 0; + + for (ncolon = 0; ncolon < 8; ncolon++) x[ncolon] = 0; + memset(buf, 0, 4); + + ncolon = 0; + run = 0; + for (p = (char *)s; *p != '\0'; p++) + { + if (*p == ':') + { + if (run > 0) sscanf(buf, "%hx", &(x[ncolon])); + ncolon++; + if (ncolon > 7) return 0; + run = 0; + memset(buf, 0, 4); + } + else if (((*p >= '0') && (*p <= '9')) || ((*p >= 'a') && (*p <= 'f')) || ((*p >= 'A') && (*p <= 'F'))) + { + buf[run] = *p; + run++; + if (run > 4) return 0; + } + } + + if (ncolon != 7) return 0; + + if (run > 0) sscanf(buf, "%hx", &(x[7])); + + a6->__u6_addr.__u6_addr32[0] = (x[0] << 16) + x[1]; + a6->__u6_addr.__u6_addr32[1] = (x[2] << 16) + x[3]; + a6->__u6_addr.__u6_addr32[2] = (x[4] << 16) + x[5]; + a6->__u6_addr.__u6_addr32[3] = (x[6] << 16) + x[7]; + + return 1; +} + +static char * +gai_inet_ntop(struct in6_addr a) +{ + static char buf[128]; + char t[32]; + unsigned short x; + char *p; + int i; + + memset(buf, 0, 128); + + p = (char *)&a.__u6_addr.__u6_addr32; + for (i = 0; i < 8; i++, x += 1) + { + memmove(&x, p, 2); + p += 2; + sprintf(t, "%hx", x); + strcat(buf, t); + if (i < 7) strcat(buf, ":"); + } + + return buf; +} + +char * +gai_strerror(int err) +{ + switch (err) + { + case EAI_ADDRFAMILY: return "Address family for nodename not supported"; + case EAI_AGAIN: return "Temporary failure in name resolution"; + case EAI_BADFLAGS: return "Invalid value for ai_flags"; + case EAI_FAIL: return "Non-recoverable failure in name resolution"; + case EAI_FAMILY: return "ai_family not supported"; + case EAI_MEMORY: return "Memory allocation failure"; + case EAI_NODATA: return "No address associated with nodename"; + case EAI_NONAME: return "nodename nor servname provided, or not known"; + case EAI_SERVICE: return "servname not supported for ai_socktype"; + case EAI_SOCKTYPE: return "ai_socktype not supported"; + case EAI_SYSTEM: return "System error"; + case EAI_BADHINTS: return "Bad hints"; + case EAI_PROTOCOL: return "ai_protocol not supported"; + } + + return "Unknown error"; +} + +static int +is_ipv4_address(const char *s) +{ + struct in_addr a; + + if (s == NULL) return 0; + return inet_aton(s, &a); +} + +static int +is_ipv6_address(const char *s) +{ + struct in6_addr a; + + if (s == NULL) return 0; + return gai_inet_pton(s, &a); +} + +static void +append_addrinfo(struct addrinfo **l, struct addrinfo *a) +{ + struct addrinfo *x; + + if (l == NULL) return; + if (a == NULL) return; + + if (*l == NULL) + { + *l = a; + return; + } + + x = *l; + while (x->ai_next != NULL) x = x->ai_next; + x->ai_next = a; +} + +static void +free_lu_dict(struct lu_dict *d) +{ + struct lu_dict *next; + + while (d != NULL) + { + next = d->lu_next; + if (d->type != NULL) free(d->type); + if (d->name != NULL) free(d->name); + if (d->cname != NULL) free(d->cname); + if (d->mx != NULL) free(d->mx); + if (d->ipv4 != NULL) free(d->ipv4); + if (d->ipv6 != NULL) free(d->ipv6); + if (d->service != NULL) free(d->service); + if (d->port != NULL) free(d->port); + if (d->protocol != NULL) free(d->protocol); + if (d->target != NULL) free(d->target); + if (d->priority != NULL) free(d->priority); + if (d->weight != NULL) free(d->weight); + free(d); + d = next; + } +} + +static void +append_lu_dict(struct lu_dict **l, struct lu_dict *d) +{ + struct lu_dict *x; + + if (l == NULL) return; + if (d == NULL) return; + + if (*l == NULL) + { + *l = d; + return; + } + + x = *l; + while (x->lu_next != NULL) x = x->lu_next; + x->lu_next = d; +} + +/* + * We collect values for the following keys: + * + * name + * cname + * port + * ip_address + * ipv6_address + * target + * mail_exchanger + * priority + * preference + * weight + */ +static void +lookupd_process_dictionary(XDR *inxdr, struct lu_dict **l) +{ + int i, nkeys, j, nvals; + int addme; + char *key, *val; + struct lu_dict *d; + + if (!xdr_int(inxdr, &nkeys)) return; + + d = (struct lu_dict *)malloc(sizeof(struct lu_dict)); + memset(d, 0, sizeof(struct lu_dict)); + + for (i = 0; i < nkeys; i++) + { + key = NULL; + + if (!xdr_string(inxdr, &key, LONG_STRING_LENGTH)) + { + free_lu_dict(d); + return; + } + + addme = 0; + if (!strcmp(key, "name")) addme = LU_NAME; + else if (!strcmp(key, "cname")) addme = LU_CNAME; + else if (!strcmp(key, "mail_exchanger")) addme = LU_MX; + else if (!strcmp(key, "ip_address")) addme = LU_IPV4; + else if (!strcmp(key, "ipv6_address")) addme = LU_IPV6; + else if (!strcmp(key, "port")) addme = LU_PORT; + else if (!strcmp(key, "target")) addme = LU_TARGET; + else if (!strcmp(key, "priority")) addme = LU_PRIORITY; + else if (!strcmp(key, "preference")) addme = LU_PRIORITY; + else if (!strcmp(key, "weight")) addme = LU_WEIGHT; + free(key); + + if (!xdr_int(inxdr, &nvals)) + { + free_lu_dict(d); + return; + } + + for (j = 0; j < nvals; j++) + { + val = NULL; + if (!xdr_string(inxdr, &val, LONG_STRING_LENGTH)) + { + free_lu_dict(d); + return; + } + + if (addme == 0) free(val); + else if (addme == LU_NAME) d->name = val; + else if (addme == LU_CNAME) d->cname = val; + else if (addme == LU_MX) d->mx = val; + else if (addme == LU_IPV4) d->ipv4 = val; + else if (addme == LU_IPV6) d->ipv6 = val; + else if (addme == LU_PORT) d->port = val; + else if (addme == LU_TARGET) d->target = val; + else if (addme == LU_PRIORITY) d->priority = val; + else if (addme == LU_WEIGHT) d->weight = val; + + if (addme != 0) d->count++; + addme = 0; + } + } + + append_lu_dict(l, d); +} + +static mach_port_t +lookupd_port(char *name) +{ + mach_port_t p; + kern_return_t status; + + status = bootstrap_look_up(bootstrap_port, name, &p); + if (status == KERN_SUCCESS) return p; + return MACH_PORT_NULL; +} + +static int +encode_kv(XDR *x, char *k, char *v) +{ + int n = 1; + + if (!xdr_string(x, &k, _LU_MAXLUSTRLEN)) return 1; + if (!xdr_int(x, &n)) return 1; + if (!xdr_string(x, &v, _LU_MAXLUSTRLEN)) return 1; + + return 0; +} + +static int +gai_files(struct lu_dict *q, struct lu_dict **list) +{ + int port, i; + struct servent *s; + struct hostent *h; + struct lu_dict *d; + char str[64]; + struct in_addr a4; + + if (!strcmp(q->type, "service")) + { + s = NULL; + if (q->name != NULL) + { + s = getservbyname(q->name, q->protocol); + } + else if (q->port != NULL) + { + port = atoi(q->port); + s = getservbyport(port, q->protocol); + } + if (s == NULL) return 0; + + d = (struct lu_dict *)malloc(sizeof(struct lu_dict)); + memset(d, 0, sizeof(struct lu_dict)); + + if (s->s_name != NULL) d->name = strdup(s->s_name); + sprintf(str, "%u", s->s_port); + d->port = strdup(str); + if (s->s_proto != NULL) d->protocol = strdup(s->s_proto); + + append_lu_dict(list, d); + return 1; + } + + else if (!strcmp(q->type, "host")) + { + h = NULL; + if (q->name != NULL) + { + h = gethostbyname(q->name); + } + else if (q->ipv4 != NULL) + { + if (inet_aton(q->ipv4, &a4) == 0) return -1; + h = gethostbyaddr((char *)&a4, sizeof(struct in_addr), PF_INET); + } + else + { + /* gethostbyaddr for IPV6? */ + return 0; + } + + if (h == NULL) return 0; + + for (i = 0; h->h_addr_list[i] != 0; i++) + { + d = (struct lu_dict *)malloc(sizeof(struct lu_dict)); + memset(d, 0, sizeof(struct lu_dict)); + + if (h->h_name != NULL) d->name = strdup(h->h_name); + memmove((void *)&a4.s_addr, h->h_addr_list[i], h->h_length); + + sprintf(str, "%s", inet_ntoa(a4)); + d->ipv4 = strdup(str); + + append_lu_dict(list, d); + } + return i; + } + + return 0; +} + +static int +gai_lookupd(struct lu_dict *q, struct lu_dict **list) +{ + unsigned datalen; + XDR outxdr; + XDR inxdr; + int proc; + char *listbuf; + char databuf[_LU_MAXLUSTRLEN * BYTES_PER_XDR_UNIT]; + int n, i, na; + kern_return_t status; + mach_port_t server_port; + + if (q == NULL) return 0; + if (q->count == 0) return 0; + if (q->type == NULL) return 0; + + if (list == NULL) return -1; + + server_port = lookupd_port(LOOKUPD_NAME); + if (server_port == NULL) return gai_files(q, list); + + status = _lookup_link(server_port, "query", &proc); + if (status != KERN_SUCCESS) return gai_files(q, list); + + xdrmem_create(&outxdr, databuf, sizeof(databuf), XDR_ENCODE); + + /* Encode attribute count */ + na = q->count; + if (!xdr_int(&outxdr, &na)) + { + xdr_destroy(&outxdr); + return -1; + } + + if (encode_kv(&outxdr, "_lookup_category", q->type) != 0) + { + xdr_destroy(&outxdr); + return -1; + } + + if (q->name != NULL) + { + if (encode_kv(&outxdr, "name", q->name) != 0) + { + xdr_destroy(&outxdr); + return -1; + } + } + + if (q->ipv4 != NULL) + { + if (encode_kv(&outxdr, "ip_address", q->ipv4) != 0) + { + xdr_destroy(&outxdr); + return -1; + } + } + + if (q->ipv6 != NULL) + { + if (encode_kv(&outxdr, "ipv6_address", q->ipv6) != 0) + { + xdr_destroy(&outxdr); + return -1; + } + } + + if (q->service != NULL) + { + if (encode_kv(&outxdr, "service", q->service) != 0) + { + xdr_destroy(&outxdr); + return -1; + } + } + + if (q->port != NULL) + { + if (encode_kv(&outxdr, "port", q->port) != 0) + { + xdr_destroy(&outxdr); + return -1; + } + } + + if (q->protocol != NULL) + { + if (encode_kv(&outxdr, "protocol", q->protocol) != 0) + { + xdr_destroy(&outxdr); + return -1; + } + } + + listbuf = NULL; + datalen = 0; + + n = xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT; + status = _lookup_all(server_port, proc, databuf, n, &listbuf, &datalen); + if (status != KERN_SUCCESS) + { + xdr_destroy(&outxdr); + return -1; + } + + xdr_destroy(&outxdr); + +#ifdef NOTDEF +/* NOTDEF because OOL buffers are counted in bytes with untyped IPC */ + datalen *= BYTES_PER_XDR_UNIT; +#endif + xdrmem_create(&inxdr, listbuf, datalen, XDR_DECODE); + + if (!xdr_int(&inxdr, &n)) + { + xdr_destroy(&inxdr); + return -1; + } + + for (i = 0; i < n; i++) + { + lookupd_process_dictionary(&inxdr, list); + } + + xdr_destroy(&inxdr); + + vm_deallocate(mach_task_self(), (vm_address_t)listbuf, datalen); + + return n; +} + +void +freeaddrinfo(struct addrinfo *a) +{ + struct addrinfo *next; + + while (a != NULL) + { + next = a->ai_next; + if (a->ai_canonname != NULL) free(a->ai_canonname); + free(a); + a = next; + } +} + +static struct addrinfo * +new_addrinfo_v4(int flags, int sock, int proto, unsigned short port, struct in_addr addr, char *cname) +{ + struct addrinfo *a; + struct sockaddr_in *sa; + int len; + + a = (struct addrinfo *)malloc(sizeof(struct addrinfo)); + memset(a, 0, sizeof(struct addrinfo)); + a->ai_next = NULL; + + a->ai_flags = flags; + a->ai_family = PF_INET; + a->ai_socktype = sock; + a->ai_protocol = proto; + + a->ai_addrlen = sizeof(struct sockaddr_in); + sa = (struct sockaddr_in *)malloc(a->ai_addrlen); + memset(sa, 0, a->ai_addrlen); + sa->sin_len = a->ai_addrlen; + sa->sin_family = PF_INET; + sa->sin_port = port; + sa->sin_addr = addr; + a->ai_addr = (struct sockaddr *)sa; + + if (cname != NULL) + { + len = strlen(cname) + 1; + a->ai_canonname = malloc(len); + memmove(a->ai_canonname, cname, len); + } + + return a; +} + +static struct addrinfo * +new_addrinfo_v6(int flags, int sock, int proto, unsigned short port, struct in6_addr addr, char *cname) +{ + struct addrinfo *a; + struct sockaddr_in6 *sa; + int len; + + a = (struct addrinfo *)malloc(sizeof(struct addrinfo)); + memset(a, 0, sizeof(struct addrinfo)); + a->ai_next = NULL; + + a->ai_flags = flags; + a->ai_family = PF_INET6; + a->ai_socktype = sock; + a->ai_protocol = proto; + + a->ai_addrlen = sizeof(struct sockaddr_in6); + sa = (struct sockaddr_in6 *)malloc(a->ai_addrlen); + memset(sa, 0, a->ai_addrlen); + sa->sin6_len = a->ai_addrlen; + sa->sin6_family = PF_INET6; + sa->sin6_port = port; + sa->sin6_addr = addr; + a->ai_addr = (struct sockaddr *)sa; + + if (cname != NULL) + { + len = strlen(cname) + 1; + a->ai_canonname = malloc(len); + memmove(a->ai_canonname, cname, len); + } + + return a; +} + +static void +grok_nodename(const char *nodename, int family, struct lu_dict *q) +{ + if (nodename == NULL) return; + if (q == NULL) return; + + if (((family == PF_UNSPEC) || (family == PF_INET)) && is_ipv4_address(nodename)) + { + q->ipv4 = (char *)nodename; + } + else if (((family == PF_UNSPEC) || (family == PF_INET6)) && is_ipv6_address(nodename)) + { + q->ipv6 = (char *)nodename; + } + else + { + q->name = (char *)nodename; + } +} + +static void +grok_service(const char *servname, struct lu_dict *q) +{ + int port; + char *p; + + if (servname == NULL) return; + if (q == NULL) return; + + port = 0; + for (p = (char *)servname; (port == 0) && (*p != '\0'); p++) + { + if (!isdigit(*p)) port = -1; + } + + if (port == 0) port = atoi(servname); + if ((port > 0) && (port < 0xffff)) q->port = (char *)servname; + else q->service = (char *)servname; +} + +static int +gai_numerichost(struct lu_dict *h, struct lu_dict **list) +{ + struct lu_dict *a; + int n; + + if (h == NULL) return 0; + if (list == NULL) return -1; + + n = 0; + + if (h->ipv4 != NULL) + { + a = (struct lu_dict *)malloc(sizeof(struct lu_dict)); + memset(a, 0, sizeof(struct lu_dict)); + a->ipv4 = strdup(h->ipv4); + append_lu_dict(list, a); + n++; + } + + if (h->ipv6 != NULL) + { + a = (struct lu_dict *)malloc(sizeof(struct lu_dict)); + memset(a, 0, sizeof(struct lu_dict)); + a->ipv6 = strdup(h->ipv6); + append_lu_dict(list, a); + n++; + } + + return n; +} + +static int +gai_numericserv(struct lu_dict *s, struct lu_dict **list) +{ + struct lu_dict *a; + + if (s == NULL) return 0; + if (s->port == NULL) return 0; + if (list == NULL) return -1; + + a = (struct lu_dict *)malloc(sizeof(struct lu_dict)); + memset(a, 0, sizeof(struct lu_dict)); + a->port = strdup(s->port); + append_lu_dict(list, a); + return 1; +} + +static void +merge_addr4(struct in_addr a, struct sockaddr_in ***l, int *n) +{ + int i; + struct sockaddr_in *sa4; + + for (i = 0; i < *n; i++) + { + if (((*l)[i]->sin_family == PF_INET) && (a.s_addr == (*l)[i]->sin_addr.s_addr)) return; + } + + sa4 = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in)); + memset(sa4, 0, sizeof(struct sockaddr_in)); + + sa4->sin_family = PF_INET; + sa4->sin_addr = a; + + if (*n == 0) *l = (struct sockaddr_in **)malloc(sizeof(struct sockaddr_in *)); + else *l = (struct sockaddr_in **)realloc(*l, (*n + 1) * sizeof(struct sockaddr_in *)); + + (*l)[*n] = sa4; + (*n)++; +} + +static void +merge_addr6(struct in6_addr a, struct sockaddr_in6 ***l, int *n) +{ + int i; + struct sockaddr_in6 *sa6; + + for (i = 0; i < *n; i++) + { + if (((*l)[i]->sin6_family == PF_INET6) + && (a.__u6_addr.__u6_addr32[0] == (*l)[i]->sin6_addr.__u6_addr.__u6_addr32[0])) return; + } + + sa6 = (struct sockaddr_in6 *)malloc(sizeof(struct sockaddr_in6)); + memset(sa6, 0, sizeof(struct sockaddr_in6)); + + sa6->sin6_family = PF_INET6; + sa6->sin6_addr = a; + + if (*n == 0) *l = (struct sockaddr_in6 **)malloc(sizeof(struct sockaddr_in6 *)); + else *l = (struct sockaddr_in6 **)realloc(*l, (*n + 1) * sizeof(struct sockaddr_in6 *)); + + (*l)[*n] = sa6; + (*n)++; +} + +/* + * N.B. We use sim_family to store protocol in the sockaddr. + * sockaddr is just used here as a data structure to keep + * (port, protocol) pairs. + */ +static void +merge_plist(unsigned short port, unsigned short proto, struct sockaddr_in ***l, int *n) +{ + int i; + struct sockaddr_in *sa4; + + for (i = 0; i < *n; i++) + { + if ((port == (*l)[i]->sin_port) && (proto == (*l)[i]->sin_family)) return; + } + + sa4 = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in)); + memset(sa4, 0, sizeof(struct sockaddr_in)); + + sa4->sin_port = port; + sa4->sin_family = proto; + + if (*n == 0) *l = (struct sockaddr_in **)malloc(sizeof(struct sockaddr_in *)); + else *l = (struct sockaddr_in **)realloc(*l, (*n + 1) * sizeof(struct sockaddr_in *)); + + (*l)[*n] = (struct sockaddr_in *)sa4; + (*n)++; +} + +/* + * Compute x[n + 1] = (7^5 * x[n]) mod (2^31 - 1). + * From "Random number generators: good ones are hard to find", + * Park and Miller, Communications of the ACM, vol. 31, no. 10, + * October 1988, p. 1195. + */ +static int +gai_random() +{ + static int did_init = 0; + static unsigned int randseed = 1; + int x, hi, lo, t; + struct timeval tv; + + if (did_init++ == 0) + { + gettimeofday(&tv, NULL); + randseed = tv.tv_usec; + if(randseed == 0) randseed = 1; + } + + x = randseed; + hi = x / 127773; + lo = x % 127773; + t = 16807 * lo - 2836 * hi; + if (t <= 0) t += 0x7fffffff; + randseed = t; + return t; +} + +/* + * Sort by priority and weight. + */ +void +lu_prioity_sort(struct lu_dict **l) +{ + struct lu_dict *d, **nodes; + unsigned int x, count, i, j, bottom, *pri, *wgt, swap, t; + + if (*l == NULL) return; + + count = 0; + for (d = *l; d != NULL; d = d->lu_next) count++; + nodes = (struct lu_dict **)malloc(count * sizeof(struct lu_dict *)); + pri = (unsigned int *)malloc(count * sizeof(unsigned int)); + wgt = (unsigned int *)malloc(count * sizeof(unsigned int)); + + for (i = 0, d = *l; d != NULL; d = d->lu_next, i++) + { + nodes[i] = d; + + x = (unsigned int)-1; + if (d->priority != NULL) x = atoi(d->priority); + pri[i] = x; + + x = 0; + if (d->weight != NULL) x = atoi(d->weight); + wgt[i] = (gai_random() % 10000) * x; + } + + /* bubble sort by priority */ + swap = 1; + bottom = count - 1; + + while (swap == 1) + { + swap = 0; + for (i = 0, j = 1; i < bottom; i++, j++) + { + if (pri[i] < pri[j]) continue; + if ((pri[i] == pri[j]) && (wgt[i] < wgt[j])) continue; + swap = 1; + + t = pri[i]; + pri[i] = pri[j]; + pri[j] = t; + + t = wgt[i]; + wgt[i] = wgt[j]; + wgt[j] = t; + + d = nodes[i]; + nodes[i] = nodes[j]; + nodes[j] = d; + } + + bottom--; + } + + *l = nodes[0]; + bottom = count - 1; + for (i = 0, j = 1; i < bottom; i++, j++) nodes[i]->lu_next = nodes[j]; + nodes[bottom]->lu_next = NULL; + + free(pri); + free(wgt); + free(nodes); +} + +/* + * Get service records from lookupd + */ +static void +gai_serv_lookupd(const char *servname, int proto, int numericserv, struct lu_dict **list) +{ + struct lu_dict q, *sub; + + memset(&q, 0, sizeof(struct lu_dict)); + q.count = 3; + q.type = "service"; + + grok_service(servname, &q); + if (q.service != NULL) + { + q.name = q.service; + q.service = NULL; + } + + if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_UDP)) + { + sub = NULL; + q.protocol = "udp"; + if (numericserv == 1) gai_numericserv(&q, &sub); + else gai_lookupd(&q, &sub); + append_lu_dict(list, sub); + for (; sub != NULL; sub = sub->lu_next) sub->protocol = strdup("udp"); + } + + if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_TCP)) + { + sub = NULL; + q.protocol = "tcp"; + if (numericserv == 1) gai_numericserv(&q, &sub); + else gai_lookupd(&q, &sub); + append_lu_dict(list, sub); + for (; sub != NULL; sub = sub->lu_next) sub->protocol = strdup("tcp"); + } +} + +/* + * Find a service. + */ +static int +gai_serv(const char *servname, const struct addrinfo *hints, struct addrinfo **res) +{ + struct lu_dict *list, *d; + int port, proto, family, socktype, setcname, wantv4, wantv6; + char *loopv4, *loopv6; + struct addrinfo *a; + struct in_addr a4; + struct in6_addr a6; + + loopv4 = "127.0.0.1"; + loopv6 = "0:0:0:0:0:0:0:1"; + + family = PF_UNSPEC; + proto = IPPROTO_UNSPEC; + setcname = 0; + + if (hints != NULL) + { + proto = hints->ai_protocol; + if (hints->ai_socktype == SOCK_DGRAM) proto = IPPROTO_UDP; + if (hints->ai_socktype == SOCK_STREAM) proto = IPPROTO_TCP; + + if (hints->ai_flags & AI_CANONNAME) setcname = 1; + + if ((hints->ai_flags & AI_PASSIVE) == 1) + { + loopv4 = "0.0.0.0"; + loopv6 = "0:0:0:0:0:0:0:0"; + } + + family = hints->ai_family; + } + + wantv4 = 1; + wantv6 = 1; + if (family == PF_INET6) wantv4 = 0; + if (family == PF_INET) wantv6 = 0; + + list = NULL; + gai_serv_lookupd(servname, proto, 0, &list); + if (list == NULL) gai_serv_lookupd(servname, proto, 1, &list); + + for (d = list; d != NULL; d = d->lu_next) + { + /* We only want records with port and protocol specified */ + if ((d->port == NULL) || (d->protocol == NULL)) continue; + + port = atoi(d->port); + proto = IPPROTO_UDP; + socktype = SOCK_DGRAM; + if (!strcasecmp(d->protocol, "tcp")) + { + proto = IPPROTO_TCP; + socktype = SOCK_STREAM; + } + + if (wantv4 == 1) + { + inet_aton(loopv4, &a4); + a = new_addrinfo_v4(0, socktype, proto, port, a4, NULL); + append_addrinfo(res, a); + } + + if (wantv6 == 1) + { + gai_inet_pton(loopv6, &a6); + a = new_addrinfo_v6(0, socktype, proto, port, a6, NULL); + append_addrinfo(res, a); + } + } + + free_lu_dict(list); + + /* Set cname in first result */ + if ((setcname == 1) && (*res != NULL)) + { + if (res[0]->ai_canonname == NULL) res[0]->ai_canonname = strdup("localhost"); + } + + return 0; +} + +/* + * Find a node. + */ +static void +gai_node_lookupd(const char *nodename, int family, int numerichost, struct lu_dict **list) +{ + struct lu_dict q; + + memset(&q, 0, sizeof(struct lu_dict)); + q.count = 2; + q.type = "host"; + + grok_nodename(nodename, family, &q); + if (numerichost) gai_numerichost(&q, list); + else gai_lookupd(&q, list); +} + +/* + * Find a node. + */ +static int +gai_node(const char *nodename, const struct addrinfo *hints, struct addrinfo **res) +{ + int i, family, numerichost, setcname, a_list_count, wantv4, wantv6; + struct lu_dict *list, *d, *t; + char *cname; + struct in_addr a4; + struct in6_addr a6; + struct addrinfo *a; + struct sockaddr **a_list; + struct sockaddr_in *sa4; + struct sockaddr_in6 *sa6; + + a_list_count = 0; + a_list = NULL; + + numerichost = 0; + family = PF_UNSPEC; + setcname = 0; + cname = NULL; + + if (hints != NULL) + { + family = hints->ai_family; + if (hints->ai_flags & AI_NUMERICHOST) numerichost = 1; + if (hints->ai_flags & AI_CANONNAME) setcname = 1; + } + + wantv4 = 1; + wantv6 = 1; + if (family == PF_INET6) wantv4 = 0; + if (family == PF_INET) wantv6 = 0; + + t = NULL; + gai_node_lookupd(nodename, family, numerichost, &t); + if ((t == NULL) && (numerichost == 0)) + { + gai_node_lookupd(nodename, family, 1, &t); + } + + /* If the nodename is an alias, look up the real name */ + list = NULL; + for (d = t; d != NULL; d = d->lu_next) + { + if (d->cname != NULL) + { + if (cname == NULL) cname = strdup(d->cname); + gai_node_lookupd(d->cname, family, 0, &t); + } + } + + append_lu_dict(&list, t); + + for (d = list; d != NULL; d = d->lu_next) + { + /* Check for cname */ + if ((cname == NULL) && (d->name != NULL) && (strchr(d->name, '.') != NULL)) + { + cname = strdup(d->name); + } + + /* Check for ipv4 address */ + if ((d->ipv4 != NULL) && (wantv4 == 1)) + { + inet_aton(d->ipv4, &a4); + merge_addr4(a4, (struct sockaddr_in ***)&a_list, &a_list_count); + } + + /* Check for ipv6 address */ + if ((d->ipv6 != NULL) && (wantv6 == 1)) + { + gai_inet_pton(d->ipv6, &a6); + merge_addr6(a6, (struct sockaddr_in6 ***)&a_list, &a_list_count); + } + } + + /* Last chance for a name */ + for (d = list; (cname == NULL) && (d != NULL); d = d->lu_next) + { + if (d->name != NULL) cname = strdup(d->name); + } + + free_lu_dict(list); + + for (i = 0; i < a_list_count; i++) + { + if (a_list[i]->sa_family == PF_INET) + { + sa4 = (struct sockaddr_in *)a_list[i]; + a = new_addrinfo_v4(0, 0, 0, 0, sa4->sin_addr, NULL); + append_addrinfo(res, a); + } + else if (a_list[i]->sa_family == PF_INET6) + { + sa6 = (struct sockaddr_in6 *)a_list[i]; + a = new_addrinfo_v6(0, 0, 0, 0, sa6->sin6_addr, NULL); + append_addrinfo(res, a); + } + + free(a_list[i]); + } + + if (a_list_count > 0) free(a_list); + + /* Set cname in first result */ + if ((setcname == 1) && (*res != NULL)) + { + if (res[0]->ai_canonname == NULL) + { + res[0]->ai_canonname = cname; + cname = NULL; + } + } + + if (cname != NULL) free(cname); + + return 0; +} + +/* + * Find a service+node. + */ +static void +gai_nodeserv_lookupd(const char *nodename, const char *servname, const struct addrinfo *hints, struct lu_dict **list) +{ + struct lu_dict q, *sub; + int proto, family; + + family = PF_UNSPEC; + proto = IPPROTO_UNSPEC; + + if (hints != NULL) + { + if (hints->ai_flags & AI_NUMERICHOST) return; + family = hints->ai_family; + + proto = hints->ai_protocol; + if (hints->ai_socktype == SOCK_DGRAM) proto = IPPROTO_UDP; + if (hints->ai_socktype == SOCK_STREAM) proto = IPPROTO_TCP; + } + + memset(&q, 0, sizeof(struct lu_dict)); + q.count = 4; + q.type = "host"; + + grok_nodename(nodename, family, &q); + grok_service(servname, &q); + + if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_UDP)) + { + sub = NULL; + q.protocol = "udp"; + gai_lookupd(&q, &sub); + append_lu_dict(list, sub); + for (; sub != NULL; sub = sub->lu_next) sub->protocol = strdup("udp"); + } + + if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_TCP)) + { + sub = NULL; + q.protocol = "tcp"; + gai_lookupd(&q, &sub); + append_lu_dict(list, sub); + for (; sub != NULL; sub = sub->lu_next) sub->protocol = strdup("tcp"); + } +} + +static void +gai_node_pp(const char *nodename, int port, int proto, int family, int setcname, struct addrinfo **res) +{ + struct lu_dict *list, *d; + int i, wantv4, wantv6, a_list_count, socktype; + char *cname; + struct sockaddr **a_list; + struct in_addr a4; + struct in6_addr a6; + struct sockaddr_in *sa4; + struct sockaddr_in6 *sa6; + struct addrinfo *a; + + socktype = SOCK_UNSPEC; + if (proto == IPPROTO_UDP) socktype = SOCK_DGRAM; + if (proto == IPPROTO_TCP) socktype = SOCK_STREAM; + + cname = NULL; + + wantv4 = 1; + wantv6 = 1; + if (family == PF_INET6) wantv4 = 0; + if (family == PF_INET) wantv6 = 0; + + /* Resolve node name */ + list = NULL; + gai_node_lookupd(nodename, family, 0, &list); + if (list == NULL) + { + gai_node_lookupd(nodename, family, 1, &list); + } + + /* Resolve aliases */ + for (d = list; d != NULL; d = d->lu_next) + { + if (d->cname != NULL) + { + cname = strdup(d->cname); + gai_node_lookupd(d->cname, family, 0, &list); + } + } + + a_list_count = 0; + + for (d = list; d != NULL; d = d->lu_next) + { + /* Check for cname */ + if ((cname == NULL) && (d->name != NULL) && (strchr(d->name, '.') != NULL)) + { + cname = strdup(d->name); + } + + /* Check for ipv4 address */ + if ((d->ipv4 != NULL) && (wantv4 == 1)) + { + inet_aton(d->ipv4, &a4); + merge_addr4(a4, (struct sockaddr_in ***)&a_list, &a_list_count); + } + + /* Check for ipv6 address */ + if ((d->ipv6 != NULL) && (wantv6 == 1)) + { + gai_inet_pton(d->ipv6, &a6); + merge_addr6(a6, (struct sockaddr_in6 ***)&a_list, &a_list_count); + } + } + + free_lu_dict(list); + + for (i = 0; i < a_list_count; i++) + { + if (a_list[i]->sa_family == PF_INET) + { + sa4 = (struct sockaddr_in *)a_list[i]; + a = new_addrinfo_v4(0, socktype, proto, port, sa4->sin_addr, NULL); + append_addrinfo(res, a); + } + else if (a_list[i]->sa_family == PF_INET6) + { + sa6 = (struct sockaddr_in6 *)a_list[i]; + a = new_addrinfo_v6(0, socktype, proto, port, sa6->sin6_addr, NULL); + append_addrinfo(res, a); + } + + free(a_list[i]); + } + + if (a_list_count > 0) free(a_list); + + /* Set cname in first result */ + if ((setcname == 1) && (*res != NULL)) + { + if (res[0]->ai_canonname == NULL) + { + res[0]->ai_canonname = cname; + cname = NULL; + } + } + + if (cname != NULL) free(cname); +} + +static int +gai_nodeserv(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res) +{ + struct lu_dict *srv_list, *node_list, *s, *n; + int numerichost, family, port, proto, setcname; + int wantv4, wantv6, i, j, gotmx, p_list_count; + char *cname; + struct sockaddr **p_list; + struct sockaddr_in *sa4; + + numerichost = 0; + family = PF_UNSPEC; + proto = IPPROTO_UNSPEC; + setcname = 0; + cname = NULL; + wantv4 = 1; + wantv6 = 1; + + if (hints != NULL) + { + family = hints->ai_family; + if (hints->ai_flags & AI_NUMERICHOST) numerichost = 1; + if (hints->ai_flags & AI_CANONNAME) setcname = 1; + + proto = hints->ai_protocol; + if (hints->ai_socktype == SOCK_DGRAM) proto = IPPROTO_UDP; + if (hints->ai_socktype == SOCK_STREAM) proto = IPPROTO_TCP; + } + + if (family == PF_INET6) wantv4 = 0; + if (family == PF_INET) wantv6 = 0; + + /* First check for this particular host / service (e.g. DNS_SRV) */ + + srv_list = NULL; + gai_nodeserv_lookupd(nodename, servname, hints, &srv_list); + lu_prioity_sort(&srv_list); + + if (srv_list != NULL) + { + for (s = srv_list; s != NULL; s = s->lu_next) + { + if (s->port == NULL) continue; + if (s->protocol == NULL) continue; + + i = atoi(s->port); + j = IPPROTO_UDP; + if (!strcmp(s->protocol, "tcp")) j = IPPROTO_TCP; + gai_node_pp(s->target, i, j, family, setcname, res); + } + + free_lu_dict(srv_list); + return 0; + } + + /* + * Special case for smtp: collect mail_exchangers. + */ + gotmx = 0; + node_list = NULL; + + if (!strcmp(servname, "smtp")) + { + gai_node_lookupd(nodename, family, numerichost, &node_list); + if ((node_list == NULL) && (numerichost == 0)) + { + gai_node_lookupd(nodename, family, 1, &node_list); + } + + lu_prioity_sort(&node_list); + + for (n = node_list; (n != NULL) && (gotmx == 0); n = n->lu_next) + { + if (n->mx != NULL) gotmx = 1; + } + + if ((gotmx == 0) && (node_list != NULL)) + { + free_lu_dict(node_list); + node_list = NULL; + } + } + + /* + * Look up service, look up node, and combine port/proto with node addresses. + */ + srv_list = NULL; + gai_serv_lookupd(servname, proto, 0, &srv_list); + if (srv_list == NULL) gai_serv_lookupd(servname, proto, 1, &srv_list); + if (srv_list == NULL) return 0; + + p_list_count = 0; + for (s = srv_list; s != NULL; s = s->lu_next) + { + if (s->port == NULL) continue; + if (s->protocol == NULL) continue; + + i = atoi(s->port); + j = IPPROTO_UDP; + if (!strcmp(s->protocol, "tcp")) j = IPPROTO_TCP; + + merge_plist(i, j, (struct sockaddr_in ***)&p_list, &p_list_count); + } + + free_lu_dict(srv_list); + + for (i = 0; i < p_list_count; i++) + { + sa4 = (struct sockaddr_in *)p_list[i]; + port = sa4->sin_port; + /* N.B. sin_family is overloaded */ + proto = sa4->sin_family; + + if (gotmx == 1) + { + for (n = node_list; n != NULL; n = n->lu_next) + { + if (n->mx != NULL) gai_node_pp(n->mx, port, proto, family, setcname, res); + } + } + else + { + gai_node_pp(nodename, port, proto, family, setcname, res); + } + + free(p_list[i]); + } + + if (node_list != NULL) free_lu_dict(node_list); + + if (p_list_count > 0) free(p_list); + return 0; +} + +int +getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res) +{ + int status; + struct lu_dict *list; + + if (res == NULL) return 0; + *res = NULL; + list = NULL; + + /* Check input */ + if ((nodename == NULL) && (servname == NULL)) return EAI_NONAME; + + /* Check hints */ + if (hints != NULL) + { + if (hints->ai_addrlen != 0) return EAI_BADHINTS; + if (hints->ai_canonname != NULL) return EAI_BADHINTS; + if (hints->ai_addr != NULL) return EAI_BADHINTS; + if (hints->ai_next != NULL) return EAI_BADHINTS; + + /* Check for supported protocol family */ + if (gai_family_type_check(hints->ai_family) != 0) return EAI_FAMILY; + + /* Check for supported socket */ + if (gai_socket_type_check(hints->ai_socktype) != 0) return EAI_BADHINTS; + + /* Check for supported protocol */ + if (gai_protocol_type_check(hints->ai_protocol) != 0) return EAI_BADHINTS; + + /* Check that socket type is compatible with protocol */ + if (gai_socket_protocol_type_check(hints->ai_socktype, hints->ai_protocol) != 0) return EAI_BADHINTS; + } + + status = 0; + + if (nodename == NULL) + { + /* If node is NULL, find service */ + return gai_serv(servname, hints, res); + } + + if (servname == NULL) + { + /* If service is NULL, find node */ + return gai_node(nodename, hints, res); + } + + /* Find node + service */ + return gai_nodeserv(nodename, servname, hints, res); +} diff --git a/gen.subproj/getgrent.c b/gen.subproj/getgrent.c new file mode 100644 index 0000000..e9552d4 --- /dev/null +++ b/gen.subproj/getgrent.c @@ -0,0 +1,204 @@ +/* + * 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) 1989, 1993 + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getgrent.c 8.2 (Berkeley) 3/21/94"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include + +static FILE *_gr_fp; +static struct group _gr_group; +static int _gr_stayopen; +static int grscan(), start_gr(); + +#define MAXGRP 200 +static char *members[MAXGRP]; +#define MAXLINELENGTH 1024 +static char line[MAXLINELENGTH]; + +struct group * +getgrent() +{ + if (!_gr_fp && !start_gr() || !grscan(0, 0, NULL)) + return(NULL); + return(&_gr_group); +} + +struct group * +getgrnam(name) + const char *name; +{ + int rval; + + if (!start_gr()) + return(NULL); + rval = grscan(1, 0, name); + if (!_gr_stayopen) + endgrent(); + return(rval ? &_gr_group : NULL); +} + +struct group * +#ifdef __STDC__ +getgrgid(gid_t gid) +#else +getgrgid(gid) + gid_t gid; +#endif +{ + int rval; + + if (!start_gr()) + return(NULL); + rval = grscan(1, gid, NULL); + if (!_gr_stayopen) + endgrent(); + return(rval ? &_gr_group : NULL); +} + +static +start_gr() +{ + if (_gr_fp) { + rewind(_gr_fp); + return(1); + } + return((_gr_fp = fopen(_PATH_GROUP, "r")) ? 1 : 0); +} + +int +setgrent() +{ + return(setgroupent(0)); +} + +int +setgroupent(stayopen) + int stayopen; +{ + if (!start_gr()) + return(0); + _gr_stayopen = stayopen; + return(1); +} + +void +endgrent() +{ + if (_gr_fp) { + (void)fclose(_gr_fp); + _gr_fp = NULL; + } +} + +static +grscan(search, gid, name) + register int search, gid; + register char *name; +{ + register char *cp, **m; + char *bp; + char *fgets(), *strsep(), *index(); + + for (;;) { + if (!fgets(line, sizeof(line), _gr_fp)) + return(0); + bp = line; + /* skip lines that are too big */ + if (!index(line, '\n')) { + int ch; + + while ((ch = getc(_gr_fp)) != '\n' && ch != EOF) + ; + continue; + } + _gr_group.gr_name = strsep(&bp, ":\n"); + if (search && name && strcmp(_gr_group.gr_name, name)) + continue; + _gr_group.gr_passwd = strsep(&bp, ":\n"); + if (!(cp = strsep(&bp, ":\n"))) + continue; + _gr_group.gr_gid = atoi(cp); + if (search && name == NULL && _gr_group.gr_gid != gid) + continue; + cp = NULL; + for (m = _gr_group.gr_mem = members;; bp++) { + if (m == &members[MAXGRP - 1]) + break; + if (*bp == ',') { + if (cp) { + *bp = '\0'; + *m++ = cp; + cp = NULL; + } + } else if (*bp == '\0' || *bp == '\n' || *bp == ' ') { + if (cp) { + *bp = '\0'; + *m++ = cp; + } + break; + } else if (cp == NULL) + cp = bp; + } + *m = NULL; + return(1); + } + /* NOTREACHED */ +} diff --git a/gen.subproj/getproto.c b/gen.subproj/getproto.c new file mode 100644 index 0000000..0c3634e --- /dev/null +++ b/gen.subproj/getproto.c @@ -0,0 +1,78 @@ +/* + * 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) 1983, 1993 + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getproto.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include + +extern int _proto_stayopen; + +struct protoent * +getprotobynumber(proto) + register int proto; +{ + register struct protoent *p; + + setprotoent(_proto_stayopen); + while (p = getprotoent()) + if (p->p_proto == proto) + break; + if (!_proto_stayopen) + endprotoent(); + return (p); +} diff --git a/gen.subproj/getprotoent.c b/gen.subproj/getprotoent.c new file mode 100644 index 0000000..0320109 --- /dev/null +++ b/gen.subproj/getprotoent.c @@ -0,0 +1,142 @@ +/* + * 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) 1983, 1993 + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getprotoent.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include + +#define MAXALIASES 35 + +static FILE *protof = NULL; +static char line[BUFSIZ+1]; +static struct protoent proto; +static char *proto_aliases[MAXALIASES]; +int _proto_stayopen; + +void +setprotoent(f) + int f; +{ + if (protof == NULL) + protof = fopen(_PATH_PROTOCOLS, "r" ); + else + rewind(protof); + _proto_stayopen |= f; +} + +void +endprotoent() +{ + if (protof) { + fclose(protof); + protof = NULL; + } + _proto_stayopen = 0; +} + +struct protoent * +getprotoent() +{ + char *p; + register char *cp, **q; + + if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL) + return (NULL); +again: + if ((p = fgets(line, BUFSIZ, protof)) == NULL) + return (NULL); + if (*p == '#') + goto again; + cp = strpbrk(p, "#\n"); + if (cp == NULL) + goto again; + *cp = '\0'; + proto.p_name = p; + cp = strpbrk(p, " \t"); + if (cp == NULL) + goto again; + *cp++ = '\0'; + while (*cp == ' ' || *cp == '\t') + cp++; + p = strpbrk(cp, " \t"); + if (p != NULL) + *p++ = '\0'; + proto.p_proto = atoi(cp); + q = proto.p_aliases = proto_aliases; + if (p != NULL) { + cp = p; + while (cp && *cp) { + if (*cp == ' ' || *cp == '\t') { + cp++; + continue; + } + if (q < &proto_aliases[MAXALIASES - 1]) + *q++ = cp; + cp = strpbrk(cp, " \t"); + if (cp != NULL) + *cp++ = '\0'; + } + } + *q = NULL; + return (&proto); +} diff --git a/gen.subproj/getprotoname.c b/gen.subproj/getprotoname.c new file mode 100644 index 0000000..49551e1 --- /dev/null +++ b/gen.subproj/getprotoname.c @@ -0,0 +1,85 @@ +/* + * 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) 1983, 1993 + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getprotoname.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +extern int _proto_stayopen; + +struct protoent * +getprotobyname(name) + register const char *name; +{ + register struct protoent *p; + register char **cp; + + setprotoent(_proto_stayopen); + while (p = getprotoent()) { + if (strcmp(p->p_name, name) == 0) + break; + for (cp = p->p_aliases; *cp != 0; cp++) + if (strcmp(*cp, name) == 0) + goto found; + } +found: + if (!_proto_stayopen) + endprotoent(); + return (p); +} diff --git a/gen.subproj/getpwent.c b/gen.subproj/getpwent.c new file mode 100644 index 0000000..a9f4798 --- /dev/null +++ b/gen.subproj/getpwent.c @@ -0,0 +1,370 @@ +/* + * 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 1997 Apple Computer, Inc. (unpublished) + * + * /etc/passwd file access routines. + * Just read from the /etc/passwd file and skip the dbm database, since + * lookupd does all flat file lookups when the system is multi-user. + * These routines are only used in single-user mode. + * + * 17 Apr 1997 file created - Marc Majka + */ + +#include +#include +#include +#include + +#define forever for (;;) + +#define _PWENT_ 0 +#define _PWNAM_ 1 +#define _PWUID_ 2 + +static struct passwd _pw = { 0 }; +static FILE *_pfp; +static int _pwStayOpen; + +static void +free_pw() +{ + if (_pw.pw_name != NULL) free(_pw.pw_name); + if (_pw.pw_passwd != NULL) free(_pw.pw_passwd); + if (_pw.pw_class != NULL) free(_pw.pw_class); + if (_pw.pw_gecos != NULL) free(_pw.pw_gecos); + if (_pw.pw_dir != NULL) free(_pw.pw_dir); + if (_pw.pw_shell != NULL) free(_pw.pw_shell); + + _pw.pw_name = NULL; + _pw.pw_passwd = NULL; + _pw.pw_class = NULL; + _pw.pw_gecos = NULL; + _pw.pw_dir = NULL; + _pw.pw_shell = NULL; +} + +static void +freeList(char **l) +{ + int i; + + if (l == NULL) return; + for (i = 0; l[i] != NULL; i++) + { + if (l[i] != NULL) free(l[i]); + l[i] = NULL; + } + if (l != NULL) free(l); +} + +static unsigned int +listLength(char **l) +{ + int i; + + if (l == NULL) return 0; + for (i = 0; l[i] != NULL; i++); + return i; +} + +static char * +copyString(char *s) +{ + int len; + char *t; + + if (s == NULL) return NULL; + + len = strlen(s) + 1; + t = malloc(len); + bcopy(s, t, len); + return t; +} + + +static char ** +insertString(char *s, char **l, unsigned int x) +{ + int i, len; + + if (s == NULL) return l; + if (l == NULL) + { + l = (char **)malloc(2 * sizeof(char *)); + l[0] = copyString(s); + l[1] = NULL; + return l; + } + + for (i = 0; l[i] != NULL; i++); + len = i + 1; /* count the NULL on the end of the list too! */ + + l = (char **)realloc(l, (len + 1) * sizeof(char *)); + + if ((x >= (len - 1)) || (x == (unsigned int)-1)) + { + l[len - 1] = copyString(s); + l[len] = NULL; + return l; + } + + for (i = len; i > x; i--) l[i] = l[i - 1]; + l[x] = copyString(s); + return l; +} + +static char ** +appendString(char *s, char **l) +{ + return insertString(s, l, (unsigned int)-1); +} + + +static char ** +tokenize(const char *data, const char *sep) +{ + char **tokens = NULL; + const char *p; + int i, j, len; + char buf[4096]; + int scanning; + + if (data == NULL) return NULL; + if (sep == NULL) + { + tokens = appendString((char *)data, tokens); + return tokens; + } + + len = strlen(sep); + + p = data; + + while (p[0] != '\0') + { + /* skip leading white space */ + while ((p[0] == ' ') || (p[0] == '\t') || (p[0] == '\n')) p++; + + /* check for end of line */ + if (p[0] == '\0') break; + + /* copy data */ + i = 0; + scanning = 1; + for (j = 0; (j < len) && (scanning == 1); j++) + { + if (p[0] == sep[j] || (p[0] == '\0')) scanning = 0; + } + + while (scanning == 1) + { + buf[i++] = p[0]; + p++; + for (j = 0; (j < len) && (scanning == 1); j++) + { + if (p[0] == sep[j] || (p[0] == '\0')) scanning = 0; + } + } + + /* back over trailing whitespace */ + i--; + while ((buf[i] == ' ') || (buf[i] == '\t') || (buf[i] == '\n')) i--; + buf[++i] = '\0'; + + tokens = appendString(buf, tokens); + + /* check for end of line */ + if (p[0] == '\0') break; + + /* skip separator */ + scanning = 1; + for (j = 0; (j < len) && (scanning == 1); j++) + { + if (p[0] == sep[j]) + { + p++; + scanning = 0; + } + } + + if ((scanning == 0) && p[0] == '\0') + { + /* line ended at a separator - add a null member */ + tokens = appendString("", tokens); + return tokens; + } + } + return tokens; +} + +struct passwd * +parseUser(char *data) +{ + char **tokens; + + if (data == NULL) return NULL; + + tokens = tokenize(data, ":"); + if (listLength(tokens) != 10) + { + freeList(tokens); + return NULL; + } + + free_pw(); + + _pw.pw_name = tokens[0]; + _pw.pw_passwd = tokens[1]; + _pw.pw_uid = atoi(tokens[2]); + free(tokens[2]); + _pw.pw_gid = atoi(tokens[3]); + free(tokens[3]); + _pw.pw_class = tokens[4]; + _pw.pw_change = atoi(tokens[5]); + free(tokens[5]); + _pw.pw_expire = atoi(tokens[6]); + free(tokens[6]); + _pw.pw_gecos = tokens[7]; + _pw.pw_dir = tokens[8]; + _pw.pw_shell = tokens[9]; + + free(tokens); + + return &_pw; +} + +static char * +getLine(FILE *fp) +{ + char s[1024]; + char *out; + + s[0] = '\0'; + + fgets(s, 1024, fp); + if (s == NULL || s[0] == '\0') return NULL; + + if (s[0] != '#') s[strlen(s) - 1] = '\0'; + + out = copyString(s); + return out; +} + +int +setpassent(int stayopen) +{ + _pwStayOpen = stayopen; + return(1); +} + +int +setpwent() +{ + if (_pfp == NULL) + { + _pfp = fopen(_PATH_MASTERPASSWD, "r"); + if (_pfp == NULL) + { + perror(_PATH_MASTERPASSWD); + return(0); + } + } + else rewind(_pfp); + _pwStayOpen = 0; + return(1); +} + +void +endpwent() +{ + if (_pfp != NULL) + { + fclose(_pfp); + _pfp = NULL; + } +} + +static struct passwd * +getpw(const char *nam, uid_t uid, int which) +{ + char *line; + struct passwd *pw; + + if (which != 0) + { + if (setpwent() == 0) return NULL; + } + + forever + { + line = getLine(_pfp); + if (line == NULL) break; + + if (line[0] == '#') + { + free(line); + line = NULL; + continue; + } + + pw = parseUser(line); + free(line); + line = NULL; + + if ((pw == NULL) || (which == _PWENT_)) + { + if (_pwStayOpen == 0) endpwent(); + return pw; + } + + if (((which == _PWNAM_) && (!strcmp(nam, pw->pw_name))) || + ((which == _PWUID_) && (uid == pw->pw_uid))) + { + if (_pwStayOpen == 0) endpwent(); + return pw; + } + } + + if (_pwStayOpen == 0) endpwent(); + return NULL; +} + +struct passwd * +getpwent() +{ + return getpw(NULL, 0, _PWENT_); +} + +struct passwd * +getpwnam(const char *nam) +{ + return getpw(nam, 0, _PWNAM_); +} + +struct passwd * +getpwuid(uid_t uid) +{ + return getpw(NULL, uid, _PWUID_); +} diff --git a/gen.subproj/getservbyname.c b/gen.subproj/getservbyname.c new file mode 100644 index 0000000..45766e3 --- /dev/null +++ b/gen.subproj/getservbyname.c @@ -0,0 +1,88 @@ +/* + * 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) 1983, 1993 + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getservbyname.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +extern int _serv_stayopen; + +struct servent * +getservbyname(name, proto) + const char *name, *proto; +{ + register struct servent *p; + register char **cp; + + setservent(_serv_stayopen); + while (p = getservent()) { + if (strcmp(name, p->s_name) == 0) + goto gotname; + for (cp = p->s_aliases; *cp; cp++) + if (strcmp(name, *cp) == 0) + goto gotname; + continue; +gotname: + if (proto == 0 || strcmp(p->s_proto, proto) == 0) + break; + } + if (!_serv_stayopen) + endservent(); + return (p); +} diff --git a/gen.subproj/getservbyport.c b/gen.subproj/getservbyport.c new file mode 100644 index 0000000..af3eeb0 --- /dev/null +++ b/gen.subproj/getservbyport.c @@ -0,0 +1,83 @@ +/* + * 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) 1983, 1993 + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getservbyport.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include + +extern int _serv_stayopen; + +struct servent * +getservbyport(port, proto) + int port; + const char *proto; +{ + register struct servent *p; + + setservent(_serv_stayopen); + while (p = getservent()) { + if (p->s_port != port) + continue; + if (proto == 0 || strcmp(p->s_proto, proto) == 0) + break; + } + if (!_serv_stayopen) + endservent(); + return (p); +} diff --git a/gen.subproj/getservent.c b/gen.subproj/getservent.c new file mode 100644 index 0000000..16d5cd9 --- /dev/null +++ b/gen.subproj/getservent.c @@ -0,0 +1,144 @@ +/* + * 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) 1983, 1993 + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getservent.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include + +#define MAXALIASES 35 + +static FILE *servf = NULL; +static char line[BUFSIZ+1]; +static struct servent serv; +static char *serv_aliases[MAXALIASES]; +int _serv_stayopen; + +void +setservent(f) + int f; +{ + if (servf == NULL) + servf = fopen(_PATH_SERVICES, "r" ); + else + rewind(servf); + _serv_stayopen |= f; +} + +void +endservent() +{ + if (servf) { + fclose(servf); + servf = NULL; + } + _serv_stayopen = 0; +} + +struct servent * +getservent() +{ + char *p; + register char *cp, **q; + + if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL) + return (NULL); +again: + if ((p = fgets(line, BUFSIZ, servf)) == NULL) + return (NULL); + if (*p == '#') + goto again; + cp = strpbrk(p, "#\n"); + if (cp == NULL) + goto again; + *cp = '\0'; + serv.s_name = p; + p = strpbrk(p, " \t"); + if (p == NULL) + goto again; + *p++ = '\0'; + while (*p == ' ' || *p == '\t') + p++; + cp = strpbrk(p, ",/"); + if (cp == NULL) + goto again; + *cp++ = '\0'; + serv.s_port = htons((u_short)atoi(p)); + serv.s_proto = cp; + q = serv.s_aliases = serv_aliases; + cp = strpbrk(cp, " \t"); + if (cp != NULL) + *cp++ = '\0'; + while (cp && *cp) { + if (*cp == ' ' || *cp == '\t') { + cp++; + continue; + } + if (q < &serv_aliases[MAXALIASES - 1]) + *q++ = cp; + cp = strpbrk(cp, " \t"); + if (cp != NULL) + *cp++ = '\0'; + } + *q = NULL; + return (&serv); +} diff --git a/gen.subproj/initgroups.c b/gen.subproj/initgroups.c new file mode 100644 index 0000000..455c363 --- /dev/null +++ b/gen.subproj/initgroups.c @@ -0,0 +1,81 @@ +/* + * 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) 1983, 1993 + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)initgroups.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#include + +int +initgroups(uname, agroup) + const char *uname; + int agroup; +{ + int groups[NGROUPS], ngroups; + + ngroups = NGROUPS; + if (getgrouplist(uname, agroup, groups, &ngroups) < 0) + warnx("%s is in too many groups, using first %d", + uname, ngroups); + if (setgroups(ngroups, groups) < 0) { + warn("setgroups"); + return (-1); + } + return (0); +} diff --git a/gen.subproj/printerdb.c b/gen.subproj/printerdb.c new file mode 100644 index 0000000..2d77bdf --- /dev/null +++ b/gen.subproj/printerdb.c @@ -0,0 +1,286 @@ +/* + * 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@ + */ +/* + * /etc/printcap reader (in case NetInfo is not running) + * Copyright (C) 1989 by NeXT, Inc. + */ +#include +#include +#include + +#define strdup(x) strcpy(malloc(strlen(x) + 1), x) + +extern size_t strlen(const char *); +extern char *index(char *, char); +extern char *strcpy(char *, const char *); +extern int strcmp(const char *, const char*); +extern void *bcopy(void *, void *, unsigned); + +static FILE *pf; +static char *getline(FILE *); +static int emptyfield(char *); + +static void +_prdb_free_ent( + prdb_ent *ent + ) +{ + int i; + + for (i = 0; ent->pe_name[i]; i++) { + free(ent->pe_name[i]); + } + free(ent->pe_name); + ent->pe_name = NULL; + for (i = 0; i < ent->pe_nprops; i++) { + free(ent->pe_prop[i].pp_key); + free(ent->pe_prop[i].pp_value); + } + free(ent->pe_prop); + ent->pe_prop = NULL; +} + +void +_old_prdb_end( + void + ) +{ + if (pf != NULL) { + fclose(pf); + pf = NULL; + } +} + +void +_old_prdb_set( + void + ) +{ + if (pf == NULL) { + pf = fopen("/etc/printcap", "r"); + } +} + +static void +pename_insert( + char ***target, + char *name, + int which + ) +{ + if (which == 0) { + *target = malloc(sizeof(char *) * 2); + } else { + *target = realloc(*target, sizeof(char *) * (which + 2)); + } + (*target)[which] = strdup(name); + (*target)[which + 1] = NULL; +} + +static void +peprop_insert( + prdb_property **target, + prdb_property prop, + int which + ) +{ + if (which == 0) { + *target = malloc(sizeof(prop)); + } else { + *target = realloc(*target, (which + 1) * sizeof(prop)); + } + (*target)[which] = prop; +} + +prdb_ent * +_old_prdb_get( + void + ) +{ + char *line; + char *p; + char *end; + char *hash; + char *equal; + char *where; + static prdb_ent ent; + prdb_property prop; + int which; + + _old_prdb_set(); + if (pf == NULL) { + return (NULL); + } + do { + line = getline(pf); + if (line == NULL) { + return (NULL); + } + } while (*line == 0); + where = line; + end = index(where, ':'); + if (end != NULL) { + *end++ = 0; + } + which = 0; + if (ent.pe_name != NULL) { + _prdb_free_ent(&ent); + } + for (;;) { + p = index(where, '|'); + if (p != NULL && (end == NULL || p < end)) { + *p++ = 0; + pename_insert(&ent.pe_name, where, which++); + where = p; + } else { + pename_insert(&ent.pe_name, where, which); + break; + } + } + where = end; + which = 0; + for (;;) { + end = index(where, ':'); + if (end != NULL) { + *end++ = 0; + } + hash = index(where, '#'); + equal = index(where, '='); + if (hash != NULL && (end == NULL || hash < end)) { + *hash = 0; + prop.pp_key = strdup(where); + *hash = '#'; + prop.pp_value = strdup(hash); + peprop_insert(&ent.pe_prop, prop, which++); + } else if (equal != NULL && (end == NULL || + equal < end)) { + *equal++ = 0; + prop.pp_key = strdup(where); + prop.pp_value = strdup(equal); + peprop_insert(&ent.pe_prop, prop, which++); + } else if (!emptyfield(where)) { + prop.pp_key = strdup(where); + prop.pp_value = strdup(""); + peprop_insert(&ent.pe_prop, prop, which++); + } + where = end; + if (end == NULL) { + break; + } + } + free(line); + ent.pe_nprops = which; + return (&ent); +} + +static int +prmatch( + prdb_ent *ent, + char *name + ) +{ + int i; + + for (i = 0; ent->pe_name[i] != NULL; i++) { + if (strcmp(ent->pe_name[i], name) == 0) { + return (1); + } + } + return (0); +} + +prdb_ent * +_old_prdb_getbyname( + char *prname + ) +{ + prdb_ent *ent; + + _old_prdb_set(); + if (pf == NULL) { + return (NULL); + } + while (ent = _old_prdb_get()) { + if (prmatch(ent, prname)) { + break; + } + } + _old_prdb_end(); + return (ent); +} + + + +static char * +getline( + FILE *f + ) +{ + char line[BUFSIZ]; + char *res = NULL; + int more = 1; + int len; + int inclen; + + len = 0; + while (more && fgets(line, sizeof(line), f)) { + inclen = strlen(line); + if (line[inclen - 1] == '\n') { + line[inclen - 1] = 0; + inclen--; + } + if (*line == '#') { + continue; + } + if (res == NULL) { + res = malloc(inclen + 1); + } else { + res = realloc(res, len + inclen + 1); + } + if (line[inclen - 1] == '\\') { + line[inclen - 1] = 0; + inclen--; + } else { + more = 0; + } + bcopy(line, res + len, inclen); + len += inclen; + res[len] = 0; + } + return (res); +} + +static int +emptyfield( + char *line + ) +{ + while (*line) { + if (*line != ' ' && *line != '\t') { + return (0); + } + line++; + } + return (1); +} diff --git a/lookup.subproj/Makefile b/lookup.subproj/Makefile new file mode 100644 index 0000000..2122bc1 --- /dev/null +++ b/lookup.subproj/Makefile @@ -0,0 +1,54 @@ +# +# Generated by the NeXT Project Builder. +# +# NOTE: Do NOT change this file -- Project Builder maintains it. +# +# Put all of your customizations in files called Makefile.preamble +# and Makefile.postamble (both optional), and Makefile will include them. +# + +NAME = lookup + +PROJECTVERSION = 2.8 +PROJECT_TYPE = Component + +HFILES = aliasdb.h bootparams.h lookup_types.h lu_overrides.h\ + lu_utils.h netgr.h printerdb.h + +CFILES = lu_alias.c lu_bootp.c lu_bootparam.c lu_fstab.c lu_group.c\ + lu_host.c lu_netgroup.c lu_network.c lu_printer.c\ + lu_protocol.c lu_rpc.c lu_service.c lu_user.c lu_utils.c + +OTHERSRCS = Makefile.preamble Makefile Makefile.postamble lookup.defs\ + _lu_types.x + + +MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles +CODE_GEN_STYLE = DYNAMIC +MAKEFILE = subproj.make +NEXTSTEP_INSTALLDIR = /Local/Developer/System +LIBS = +DEBUG_LIBS = $(LIBS) +PROF_LIBS = $(LIBS) + + +PUBLIC_HEADERS = aliasdb.h bootparams.h printerdb.h + + + +NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc +WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc +PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc +NEXTSTEP_JAVA_COMPILER = /usr/bin/javac +WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe +PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac + +include $(MAKEFILEDIR)/platform.make + +-include Makefile.preamble + +include $(MAKEFILEDIR)/$(MAKEFILE) + +-include Makefile.postamble + +-include Makefile.dependencies diff --git a/lookup.subproj/Makefile.postamble b/lookup.subproj/Makefile.postamble new file mode 100644 index 0000000..cf76087 --- /dev/null +++ b/lookup.subproj/Makefile.postamble @@ -0,0 +1,8 @@ +%_xdr.c: %.x + $(RPCGEN) $(ALL_RPCFLAGS) -c -o $(SYM_DIR)/$*_xdr.c $*.x + +netinfo_hdrs: $(DSTROOT)$(PUBLIC_HDR_INSTALLDIR)$(NETINFO_HEADER_DIR_SUFFIX) + $(SILENT) $(FASTCP) $(NETINFO_HDRS) $(DSTROOT)$(PUBLIC_HDR_INSTALLDIR)$(NETINFO_HEADER_DIR_SUFFIX) + +$(DSTROOT)$(PUBLIC_HDR_INSTALLDIR)$(NETINFO_HEADER_DIR_SUFFIX): + $(MKDIRS) $@ diff --git a/lookup.subproj/Makefile.preamble b/lookup.subproj/Makefile.preamble new file mode 100644 index 0000000..9a094c2 --- /dev/null +++ b/lookup.subproj/Makefile.preamble @@ -0,0 +1,8 @@ +RPCFILES = _lu_types.x +OTHER_OFILES = lookupUser.o _lu_types_xdr.o +AFTER_PREBUILD = _lu_types.h lookupUser.c +NETINFO_HDRS = lookup.h _lu_types.h lookup_types.h lookup.defs _lu_types.x +BEFORE_INSTALLHDRS += $(SFILE_DIR) $(NETINFO_HDRS) +AFTER_INSTALLHDRS += netinfo_hdrs +PUBLIC_HEADER_DIR_SUFFIX = +NETINFO_HEADER_DIR_SUFFIX = /netinfo diff --git a/lookup.subproj/PB.project b/lookup.subproj/PB.project new file mode 100644 index 0000000..8270f85 --- /dev/null +++ b/lookup.subproj/PB.project @@ -0,0 +1,48 @@ +{ + DYNAMIC_CODE_GEN = YES; + FILESTABLE = { + H_FILES = ( + aliasdb.h, + bootparams.h, + lookup_types.h, + lu_overrides.h, + lu_utils.h, + netgr.h, + printerdb.h + ); + OTHER_LINKED = ( + lu_alias.c, + lu_bootp.c, + lu_bootparam.c, + lu_fstab.c, + lu_group.c, + lu_host.c, + lu_netgroup.c, + lu_network.c, + lu_printer.c, + lu_protocol.c, + lu_rpc.c, + lu_service.c, + lu_user.c + ); + OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, lookup.defs, _lu_types.x); + PRECOMPILED_HEADERS = (); + PROJECT_HEADERS = (); + PUBLIC_HEADERS = (aliasdb.h, bootparams.h, printerdb.h); + }; + LANGUAGE = English; + MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; + NEXTSTEP_BUILDTOOL = /bin/gnumake; + NEXTSTEP_INSTALLDIR = /Local/Developer/System; + NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; + NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; + PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; + PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; + PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; + PROJECTNAME = lookup; + PROJECTTYPE = Component; + PROJECTVERSION = 2.8; + WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; + WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; + WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; +} diff --git a/lookup.subproj/_lu_types.x b/lookup.subproj/_lu_types.x new file mode 100644 index 0000000..0fa320e --- /dev/null +++ b/lookup.subproj/_lu_types.x @@ -0,0 +1,247 @@ +/* + * 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@ + */ +/* + * Lookup server protocol - Internal to NeXT + * Copyright (C) 1989 by NeXT, Inc. + * + * This server uses a protocol based upon XDR layered on top of + * a mach rpc call. There are three procedures defined in the "lookup.defs" + * file. A "lookup_link" operation takes a procedure string name and returns a + * number to be used in the other two calls. "lookup_all" takes a procedure + * number and XDR'd arguments and returns XDR'd results. It returns the + * entire list of entries. "lookup_one" has a similar calling convention, + * but returns only a single entry. + * + * The syntax of calls described here in comments looks like this: + * + * result_type procedure_name(arg_type1 arg1, arg_type2 arg2, ...) + * + * The arguments are assumed to be XDR'd in sequence and a single XDR'd + * result is returned. + */ +const _LU_MAXLUSTRLEN = 256; + +const _LU_MAXGRP = 1024; +const _LU_MAXHNAMES = 32; +const _LU_MAXADDRS = 32; +const _LU_MAXNNAMES = 32; +const _LU_MAXPNAMES = 32; +const _LU_MAXSNAMES = 32; +const _LU_MAXRNAMES = 32; +const _LU_MAXPRNAMES = 32; +const _LU_MAXPRPROPS = 1024; +const _LU_MAX_BOOTPARAMS_KV = 32; +const _LU_MAXALIASMEMBERS = 4096; + + +typedef string _lu_string<_LU_MAXLUSTRLEN>; + + +/* + * Calls available: + * int putpwpasswd(_lu_string long, _lu_string old, _lu_string new) + * _lu_passwd * getpwuid(int uid) + * _lu_passwd * getpwnam(_lu_string name) + * _lu_passwd<> getpwent(void) + */ +struct _lu_passwd { + _lu_string pw_name; + _lu_string pw_passwd; + int pw_uid; + int pw_gid; + int pw_change; + _lu_string pw_class; + _lu_string pw_gecos; + _lu_string pw_dir; + _lu_string pw_shell; + int pw_expire; +}; +typedef _lu_passwd *_lu_passwd_ptr; + + +/* + * Calls available: + * _lu_group * getgrgid(int gid) + * _lu_group * getgrnam(_lu_string name) + * _lu_group<> getgrent(void) + */ +struct _lu_group { + _lu_string gr_name; + _lu_string gr_passwd; + int gr_gid; + _lu_string gr_mem<_LU_MAXGRP>; +}; +typedef _lu_group *_lu_group_ptr; + +/* + * Calls available: + * _lu_hostent * gethostbyaddr(unsigned long addr) -- IP only + * _lu_hostent * gethostbyname(_lu_string name) + * _lu_hostent<> gethostent(void) + */ +struct _lu_hostent { + _lu_string h_names<_LU_MAXHNAMES>; + unsigned long h_addrs<_LU_MAXADDRS>; /* IP only */ +}; +typedef _lu_hostent *_lu_hostent_ptr; + +/* + * Calls available: + * _lu_netent * getnetbyaddr(unsigned long addr) --IP only + * _lu_netent * getnetbyname(_lu_string name) + * _lu_netent<> getnetent(void) + */ +struct _lu_netent { + _lu_string n_names<_LU_MAXNNAMES>; + unsigned long n_net; /* IP only */ +}; +typedef _lu_netent *_lu_netent_ptr; + + +/* + * Calls available: + * _lu_servent * getservbyport(int port, _lu_string proto) + * _lu_servent * getservbyname(_lu_string name, _lu_string proto) + * _lu_servent<> getservent(void) + */ +struct _lu_servent { + _lu_string s_names<_LU_MAXSNAMES>; + int s_port; + _lu_string s_proto; +}; +typedef _lu_servent *_lu_servent_ptr; + +/* + * Calls available: + * _lu_protoent * getprotobynumber(int number) + * _lu_protoent * getprotobyname(_lu_string name) + * _lu_protoent<> getprotoent(void) + */ +struct _lu_protoent { + _lu_string p_names<_LU_MAXPNAMES>; + int p_proto; +}; +typedef _lu_protoent *_lu_protoent_ptr; + + +/* + * Calls available: + * _lu_rpcent * getrpcbynumber(int number) + * _lu_rpcent * getrpcbyname(_lu_string name) + * _lu_rpcent<> getrpcent(void) + */ +struct _lu_rpcent { + _lu_string r_names<_LU_MAXRNAMES>; + int r_number; +}; +typedef _lu_rpcent *_lu_rpcent_ptr; + +/* + * Calls available: + * _lu_fsent<> getfsent(void) + * _lu_fsent * getfsbyname(_lu_string name) + */ +struct _lu_fsent { + _lu_string fs_spec; + _lu_string fs_file; + _lu_string fs_vfstype; + _lu_string fs_mntops; + _lu_string fs_type; + int fs_freq; + int fs_passno; +}; +typedef _lu_fsent *_lu_fsent_ptr; + +/* + * Calls available: + * _lu_prdb_ent * prdb_getbyname + * _lu_prdb_ent<> prdb_get(void) + */ +struct _lu_prdb_property { + _lu_string pp_key; + _lu_string pp_value; +}; + +struct _lu_prdb_ent { + _lu_string pe_names<_LU_MAXPRNAMES>; + _lu_prdb_property pe_props<_LU_MAXPRPROPS>; +}; +typedef _lu_prdb_ent *_lu_prdb_ent_ptr; + + +/* + * Calls available: + * _lu_bootp_ent * bootp_getbyip(unsigned long addr) + * _lu_bootp_ent * bootp_getbyether(opaque bootp_enaddr[6]) + */ +struct _lu_bootp_ent { + _lu_string bootp_name; + _lu_string bootp_bootfile; + unsigned long bootp_ipaddr; + opaque bootp_enaddr[6]; +}; +typedef _lu_bootp_ent *_lu_bootp_ent_ptr; + +/* + * Calls available: + * _lu_bootparams_ent * bootparams_getbyname(_lu_string name) + * _lu_bootparams_ent<> bootparams_getent(void) + */ +struct _lu_bootparams_ent { + _lu_string bootparams_name; + _lu_string bootparams_keyvalues<_LU_MAX_BOOTPARAMS_KV>; +}; +typedef _lu_bootparams_ent *_lu_bootparams_ent_ptr; + + +/* + * Calls available: + * _lu_aliasent * alias_getbyname(_lu_string name) + * _lu_aliasent<> alias_getent(void) + */ +struct _lu_aliasent { + _lu_string alias_name; + _lu_string alias_members<_LU_MAXALIASMEMBERS>; + int alias_local; +}; +typedef _lu_aliasent *_lu_aliasent_ptr; + +/* + * Calls available: + * int innetgr(_lu_innetgr_args args) + * _lu_netgrent<> getnetgrent(_lu_string group) + */ +struct _lu_innetgr_args { + _lu_string group; + _lu_string *host; + _lu_string *user; + _lu_string *domain; +}; + +struct _lu_netgrent{ + _lu_string ng_host; + _lu_string ng_user; + _lu_string ng_domain; +}; + diff --git a/lookup.subproj/aliasdb.h b/lookup.subproj/aliasdb.h new file mode 100644 index 0000000..7961135 --- /dev/null +++ b/lookup.subproj/aliasdb.h @@ -0,0 +1,48 @@ +/* + * 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@ + */ +/* + * Mail alias lookup routines + * Copyright (c) 1989 by NeXT, Inc. + */ + +#ifndef _ALIAS_H_ +#define _ALIAS_H_ + +struct aliasent { + char *alias_name; + unsigned alias_members_len; + char **alias_members; + int alias_local; +}; + +#include + +__BEGIN_DECLS +void alias_setent __P((void)); +struct aliasent *alias_getent __P((void)); +void alias_endent __P((void)); +struct aliasent *alias_getbyname __P((const char *)); +__END_DECLS + +#endif /* !_ALIAS_H_ */ diff --git a/lookup.subproj/bootparams.h b/lookup.subproj/bootparams.h new file mode 100644 index 0000000..377298d --- /dev/null +++ b/lookup.subproj/bootparams.h @@ -0,0 +1,52 @@ +/* + * 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@ + */ +/* + * Bootparams lookup routines + * + * Copyright 1997 + * Apple Computer Inc. + */ + +#ifndef _BOOTPARAMS_H_ +#define _BOOTPARAMS_H_ + +#include +#include + +/* + * Structures returned by bootparams calls. + */ +struct bootparamsent { + char *bp_name; /* name of host */ + char **bp_bootparams; /* bootparams list */ +}; + +__BEGIN_DECLS +void bootparams_endent __P((void)); +struct bootparamsent *bootparams_getbyname __P((const char *)); +struct bootparamsent *bootparams_getent __P((void)); +void bootparams_setent __P((void)); +__END_DECLS + +#endif /* !_BOOTPARAMS_H_ */ diff --git a/lookup.subproj/lookup.defs b/lookup.subproj/lookup.defs new file mode 100644 index 0000000..167d609 --- /dev/null +++ b/lookup.subproj/lookup.defs @@ -0,0 +1,71 @@ +/* + * 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@ + */ +/* + * Lookup protocol specification - internal to NeXT + * Copyright (C) 1989 by NeXT, Inc. + * + * History: + * 25-Jun-1998 Umesh Vaishampayan (umeshv@apple.com) + * Ported to MacOSX. + */ + +subsystem lookup 4241775; +serverprefix _; + +import ; + + +type int = MACH_MSG_TYPE_INTEGER_32; +type mach_port_t = MACH_MSG_TYPE_COPY_SEND; +type lookup_name = array [256] of MACH_MSG_TYPE_CHAR; +type unit = array [4] of MACH_MSG_TYPE_CHAR; + +/* + * Can't reduce the size of the following without blowing binary compatibility + * with libc (but not libsys, since it is always shared). + */ +type inline_data = array [ * : 4096 ] of unit; +type ooline_data = ^ array [] of unit; + + +routine _lookup_link( server : mach_port_t; + name : lookup_name; + out procno: int); + +routine _lookup_all( server : mach_port_t; + proc : int; + indata : inline_data; + out outdata : ooline_data); + +routine _lookup_one( server : mach_port_t; + proc : int; + indata : inline_data; + out outdata : inline_data); + + +routine _lookup_ooall( server : mach_port_t; + proc : int; + indata : ooline_data; + out outdata : ooline_data); + diff --git a/lookup.subproj/lookup_types.h b/lookup.subproj/lookup_types.h new file mode 100644 index 0000000..7d8fcd2 --- /dev/null +++ b/lookup.subproj/lookup_types.h @@ -0,0 +1,47 @@ +/* + * 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@ + */ +/* + * Lookup protocol definitions - internal to NeXT + * Copyright (C) 1989 by NeXT, Inc. + */ + +/* + * the port to lookupd is obtained through the (internal) + * _lookupd_port() syscall instead of through the nameserver + * with LOOKUP_SERVER_NAME as "C Library Lookup" + */ + +#define UNIT_SIZE 4 + +typedef struct unit { + char data[UNIT_SIZE]; +} unit; + +#define MAX_INLINE_UNITS 4095 +#define MAX_LOOKUP_NAMELEN 256 +#define MAX_INLINE_DATA (MAX_INLINE_UNITS * sizeof(unit)) + +typedef char lookup_name[MAX_LOOKUP_NAMELEN]; +typedef unit inline_data[MAX_INLINE_UNITS]; +typedef char *ooline_data; diff --git a/lookup.subproj/lu_alias.c b/lookup.subproj/lu_alias.c new file mode 100644 index 0000000..f215067 --- /dev/null +++ b/lookup.subproj/lu_alias.c @@ -0,0 +1,249 @@ +/* + * 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@ + */ +/* + * Alias lookup + * Copyright (C) 1989 by NeXT, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "lookup.h" +#include "_lu_types.h" +#include "lu_utils.h" +#include "lu_overrides.h" + +static lookup_state alias_state = LOOKUP_CACHE; +static struct aliasent global_aliasent; +static int global_free = 1; +static char *alias_data = NULL; +static unsigned alias_datalen; +static int alias_nentries = 0; +static int alias_start = 1; +static XDR alias_xdr; + +static void +freeold(void) +{ + int i, len; + + if (global_free == 1) return; + + free(global_aliasent.alias_name); + + len = global_aliasent.alias_members_len; + for (i = 0; i < len; i++) + free(global_aliasent.alias_members[i]); + + free(global_aliasent.alias_members); + + global_free = 1; +} + +static void +convert_aliasent(_lu_aliasent *lu_aliasent) +{ + int i, len; + + freeold(); + + global_aliasent.alias_name = strdup(lu_aliasent->alias_name); + + len = lu_aliasent->alias_members.alias_members_len; + global_aliasent.alias_members_len = len; + global_aliasent.alias_members = (char **)malloc(len * sizeof(char *)); + + for (i = 0; i < len; i++) + { + global_aliasent.alias_members[i] = + strdup(lu_aliasent->alias_members.alias_members_val[i]); + } + + global_aliasent.alias_local = lu_aliasent->alias_local; + + global_free = 0; +} + +static struct aliasent * +lu_alias_getbyname(const char *name) +{ + unsigned datalen; + char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT]; + unit lookup_buf[MAX_INLINE_UNITS]; + XDR outxdr; + XDR inxdr; + _lu_aliasent_ptr lu_aliasent; + static int proc = -1; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "alias_getbyname", &proc) != KERN_SUCCESS) + { + return (NULL); + } + } + + xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE); + if (!xdr__lu_string(&outxdr, &name)) + { + xdr_destroy(&outxdr); + return (NULL); + } + + datalen = MAX_INLINE_UNITS; + if (_lookup_one(_lu_port, proc, (unit *)namebuf, + xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, lookup_buf, &datalen) + != KERN_SUCCESS) + { + xdr_destroy(&outxdr); + return (NULL); + } + + xdr_destroy(&outxdr); + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&inxdr, lookup_buf, datalen, + XDR_DECODE); + lu_aliasent = NULL; + if (!xdr__lu_aliasent_ptr(&inxdr, &lu_aliasent) || (lu_aliasent == NULL)) + { + xdr_destroy(&inxdr); + return (NULL); + } + + xdr_destroy(&inxdr); + + convert_aliasent(lu_aliasent); + xdr_free(xdr__lu_aliasent_ptr, &lu_aliasent); + return (&global_aliasent); +} + +static void +lu_alias_endent(void) +{ + alias_nentries = 0; + if (alias_data != NULL) + { + freeold(); + vm_deallocate(mach_task_self(), (vm_address_t)alias_data, alias_datalen); + alias_data = NULL; + } +} + +static void +lu_alias_setent(void) +{ + lu_alias_endent(); + alias_start = 1; +} + +static struct aliasent * +lu_alias_getent(void) +{ + static int proc = -1; + _lu_aliasent lu_aliasent; + + if (alias_start == 1) + { + alias_start = 0; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "alias_getent", &proc) != KERN_SUCCESS) + { + lu_alias_endent(); + return (NULL); + } + } + + if (_lookup_all(_lu_port, proc, NULL, 0, &alias_data, &alias_datalen) + != KERN_SUCCESS) + { + lu_alias_endent(); + return (NULL); + } + +#ifdef NOTDEF +/* NOTDEF because OOL buffers are counted in bytes with untyped IPC */ + alias_datalen *= BYTES_PER_XDR_UNIT; +#endif + xdrmem_create(&alias_xdr, alias_data, + alias_datalen, XDR_DECODE); + if (!xdr_int(&alias_xdr, &alias_nentries)) + { + xdr_destroy(&alias_xdr); + lu_alias_endent(); + return (NULL); + } + } + + if (alias_nentries == 0) + { + xdr_destroy(&alias_xdr); + lu_alias_endent(); + return (NULL); + } + + bzero(&lu_aliasent, sizeof(lu_aliasent)); + if (!xdr__lu_aliasent(&alias_xdr, &lu_aliasent)) + { + xdr_destroy(&alias_xdr); + lu_alias_endent(); + return (NULL); + } + + alias_nentries--; + convert_aliasent(&lu_aliasent); + xdr_free(xdr__lu_aliasent, &lu_aliasent); + return (&global_aliasent); +} + +struct aliasent * +alias_getbyname(const char *name) +{ + LOOKUP1(lu_alias_getbyname, _old_alias_getbyname, name, struct aliasent); +} + +struct aliasent * +alias_getent(void) +{ + GETENT(lu_alias_getent, _old_alias_getent, &alias_state, struct aliasent); +} + +void +alias_setent(void) +{ + SETSTATEVOID(lu_alias_setent, _old_alias_setent, &alias_state); +} + +void +alias_endent(void) +{ + UNSETSTATE(lu_alias_endent, _old_alias_endent, &alias_state); +} diff --git a/lookup.subproj/lu_bootp.c b/lookup.subproj/lu_bootp.c new file mode 100644 index 0000000..ca85dbe --- /dev/null +++ b/lookup.subproj/lu_bootp.c @@ -0,0 +1,145 @@ +/* + * 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@ + */ +/* + * Bootp lookup - netinfo only + * Copyright (C) 1989 by NeXT, Inc. + */ +#include +#include +#include +#include "lookup.h" +#include +#include +#include "_lu_types.h" +#include "lu_utils.h" +#include +#include +#include +#include +#include + +static int +lu_bootp_getbyether(struct ether_addr *enaddr, char **name, + struct in_addr *ipaddr, char **bootfile) +{ + unsigned datalen; + XDR xdr; + static _lu_bootp_ent_ptr bp; + static int proc = -1; + unit lookup_buf[MAX_INLINE_UNITS]; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "bootp_getbyether", &proc) != KERN_SUCCESS) + { + return (0); + } + } + + datalen = MAX_INLINE_UNITS; + if (_lookup_one(_lu_port, proc, (unit *)enaddr, + ((sizeof(*enaddr) + sizeof(unit) - 1) / sizeof(unit)), lookup_buf, + &datalen) != KERN_SUCCESS) + { + return (0); + } + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&xdr, lookup_buf, datalen, XDR_DECODE); + xdr_free(xdr__lu_bootp_ent_ptr, &bp); + if (!xdr__lu_bootp_ent_ptr(&xdr, &bp) || (bp == NULL)) + { + xdr_destroy(&xdr); + return (0); + } + + xdr_destroy(&xdr); + + *name = bp->bootp_name; + *bootfile = bp->bootp_bootfile; + ipaddr->s_addr = bp->bootp_ipaddr; + return (1); +} + +static int +lu_bootp_getbyip(struct ether_addr *enaddr, char **name, + struct in_addr *ipaddr, char **bootfile) +{ + unsigned datalen; + XDR xdr; + static _lu_bootp_ent_ptr bp; + static int proc = -1; + unit lookup_buf[MAX_INLINE_UNITS]; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "bootp_getbyip", &proc) != KERN_SUCCESS) + { + return (0); + } + } + + datalen = MAX_INLINE_UNITS; + if (_lookup_one(_lu_port, proc, (unit *)ipaddr, + ((sizeof(*ipaddr) + sizeof(unit) - 1) / sizeof(unit)), lookup_buf, + &datalen) != KERN_SUCCESS) + { + return (0); + } + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&xdr, lookup_buf, datalen, XDR_DECODE); + xdr_free(xdr__lu_bootp_ent_ptr, &bp); + if (!xdr__lu_bootp_ent_ptr(&xdr, &bp) || (bp == NULL)) + { + xdr_destroy(&xdr); + return (0); + } + + xdr_destroy(&xdr); + + *name = bp->bootp_name; + *bootfile = bp->bootp_bootfile; + bcopy(bp->bootp_enaddr, enaddr, sizeof(*enaddr)); + return (1); +} + +int +bootp_getbyether(struct ether_addr *enaddr, char **name, + struct in_addr *ipaddr, char **bootfile) +{ + if (_lu_running()) + return (lu_bootp_getbyether(enaddr, name, ipaddr, bootfile)); + return (0); +} + +int +bootp_getbyip(struct ether_addr *enaddr, char **name, + struct in_addr *ipaddr, char **bootfile) +{ + if (_lu_running()) + return (lu_bootp_getbyip(enaddr, name, ipaddr, bootfile)); + return (0); +} + diff --git a/lookup.subproj/lu_bootparam.c b/lookup.subproj/lu_bootparam.c new file mode 100644 index 0000000..9386e98 --- /dev/null +++ b/lookup.subproj/lu_bootparam.c @@ -0,0 +1,246 @@ +/* + * 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@ + */ +/* + * Bootparams lookup - netinfo only + * Copyright (C) 1989 by NeXT, Inc. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "lookup.h" +#include "_lu_types.h" +#include "lu_utils.h" + +static lookup_state bp_state = LOOKUP_CACHE; +static struct bootparamsent global_bp; +static int global_free = 1; +static char *bp_data = NULL; +static unsigned bp_datalen; +static int bp_nentries; +static int bp_start = 1; +static XDR bp_xdr; + +static void +freeold(void) +{ + int i; + if (global_free == 1) return; + + free(global_bp.bp_name); + + for (i = 0; global_bp.bp_bootparams[i] != NULL; i++) + free(global_bp.bp_bootparams[i]); + + global_free = 1; +} + +static void +convert_bootparamsent(_lu_bootparams_ent *lu_bpent) +{ + int i, len; + + freeold(); + + global_bp.bp_name = strdup(lu_bpent->bootparams_name); + + len = lu_bpent->bootparams_keyvalues.bootparams_keyvalues_len; + global_bp.bp_bootparams = (char **)malloc((len + 1) * sizeof(char *)); + + for (i = 0; i < len; i++) + { + global_bp.bp_bootparams[i] = + strdup(lu_bpent->bootparams_keyvalues.bootparams_keyvalues_val[i]); + } + + global_bp.bp_bootparams[len] = NULL; + + global_free = 0; +} + +static struct bootparamsent * +lu_bootparams_getbyname(const char *name) +{ + unsigned datalen; + char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT]; + unit lookup_buf[MAX_INLINE_UNITS]; + XDR outxdr; + XDR inxdr; + int size; + _lu_bootparams_ent_ptr lu_bpent; + static int proc = -1; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "bootparams_getbyname", &proc) + != KERN_SUCCESS) + { + return (NULL); + } + } + + xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE); + if (!xdr__lu_string(&outxdr, &name)) + { + xdr_destroy(&outxdr); + return (NULL); + } + + size = xdr_getpos(&outxdr); + xdr_destroy(&outxdr); + + datalen = MAX_INLINE_UNITS; + if (_lookup_one(_lu_port, proc, (unit *)namebuf, size, lookup_buf, + &datalen) != KERN_SUCCESS) + { + return (NULL); + } + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&inxdr, lookup_buf, datalen, + XDR_DECODE); + lu_bpent = NULL; + if (!xdr__lu_bootparams_ent_ptr(&inxdr, &lu_bpent) || (lu_bpent == NULL)) + { + xdr_destroy(&inxdr); + return (NULL); + } + + xdr_destroy(&inxdr); + + convert_bootparamsent(lu_bpent); + xdr_free(xdr__lu_bootparams_ent_ptr, &lu_bpent); + return (&global_bp); +} + +static void +lu_bootparams_endent(void) +{ + bp_nentries = 0; + if (bp_data != NULL) + { + freeold(); + vm_deallocate(mach_task_self(), (vm_address_t)bp_data, bp_datalen); + bp_data = NULL; + } +} + +static void +lu_bootparams_setent(void) +{ + lu_bootparams_endent(); + bp_start = 1; +} + +static struct bootparamsent * +lu_bootparams_getent(void) +{ + static int proc = -1; + _lu_bootparams_ent lu_bpent; + + if (bp_start == 1) + { + bp_start = 0; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "bootparams_getent", &proc) + != KERN_SUCCESS) + { + lu_bootparams_endent(); + return (NULL); + } + } + + if (_lookup_all(_lu_port, proc, NULL, 0, &bp_data, &bp_datalen) + != KERN_SUCCESS) + { + lu_bootparams_endent(); + return (NULL); + } + +#ifdef NOTDEF +/* NOTDEF because OOL buffers are counted in bytes with untyped IPC */ + bp_datalen *= BYTES_PER_XDR_UNIT; +#endif + xdrmem_create(&bp_xdr, bp_data, bp_datalen, + XDR_DECODE); + if (!xdr_int(&bp_xdr, &bp_nentries)) + { + xdr_destroy(&bp_xdr); + lu_bootparams_endent(); + return (NULL); + } + } + + if (bp_nentries == 0) + { + xdr_destroy(&bp_xdr); + lu_bootparams_endent(); + return (NULL); + } + + bzero(&lu_bpent, sizeof(lu_bpent)); + if (!xdr__lu_bootparams_ent(&bp_xdr, &lu_bpent)) + { + xdr_destroy(&bp_xdr); + lu_bootparams_endent(); + return (NULL); + } + + bp_nentries--; + convert_bootparamsent(&lu_bpent); + xdr_free(xdr__lu_bootparams_ent, &lu_bpent); + return (&global_bp); +} + +struct bootparamsent * +bootparams_getbyname(const char *name) +{ + if (_lu_running()) return (lu_bootparams_getbyname(name)); + return (NULL); +} + +struct bootparamsent * +bootparams_getent(void) +{ + if (_lu_running()) return (lu_bootparams_getent()); + return (NULL); +} + +void +bootparams_setent(void) +{ + if (_lu_running()) lu_bootparams_setent(); +} + +void +bootparams_endent(void) +{ + if (_lu_running()) lu_bootparams_endent(); +} diff --git a/lookup.subproj/lu_fstab.c b/lookup.subproj/lu_fstab.c new file mode 100644 index 0000000..b206a8a --- /dev/null +++ b/lookup.subproj/lu_fstab.c @@ -0,0 +1,296 @@ +/* + * 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@ + */ +/* + * fstab entry lookup + * Copyright (C) 1989 by NeXT, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "lookup.h" +#include "_lu_types.h" +#include "lu_utils.h" +#include "lu_overrides.h" + +static struct fstab global_fs; +static int global_free = 1; +static char *fs_data = NULL; +static unsigned fs_datalen = 0; +static int fs_nentries = 0; +static int fs_start = 1; +static XDR fs_xdr = { 0 }; + +static void +freeold(void) +{ + if (global_free == 1) return; + + free(global_fs.fs_spec); + free(global_fs.fs_file); + free(global_fs.fs_type); + free(global_fs.fs_vfstype); + free(global_fs.fs_mntops); + + global_free = 1; +} + +static void +convert_fs(_lu_fsent *lu_fs) +{ + freeold(); + + global_fs.fs_spec = strdup(lu_fs->fs_spec); + global_fs.fs_file = strdup(lu_fs->fs_file); + + /* + * Special case - if vfstype is unknown and spec is + * of the form foo:bar, then assume nfs. + */ + if (lu_fs->fs_vfstype[0] == '\0') + { + if (strchr(lu_fs->fs_spec, ':') != NULL) + { + global_fs.fs_vfstype = malloc(4); + strcpy(global_fs.fs_vfstype, "nfs"); + } + else global_fs.fs_vfstype = strdup(lu_fs->fs_vfstype); + } + else + { + global_fs.fs_vfstype = strdup(lu_fs->fs_vfstype); + } + + global_fs.fs_mntops = strdup(lu_fs->fs_mntops); + global_fs.fs_type = strdup(lu_fs->fs_type); + global_fs.fs_freq = lu_fs->fs_freq; + global_fs.fs_passno = lu_fs->fs_passno; + + global_free = 0; +} + +static struct fstab * +lu_getfsbyname(const char *name) +{ + unsigned datalen; + char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT]; + XDR outxdr; + XDR inxdr; + _lu_fsent_ptr lu_fs; + static int proc = -1; + unit lookup_buf[MAX_INLINE_UNITS]; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "getfsbyname", &proc) != KERN_SUCCESS) + { + return (NULL); + } + } + + xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE); + if (!xdr__lu_string(&outxdr, &name)) + { + xdr_destroy(&outxdr); + return (NULL); + } + + datalen = MAX_INLINE_UNITS; + if (_lookup_one(_lu_port, proc, (unit *)namebuf, + xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, lookup_buf, &datalen) + != KERN_SUCCESS) + { + xdr_destroy(&outxdr); + return (NULL); + } + + xdr_destroy(&outxdr); + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&inxdr, lookup_buf, datalen, + XDR_DECODE); + lu_fs = NULL; + if (!xdr__lu_fsent_ptr(&inxdr, &lu_fs) || (lu_fs == NULL)) + { + xdr_destroy(&inxdr); + return (NULL); + } + + xdr_destroy(&inxdr); + + convert_fs(lu_fs); + xdr_free(xdr__lu_fsent_ptr, &lu_fs); + return (&global_fs); +} + +static void +lu_endfsent(void) +{ + fs_nentries = 0; + if (fs_data != NULL) + { + freeold(); + vm_deallocate(mach_task_self(), (vm_address_t)fs_data, fs_datalen); + fs_data = NULL; + } +} + +static int +lu_setfsent(void) +{ + lu_endfsent(); + fs_start = 1; + return (1); +} + +static struct fstab * +lu_getfsent() +{ + static int proc = -1; + _lu_fsent lu_fs; + + if (fs_start == 1) + { + fs_start = 0; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "getfsent", &proc) != + KERN_SUCCESS) + { + lu_endfsent(); + return (NULL); + } + } + + if (_lookup_all(_lu_port, proc, NULL, 0, &fs_data, &fs_datalen) + != KERN_SUCCESS) + { + lu_endfsent(); + return (NULL); + } + +#ifdef NOTDEF +/* NOTDEF because OOL buffers are counted in bytes with untyped IPC */ + fs_datalen *= BYTES_PER_XDR_UNIT; +#endif + xdrmem_create(&fs_xdr, fs_data, + fs_datalen, XDR_DECODE); + if (!xdr_int(&fs_xdr, &fs_nentries)) + { + xdr_destroy(&fs_xdr); + lu_endfsent(); + return (NULL); + } + } + + if (fs_nentries == 0) + { + xdr_destroy(&fs_xdr); + lu_endfsent(); + return (NULL); + } + + bzero(&lu_fs, sizeof(lu_fs)); + if (!xdr__lu_fsent(&fs_xdr, &lu_fs)) + { + xdr_destroy(&fs_xdr); + lu_endfsent(); + return (NULL); + } + + fs_nentries--; + convert_fs(&lu_fs); + xdr_free(xdr__lu_fsent, &lu_fs); + return (&global_fs); +} + +struct fstab * +lu_getfsspec(const char *name) +{ + if (name == NULL) return (struct fstab *)NULL; + return lu_getfsbyname(name); +} + +struct fstab * +lu_getfsfile(const char *name) +{ + struct fstab *fs; + + if (name == NULL) return (struct fstab *)NULL; + + setfsent(); + for (fs = lu_getfsent(); fs != NULL; fs = lu_getfsent()) + if (!strcmp(fs->fs_file, name)) return fs; + + endfsent(); + return (struct fstab *)NULL; +} + +struct fstab * +getfsbyname(const char *name) +{ + if (_lu_running()) return (lu_getfsbyname(name)); + return (NULL); +} + +struct fstab * +getfsent(void) +{ + if (_lu_running()) return (lu_getfsent()); + return (_old_getfsent()); +} + +int +setfsent(void) +{ + if (_lu_running()) return (lu_setfsent()); + return (_old_setfsent()); +} + +void +endfsent(void) +{ + if (_lu_running()) lu_endfsent(); + else _old_endfsent(); +} + +struct fstab * +getfsspec(const char *name) +{ + if (_lu_running()) return (lu_getfsspec(name)); + return (_old_getfsspec(name)); +} + +struct fstab * +getfsfile(const char *name) +{ + if (_lu_running()) return (lu_getfsfile(name)); + return (_old_getfsfile(name)); +} diff --git a/lookup.subproj/lu_group.c b/lookup.subproj/lu_group.c new file mode 100644 index 0000000..5022f9c --- /dev/null +++ b/lookup.subproj/lu_group.c @@ -0,0 +1,396 @@ +/* + * 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@ + */ +/* + * Unix group lookup + * Copyright (C) 1989 by NeXT, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "_lu_types.h" +#include "lookup.h" +#include "lu_utils.h" +#include "lu_overrides.h" + +#define GROUP_SENTINEL -99 + +static lookup_state gr_state = LOOKUP_CACHE; +static struct group global_gr; +static int global_free = 1; +static char *gr_data; +static unsigned gr_datalen = 0; +static int gr_nentries = 0; +static int gr_start = 1; +static XDR gr_xdr; + +static void +freeold(void) +{ + char **mem; + + if (global_free == 1) return; + + free(global_gr.gr_name); + global_gr.gr_name = NULL; + + free(global_gr.gr_passwd); + global_gr.gr_passwd = NULL; + + mem = global_gr.gr_mem; + if (mem != NULL) + { + while (*mem != NULL) free(*mem++); + free(global_gr.gr_mem); + global_gr.gr_mem = NULL; + } + + global_free = 1; +} + +static void +convert_gr(_lu_group *lu_gr) +{ + int i, len; + + freeold(); + + global_gr.gr_name = strdup(lu_gr->gr_name); + global_gr.gr_passwd = strdup(lu_gr->gr_passwd); + global_gr.gr_gid = lu_gr->gr_gid; + + len = lu_gr->gr_mem.gr_mem_len; + global_gr.gr_mem = (char **)malloc((len + 1) * sizeof(char *)); + + for (i = 0; i < len; i++) + { + global_gr.gr_mem[i] = strdup(lu_gr->gr_mem.gr_mem_val[i]); + } + + global_gr.gr_mem[len] = NULL; + + global_free = 0; +} + +static struct group * +lu_getgrgid(int gid) +{ + unsigned datalen; + _lu_group_ptr lu_gr; + XDR xdr; + static int proc = -1; + unit lookup_buf[MAX_INLINE_UNITS]; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "getgrgid", &proc) != KERN_SUCCESS) + { + return (NULL); + } + } + + gid = htonl(gid); + datalen = MAX_INLINE_UNITS; + + if (_lookup_one(_lu_port, proc, (unit *)&gid, 1, lookup_buf, &datalen) + != KERN_SUCCESS) + { + return (NULL); + } + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&xdr, lookup_buf, datalen, XDR_DECODE); + lu_gr = NULL; + + if (!xdr__lu_group_ptr(&xdr, &lu_gr) || lu_gr == NULL) + { + xdr_destroy(&xdr); + return (NULL); + } + + xdr_destroy(&xdr); + + convert_gr(lu_gr); + xdr_free(xdr__lu_group_ptr, &lu_gr); + return (&global_gr); +} + +static struct group * +lu_getgrnam(const char *name) +{ + unsigned datalen; + char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT]; + XDR outxdr; + XDR inxdr; + _lu_group_ptr lu_gr; + static int proc = -1; + unit lookup_buf[MAX_INLINE_UNITS]; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "getgrnam", &proc) != KERN_SUCCESS) + { + return (NULL); + } + } + + xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE); + + if (!xdr__lu_string(&outxdr, &name)) + { + xdr_destroy(&outxdr); + return (NULL); + } + + datalen = MAX_INLINE_UNITS; + + if (_lookup_one(_lu_port, proc, (unit *)namebuf, + xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, lookup_buf, &datalen) + != KERN_SUCCESS) + { + return (NULL); + } + + xdr_destroy(&outxdr); + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&inxdr, lookup_buf, datalen, + XDR_DECODE); + lu_gr = NULL; + + if (!xdr__lu_group_ptr(&inxdr, &lu_gr) || (lu_gr == NULL)) + { + xdr_destroy(&inxdr); + return (NULL); + } + + xdr_destroy(&inxdr); + + convert_gr(lu_gr); + xdr_free(xdr__lu_group_ptr, &lu_gr); + return (&global_gr); +} + + +static int +lu_initgroups(const char *name, int basegid) +{ + unsigned datalen; + XDR outxdr; + XDR inxdr; + static int proc = -1; + unit lookup_buf[MAX_INLINE_UNITS]; + char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT]; + int groups[NGROUPS]; + int ngroups = 1; + int a_group; + int count; + + groups[0] = basegid; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "initgroups", &proc) != KERN_SUCCESS) + { + return -1; + } + } + + xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE); + if (!xdr__lu_string(&outxdr, &name)) + { + xdr_destroy(&outxdr); + return -1; + } + + datalen = MAX_INLINE_UNITS; + if (_lookup_one(_lu_port, proc, (unit *)namebuf, + xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, lookup_buf, &datalen) + != KERN_SUCCESS) + { + xdr_destroy(&outxdr); + return -1; + } + + xdr_destroy(&outxdr); + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&inxdr, lookup_buf, datalen, + XDR_DECODE); + + while (xdr_int(&inxdr, &a_group)) + { + if (a_group == GROUP_SENTINEL) break; + + for (count = 0; count < ngroups; count++) + { + if (groups[count] == a_group) break; + } + + if (count >= ngroups) groups[ngroups++] = a_group; + } + xdr_destroy(&inxdr); + + return setgroups(ngroups, groups); +} + +static void +lu_endgrent(void) +{ + gr_nentries = 0; + if (gr_data != NULL) + { + freeold(); + vm_deallocate(mach_task_self(), (vm_address_t)gr_data, gr_datalen); + gr_data = NULL; + } +} + +static int +lu_setgrent(void) +{ + lu_endgrent(); + gr_start = 1; + return (1); +} + +static struct group * +lu_getgrent() +{ + static int proc = -1; + _lu_group lu_gr; + + if (gr_start == 1) + { + gr_start = 0; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "getgrent", &proc) != KERN_SUCCESS) + { + lu_endgrent(); + return (NULL); + } + } + + if (_lookup_all(_lu_port, proc, NULL, 0, &gr_data, &gr_datalen) + != KERN_SUCCESS) + { + lu_endgrent(); + return (NULL); + } + +#ifdef NOTDEF +/* NOTDEF because OOL buffers are counted in bytes with untyped IPC */ + gr_datalen *= BYTES_PER_XDR_UNIT; +#endif + xdrmem_create(&gr_xdr, gr_data, gr_datalen, + XDR_DECODE); + if (!xdr_int(&gr_xdr, &gr_nentries)) + { + xdr_destroy(&gr_xdr); + lu_endgrent(); + return (NULL); + } + } + + if (gr_nentries == 0) + { + xdr_destroy(&gr_xdr); + lu_endgrent(); + return (NULL); + } + + bzero(&lu_gr, sizeof(lu_gr)); + if (!xdr__lu_group(&gr_xdr, &lu_gr)) + { + xdr_destroy(&gr_xdr); + lu_endgrent(); + return (NULL); + } + + gr_nentries--; + convert_gr(&lu_gr); + xdr_free(xdr__lu_group, &lu_gr); + return (&global_gr); +} + +struct group * +getgrgid(gid_t gid) +{ + LOOKUP1(lu_getgrgid, _old_getgrgid, gid, struct group); +} + +struct group * +getgrnam(const char *name) +{ + LOOKUP1(lu_getgrnam, _old_getgrnam, name, struct group); +} + +int +initgroups(const char *name, int basegid) +{ + int res; + + if (_lu_running()) + { + if ((res = lu_initgroups(name, basegid))) + { + res = _old_initgroups(name, basegid); + } + } + else + { + res = _old_initgroups(name, basegid); + } + + return (res); +} + +struct group * +getgrent(void) +{ + GETENT(lu_getgrent, _old_getgrent, &gr_state, struct group); +} + +int +setgrent(void) +{ + INTSETSTATEVOID(lu_setgrent, _old_setgrent, &gr_state); +} + +void +endgrent(void) +{ + UNSETSTATE(lu_endgrent, _old_endgrent, &gr_state); +} diff --git a/lookup.subproj/lu_host.c b/lookup.subproj/lu_host.c new file mode 100644 index 0000000..ca56659 --- /dev/null +++ b/lookup.subproj/lu_host.c @@ -0,0 +1,378 @@ +/* + * 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@ + */ +/* + * host lookup + * Copyright (C) 1989 by NeXT, Inc. + */ +#include +#include +#include +#include +#include "lookup.h" +#include +#include +#include "_lu_types.h" +#include +#include "lu_utils.h" +#include +#import + +extern struct hostent *_res_gethostbyaddr(); +extern struct hostent *_res_gethostbyname(); +extern struct hostent *_old_gethostbyaddr(); +extern struct hostent *_old_gethostbyname(); +extern struct hostent *_old_gethostent(); +extern void _old_sethostent(); +extern void _old_endhostent(); +extern void _old_sethostfile(); + +extern int h_errno; + +static lookup_state h_state = LOOKUP_CACHE; +/* + * The static return value from get*ent functions + */ +static struct hostent global_h; +static int global_free = 1; +static char *h_data = NULL; +static unsigned h_datalen; +static int h_nentries; +static int h_start = 1; +static XDR h_xdr; + +static void +freeold(void) +{ + char **aliases; + int i; + + if (global_free == 1) return; + + free(global_h.h_name); + aliases = global_h.h_aliases; + if (aliases != NULL) + { + while (*aliases != NULL) free(*aliases++); + free(global_h.h_aliases); + } + + for (i = 0; global_h.h_addr_list[i] != NULL; i++) + free(global_h.h_addr_list[i]); + + free(global_h.h_addr_list); + + global_free = 1; +} + +static void +convert_h(_lu_hostent *lu_h) +{ + int i, len, addr_len; + + freeold(); + + global_h.h_name = strdup(lu_h->h_names.h_names_val[0]); + + len = lu_h->h_names.h_names_len - 1; + global_h.h_aliases = (char **)malloc((len + 1) * sizeof(char *)); + + for (i = 0; i < len; i++) + { + global_h.h_aliases[i] = strdup(lu_h->h_names.h_names_val[i + 1]); + } + + global_h.h_aliases[len] = NULL; + + global_h.h_addrtype = AF_INET; + global_h.h_length = sizeof(long); + + len = lu_h->h_addrs.h_addrs_len; + addr_len = sizeof(u_long *); + + global_h.h_addr_list = (char **)malloc((len + 1) * addr_len); + + for (i = 0; i < len; i++) + { + global_h.h_addr_list[i] = (char *)malloc(sizeof(long)); + bcopy((const void *)&(lu_h->h_addrs.h_addrs_val[i]), + (void *)global_h.h_addr_list[i], sizeof(long)); + } + + global_h.h_addr_list[len] = NULL; + + global_free = 0; +} + +static struct hostent * +lu_gethostbyaddr(const char *addr, int len, int type) +{ + unsigned datalen; + _lu_hostent_ptr lu_h; + XDR xdr; + long address; + static int proc = -1; + unit lookup_buf[MAX_INLINE_UNITS]; + + if (len != sizeof(long) || (type != AF_INET)) + { + h_errno = HOST_NOT_FOUND; + return (NULL); + } + + if (proc < 0) + { + if (_lookup_link(_lu_port, "gethostbyaddr", &proc) != KERN_SUCCESS) + { + h_errno = HOST_NOT_FOUND; + return (NULL); + } + } + + bcopy(addr, &address, sizeof(address)); + address = htonl(address); + datalen = MAX_INLINE_UNITS; + if (_lookup_one(_lu_port, proc, (unit *)&address, 1, lookup_buf, &datalen) + != KERN_SUCCESS) + { + h_errno = HOST_NOT_FOUND; + return (NULL); + } + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&xdr, lookup_buf, datalen, XDR_DECODE); + lu_h = NULL; + h_errno = HOST_NOT_FOUND; + if (!xdr__lu_hostent_ptr(&xdr, &lu_h) || + !xdr_int(&xdr, &h_errno) || (lu_h == NULL)) + { + xdr_destroy(&xdr); + return (NULL); + } + + xdr_destroy(&xdr); + + convert_h(lu_h); + xdr_free(xdr__lu_hostent_ptr, &lu_h); + return (&global_h); +} + +static struct hostent * +lu_gethostbyname(const char *name) +{ + unsigned datalen; + char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT]; + XDR outxdr; + XDR inxdr; + _lu_hostent_ptr lu_h; + static int proc = -1; + unit lookup_buf[MAX_INLINE_UNITS]; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "gethostbyname", &proc) != KERN_SUCCESS) + { + h_errno = HOST_NOT_FOUND; + return (NULL); + } + } + + xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE); + if (!xdr__lu_string(&outxdr, &name)) + { + xdr_destroy(&outxdr); + h_errno = HOST_NOT_FOUND; + return (NULL); + } + + datalen = MAX_INLINE_UNITS; + if (_lookup_one(_lu_port, proc, (unit *)namebuf, + xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, lookup_buf, &datalen) + != KERN_SUCCESS) + { + xdr_destroy(&outxdr); + h_errno = HOST_NOT_FOUND; + return (NULL); + } + + xdr_destroy(&outxdr); + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&inxdr, lookup_buf, datalen, + XDR_DECODE); + lu_h = NULL; + h_errno = HOST_NOT_FOUND; + if (!xdr__lu_hostent_ptr(&inxdr, &lu_h) || + !xdr_int(&inxdr, &h_errno) || (lu_h == NULL)) + { + xdr_destroy(&inxdr); + return (NULL); + } + + xdr_destroy(&inxdr); + + convert_h(lu_h); + xdr_free(xdr__lu_hostent_ptr, &lu_h); + return (&global_h); +} + +static void +lu_endhostent() +{ + h_nentries = 0; + if (h_data != NULL) + { + freeold(); + vm_deallocate(mach_task_self(), (vm_address_t)h_data, h_datalen); + h_data = NULL; + } +} + +static void +lu_sethostent() +{ + lu_endhostent(); + h_start = 1; +} + +static struct hostent * +lu_gethostent() +{ + static int proc = -1; + _lu_hostent lu_h; + + if (h_start == 1) + { + h_start = 0; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "gethostent", &proc) != KERN_SUCCESS) + { + lu_endhostent(); + return (NULL); + } + } + + if (_lookup_all(_lu_port, proc, NULL, 0, &h_data, &h_datalen) + != KERN_SUCCESS) + { + lu_endhostent(); + return (NULL); + } + +#ifdef NOTDEF +/* NOTDEF because OOL buffers are counted in bytes with untyped IPC */ + h_datalen *= BYTES_PER_XDR_UNIT; +#endif + xdrmem_create(&h_xdr, h_data, h_datalen, + XDR_DECODE); + if (!xdr_int(&h_xdr, &h_nentries)) + { + xdr_destroy(&h_xdr); + lu_endhostent(); + return (NULL); + } + } + + if (h_nentries == 0) + { + xdr_destroy(&h_xdr); + lu_endhostent(); + return (NULL); + } + + bzero(&lu_h, sizeof(lu_h)); + if (!xdr__lu_hostent(&h_xdr, &lu_h)) + { + xdr_destroy(&h_xdr); + lu_endhostent(); + return (NULL); + } + + h_nentries--; + convert_h(&lu_h); + xdr_free(xdr__lu_hostent, &lu_h); + return (&global_h); +} + +struct hostent * +gethostbyaddr(const char *addr, int len, int type) +{ + struct hostent *res; + + if (_lu_running()) + { + res = lu_gethostbyaddr(addr, len, type); + } + else + { + res = _res_gethostbyaddr(addr, len, type); + if (res == NULL) res = _old_gethostbyaddr(addr, len, type); + } + + return (res); +} + +struct hostent * +gethostbyname(const char *name) +{ + struct hostent *res; + struct in_addr addr; + + if (_lu_running()) + { + res = lu_gethostbyname(name); + } + else + { + res = _res_gethostbyname(name); + if (res == NULL) res = _old_gethostbyname(name); + } + + if (res == NULL) + { + if (inet_aton(name, &addr) == 0) return NULL; + return gethostbyaddr((char *)&addr, sizeof(addr), AF_INET); + } + + return res; +} + +struct hostent * +gethostent(void) +{ + GETENT(lu_gethostent, _old_gethostent, &h_state, struct hostent); +} + +void +sethostent(int stayopen) +{ + SETSTATE(lu_sethostent, _old_sethostent, &h_state, stayopen); +} + +void +endhostent(void) +{ + UNSETSTATE(lu_endhostent, _old_endhostent, &h_state); +} diff --git a/lookup.subproj/lu_netgroup.c b/lookup.subproj/lu_netgroup.c new file mode 100644 index 0000000..8e52272 --- /dev/null +++ b/lookup.subproj/lu_netgroup.c @@ -0,0 +1,257 @@ +/* + * 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@ + */ +/* + * Netgroup lookup + * Copyright (C) 1989 by NeXT, Inc. + */ +#include +#include +#include +#include +#include +#include +#include + +#include "_lu_types.h" +#include "lookup.h" +#include "lu_utils.h" +#include "lu_overrides.h" + +#define FIX(x) ((x == NULL) ? NULL : &(x)) + +static struct netgrent global_netgr; +static int global_free = 1; +static char *netgr_data = NULL; +static unsigned netgr_datalen; +static int netgr_nentries = 0; +static int netgr_start = 1; +static XDR netgr_xdr; + +static void +freeold(void) +{ + if (global_free == 1) return; + + free(global_netgr.ng_host); + free(global_netgr.ng_user); + free(global_netgr.ng_domain); + + global_free = 1; +} + +static void +convert_netgr(_lu_netgrent *lu_netgr) +{ + freeold(); + + global_netgr.ng_host = strdup(lu_netgr->ng_host); + global_netgr.ng_user = strdup(lu_netgr->ng_user); + global_netgr.ng_domain = strdup(lu_netgr->ng_domain); + + global_free = 0; +} + + +static int +lu_innetgr(const char *group, const char *host, const char *user, + const char *domain) +{ + unsigned datalen; + XDR xdr; + char namebuf[4*_LU_MAXLUSTRLEN + 3*BYTES_PER_XDR_UNIT]; + static int proc = -1; + int size; + int res; + _lu_innetgr_args args; + unit lookup_buf[MAX_INLINE_UNITS]; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "innetgr", &proc) != KERN_SUCCESS) + { + return (0); + } + } + + args.group = (char *)group; + args.host = FIX(host); + args.user = FIX(user); + args.domain = FIX(domain); + + xdrmem_create(&xdr, namebuf, sizeof(namebuf), XDR_ENCODE); + if (!xdr__lu_innetgr_args(&xdr, &args)) + { + xdr_destroy(&xdr); + return (0); + } + + size = xdr_getpos(&xdr) / BYTES_PER_XDR_UNIT; + xdr_destroy(&xdr); + + datalen = MAX_INLINE_UNITS; + if (_lookup_one(_lu_port, proc, (unit *)namebuf, size, lookup_buf, + &datalen) != KERN_SUCCESS) + { + return (0); + } + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&xdr, lookup_buf, datalen, XDR_DECODE); + if (!xdr_int(&xdr, &res)) + { + xdr_destroy(&xdr); + return (0); + } + + xdr_destroy(&xdr); + return (res); +} + +static void +lu_endnetgrent(void) +{ + netgr_nentries = 0; + if (netgr_data != NULL) + { + freeold(); + vm_deallocate(mach_task_self(), (vm_address_t)netgr_data, netgr_datalen); + netgr_data = NULL; + } +} + +/* + * This is different than the other setXXXent routines + * since this is really more like getnetgrbyname() than + * getnetgrent(). + */ +static void +lu_setnetgrent(const char *group) +{ + unsigned datalen; + char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT]; + XDR outxdr; + static int proc = -1; + + lu_endnetgrent(); + + if (proc < 0) + { + if (_lookup_link(_lu_port, "getnetgrent", &proc) != KERN_SUCCESS) + { + lu_endnetgrent(); + return; + } + } + + xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE); + if (!xdr__lu_string(&outxdr, &group)) + { + xdr_destroy(&outxdr); + lu_endnetgrent(); + return; + } + + datalen = MAX_INLINE_UNITS; + if (_lookup_all(_lu_port, proc, (unit *)namebuf, + xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, + &netgr_data, &netgr_datalen) != KERN_SUCCESS) + { + xdr_destroy(&outxdr); + lu_endnetgrent(); + return; + } + + xdr_destroy(&outxdr); + +#ifdef NOTDEF +/* NOTDEF because OOL buffers are counted in bytes with untyped IPC */ + netgr_datalen *= BYTES_PER_XDR_UNIT; +#endif + + xdrmem_create(&netgr_xdr, netgr_data, + netgr_datalen, XDR_DECODE); + if (!xdr_int(&netgr_xdr, &netgr_nentries)) + { + xdr_destroy(&netgr_xdr); + lu_endnetgrent(); + } +} + + +struct netgrent * +lu_getnetgrent(void) +{ + _lu_netgrent lu_netgr; + + if (netgr_nentries == 0) + { + xdr_destroy(&netgr_xdr); + lu_endnetgrent(); + return (NULL); + } + + bzero(&lu_netgr, sizeof(lu_netgr)); + if (!xdr__lu_netgrent(&netgr_xdr, &lu_netgr)) + { + xdr_destroy(&netgr_xdr); + lu_endnetgrent(); + return (NULL); + } + + netgr_nentries--; + convert_netgr(&lu_netgr); + xdr_free(xdr__lu_netgrent, &lu_netgr); + return (&global_netgr); +} + +int +innetgr(const char *group, const char *host, const char *user, + const char *domain) +{ + if (_lu_running()) return (lu_innetgr(group, host, user, domain)); +// return (_old_innetgr(group, host, user, domain)); + return (0); +} + +struct netgrent * +getnetgrent(void) +{ + if (_lu_running()) return (lu_getnetgrent()); +// return (_old_getnetgrent()); + return (NULL); +} + +void +setnetgrent(const char *group) +{ + if (_lu_running()) lu_setnetgrent(group); +// else _old_setnetgrent(group); +} + +void +endnetgrent(void) +{ + if (_lu_running()) lu_endnetgrent(); +// else _old_endnetgrent(); +} diff --git a/lookup.subproj/lu_network.c b/lookup.subproj/lu_network.c new file mode 100644 index 0000000..78533f9 --- /dev/null +++ b/lookup.subproj/lu_network.c @@ -0,0 +1,334 @@ +/* + * 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@ + */ +/* + * network lookup + * Copyright (C) 1989 by NeXT, Inc. + */ +#include +#include +#include +#include +#include "lookup.h" +#include +#include +#include "_lu_types.h" +#include +#include "lu_utils.h" +#include +#import + +extern struct netent *_res_getnetbyaddr(); +extern struct netent *_res_getnetbyname(); +extern struct netent *_old_getnetbyaddr(); +extern struct netent *_old_getnetbyname(); +extern struct netent *_old_getnetent(); +extern void _old_setnetent(); +extern void _old_endnetent(); + +static lookup_state n_state = LOOKUP_CACHE; +static struct netent global_n; +static int global_free = 1; +static char *n_data = NULL; +static unsigned n_datalen; +static int n_nentries; +static int n_start = 1; +static XDR n_xdr; + +static void +freeold(void) +{ + char **aliases; + + if (global_free == 1) return; + + free(global_n.n_name); + + aliases = global_n.n_aliases; + if (aliases != NULL) + { + while (*aliases != NULL) free(*aliases++); + free(global_n.n_aliases); + } + + global_free = 1; +} + +static void +convert_n(_lu_netent *lu_n) +{ + int i, len; + + freeold(); + + global_n.n_name = strdup(lu_n->n_names.n_names_val[0]); + + len = lu_n->n_names.n_names_len - 1; + global_n.n_aliases = malloc((len + 1) * sizeof(char *)); + + for (i = 0; i < len; i++) + { + global_n.n_aliases[i] = strdup(lu_n->n_names.n_names_val[i + 1]); + } + + global_n.n_aliases[len] = NULL; + + global_n.n_addrtype = AF_INET; + global_n.n_net = lu_n->n_net; + + global_free = 0; +} + +static struct netent * +lu_getnetbyaddr(long addr, int type) +{ + unsigned datalen; + _lu_netent_ptr lu_n; + XDR xdr; + static int proc = -1; + unit lookup_buf[MAX_INLINE_UNITS]; + + if (type != AF_INET) + { + return (NULL); + } + + if (proc < 0) + { + if (_lookup_link(_lu_port, "getnetbyaddr", &proc) != KERN_SUCCESS) + { + return (NULL); + } + } + + addr = htonl(addr); + datalen = MAX_INLINE_UNITS; + if (_lookup_one(_lu_port, proc, (unit *)&addr, 1, lookup_buf, &datalen) + != KERN_SUCCESS) + { + return (NULL); + } + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&xdr, lookup_buf, datalen, XDR_DECODE); + lu_n = NULL; + if (!xdr__lu_netent_ptr(&xdr, &lu_n) || (lu_n == NULL)) + { + xdr_destroy(&xdr); + return (NULL); + } + + xdr_destroy(&xdr); + + convert_n(lu_n); + xdr_free(xdr__lu_netent_ptr, &lu_n); + return (&global_n); +} + +static struct netent * +lu_getnetbyname(const char *name) +{ + unsigned datalen; + char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT]; + XDR outxdr; + XDR inxdr; + _lu_netent_ptr lu_n; + static int proc = -1; + unit lookup_buf[MAX_INLINE_UNITS]; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "getnetbyname", &proc) != KERN_SUCCESS) + { + return (NULL); + } + } + + xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE); + if (!xdr__lu_string(&outxdr, &name)) + { + xdr_destroy(&outxdr); + return (NULL); + } + + datalen = MAX_INLINE_UNITS; + if (_lookup_one(_lu_port, proc, (unit *)namebuf, + xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, lookup_buf, &datalen) + != KERN_SUCCESS) + { + xdr_destroy(&outxdr); + return (NULL); + } + + xdr_destroy(&outxdr); + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&inxdr, lookup_buf, datalen, + XDR_DECODE); + lu_n = NULL; + if (!xdr__lu_netent_ptr(&inxdr, &lu_n) || (lu_n == NULL)) + { + xdr_destroy(&inxdr); + return (NULL); + } + + xdr_destroy(&inxdr); + + convert_n(lu_n); + xdr_free(xdr__lu_netent_ptr, &lu_n); + return (&global_n); +} + +static void +lu_endnetent() +{ + n_nentries = 0; + if (n_data != NULL) + { + freeold(); + vm_deallocate(mach_task_self(), (vm_address_t)n_data, n_datalen); + n_data = NULL; + } +} + +static void +lu_setnetent() +{ + lu_endnetent(); + n_start = 1; +} + +static struct netent * +lu_getnetent() +{ + static int proc = -1; + _lu_netent lu_n; + + if (n_start == 1) + { + n_start = 0; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "getnetent", &proc) != KERN_SUCCESS) + { + lu_endnetent(); + return (NULL); + } + } + + if (_lookup_all(_lu_port, proc, NULL, 0, &n_data, &n_datalen) + != KERN_SUCCESS) + { + lu_endnetent(); + return (NULL); + } + +#ifdef NOTDEF +/* NOTDEF because OOL buffers are counted in bytes with untyped IPC */ + n_datalen *= BYTES_PER_XDR_UNIT; +#endif + xdrmem_create(&n_xdr, n_data, n_datalen, + XDR_DECODE); + if (!xdr_int(&n_xdr, &n_nentries)) + { + xdr_destroy(&n_xdr); + lu_endnetent(); + return (NULL); + } + } + + if (n_nentries == 0) + { + xdr_destroy(&n_xdr); + lu_endnetent(); + return (NULL); + } + + bzero(&lu_n, sizeof(lu_n)); + if (!xdr__lu_netent(&n_xdr, &lu_n)) + { + xdr_destroy(&n_xdr); + lu_endnetent(); + return (NULL); + } + + n_nentries--; + convert_n(&lu_n); + xdr_free(xdr__lu_netent, &lu_n); + return (&global_n); +} + +struct netent * +getnetbyaddr(long addr, int type) +{ + struct netent *res; + + if (_lu_running()) + { + res = lu_getnetbyaddr(addr, type); + } + else + { + res = _res_getnetbyaddr(addr, type); + if (res == NULL) res = _old_getnetbyaddr(addr, type); + } + + return res; +} + +struct netent * +getnetbyname(const char *name) +{ + struct netent *res; + + if (_lu_running()) + { + res = lu_getnetbyname(name); + } + else + { + res = _res_getnetbyname(name); + if (res == NULL) res = _old_getnetbyname(name); + } + + return res; +} + +struct netent * +getnetent(void) +{ + GETENT(lu_getnetent, _old_getnetent, &n_state, struct netent); +} + +void +setnetent(int stayopen) +{ + SETSTATE(lu_setnetent, _old_setnetent, &n_state, stayopen); +} + +void +endnetent(void) +{ + UNSETSTATE(lu_endnetent, _old_endnetent, &n_state); +} diff --git a/lookup.subproj/lu_overrides.h b/lookup.subproj/lu_overrides.h new file mode 100644 index 0000000..c7134b2 --- /dev/null +++ b/lookup.subproj/lu_overrides.h @@ -0,0 +1,106 @@ +/* + * 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@ + */ +/* + * These are routines typically defined in libc + * that are replaced by NetInfo. + * + * Copyright (c) 1995, NeXT Computer Inc. + */ + +#ifndef _LU_OVERRIDES_H_ +#define _LU_OVERRIDES_H_ + +#include +#include + +__BEGIN_DECLS +struct passwd *_old_getpwnam __P((const char *)); +struct passwd *_old_getpwuid __P((uid_t)); +struct passwd *_old_getpwent __P((void)); +int _old_setpwent __P((void)); +void _old_endpwent __P((void)); +int _old_putpwpasswd(); /*XXX*/ + +struct group *_old_getgrnam __P((const char *)); +struct group *_old_getgrgid __P((gid_t)); +int _old_setgrent __P((void)); +struct group *_old_getgrent __P((void)); +void _old_endgrent __P((void)); + +struct hostent *_old_gethostbyname __P((const char *)); +struct hostent *_old_gethostbyaddr __P((const char *, int, int)); +void _old_sethostent __P((int)); +struct hostent *_old_gethostent __P((void)); +void _old_endhostent __P((void)); +void _old_sethostfile __P((const char *)); + +struct netent *_old_getnetbyname(); +struct netent *_old_getnetbyaddr(); +void _old_setnetent(); +struct netent *_old_getnetent(); +void _old_endnetent(); + +struct servent *_old_getservbyname __P((const char *, const char *)); +struct servent *_old_getservbyport __P((int, const char *)); +void _old_setservent __P((int)); +struct servent *_old_getservent __P((void)); +void _old_endservent __P((void)); + +struct protoent *_old_getprotobyname __P((const char *)); +struct protoent *_old_getprotobynumber __P((int)); +void _old_setprotoent __P((int)); +struct protoent *_old_getprotoent __P((void)); +void _old_endprotoent __P((void));; + +struct rpcent *_old_getrpcbyname(); +struct rpcent *_old_getrpcbynumber(); +void _old_setrpcent(); +struct rpcent *_old_getrpcent(); +void _old_endrpcent(); + +struct fstab *_old_getfsent __P((void)); +struct fstab *_old_getfsspec __P((const char *)); +struct fstab *_old_getfsfile __P((const char *)); +int _old_setfsent __P((void)); +void _old_endfsent __P((void)); + +struct prdb_ent *_old_prdb_getbyname __P((const char *)); +void _old_prdb_set __P((void)); +struct prdb_ent *_old_prdb_get __P((void)); +void _old_prdb_end __P((void)); + +struct aliasent *_old_alias_getbyname __P((const char *)); +void _old_alias_setent __P((void)); +struct aliasent *_old_alias_getent __P((void)); +void _old_alias_endent __P((void)); + +int _old_innetgr __P((const char *,const char *,const char *,const char *)); +void _old_setnetgrent __P((const char *)); +struct netgrent *_old_getnetgrent __P((void)); +void _old_endnetgrent __P((void)); + +int _old_initgroups(); +__END_DECLS + +#endif /* !_LU_OVERRIDES_H_ */ diff --git a/lookup.subproj/lu_printer.c b/lookup.subproj/lu_printer.c new file mode 100644 index 0000000..0290e10 --- /dev/null +++ b/lookup.subproj/lu_printer.c @@ -0,0 +1,268 @@ +/* + * 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@ + */ +/* + * Printer lookup + * Copyright (C) 1989 by NeXT, Inc. + */ +#include +#include +#include +#include +#include "lookup.h" +#include +#include +#include "_lu_types.h" +#include "printerdb.h" +#include "lu_utils.h" + +extern struct prdb_ent *_old_prdb_get(); +extern struct prdb_ent *_old_prdb_getbyname(); +extern void _old_prdb_set(); +extern void _old_prdb_end(); + +static lookup_state prdb_state = LOOKUP_CACHE; +static struct prdb_ent global_prdb; +static int global_free = 1; +static char *prdb_data = NULL; +static unsigned prdb_datalen = 0; +static int prdb_nentries; +static int prdb_start = 1; +static XDR prdb_xdr = { 0 }; + +static void +freeold(void) +{ + char **names; + int i; + + if (global_free == 1) return; + + names = global_prdb.pe_name; + if (names != NULL) + { + while (*names) free(*names++); + free(global_prdb.pe_name); + } + + for (i = 0; i < global_prdb.pe_nprops; i++) + { + free(global_prdb.pe_prop[i].pp_key); + free(global_prdb.pe_prop[i].pp_value); + } + + free(global_prdb.pe_prop); + + global_free = 1; +} + + +static void +convert_prdb(_lu_prdb_ent *lu_prdb) +{ + int i, len; + + freeold(); + + len = lu_prdb->pe_names.pe_names_len; + global_prdb.pe_name = (char **)malloc((len + 1) * sizeof(char *)); + for (i = 0; i < len; i++) + { + global_prdb.pe_name[i] = strdup(lu_prdb->pe_names.pe_names_val[i]); + } + + global_prdb.pe_name[len] = NULL; + + len = lu_prdb->pe_props.pe_props_len; + global_prdb.pe_prop = (prdb_property *)malloc(len * sizeof(prdb_property)); + for (i = 0; i < len; i++) + { + global_prdb.pe_prop[i].pp_key = + strdup(lu_prdb->pe_props.pe_props_val[i].pp_key); + + global_prdb.pe_prop[i].pp_value = + strdup(lu_prdb->pe_props.pe_props_val[i].pp_value); + } + + global_prdb.pe_nprops = lu_prdb->pe_props.pe_props_len; + + global_free = 0; +} + +static void +lu_prdb_end() +{ + prdb_nentries = 0; + if (prdb_data != NULL) + { + freeold(); + vm_deallocate(mach_task_self(), (vm_address_t)prdb_data, prdb_datalen); + prdb_data = NULL; + } +} + +static void +lu_prdb_set() +{ + lu_prdb_end(); + prdb_start = 1; +} + +static struct prdb_ent * +lu_prdb_getbyname(const char *name) +{ + unsigned datalen; + char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT]; + XDR outxdr; + XDR inxdr; + _lu_prdb_ent_ptr lu_prdb; + static int proc = -1; + unit lookup_buf[MAX_INLINE_UNITS]; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "prdb_getbyname", &proc) != KERN_SUCCESS) + { + return (NULL); + } + } + + xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE); + if (!xdr__lu_string(&outxdr, &name)) + { + xdr_destroy(&outxdr); + return (NULL); + } + + datalen = MAX_INLINE_UNITS; + if (_lookup_one(_lu_port, proc, (unit *)namebuf, + xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, lookup_buf, &datalen) + != KERN_SUCCESS) + { + xdr_destroy(&outxdr); + return (NULL); + } + + xdr_destroy(&outxdr); + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&inxdr, lookup_buf, datalen, + XDR_DECODE); + lu_prdb = NULL; + if (!xdr__lu_prdb_ent_ptr(&inxdr, &lu_prdb) || (lu_prdb == NULL)) + { + xdr_destroy(&inxdr); + return (NULL); + } + + xdr_destroy(&inxdr); + + convert_prdb(lu_prdb); + xdr_free(xdr__lu_prdb_ent_ptr, &lu_prdb); + return (&global_prdb); +} + +static prdb_ent * +lu_prdb_get() +{ + static int proc = -1; + _lu_prdb_ent lu_prdb; + + if (prdb_start == 1) + { + prdb_start = 0; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "prdb_get", &proc) != KERN_SUCCESS) + { + lu_prdb_end(); + return (NULL); + } + } + if (_lookup_all(_lu_port, proc, NULL, 0, &prdb_data, &prdb_datalen) + != KERN_SUCCESS) + { + lu_prdb_end(); + return (NULL); + } + +#ifdef NOTDEF +/* NOTDEF because OOL buffers are counted in bytes with untyped IPC */ + prdb_datalen *= BYTES_PER_XDR_UNIT; +#endif + + xdrmem_create(&prdb_xdr, prdb_data, prdb_datalen, + XDR_DECODE); + if (!xdr_int(&prdb_xdr, &prdb_nentries)) + { + xdr_destroy(&prdb_xdr); + lu_prdb_end(); + return (NULL); + } + } + + if (prdb_nentries == 0) + { + xdr_destroy(&prdb_xdr); + lu_prdb_end(); + return (NULL); + } + + bzero(&lu_prdb, sizeof(lu_prdb)); + if (!xdr__lu_prdb_ent(&prdb_xdr, &lu_prdb)) + { + xdr_destroy(&prdb_xdr); + lu_prdb_end(); + return (NULL); + } + + prdb_nentries--; + convert_prdb(&lu_prdb); + xdr_free(xdr__lu_prdb_ent, &lu_prdb); + return (&global_prdb); +} + +const prdb_ent * +prdb_getbyname(const char *name) +{ + LOOKUP1(lu_prdb_getbyname, _old_prdb_getbyname, name, prdb_ent); +} + +const prdb_ent * +prdb_get(void) +{ + GETENT(lu_prdb_get, _old_prdb_get, &prdb_state, prdb_ent); +} + +void +prdb_set(const char *name) +{ + SETSTATE(lu_prdb_set, _old_prdb_set, &prdb_state, name); +} + +void +prdb_end(void) +{ + UNSETSTATE(lu_prdb_end, _old_prdb_end, &prdb_state); +} diff --git a/lookup.subproj/lu_protocol.c b/lookup.subproj/lu_protocol.c new file mode 100644 index 0000000..f3c0e4b --- /dev/null +++ b/lookup.subproj/lu_protocol.c @@ -0,0 +1,299 @@ +/* + * 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@ + */ +/* + * Protocol lookup + * Copyright (C) 1989 by NeXT, Inc. + */ +#include +#include +#include +#include +#include "lookup.h" +#include +#include +#include "_lu_types.h" +#include +#include "lu_utils.h" +#import + +extern struct protoent *_old_getprotobynumber(); +extern struct protoent *_old_getprotobyname(); +extern struct protoent *_old_getprotoent(); +extern void _old_setprotoent(); +extern void _old_endprotoent(); + +static lookup_state p_state = LOOKUP_CACHE; +static struct protoent global_p; +static int global_free = 1; +static char *p_data = NULL; +static unsigned p_datalen; +static int p_nentries; +static int p_start; +static XDR p_xdr; + +static void +freeold(void) +{ + char **aliases; + + if (global_free == 1) return; + + free(global_p.p_name); + aliases = global_p.p_aliases; + if (aliases != NULL) + { + while (*aliases != NULL) free(*aliases++); + free(global_p.p_aliases); + } + + global_free = 1; +} + +static void +convert_p(_lu_protoent *lu_p) +{ + int i, len; + + freeold(); + + global_p.p_name = strdup(lu_p->p_names.p_names_val[0]); + + len = lu_p->p_names.p_names_len - 1; + global_p.p_aliases = (char **)malloc((len + 1) * sizeof(char *)); + + for (i = 0; i < len; i++) + { + global_p.p_aliases[i] = strdup(lu_p->p_names.p_names_val[i+1]); + } + + global_p.p_aliases[len] = NULL; + + global_p.p_proto = lu_p->p_proto; + + global_free = 0; +} + +static struct protoent * +lu_getprotobynumber(long number) +{ + unsigned datalen; + _lu_protoent_ptr lu_p; + XDR xdr; + static int proc = -1; + unit lookup_buf[MAX_INLINE_UNITS]; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "getprotobynumber", &proc) != KERN_SUCCESS) + { + return (NULL); + } + } + + number = htonl(number); + datalen = MAX_INLINE_UNITS; + if (_lookup_one(_lu_port, proc, (unit *)&number, 1, lookup_buf, &datalen) + != KERN_SUCCESS) + { + return (NULL); + } + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&xdr, lookup_buf, datalen, + XDR_DECODE); + lu_p = NULL; + if (!xdr__lu_protoent_ptr(&xdr, &lu_p) || (lu_p == NULL)) + { + xdr_destroy(&xdr); + return (NULL); + } + + xdr_destroy(&xdr); + + convert_p(lu_p); + xdr_free(xdr__lu_protoent_ptr, &lu_p); + return (&global_p); +} + +static struct protoent * +lu_getprotobyname(const char *name) +{ + unsigned datalen; + char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT]; + XDR outxdr; + XDR inxdr; + _lu_protoent_ptr lu_p; + static int proc = -1; + unit lookup_buf[MAX_INLINE_UNITS]; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "getprotobyname", &proc) != KERN_SUCCESS) + { + return (NULL); + } + } + + xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE); + if (!xdr__lu_string(&outxdr, &name)) + { + xdr_destroy(&outxdr); + return (NULL); + } + + datalen = MAX_INLINE_UNITS; + if (_lookup_one(_lu_port, proc, (unit *)namebuf, + xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, lookup_buf, &datalen) + != KERN_SUCCESS) + { + xdr_destroy(&outxdr); + return (NULL); + } + + xdr_destroy(&outxdr); + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&inxdr, lookup_buf, datalen, + XDR_DECODE); + lu_p = NULL; + if (!xdr__lu_protoent_ptr(&inxdr, &lu_p) || (lu_p == NULL)) + { + xdr_destroy(&inxdr); + return (NULL); + } + + xdr_destroy(&inxdr); + + convert_p(lu_p); + xdr_free(xdr__lu_protoent_ptr, &lu_p); + return (&global_p); +} + +static void +lu_endprotoent() +{ + p_nentries = 0; + if (p_data != NULL) + { + freeold(); + vm_deallocate(mach_task_self(), (vm_address_t)p_data, p_datalen); + p_data = NULL; + } +} + +static void +lu_setprotoent() +{ + lu_endprotoent(); + p_start = 1; +} + +static struct protoent * +lu_getprotoent() +{ + static int proc = -1; + _lu_protoent lu_p; + + if (p_start == 1) + { + p_start = 0; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "getprotoent", &proc) != KERN_SUCCESS) + { + lu_endprotoent(); + return (NULL); + } + } + + if (_lookup_all(_lu_port, proc, NULL, 0, &p_data, &p_datalen) + != KERN_SUCCESS) + { + lu_endprotoent(); + return (NULL); + } + + p_datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&p_xdr, p_data, p_datalen, + XDR_DECODE); + if (!xdr_int(&p_xdr, &p_nentries)) + { + xdr_destroy(&p_xdr); + lu_endprotoent(); + return (NULL); + } + } + + if (p_nentries == 0) + { + xdr_destroy(&p_xdr); + lu_endprotoent(); + return (NULL); + } + + bzero(&lu_p, sizeof(lu_p)); + if (!xdr__lu_protoent(&p_xdr, &lu_p)) + { + xdr_destroy(&p_xdr); + lu_endprotoent(); + return (NULL); + } + + p_nentries--; + convert_p(&lu_p); + xdr_free(xdr__lu_protoent, &lu_p); + return (&global_p); +} + +struct protoent * +getprotobynumber(int number) +{ + LOOKUP1(lu_getprotobynumber, _old_getprotobynumber, number, + struct protoent); +} + +struct protoent * +getprotobyname(const char *name) +{ + LOOKUP1(lu_getprotobyname, _old_getprotobyname, name, struct protoent); +} + +struct protoent * +getprotoent(void) +{ + GETENT(lu_getprotoent, _old_getprotoent, &p_state, struct protoent); +} + +void +setprotoent(int stayopen) +{ + SETSTATE(lu_setprotoent, _old_setprotoent, &p_state, stayopen); +} + +void +endprotoent(void) +{ + UNSETSTATE(lu_endprotoent, _old_endprotoent, &p_state); +} diff --git a/lookup.subproj/lu_rpc.c b/lookup.subproj/lu_rpc.c new file mode 100644 index 0000000..3bd9460 --- /dev/null +++ b/lookup.subproj/lu_rpc.c @@ -0,0 +1,301 @@ +/* + * 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@ + */ +/* + * RPC lookup + * Copyright (C) 1989 by NeXT, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "_lu_types.h" +#include "lookup.h" +#include "lu_utils.h" +#include "lu_overrides.h" + +static lookup_state r_state = LOOKUP_CACHE; +static struct rpcent global_r; +static int global_free = 1; +static char *r_data = NULL; +static unsigned r_datalen; +static int r_nentries; +static int r_start = 1; +static XDR r_xdr; + +static void +freeold(void) +{ + char **aliases; + + if (global_free == 1) return; + + free(global_r.r_name); + + aliases = global_r.r_aliases; + if (aliases != NULL) + { + while (*aliases != NULL) free(*aliases++); + free(global_r.r_aliases); + } + + global_free = 1; +} + +static void +convert_r(_lu_rpcent *lu_r) +{ + int i, len; + + freeold(); + + global_r.r_name = strdup(lu_r->r_names.r_names_val[0]); + + len = lu_r->r_names.r_names_len - 1; + global_r.r_aliases = (char **)malloc((len + 1) * sizeof(char *)); + + for (i = 0; i < len; i++) + { + global_r.r_aliases[i] = strdup(lu_r->r_names.r_names_val[i+1]); + } + + global_r.r_aliases[len] = NULL; + + global_r.r_number = lu_r->r_number; + + global_free = 0; +} + + + +static struct rpcent * +lu_getrpcbynumber(long number) +{ + unsigned datalen; + _lu_rpcent_ptr lu_r; + XDR xdr; + static int proc = -1; + unit lookup_buf[MAX_INLINE_UNITS]; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "getrpcbynumber", &proc) != KERN_SUCCESS) + { + return (NULL); + } + } + + number = htonl(number); + datalen = MAX_INLINE_UNITS; + if (_lookup_one(_lu_port, proc, (unit *)&number, 1, lookup_buf, &datalen) + != KERN_SUCCESS) + { + return (NULL); + } + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&xdr, lookup_buf, datalen, XDR_DECODE); + lu_r = NULL; + if (!xdr__lu_rpcent_ptr(&xdr, &lu_r) || lu_r == NULL) + { + xdr_destroy(&xdr); + return (NULL); + } + + xdr_destroy(&xdr); + + convert_r(lu_r); + xdr_free(xdr__lu_rpcent_ptr, &lu_r); + return (&global_r); +} + +static struct rpcent * +lu_getrpcbyname(const char *name) +{ + unsigned datalen; + char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT]; + XDR outxdr; + XDR inxdr; + _lu_rpcent_ptr lu_r; + static int proc = -1; + unit lookup_buf[MAX_INLINE_UNITS]; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "getrpcbyname", &proc) != KERN_SUCCESS) + { + return (NULL); + } + } + + xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE); + if (!xdr__lu_string(&outxdr, &name)) + { + xdr_destroy(&outxdr); + return (NULL); + } + + datalen = MAX_INLINE_UNITS; + if (_lookup_one(_lu_port, proc, (unit *)namebuf, + xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, lookup_buf, &datalen) + != KERN_SUCCESS) + { + xdr_destroy(&outxdr); + return (NULL); + } + + xdr_destroy(&outxdr); + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&inxdr, lookup_buf, datalen, + XDR_DECODE); + lu_r = NULL; + if (!xdr__lu_rpcent_ptr(&inxdr, &lu_r) || (lu_r == NULL)) + { + xdr_destroy(&inxdr); + return (NULL); + } + + xdr_destroy(&inxdr); + + convert_r(lu_r); + xdr_free(xdr__lu_rpcent_ptr, &lu_r); + return (&global_r); +} + +static void +lu_endrpcent(void) +{ + r_nentries = 0; + if (r_data != NULL) + { + freeold(); + vm_deallocate(mach_task_self(), (vm_address_t)r_data, r_datalen); + r_data = NULL; + } +} + +static int +lu_setrpcent(int stayopen) +{ + lu_endrpcent(); + r_start = 1; + return (1); +} + +static struct rpcent * +lu_getrpcent() +{ + static int proc = -1; + _lu_rpcent lu_r; + + if (r_start == 1) + { + r_start = 0; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "getrpcent", &proc) != KERN_SUCCESS) + { + lu_endrpcent(); + return (NULL); + } + } + + if (_lookup_all(_lu_port, proc, NULL, 0, &r_data, &r_datalen) + != KERN_SUCCESS) + { + lu_endrpcent(); + return (NULL); + } + +#ifdef NOTDEF +/* NOTDEF because OOL buffers are counted in bytes with untyped IPC */ + r_datalen *= BYTES_PER_XDR_UNIT; +#endif + + xdrmem_create(&r_xdr, r_data, r_datalen, + XDR_DECODE); + if (!xdr_int(&r_xdr, &r_nentries)) + { + xdr_destroy(&r_xdr); + lu_endrpcent(); + return (NULL); + } + } + + if (r_nentries == 0) + { + xdr_destroy(&r_xdr); + lu_endrpcent(); + return (NULL); + } + + bzero(&lu_r, sizeof(lu_r)); + if (!xdr__lu_rpcent(&r_xdr, &lu_r)) + { + xdr_destroy(&r_xdr); + lu_endrpcent(); + return (NULL); + } + + r_nentries--; + convert_r(&lu_r); + xdr_free(xdr__lu_rpcent, &lu_r); + return (&global_r); +} + +struct rpcent * +getrpcbynumber(long number) +{ + LOOKUP1(lu_getrpcbynumber, _old_getrpcbynumber, number, struct rpcent); +} + +struct rpcent * +getrpcbyname(const char *name) +{ + LOOKUP1(lu_getrpcbyname, _old_getrpcbyname, name, struct rpcent); +} + +struct rpcent * +getrpcent(void) +{ + GETENT(lu_getrpcent, _old_getrpcent, &r_state, struct rpcent); +} + +void +setrpcent(int stayopen) +{ + SETSTATE(lu_setrpcent, _old_setrpcent, &r_state, stayopen); +} + +void +endrpcent(void) +{ + UNSETSTATE(lu_endrpcent, _old_endrpcent, &r_state); +} diff --git a/lookup.subproj/lu_service.c b/lookup.subproj/lu_service.c new file mode 100644 index 0000000..2fd3e2a --- /dev/null +++ b/lookup.subproj/lu_service.c @@ -0,0 +1,323 @@ +/* + * 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@ + */ +/* + * Services file lookup + * Copyright (C) 1989 by NeXT, Inc. + */ +#include +#include +#include +#include +#include "lookup.h" +#include +#include +#include "_lu_types.h" +#include +#include "lu_utils.h" +#import + +extern struct servent *_old_getservbyport(); +extern struct servent *_old_getservbyname(); +extern struct servent *_old_getservent(); +extern void _old_setservent(); +extern void _old_endservent(); +extern void _old_setservfile(); + +static lookup_state s_state = LOOKUP_CACHE; +static struct servent global_s; +static int global_free = 1; +static char *s_data = NULL; +static unsigned s_datalen; +static int s_nentries; +static int s_start = 1; +static XDR s_xdr; + +static void +freeold(void) +{ + char **aliases; + + if (global_free == 1) return; + + free(global_s.s_name); + + aliases = global_s.s_aliases; + if (aliases != NULL) + { + while (*aliases != NULL) free(*aliases++); + free(global_s.s_aliases); + } + + global_free = 1; +} + +static void +convert_s(_lu_servent *lu_s) +{ + int i, len; + + freeold(); + + global_s.s_name = strdup(lu_s->s_names.s_names_val[0]); + + len = lu_s->s_names.s_names_len - 1; + global_s.s_aliases = (char **)malloc((len + 1) * sizeof(char *)); + + for (i = 0; i < len; i++) + { + global_s.s_aliases[i] = strdup(lu_s->s_names.s_names_val[i+1]); + } + + global_s.s_aliases[len] = NULL; + + global_s.s_proto = lu_s->s_proto; + global_s.s_port = lu_s->s_port; + + global_free = 0; +} + +static struct servent * +lu_getservbyport(int port, const char *proto) +{ + unsigned datalen; + _lu_servent_ptr lu_s; + XDR xdr; + static int proc = -1; + char output_buf[_LU_MAXLUSTRLEN + 3 * BYTES_PER_XDR_UNIT]; + unit lookup_buf[MAX_INLINE_UNITS]; + XDR outxdr; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "getservbyport", &proc) != KERN_SUCCESS) + { + return (NULL); + } + } + + /* Encode NULL for xmission to lookupd. */ + if (!proto) proto = ""; + + xdrmem_create(&outxdr, output_buf, sizeof(output_buf), XDR_ENCODE); + if (!xdr_int(&outxdr, &port) || !xdr__lu_string(&outxdr, &proto)) + { + xdr_destroy(&outxdr); + return (NULL); + } + + datalen = MAX_INLINE_UNITS; + if (_lookup_one(_lu_port, proc, (unit *)output_buf, + xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, lookup_buf, &datalen) + != KERN_SUCCESS) + { + xdr_destroy(&outxdr); + return (NULL); + } + + xdr_destroy(&outxdr); + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&xdr, lookup_buf, datalen, XDR_DECODE); + lu_s = NULL; + if (!xdr__lu_servent_ptr(&xdr, &lu_s) || (lu_s == NULL)) + { + xdr_destroy(&xdr); + return (NULL); + } + + xdr_destroy(&xdr); + + convert_s(lu_s); + xdr_free(xdr__lu_servent_ptr, &lu_s); + return (&global_s); +} + +static struct servent * +lu_getservbyname(const char *name, const char *proto) +{ + unsigned datalen; + unit lookup_buf[MAX_INLINE_UNITS]; + char output_buf[2 * (_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT)]; + XDR outxdr; + XDR inxdr; + _lu_servent_ptr lu_s; + static int proc = -1; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "getservbyname", &proc) != KERN_SUCCESS) + { + return (NULL); + } + } + + /* Encode NULL for xmission to lookupd. */ + if (!proto) proto = ""; + + xdrmem_create(&outxdr, output_buf, sizeof(output_buf), XDR_ENCODE); + if (!xdr__lu_string(&outxdr, &name) || !xdr__lu_string(&outxdr, &proto)) + { + xdr_destroy(&outxdr); + return (NULL); + } + + datalen = MAX_INLINE_UNITS; + if (_lookup_one(_lu_port, proc, (unit *)output_buf, + xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, lookup_buf, &datalen) + != KERN_SUCCESS) + { + xdr_destroy(&outxdr); + return (NULL); + } + + xdr_destroy(&outxdr); + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&inxdr, lookup_buf, datalen, + XDR_DECODE); + lu_s = NULL; + if (!xdr__lu_servent_ptr(&inxdr, &lu_s) || (lu_s == NULL)) + { + xdr_destroy(&inxdr); + return (NULL); + } + + xdr_destroy(&inxdr); + + convert_s(lu_s); + xdr_free(xdr__lu_servent_ptr, &lu_s); + return (&global_s); +} + +static void +lu_endservent() +{ + s_nentries = 0; + if (s_data != NULL) + { + freeold(); + vm_deallocate(mach_task_self(), (vm_address_t)s_data, s_datalen); + s_data = NULL; + } +} + +static void +lu_setservent() +{ + lu_endservent(); + s_start = 1; +} + +static struct servent * +lu_getservent() +{ + static int proc = -1; + _lu_servent lu_s; + + if (s_start == 1) + { + s_start = 0; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "getservent", &proc) != KERN_SUCCESS) + { + lu_endservent(); + return (NULL); + } + } + + if (_lookup_all(_lu_port, proc, NULL, 0, &s_data, &s_datalen) + != KERN_SUCCESS) + { + lu_endservent(); + return (NULL); + } + +#ifdef NOTDEF +/* NOTDEF because OOL buffers are counted in bytes with untyped IPC */ + s_datalen *= BYTES_PER_XDR_UNIT; +#endif + + xdrmem_create(&s_xdr, s_data, s_datalen, + XDR_DECODE); + if (!xdr_int(&s_xdr, &s_nentries)) + { + xdr_destroy(&s_xdr); + lu_endservent(); + return (NULL); + } + } + + if (s_nentries == 0) + { + xdr_destroy(&s_xdr); + lu_endservent(); + return (NULL); + } + + bzero(&lu_s, sizeof(lu_s)); + if (!xdr__lu_servent(&s_xdr, &lu_s)) + { + xdr_destroy(&s_xdr); + lu_endservent(); + return (NULL); + } + + s_nentries--; + convert_s(&lu_s); + xdr_free(xdr__lu_servent, &lu_s); + return (&global_s); +} + +struct servent * +getservbyport(int port, const char *proto) +{ + LOOKUP2(lu_getservbyport, _old_getservbyport, port, proto, struct servent); +} + +struct servent * +getservbyname(const char *name, const char *proto) +{ + LOOKUP2(lu_getservbyname, _old_getservbyname, name, proto, + struct servent); +} + +struct servent * +getservent(void) +{ + GETENT(lu_getservent, _old_getservent, &s_state, struct servent); +} + +void +setservent(int stayopen) +{ + SETSTATE(lu_setservent, _old_setservent, &s_state, stayopen); +} + +void +endservent(void) +{ + UNSETSTATE(lu_endservent, _old_endservent, &s_state); +} diff --git a/lookup.subproj/lu_user.c b/lookup.subproj/lu_user.c new file mode 100644 index 0000000..ecf36f6 --- /dev/null +++ b/lookup.subproj/lu_user.c @@ -0,0 +1,380 @@ +/* + * 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@ + */ +/* + * user information (passwd) lookup + * Copyright (C) 1989 by NeXT, Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "_lu_types.h" +#include "lookup.h" +#include "lu_utils.h" +#include "lu_overrides.h" + +static lookup_state pw_state = LOOKUP_CACHE; +static struct passwd global_pw; +static int global_free = 1; +static char *pw_data = NULL; +static unsigned pw_datalen; +static int pw_nentries; +static int pw_start = 1; +static XDR pw_xdr; + +static void +freeold(void) +{ + if (global_free == 1) return; + + free(global_pw.pw_name); + free(global_pw.pw_passwd); + free(global_pw.pw_class); + free(global_pw.pw_gecos); + free(global_pw.pw_dir); + free(global_pw.pw_shell); + + global_free = 1; +} + +static void +convert_pw(_lu_passwd *lu_pw) +{ + freeold(); + + global_pw.pw_name = strdup(lu_pw->pw_name); + global_pw.pw_passwd = strdup(lu_pw->pw_passwd); + global_pw.pw_uid = lu_pw->pw_uid; + global_pw.pw_gid = lu_pw->pw_gid; + global_pw.pw_change = lu_pw->pw_change; + global_pw.pw_class = strdup(lu_pw->pw_class); + global_pw.pw_gecos = strdup(lu_pw->pw_gecos); + global_pw.pw_dir = strdup(lu_pw->pw_dir); + global_pw.pw_shell = strdup(lu_pw->pw_shell); + global_pw.pw_expire = lu_pw->pw_expire; + + global_free = 0; +} + +static struct passwd * +lu_getpwuid(int uid) +{ + unsigned datalen; + _lu_passwd_ptr lu_pw; + XDR xdr; + static int proc = -1; + unit lookup_buf[MAX_INLINE_UNITS]; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "getpwuid_A", &proc) != KERN_SUCCESS) + { + return (NULL); + } + } + + uid = htonl(uid); + datalen = MAX_INLINE_UNITS; + if (_lookup_one(_lu_port, proc, (unit *)&uid, 1, lookup_buf, &datalen) + != KERN_SUCCESS) + { + return (NULL); + } + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&xdr, lookup_buf, datalen, XDR_DECODE); + lu_pw = NULL; + if (!xdr__lu_passwd_ptr(&xdr, &lu_pw) || (lu_pw == NULL)) + { + xdr_destroy(&xdr); + return (NULL); + } + + xdr_destroy(&xdr); + + convert_pw(lu_pw); + xdr_free(xdr__lu_passwd_ptr, &lu_pw); + return (&global_pw); +} + +static struct passwd * +lu_getpwnam(const char *name) +{ + unsigned datalen; + char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT]; + XDR outxdr; + XDR inxdr; + _lu_passwd_ptr lu_pw; + static int proc = -1; + unit lookup_buf[MAX_INLINE_UNITS]; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "getpwnam_A", &proc) != KERN_SUCCESS) + { + return (NULL); + } + } + + xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE); + if (!xdr__lu_string(&outxdr, &name)) + { + xdr_destroy(&outxdr); + return (NULL); + } + + datalen = MAX_INLINE_UNITS; + if (_lookup_one(_lu_port, proc, (unit *)namebuf, + xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, lookup_buf, &datalen) + != KERN_SUCCESS) + { + xdr_destroy(&outxdr); + return (NULL); + } + + xdr_destroy(&outxdr); + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&inxdr, lookup_buf, datalen, + XDR_DECODE); + lu_pw = NULL; + if (!xdr__lu_passwd_ptr(&inxdr, &lu_pw) || (lu_pw == NULL)) + { + xdr_destroy(&inxdr); + return (NULL); + } + + xdr_destroy(&inxdr); + + convert_pw(lu_pw); + xdr_free(xdr__lu_passwd_ptr, &lu_pw); + return (&global_pw); +} + +#ifdef notdef +static int +lu_putpwpasswd(char *login, char *old_passwd, char *new_passwd) +{ + unsigned datalen; + int changed; + XDR xdr; + static int proc = -1; + char output_buf[3 * (_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT)]; + unit lookup_buf[MAX_INLINE_UNITS]; + XDR outxdr; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "putpwpasswd", &proc) != KERN_SUCCESS) + { + return (0); + } + } + + xdrmem_create(&outxdr, output_buf, sizeof(output_buf), XDR_ENCODE); + if (!xdr__lu_string(&outxdr, &login) || + !xdr__lu_string(&outxdr, &old_passwd) || + !xdr__lu_string(&outxdr, &new_passwd)) + { + xdr_destroy(&outxdr); + return (0); + } + + datalen = MAX_INLINE_UNITS; + if (_lookup_one(_lu_port, proc, output_buf, + xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, lookup_buf, &datalen) + != KERN_SUCCESS) + { + xdr_destroy(&outxdr); + return (0); + } + + xdr_destroy(&outxdr); + + datalen *= BYTES_PER_XDR_UNIT; + xdrmem_create(&xdr, lookup_buf, datalen, XDR_DECODE); + if (!xdr_int(&xdr, &changed)) + { + xdr_destroy(&xdr); + return (0); + } + + xdr_destroy(&xdr); + + return (changed); +} +#endif + +static void +lu_endpwent(void) +{ + pw_nentries = 0; + if (pw_data != NULL) + { + freeold(); + vm_deallocate(mach_task_self(), (vm_address_t)pw_data, pw_datalen); + pw_data = NULL; + } +} + +static int +lu_setpwent(void) +{ + lu_endpwent(); + pw_start = 1; + return (1); +} + +static struct passwd * +lu_getpwent() +{ + static int proc = -1; + _lu_passwd lu_pw; + + if (pw_start == 1) + { + pw_start = 0; + + if (proc < 0) + { + if (_lookup_link(_lu_port, "getpwent_A", &proc) != KERN_SUCCESS) + { + lu_endpwent(); + return (NULL); + } + } + + if (_lookup_all(_lu_port, proc, NULL, 0, &pw_data, &pw_datalen) + != KERN_SUCCESS) + { + lu_endpwent(); + return (NULL); + } + +#ifdef NOTDEF +/* NOTDEF because OOL buffers are counted in bytes with untyped IPC */ + pw_datalen *= BYTES_PER_XDR_UNIT; +#endif + + xdrmem_create(&pw_xdr, pw_data, pw_datalen, + XDR_DECODE); + if (!xdr_int(&pw_xdr, &pw_nentries)) + { + xdr_destroy(&pw_xdr); + lu_endpwent(); + return (NULL); + } + } + + if (pw_nentries == 0) + { + xdr_destroy(&pw_xdr); + lu_endpwent(); + return (NULL); + } + + bzero(&lu_pw, sizeof(lu_pw)); + if (!xdr__lu_passwd(&pw_xdr, &lu_pw)) + { + xdr_destroy(&pw_xdr); + lu_endpwent(); + return (NULL); + } + + pw_nentries--; + convert_pw(&lu_pw); + xdr_free(xdr__lu_passwd, &lu_pw); + return (&global_pw); +} + +static char *loginName = NULL; +static uid_t loginUid = -1; + +extern char *getlogin(void); + +struct passwd * +getpwuid(uid_t uid) +{ + if (uid != 0) { + if (loginName == NULL) { + char *l = getlogin(); + if (l != NULL) { + struct passwd *p = getpwnam(l); + if (p != NULL) { + loginUid = p->pw_uid; + loginName = l; + } + } + } + if (uid == loginUid) { + LOOKUP1(lu_getpwnam, _old_getpwnam, loginName, struct passwd); + } + } + LOOKUP1(lu_getpwuid, _old_getpwuid, uid, struct passwd); +} + +struct passwd * +getpwnam(const char *name) +{ + LOOKUP1(lu_getpwnam, _old_getpwnam, name, struct passwd); +} + +#ifdef notdef +/* + * putpwpasswd() is not supported with anything other than netinfo + * right now. + * old_passwd is clear text. + * new_passwd is encrypted. + */ +#define _old_passwd(name, oldpass, newpass) 0 +int +putpwpasswd(char *login, char *old_passwd, char *new_passwd) +{ + if (_lu_running()) return (lu_putpwpasswd(login, old_passwd, new_passwd)); + return (old_passwd(login, old_passwd, new_passwd)); +} +#endif + +struct passwd * +getpwent(void) +{ + GETENT(lu_getpwent, _old_getpwent, &pw_state, struct passwd); +} + +int +setpwent(void) +{ + INTSETSTATEVOID(lu_setpwent, _old_setpwent, &pw_state); +} + +void +endpwent(void) +{ + UNSETSTATE(lu_endpwent, _old_endpwent, &pw_state); +} diff --git a/lookup.subproj/lu_utils.c b/lookup.subproj/lu_utils.c new file mode 100644 index 0000000..b458b74 --- /dev/null +++ b/lookup.subproj/lu_utils.c @@ -0,0 +1,332 @@ +/* + * 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@ + */ + +#include +#include +#include + +#include "_lu_types.h" +#include "lookup.h" +#include "lu_utils.h" + +#define LONG_STRING_LENGTH 8192 +#define _LU_MAXLUSTRLEN 256 + +static ni_proplist * +lookupd_process_dictionary(XDR *inxdr) +{ + int i, nkeys, j, nvals; + char *key, *val; + ni_proplist *l; + + if (!xdr_int(inxdr, &nkeys)) return NULL; + + l = (ni_proplist *)malloc(sizeof(ni_proplist)); + NI_INIT(l); + + l->ni_proplist_len = nkeys; + l->ni_proplist_val = NULL; + if (nkeys > 0) + { + i = nkeys * sizeof(ni_property); + l->ni_proplist_val = (ni_property *)malloc(i); + memset(l->ni_proplist_val, 0, i); + } + + for (i = 0; i < nkeys; i++) + { + key = NULL; + + if (!xdr_string(inxdr, &key, LONG_STRING_LENGTH)) + { + ni_proplist_free(l); + return NULL; + } + + l->ni_proplist_val[i].nip_name = key; + + if (!xdr_int(inxdr, &nvals)) + { + ni_proplist_free(l); + return NULL; + } + + l->ni_proplist_val[i].nip_val.ni_namelist_len = nvals; + if (nvals > 0) + { + j = nvals * sizeof(ni_name); + l->ni_proplist_val[i].nip_val.ni_namelist_val = (ni_name *)malloc(j); + memset(l->ni_proplist_val[i].nip_val.ni_namelist_val, 0 , j); + } + + for (j = 0; j < nvals; j++) + { + val = NULL; + if (!xdr_string(inxdr, &val, LONG_STRING_LENGTH)) + { + ni_proplist_free(l); + return NULL; + } + + l->ni_proplist_val[i].nip_val.ni_namelist_val[j] = val; + } + } + + return l; +} + +int +lookupd_query(ni_proplist *l, ni_proplist ***out) +{ + unsigned datalen; + XDR outxdr; + XDR inxdr; + int proc; + char *listbuf; + char databuf[_LU_MAXLUSTRLEN * BYTES_PER_XDR_UNIT]; + int n, i, j, na; + kern_return_t status; + ni_property *p; + + if (l == NULL) return 0; + if (out == NULL) return 0; + + if (_lu_port == NULL) return 0; + + status = _lookup_link(_lu_port, "query", &proc); + if (status != KERN_SUCCESS) return 0; + + xdrmem_create(&outxdr, databuf, sizeof(databuf), XDR_ENCODE); + + na = l->ni_proplist_len; + + /* Encode attribute count */ + if (!xdr_int(&outxdr, &na)) + { + xdr_destroy(&outxdr); + return 0; + } + + for (i = 0; i < l->ni_proplist_len; i++) + { + p = &(l->ni_proplist_val[i]); + if (!xdr_string(&outxdr, &(p->nip_name), _LU_MAXLUSTRLEN)) + { + xdr_destroy(&outxdr); + return 0; + } + + if (!xdr_int(&outxdr, &(p->nip_val.ni_namelist_len))) + { + xdr_destroy(&outxdr); + return 0; + } + + for (j = 0; j < p->nip_val.ni_namelist_len; j++) + { + if (!xdr_string(&outxdr, &(p->nip_val.ni_namelist_val[j]), _LU_MAXLUSTRLEN)) + { + xdr_destroy(&outxdr); + return 0; + } + } + } + + listbuf = NULL; + datalen = 0; + + n = xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT; + status = _lookup_all(_lu_port, proc, (unit *)databuf, n, &listbuf, &datalen); + if (status != KERN_SUCCESS) + { + xdr_destroy(&outxdr); + return 0; + } + + xdr_destroy(&outxdr); + +#ifdef NOTDEF +/* NOTDEF because OOL buffers are counted in bytes with untyped IPC */ + datalen *= BYTES_PER_XDR_UNIT; +#endif + + xdrmem_create(&inxdr, listbuf, datalen, XDR_DECODE); + + if (!xdr_int(&inxdr, &n)) + { + xdr_destroy(&inxdr); + return 0; + } + + if (n == 0) + { + xdr_destroy(&inxdr); + return 0; + } + + *out = (ni_proplist **)malloc(n * sizeof(ni_proplist *)); + + for (i = 0; i < n; i++) + { + (*out)[i] = lookupd_process_dictionary(&inxdr); + } + + xdr_destroy(&inxdr); + + vm_deallocate(mach_task_self(), (vm_address_t)listbuf, datalen); + + return n; +} + +ni_proplist * +lookupd_make_query(char *cat, char *fmt, ...) +{ + va_list ap; + char *arg, *f; + int na, x; + ni_proplist *l; + ni_property *p; + + if (fmt == NULL) return NULL; + if (fmt[0] != 'k') return NULL; + + l = (ni_proplist *)malloc(sizeof(ni_proplist)); + NI_INIT(l); + + na = 0; + x = -1; + + if (cat != NULL) + { + l->ni_proplist_val = (ni_property *)malloc(sizeof(ni_property)); + p = &(l->ni_proplist_val[0]); + arg = "_lookup_category"; + p->nip_name = strdup(arg); + p->nip_val.ni_namelist_len = 1; + p->nip_val.ni_namelist_val = (ni_name *)malloc(sizeof(ni_name)); + p->nip_val.ni_namelist_val[0] = strdup(cat); + + l->ni_proplist_len++; + x++; + } + + va_start(ap, fmt); + for (f = fmt; *f != NULL; f++) + { + arg = va_arg(ap, char *); + if (*f == 'k') + { + l->ni_proplist_val = (ni_property *)realloc(l->ni_proplist_val, (l->ni_proplist_len + 1) * sizeof(ni_property)); + + p = &(l->ni_proplist_val[l->ni_proplist_len]); + p->nip_name = strdup(arg); + p->nip_val.ni_namelist_len = 0; + p->nip_val.ni_namelist_val = NULL; + + l->ni_proplist_len++; + x++; + } + else + { + p = &(l->ni_proplist_val[x]); + if (p->nip_val.ni_namelist_len == 0) + { + p->nip_val.ni_namelist_val = (ni_name *)malloc(sizeof(ni_name)); + } + else + { + p->nip_val.ni_namelist_val = (ni_name *)realloc(p->nip_val.ni_namelist_val, (p->nip_val.ni_namelist_len + 1) * sizeof(ni_name)); + } + p->nip_val.ni_namelist_val[p->nip_val.ni_namelist_len] = strdup(arg); + p->nip_val.ni_namelist_len++; + } + } + va_end(ap); + + return l; +} + +void +ni_property_merge(ni_property *a, ni_property *b) +{ + int i, j, addme; + + if (a == NULL) return; + if (b == NULL) return; + + for (j = 0; j < b->nip_val.ni_namelist_len; j++) + { + addme = 1; + for (i = 0; i < (a->nip_val.ni_namelist_len) && (addme == 1); i++) + { + if (!strcmp(a->nip_val.ni_namelist_val[i], b->nip_val.ni_namelist_val[j])) addme = 0; + } + + if (addme == 1) + { + a->nip_val.ni_namelist_val = (ni_name *)realloc(a->nip_val.ni_namelist_val, (a->nip_val.ni_namelist_len + 1) * sizeof(ni_name)); + a->nip_val.ni_namelist_val[a->nip_val.ni_namelist_len] = strdup(b->nip_val.ni_namelist_val[j]); + a->nip_val.ni_namelist_len++; + } + } +} + +void +ni_proplist_merge(ni_proplist *a, ni_proplist *b) +{ + ni_index wa, wb; + int addme; + + if (a == NULL) return; + if (b == NULL) return; + + for (wb = 0; wb < b->ni_proplist_len; wb++) + { + addme = 1; + for (wa = 0; (wa < a->ni_proplist_len) && (addme == 1) ; wa++) + { + if (!strcmp(a->ni_proplist_val[wa].nip_name, b->ni_proplist_val[wb].nip_name)) addme = 0; + } + if (addme == 1) + { + a->ni_proplist_val = (ni_property *)realloc(a->ni_proplist_val, (a->ni_proplist_len + 1) * sizeof(ni_property)); + a->ni_proplist_val[a->ni_proplist_len].nip_name = strdup(b->ni_proplist_val[wb].nip_name); + a->ni_proplist_val[a->ni_proplist_len].nip_val.ni_namelist_len = 0; + a->ni_proplist_val[a->ni_proplist_len].nip_val.ni_namelist_val = NULL; + a->ni_proplist_len++; + } + } + + for (wb = 0; wb < b->ni_proplist_len; wb++) + { + for (wa = 0; wa < a->ni_proplist_len; wa++) + { + if (!strcmp(a->ni_proplist_val[wa].nip_name, b->ni_proplist_val[wb].nip_name)) + { + ni_property_merge(&(a->ni_proplist_val[wa]), &(b->ni_proplist_val[wb])); + } + } + } +} + diff --git a/lookup.subproj/lu_utils.h b/lookup.subproj/lu_utils.h new file mode 100644 index 0000000..d1a268c --- /dev/null +++ b/lookup.subproj/lu_utils.h @@ -0,0 +1,130 @@ +/* + * 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@ + */ +/* + * Useful macros and other stuff for generic lookups + * Copyright (C) 1989 by NeXT, Inc. + */ + +#import +#include +#include + +extern mach_port_t _lu_port; +extern unit *_lookup_buf; +extern int _lu_running(void); + +int lookupd_query(ni_proplist *l, ni_proplist ***out); +ni_proplist *lookupd_make_query(char *cat, char *fmt, ...); +void ni_property_merge(ni_property *a, ni_property *b); +void ni_proplist_merge(ni_proplist *a, ni_proplist *b); + +typedef enum lookup_state { + LOOKUP_CACHE, + LOOKUP_FILE, +} lookup_state; + +#define SETSTATE(_lu_set, _old_set, state, stayopen) \ +{ \ + if (_lu_running()) { \ + _lu_set(stayopen); \ + *state = LOOKUP_CACHE; \ + } else { \ + _old_set(stayopen); \ + *state = LOOKUP_FILE; \ + } \ +} + +#define SETSTATEVOID(_lu_set, _old_set, state) \ +{ \ + if (_lu_running()) { \ + _lu_set(); \ + *state = LOOKUP_CACHE; \ + } else { \ + _old_set(); \ + *state = LOOKUP_FILE; \ + } \ +} + +#define INTSETSTATEVOID(_lu_set, _old_set, state) \ +{ \ + int result; \ + if (_lu_running()) { \ + result = _lu_set(); \ + *state = LOOKUP_CACHE; \ + } else { \ + result = _old_set(); \ + *state = LOOKUP_FILE; \ + } \ + return result; \ +} + +#define UNSETSTATE(_lu_unset, _old_unset, state) \ +{ \ + if (_lu_running()) { \ + _lu_unset(); \ + } else { \ + _old_unset(); \ + } \ + *state = LOOKUP_CACHE; \ +} + +#define GETENT(_lu_get, _old_get, state, res_type) \ +{ \ + res_type *res; \ +\ + if (_lu_running()) { \ + if (*state == LOOKUP_CACHE) { \ + res = _lu_get(); \ + } else { \ + res = _old_get(); \ + } \ + } else { \ + res = _old_get(); \ + } \ + return (res); \ +} + +#define LOOKUP1(_lu_lookup, _old_lookup, arg, res_type) \ +{ \ + res_type *res; \ + \ + if (_lu_running()) { \ + res = _lu_lookup(arg); \ + } else { \ + res = _old_lookup(arg); \ + } \ + return (res); \ +} + +#define LOOKUP2(_lu_lookup, _old_lookup, arg1, arg2, res_type) \ +{ \ + res_type *res; \ + \ + if (_lu_running()) { \ + res = _lu_lookup(arg1, arg2); \ + } else { \ + res = _old_lookup(arg1, arg2); \ + } \ + return (res); \ +} diff --git a/lookup.subproj/netgr.h b/lookup.subproj/netgr.h new file mode 100644 index 0000000..f2b1917 --- /dev/null +++ b/lookup.subproj/netgr.h @@ -0,0 +1,47 @@ +/* + * 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@ + */ +/* + * Netgroup lookup routines + * Copyright (c) 1989 by NeXT, Inc. + */ + +#ifndef _NETGR_H_ +#define _NETGR_H_ + +struct netgrent { + char *ng_host; + char *ng_user; + char *ng_domain; +}; + +#include + +__BEGIN_DECLS +int innetgr __P((const char *,const char *,const char *,const char *)); +void setnetgrent __P((const char *)); +struct netgrent *getnetgrent __P((void)); +void endnetgrent __P((void)); +__END_DECLS + +#endif /* !_NETGR_H_ */ diff --git a/lookup.subproj/printerdb.h b/lookup.subproj/printerdb.h new file mode 100644 index 0000000..8058f4d --- /dev/null +++ b/lookup.subproj/printerdb.h @@ -0,0 +1,54 @@ +/* + * 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@ + */ +/* + * Printer database lookup routines + * Copyright (c) 1989 by NeXT, Inc. + */ + +#ifndef _PRDB_H_ +#define _PRDB_H_ + +typedef struct prdb_property { + char *pp_key; + char *pp_value; +} prdb_property; + +typedef struct prdb_ent { + char **pe_name; + unsigned pe_nprops; + prdb_property *pe_prop; +} prdb_ent; + +#include + +__BEGIN_DECLS + +void prdb_set __P((const char *)); +const prdb_ent *prdb_get __P((void)); +const prdb_ent *prdb_getbyname __P((const char *)); +void prdb_end __P((void)); + +__END_DECLS + +#endif /* !_PRDB_H_ */ diff --git a/netinfo.subproj/Makefile b/netinfo.subproj/Makefile new file mode 100644 index 0000000..baf2315 --- /dev/null +++ b/netinfo.subproj/Makefile @@ -0,0 +1,51 @@ +# +# Generated by the NeXT Project Builder. +# +# NOTE: Do NOT change this file -- Project Builder maintains it. +# +# Put all of your customizations in files called Makefile.preamble +# and Makefile.postamble (both optional), and Makefile will include them. +# + +NAME = netinfo + +PROJECTVERSION = 2.8 +PROJECT_TYPE = Component + +HFILES = clib.h mm.h ni.h ni_util.h + +CFILES = multi_call.c ni_error.c ni_glue.c ni_pwdomain.c ni_useful.c\ + ni_util.c + +OTHERSRCS = Makefile.preamble Makefile Makefile.postamble nibind_prot.x\ + ni_prot.x + + +MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles +CODE_GEN_STYLE = DYNAMIC +MAKEFILE = subproj.make +LIBS = +DEBUG_LIBS = $(LIBS) +PROF_LIBS = $(LIBS) + + +PUBLIC_HEADERS = ni.h ni_util.h nibind_prot.x ni_prot.x + + + +NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc +WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc +PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc +NEXTSTEP_JAVA_COMPILER = /usr/bin/javac +WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe +PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac + +include $(MAKEFILEDIR)/platform.make + +-include Makefile.preamble + +include $(MAKEFILEDIR)/$(MAKEFILE) + +-include Makefile.postamble + +-include Makefile.dependencies diff --git a/netinfo.subproj/Makefile.postamble b/netinfo.subproj/Makefile.postamble new file mode 100644 index 0000000..8361d56 --- /dev/null +++ b/netinfo.subproj/Makefile.postamble @@ -0,0 +1,5 @@ +%_clnt.c: %.x + $(RPCGEN) $(ALL_RPCFLAGS) -l -o $(SYM_DIR)/$*_clnt.c $*.x + +%_xdr.c: %.x + $(RPCGEN) $(ALL_RPCFLAGS) -c -o $(SYM_DIR)/$*_xdr.c $*.x diff --git a/netinfo.subproj/Makefile.preamble b/netinfo.subproj/Makefile.preamble new file mode 100644 index 0000000..77e442b --- /dev/null +++ b/netinfo.subproj/Makefile.preamble @@ -0,0 +1,6 @@ +OTHER_OFILES = nibind_prot_clnt.o ni_prot_clnt.o nibind_prot_xdr.o ni_prot_xdr.o +NETINFO_HEADERS = nibind_prot.h ni_prot.h +AFTER_PREBUILD = $(NETINFO_HEADERS) +OTHER_PUBLIC_HEADERS = $(NETINFO_HEADERS) +BEFORE_INSTALLHEADERS += $(NETINFO_HEADERS) +PUBLIC_HEADER_DIR_SUFFIX = /netinfo diff --git a/netinfo.subproj/PB.project b/netinfo.subproj/PB.project new file mode 100644 index 0000000..ecd1da8 --- /dev/null +++ b/netinfo.subproj/PB.project @@ -0,0 +1,23 @@ +{ + DYNAMIC_CODE_GEN = YES; + FILESTABLE = { + H_FILES = (clib.h, mm.h, ni.h, ni_util.h); + OTHER_LINKED = (multi_call.c, ni_error.c, ni_glue.c, ni_pwdomain.c, ni_useful.c, ni_util.c); + OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, nibind_prot.x, ni_prot.x); + PUBLIC_HEADERS = (ni.h, ni_util.h); + }; + LANGUAGE = English; + MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; + NEXTSTEP_BUILDTOOL = /bin/gnumake; + NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; + NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; + PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; + PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; + PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; + PROJECTNAME = netinfo; + PROJECTTYPE = Component; + PROJECTVERSION = 2.8; + WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; + WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; + WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; +} diff --git a/netinfo.subproj/clib.h b/netinfo.subproj/clib.h new file mode 100644 index 0000000..d284ec5 --- /dev/null +++ b/netinfo.subproj/clib.h @@ -0,0 +1,34 @@ +/* + * 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@ + */ +/* + * Standard libc stuff used by source files in this directory + * Copyright (C) 1989 by NeXT, Inc. + */ + +enum clnt_stat multi_call(unsigned, + struct in_addr *, u_long, u_long, u_long, + xdrproc_t, void *, unsigned, xdrproc_t, + void *, + int (*)(), int); +//bool_t xdr_free(xdrproc_t, void *); diff --git a/netinfo.subproj/mm.h b/netinfo.subproj/mm.h new file mode 100644 index 0000000..7c32dee --- /dev/null +++ b/netinfo.subproj/mm.h @@ -0,0 +1,57 @@ +/* + * 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@ + */ +/* + * Useful memory managment macros + * Copyright (C) 1989 by NeXT, Inc. + */ +#define mm_used() mstats() + +#define MM_ALLOC(obj) obj = ((void *)malloc(sizeof(*(obj)))) + +#define MM_FREE(obj) free((void *)(obj)) + +#define MM_ZERO(obj) bzero((void *)(obj), sizeof(*(obj))) + +#define MM_BCOPY(b1, b2, size) bcopy((void *)(b1), (void *)(b2), \ + (unsigned)(size)) + +#define MM_BEQ(b1, b2, size) (bcmp((void *)(b1), (void *)(b2), \ + (unsigned)(size)) == 0) + +#define MM_ALLOC_ARRAY(obj, len) \ + obj = ((void *)malloc(sizeof(*(obj)) * (len))) + +#define MM_ZERO_ARRAY(obj, len) bzero((void *)(obj), sizeof(*obj) * len) + +#define MM_FREE_ARRAY(obj, len) free((void *)(obj)) + +#define MM_GROW_ARRAY(obj, len) \ + ((obj == NULL) ? (MM_ALLOC_ARRAY((obj), (len) + 1)) : \ + (obj = (void *)realloc((void *)(obj), \ + sizeof(*(obj)) * ((len) + 1)))) + +#define MM_SHRINK_ARRAY(obj, len) \ + obj = (void *)realloc((void *)(obj), \ + sizeof(*(obj)) * ((len) - 1)) + diff --git a/netinfo.subproj/multi_call.c b/netinfo.subproj/multi_call.c new file mode 100644 index 0000000..47b031f --- /dev/null +++ b/netinfo.subproj/multi_call.c @@ -0,0 +1,352 @@ +/* + * 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@ + */ +/* + * multi_call: send out multiple call messages, wait for first reply + * Copyright (C) 1991 by NeXT, Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef NETINFOD +# include "socket_lock.h" +# include "clib.h" +# define multi_call _multi_call +#else +# define socket_lock() +# define socket_unlock() +# include "clib.h" +#endif + + +#define NRETRIES 5 +#define USECS_PER_SEC 1000000 + + +/* + * Wrapper for gethostname() syscall + */ +static char * +get_hostname(void) +{ + int len; + static char hostname[MAXHOSTNAMELEN + 1]; + + len = gethostname(hostname, sizeof(hostname)); + if (len < 0) { + hostname[0] = 0; + } else { + hostname[len] = 0; + } + return (hostname); +} + + +/* + * Encode a call message + */ +static int +encodemsg( + char *buf, + int buflen, + struct rpc_msg *call, + unsigned prognum, + unsigned versnum, + unsigned procnum, + xdrproc_t xdr_args, + void *arg + ) +{ + XDR xdr; + unsigned size; + unsigned pos; + + xdrmem_create(&xdr, buf, buflen, XDR_ENCODE); + if (!xdr_callmsg(&xdr, call) || + !xdr_u_int(&xdr, &prognum) || + !xdr_u_int(&xdr, &versnum) || + !xdr_u_int(&xdr, &procnum)) { + return (0); + } + pos = xdr_getpos(&xdr); + xdr_setpos(&xdr, pos + BYTES_PER_XDR_UNIT); + if (!(*xdr_args)(&xdr, arg)) { + return (0); + } + size = xdr_getpos(&xdr) - pos; + xdr_setpos(&xdr, pos); + if (!xdr_u_int(&xdr, &size)) { + return (0); + } + return (pos + BYTES_PER_XDR_UNIT + size); +} + +/* + * Decode a reply message + */ +static int +decodemsg( + XDR *xdr, + xdrproc_t xdr_res, + void *res + ) +{ + unsigned port; + unsigned len; + long *buf; + XDR bufxdr; + + if (!xdr_u_int(xdr, &port) || + !xdr_u_int(xdr, &len) || + !(buf = xdr_inline(xdr, len))) { + return (0); + } + xdrmem_create(&bufxdr, (char *)buf, len * BYTES_PER_XDR_UNIT, + XDR_DECODE); + if (!(*xdr_res)(&bufxdr, res)) { + return (0); + } + return (1); + +} + +/* + * Do the real work + */ +enum clnt_stat +multi_call( + unsigned naddrs, + struct in_addr *addrs, + u_long prognum, + u_long versnum, + u_long procnum, + xdrproc_t xdr_args, + void *argsvec, + unsigned argsize, + xdrproc_t xdr_res, + void *res, + int (*eachresult)(void *, struct sockaddr_in *, int), + int timeout + ) +{ + struct authunix_parms aup; + char credbuf[MAX_AUTH_BYTES]; + struct opaque_auth cred; + struct opaque_auth verf; + int gids[NGROUPS]; + int s; + struct timeval tv; + struct timeval subtimeout; + unsigned long long utimeout; + int callno; + int serverno; + struct rpc_msg call; + struct rpc_msg reply; + struct sockaddr_in sin; + struct sockaddr_in from; + int fromsize; + char buf[UDPMSGSIZE]; + int buflen; + unsigned trans_id; + int dtablesize = getdtablesize(); + XDR xdr; + int sendlen; + fd_set fds; + + /* + * Fill in Unix auth stuff + */ + aup.aup_time = time(0); + aup.aup_machname = get_hostname(); + aup.aup_uid = getuid(); + aup.aup_gid = getgid(); + aup.aup_gids = gids; + aup.aup_len = getgroups(NGROUPS, aup.aup_gids); + + /* + * Encode unix auth + */ + xdrmem_create(&xdr, credbuf, sizeof(credbuf), XDR_ENCODE); + if (!xdr_authunix_parms(&xdr, &aup)) { + return (RPC_CANTENCODEARGS); + } + cred.oa_flavor = AUTH_UNIX; + cred.oa_base = credbuf; + cred.oa_length = xdr_getpos(&xdr); + + verf.oa_flavor = AUTH_NULL; + verf.oa_length = 0; + + /* + * Set up call header information + */ + trans_id = time(0) ^ getpid(); + call.rm_xid = trans_id; + call.rm_direction = CALL; + call.rm_call.cb_rpcvers = 2; + call.rm_call.cb_prog = PMAPPROG; + call.rm_call.cb_vers = PMAPVERS; + call.rm_call.cb_proc = PMAPPROC_CALLIT; + call.rm_call.cb_cred = cred; + call.rm_call.cb_verf = verf; + + + /* + * Open socket + */ + socket_lock(); + s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + socket_unlock(); + if (s < 0) { + syslog(LOG_ERR, "multi_call: socket: %m"); + return (RPC_FAILED); + } + + /* + * Init timeouts + */ + utimeout = ((unsigned long long) timeout) * USECS_PER_SEC; + subtimeout.tv_sec = (utimeout >> NRETRIES) / USECS_PER_SEC; + subtimeout.tv_usec = (utimeout >> NRETRIES) % USECS_PER_SEC; + tv = subtimeout; + + /* + * Init address info + */ + sin.sin_family = AF_INET; + sin.sin_port = htons(PMAPPORT); + bzero(sin.sin_zero, sizeof(sin.sin_zero)); + + for (callno = 0; callno <= NRETRIES; callno++) { + /* + * Send a call message to each host with the appropriate args + */ + for (serverno = 0; serverno < naddrs; serverno++) { + call.rm_xid = trans_id + serverno; + buflen = encodemsg(buf, sizeof(buf), &call, + prognum, versnum, procnum, + xdr_args, (argsvec + + (serverno * argsize))); + if (buflen == 0) { + /* + * Encode failed + */ + continue; + } + sin.sin_addr = addrs[serverno]; + sendlen = sendto(s, buf, buflen, 0, + (struct sockaddr *)&sin, sizeof(sin)); + if (sendlen != buflen) { + syslog(LOG_ERR, + "Cannot send multicall packet to %s: %m", + inet_ntoa(addrs[serverno])); + } + } + + /* + * Double the timeout from previous timeout, if necessary + */ + if (callno > 1) { + tv.tv_sec *= 2; + tv.tv_usec *= 2; + if (tv.tv_usec >= USECS_PER_SEC) { + tv.tv_usec -= USECS_PER_SEC; + tv.tv_sec++; + } + } + + +#ifdef NETINFOD + /* + * Check for cancel by user + */ + if (alert_aborted()) { + socket_lock(); + close(s); + socket_unlock(); + return (RPC_FAILED); + } +#endif + /* + * Wait for reply + */ + FD_ZERO(&fds); + FD_SET(s, &fds); + switch (select(dtablesize, &fds, NULL, NULL, &tv)) { + case -1: + syslog(LOG_ERR, "select failure: %m"); + continue; + case 0: + continue; + default: + break; + } + + /* + * Receive packet + */ + fromsize = sizeof(from); + buflen = recvfrom(s, buf, sizeof(buf), 0, + (struct sockaddr *)&from, &fromsize); + if (buflen < 0) { + continue; + } + + /* + * Decode packet and if no errors, call eachresult + */ + xdrmem_create(&xdr, buf, buflen, XDR_DECODE); + reply.rm_reply.rp_acpt.ar_results.proc = xdr_void; + reply.rm_reply.rp_acpt.ar_results.where = NULL; + if (xdr_replymsg(&xdr, &reply) && + (reply.rm_xid >= trans_id) && + (reply.rm_xid < trans_id + naddrs) && + (reply.rm_reply.rp_stat == MSG_ACCEPTED) && + (reply.acpted_rply.ar_stat == SUCCESS) && + decodemsg(&xdr, xdr_res, res)) { + if ((*eachresult)(res, &from, + reply.rm_xid - trans_id)) { + xdr_free(xdr_res, res); + socket_lock(); + close(s); + socket_unlock(); + return (RPC_SUCCESS); + } + } + xdr_free(xdr_res, res); + } + socket_lock(); + close(s); + socket_unlock(); + return (RPC_TIMEDOUT); +} + + + + diff --git a/netinfo.subproj/ni.h b/netinfo.subproj/ni.h new file mode 100644 index 0000000..6de58bc --- /dev/null +++ b/netinfo.subproj/ni.h @@ -0,0 +1,124 @@ +/* + * 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@ + */ +/* + * NetInfo library entry points + * Copyright (C) 1989 by NeXT, Inc. + */ + +#ifndef __NI_HEADER__ +#define __NI_HEADER__ + +#ifndef SUN_RPC +#define SUN_RPC 1 +#endif + +#include +#include +#include +typedef const char *ni_name_const; +#include + +/* + * Define some shortcuts + */ +#define ninl_len ni_namelist_len +#define ninl_val ni_namelist_val + +#define nipl_len ni_proplist_len +#define nipl_val ni_proplist_val + +#define niil_len ni_idlist_len +#define niil_val ni_idlist_val + +#define niel_len ni_entrylist_len +#define niel_val ni_entrylist_val + +#define nipll_len ni_proplist_list_len +#define nipll_val ni_proplist_list_val + +/* + * Arg struct for ni_fancyopen + */ +typedef struct ni_fancyopenargs { + int rtimeout; /* read timeout - 0 for default */ + int wtimeout; /* write timeout - 0 for default */ + int abort; /* give up on timeout or failure? */ + int needwrite; /* need to do writes on this handle? */ +} ni_fancyopenargs; + + +void *ni_new(void *, const char *); +void *ni_connect(struct sockaddr_in *, const char *); +ni_status ni_addrtag(void *, struct sockaddr_in *, ni_name *); +void ni_free(void *); +const char *ni_error(ni_status); + +ni_status ni_statistics(void *, ni_proplist *); +ni_status ni_root(void *, ni_id *); +ni_status ni_self(void *, ni_id *); +ni_status ni_parent(void *, ni_id *, ni_index *); + +ni_status ni_create(void *, ni_id *, ni_proplist, ni_id *, ni_index); +ni_status ni_destroy(void *, ni_id *, ni_id); + +ni_status ni_read(void *, ni_id *, ni_proplist *); +ni_status ni_write(void *, ni_id *, ni_proplist); + +ni_status ni_children(void *, ni_id *, ni_idlist *); +ni_status ni_list(void *, ni_id *, ni_name_const, ni_entrylist *); +ni_status ni_listall(void *, ni_id *, ni_proplist_list *); +ni_status ni_lookup(void *, ni_id *, ni_name_const, ni_name_const, + ni_idlist *); +ni_status ni_lookupread(void *, ni_id *, ni_name_const, ni_name_const, + ni_proplist *); +ni_status ni_lookupprop(void *, ni_id *, ni_name_const, ni_namelist *); +ni_status ni_renameprop(void *, ni_id *, ni_index, ni_name_const); +ni_status ni_listprops(void *, ni_id *, ni_namelist *); + +ni_status ni_createprop(void *, ni_id *, ni_property, ni_index); +ni_status ni_destroyprop(void *, ni_id *, ni_index); +ni_status ni_readprop(void *, ni_id *, ni_index, ni_namelist *); +ni_status ni_writeprop(void *, ni_id *, ni_index, ni_namelist); + +ni_status ni_createname(void *, ni_id *, ni_index, ni_name_const, ni_index); +ni_status ni_destroyname(void *, ni_id *, ni_index, ni_index); +ni_status ni_readname(void *, ni_id *, ni_index, ni_index, ni_name *); +ni_status ni_writename(void *, ni_id *, ni_index, ni_index, ni_name_const); + +ni_status ni_pathsearch(void *, ni_id *, ni_name_const); +ni_status ni_open(void *, ni_name_const, void **); +ni_status ni_fancyopen(void *, ni_name_const, void **, ni_fancyopenargs *); + +ni_status ni_pwdomain(void *, ni_name *); + +ni_status ni_resync(void *); + +ni_status ni_setuser(void *, ni_name_const); +ni_status ni_setpassword(void *, ni_name_const); +void ni_setreadtimeout(void *, int); +void ni_setwritetimeout(void *, int); +void ni_setabort(void *, int); +void ni_needwrite(void *, int); + +#endif __NI_HEADER__ \ No newline at end of file diff --git a/netinfo.subproj/ni_error.c b/netinfo.subproj/ni_error.c new file mode 100644 index 0000000..63aaff8 --- /dev/null +++ b/netinfo.subproj/ni_error.c @@ -0,0 +1,77 @@ +/* + * 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@ + */ +/* + * NetInfo error status -> string conversion. + * Copyright (C) 1989 by NeXT, Inc. + */ +#include + +static const struct { + ni_status status; + char *message; +} ni_errmsgs[] = { + { NI_OK, "Operation succeeded" }, + { NI_BADID, "ID is invalid" }, + { NI_STALE, "Write attempted on stale version of object" }, + { NI_NOSPACE, "No space available for write operation" }, + { NI_PERM, "Permission denied" }, + { NI_NODIR, "No such directory" }, + { NI_NOPROP, "No such property" }, + { NI_NONAME, "No such name" }, + { NI_NOTEMPTY, "Cannot delete name object with children" }, + { NI_UNRELATED, "Object is not child of parent: cannot destroy" }, + { NI_SERIAL, "Serialization error" }, + { NI_NETROOT, "Hit network root domain" }, + { NI_NORESPONSE, "No response from remote parent" }, + { NI_RDONLY, "No writes allowed: all objects are read-only" }, + { NI_SYSTEMERR, "Remote system error" }, + { NI_ALIVE, "Can't regenerate: already in use" }, + { NI_NOTMASTER, "Operation makes no sense on clone" }, + { NI_CANTFINDADDRESS, "Can't find address of server" }, + { NI_DUPTAG, "Duplicate domain tag: can't serve it" }, + { NI_NOTAG, "No such tag" }, + { NI_AUTHERROR, "Authentication error" }, + { NI_NOUSER, "No such user" }, + { NI_MASTERBUSY, "Master server is busy" }, + { NI_INVALIDDOMAIN, "Invalid domain" }, + { NI_BADOP, "Invalid operation on master" }, + { NI_FAILED, "Communication failure" } +}; + +#define NI_ERRMSGSZ (sizeof(ni_errmsgs)/sizeof(ni_errmsgs[0])) + +const char * +ni_error( + ni_status status + ) +{ + int i; + + for (i = 0; i < NI_ERRMSGSZ; i++) { + if (ni_errmsgs[i].status == status) { + return (ni_errmsgs[i].message); + } + } + return ("(unknown error)"); +} diff --git a/netinfo.subproj/ni_glue.c b/netinfo.subproj/ni_glue.c new file mode 100644 index 0000000..0a22e74 --- /dev/null +++ b/netinfo.subproj/ni_glue.c @@ -0,0 +1,2251 @@ +/* + * 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@ + */ +/* + * Glues the library routines to the stub routines + * Copyright (C) 1989 by NeXT, Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include "clib.h" + +#define NI_TIMEOUT_SHORT 5 /* 5 second timeout for transactions */ +#define NI_TIMEOUT_LONG 60 /* 60 second timeout for writes */ +#define NI_TRIES 5 /* number of retries per timeout (udp only) */ +#define NI_SLEEPTIME 4 /* 4 second sleeptime, in case of errors */ +#define NI_MAXSLEEPTIME 64 /* 64 second max sleep time */ +#define NI_MAXCONNTRIES 2 /* Try to form a connection twice before sleeping */ + +/* Hack for determining if an IP address is a broadcast address. -GRS */ +/* Note that addr is network byte order (big endian) - BKM */ + +#define IS_BROADCASTADDR(addr) (((unsigned char *) &addr)[0] == 0xFF) + +#ifndef INADDR_LOOPBACK +#define INADDR_LOOPBACK (u_long)0x7f000001 +#endif +#define debug(msg) syslog(LOG_ERR, msg) + +#define clnt_debug(ni, msg) /* do nothing */ + +typedef struct ni_private { + int naddrs; /* number of addresses */ + struct in_addr *addrs; /* addresses of servers - network byte order */ + int whichwrite; /* which one of the above is the master */ + ni_name *tags; /* tags of servers */ + int pid; /* pid, to detect forks */ + int tsock; /* tcp socket */ + int tport; /* tcp local port name - host byte order */ + CLIENT *tc; /* tcp client */ + long tv_sec; /* timeout for this call */ + long rtv_sec; /* read timeout - 0 if default */ + long wtv_sec; /* write timeout - 0 if default */ + int abort; /* abort on timeout? */ + int needwrite; /* need to lock writes? */ + int uid; /* user id */ + ni_name passwd; /* password */ +} ni_private; + +#define NIP(ni) ((ni_private *)(ni)) + +static const ni_name NAME_NAME = "name"; +static const ni_name NAME_SERVES = "serves"; +static const ni_name NAME_MACHINES = "machines"; +static const ni_name NAME_IP_ADDRESS = "ip_address"; +static const ni_name NAME_MASTER = "master"; +static const ni_name NAME_USERS = "users"; +static const ni_name NAME_UID = "uid"; + +typedef struct getreg_stuff { + nibind_getregister_res res; + ni_private *ni; +} getreg_stuff; + + +static int socket_open(struct sockaddr_in *raddr, int, int, int, int, int); + + +/* + * Keep track of our port, in case somebody closes our socket + * on us. + */ +static int +getmyport( + int sock + ) +{ + struct sockaddr_in sin; + int sinlen; + + sinlen = sizeof(sin); + if (getsockname(sock, (struct sockaddr *)&sin, &sinlen) == 0) { + if (sin.sin_port == 0) { + (void)bind(sock, (struct sockaddr *)&sin, sizeof(sin)); + sinlen = sizeof(sin); + (void)getsockname(sock, (struct sockaddr *)&sin, + &sinlen); + } + return (ntohs(sin.sin_port)); + } + return (-1); +} + + +/* + * Is the NetInfo binder running? + */ +static int +nibind_up( + ni_private *ni + ) +{ + int sock; + struct sockaddr_in sin; + int res; + + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sock < 0) { + return (0); + } + sin.sin_family = AF_INET; + sin.sin_port = htons(PMAPPORT); + sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + bzero(sin.sin_zero, sizeof(sin.sin_zero)); + res = connect(sock, (struct sockaddr *)&sin, sizeof(sin)); + close(sock); + if (res != 0) { + return (0); + } + sin.sin_port = htons(pmap_getport(&sin, NIBIND_PROG, NIBIND_VERS, + IPPROTO_TCP)); + if (sin.sin_port == 0) { + return (0); + } + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sock < 0) { + return (0); + } + res = connect(sock, (struct sockaddr *)&sin, sizeof(sin)); + close(sock); + return (res == 0); +} + + +static void +createauth( + ni_private *ni + ) +{ + if (ni->passwd != NULL && ni->tc != NULL) { + auth_destroy(ni->tc->cl_auth); + ni->tc->cl_auth = authunix_create(ni->passwd, ni->uid, 0, 0, + NULL); + } +} + + +static void +fixtimeout( + struct timeval *tv, + long sec, + int tries + ) +{ + tv->tv_sec = sec / tries; + tv->tv_usec = ((sec % tries) * 1000000) / tries; +} + + +static void +ni_settimeout( + ni_private *ni, + int timeout + ) +{ + struct timeval tv; + + tv.tv_sec = timeout; + tv.tv_usec = 0; + ni->tv_sec = timeout; + if (ni->tc != NULL) { + clnt_control(ni->tc, CLSET_TIMEOUT, &tv); + } +} + + +/* + * Connect to a given address/tag + */ +static int +connectit( + ni_private *ni + ) +{ + struct sockaddr_in sin; + int sock; + CLIENT *cl; + struct timeval tv; + enum clnt_stat stat; + nibind_getregister_res res; + + bzero(&sin, sizeof(sin)); + sin.sin_port = 0; + sin.sin_family = AF_INET; + sin.sin_addr = ni->addrs[0]; + ni_settimeout(ni, ni->rtv_sec == 0 ? NI_TIMEOUT_SHORT : ni->rtv_sec); + fixtimeout(&tv, ni->tv_sec, NI_TRIES); + sock = socket_open(&sin, NIBIND_PROG, NIBIND_VERS, ni->tv_sec, + NI_TRIES, IPPROTO_UDP); + if (sock < 0) { + return (0); + } + cl = clntudp_create(&sin, NIBIND_PROG, NIBIND_VERS, tv, + &sock); + if (cl == NULL) { + close(sock); + return (0); + } + tv.tv_sec = ni->rtv_sec == 0 ? NI_TIMEOUT_SHORT : ni->rtv_sec; + tv.tv_usec = 0; + stat = clnt_call(cl, NIBIND_GETREGISTER, xdr_ni_name, &ni->tags[0], + xdr_nibind_getregister_res, &res, tv); + clnt_destroy(cl); + close(sock); + if (stat != RPC_SUCCESS || res.status != NI_OK) { + return (0); + } + + /* + * Found the address, now connect to it. + */ + sin.sin_port = htons(res.nibind_getregister_res_u.addrs.tcp_port); + sock = socket_open(&sin, NI_PROG, NI_VERS, ni->tv_sec, NI_TRIES, + IPPROTO_TCP); + if (sock < 0) { + return (0); + } + cl = clnttcp_create(&sin, NI_PROG, NI_VERS, &sock, 0, 0); + if (cl == NULL) { + close(sock); + return (0); + } + clnt_control(cl, CLSET_TIMEOUT, &tv); + ni->tc = cl; + ni->tsock = sock; + ni->tport = getmyport(sock); + createauth(ni); + (void) fcntl(ni->tsock, F_SETFD, 1); + return (1); +} + + +void +ni_setabort( + void *ni, + int abort + ) +{ + ((ni_private *)ni)->abort = abort; +} + + +void +ni_setwritetimeout( + void *ni, + int timeout + ) +{ + ((ni_private *)ni)->wtv_sec = timeout; +} + + +void +ni_setreadtimeout( + void *ni, + int timeout + ) +{ + ((ni_private *)ni)->rtv_sec = timeout; +} + + +void +ni_needwrite( + void *ni, + int needwrite + ) +{ + ((ni_private *)ni)->needwrite = needwrite; +} + + +static unsigned long +sys_netmask(void) +{ + struct ifconf ifc; + struct ifreq *ifr; + char buf[1024]; /* XXX */ + int i, len, ifreq_size, offset, sockaddr_size, size; + int sock; + struct sockaddr_in *sin; + unsigned long n_addr; + + sock = socket(AF_INET, SOCK_DGRAM, 0); + + if (sock < 0) return (htonl(IN_CLASSA_NET)); + + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = buf; + + if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) + { + close(sock); + return (htonl(IN_CLASSA_NET)); + } + + ifreq_size = sizeof(struct ifreq); + sockaddr_size = sizeof(struct sockaddr); + + offset = 0; + len = ifc.ifc_len / ifreq_size; + for (i = 0; i < len; i++) + { + ifr = (struct ifreq *)(ifc.ifc_buf + offset); + offset += IFNAMSIZ; + offset += sockaddr_size; + + size = ifr->ifr_addr.sa_len; + if (size > sockaddr_size) offset += (size - sockaddr_size); + + if (ifr->ifr_addr.sa_family != AF_INET) continue; + if (ioctl(sock, SIOCGIFFLAGS, (char *)ifr) < 0) continue; + + sin = (struct sockaddr_in *)&ifr->ifr_addr; + if ((ifr->ifr_flags & IFF_UP) && + !(ifr->ifr_flags & IFF_LOOPBACK) && + (sin->sin_addr.s_addr != 0)) + { + ioctl(sock, SIOCGIFNETMASK, (char *)ifr); + n_addr = ((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr; + close(sock); + return (n_addr); + } + } + + close(sock); + return (htonl(IN_CLASSA_NET)); +} + + +static unsigned long +sys_address(void) +{ + struct ifconf ifc; + struct ifreq *ifr; + char buf[1024]; /* XXX */ + int i, len, ifreq_size, offset, sockaddr_size, size; + int sock; + + sock = socket(AF_INET, SOCK_DGRAM, 0); + + if (sock < 0) + { + return (htonl(INADDR_LOOPBACK)); + } + + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = buf; + + if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) + { + close(sock); + return (htonl(INADDR_LOOPBACK)); + } + + ifreq_size = sizeof(struct ifreq); + sockaddr_size = sizeof(struct sockaddr); + + offset = 0; + len = ifc.ifc_len / ifreq_size; + for (i = 0; i < len; i++) + { + ifr = (struct ifreq *)(ifc.ifc_buf + offset); + offset += IFNAMSIZ; + offset += sockaddr_size; + + size = ifr->ifr_addr.sa_len; + if (size > sockaddr_size) offset += (size - sockaddr_size); + + if (ifr->ifr_addr.sa_family != AF_INET) continue; + if (ioctl(sock, SIOCGIFFLAGS, ifr) < 0) continue; + + if ((ifr->ifr_flags & IFF_UP) && (!(ifr->ifr_flags & IFF_LOOPBACK))) + { + close(sock); + return (((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr); + } + } + + close(sock); + return (htonl(INADDR_LOOPBACK)); +} + + +/* + * Returns a client handle to the NetInfo server, if it's running + */ +static int +connectlocal(ni_private *ni) +{ + int printed = 0; + + if (!nibind_up(ni)) { + return (0); + } + ni->naddrs = 1; + ni->addrs = (struct in_addr *)malloc(sizeof(struct in_addr)); + ni->addrs[0].s_addr = htonl(INADDR_LOOPBACK); + ni->tags = (ni_name *)malloc(sizeof(ni_name)); + ni->tags[0] = ni_name_dup("local"); + ni->whichwrite = 0; + while (!connectit(ni)) { + if (!printed) { + syslog(LOG_ERR, "NetInfo timeout connecting to local domain, sleeping"); + printed++; + } + sleep(NI_SLEEPTIME); + /* wait forever */ + } + if (printed) { + syslog(LOG_ERR, "NetInfo connection to local domain waking"); + } + return (1); +} + + +/* + * Destroy the client handle + */ +static void +clnt_kill( + CLIENT *cl, + int sock, + int port + ) +{ + int save = 0; + + if (sock >= 0 && getmyport(sock) != port) { + /* + * Somebody else has the descriptor open. Do not close it, + * it's not ours. + */ + save++; + } + if (cl != NULL) { + auth_destroy(cl->cl_auth); + clnt_destroy(cl); + } + if (!save) { + /* + * It's ours and we can close it + */ + (void)close(sock); + } +} + + +/* + * Reinitialize everything + */ +static void +reinit( + ni_private *ni + ) +{ + if (ni->tc != NULL) { + clnt_kill(ni->tc, ni->tsock, ni->tport); + ni->tc = NULL; + } + ni->tsock = -1; + ni->tport = -1; + ni->pid = getpid(); +} + + +/* + * Switch to a new server + */ +static void +ni_switch( + ni_private *ni, + ni_index which + ) +{ + struct in_addr tmp_addr; + ni_name tmp_tag; + + if (which == 0) { + return; + } + reinit(ni); + tmp_addr = ni->addrs[0]; + tmp_tag = ni->tags[0]; + + ni->addrs[0] = ni->addrs[which]; + ni->tags[0] = ni->tags[which]; + + ni->addrs[which] = tmp_addr; + ni->tags[which] = tmp_tag; + + if (ni->whichwrite == 0) { + ni->whichwrite = which; + } + else if (ni->whichwrite == which) { + ni->whichwrite = 0; + } +} + + +/* + * Swap two servers' positions + */ +static void +ni_swap( + ni_private *ni, + ni_index a, + ni_index b + ) +{ + struct in_addr tmp_addr; + ni_name tmp_tag; + + tmp_addr = ni->addrs[a]; + tmp_tag = ni->tags[a]; + + ni->addrs[a] = ni->addrs[b]; + ni->tags[a] = ni->tags[b]; + + ni->addrs[b] = tmp_addr; + ni->tags[b] = tmp_tag; + + if (ni->whichwrite == a) { + ni->whichwrite = b; + } + else if (ni->whichwrite == b) { + ni->whichwrite = a; + } +} + + +/* + * Callback routine for multi_call + * XXX: should save returned port numbers + */ +static bool_t +eachresult( + void *vstuff, + struct sockaddr_in *sin, + int which + ) +{ + getreg_stuff *stuff = (getreg_stuff *)vstuff; + + if (stuff->res.status != NI_OK) { + return (FALSE); + } + ni_switch(stuff->ni, which); + return (TRUE); +} + + +static int +rebind( + ni_private *ni + ) +{ + enum clnt_stat stat; + getreg_stuff stuff; + int sleeptime = NI_SLEEPTIME; + int printed = 0; + int nlocal; + int nnetwork; + unsigned long myaddr; + unsigned long mynetmask; + unsigned long mynetwork; + int i; + + if (ni->naddrs == 1) { + ni->whichwrite = 0; + return (1); + } + + /* + * Majka - 1994.04.27 + * re-order the servers so that: + * servers on the local host are at the start of the list, then + * servers on the local network are next, then + * all other servers are next + */ + + myaddr = sys_address(); + mynetmask = sys_netmask(); + mynetwork = myaddr & mynetmask; + + /* + * move local servers to the head of the list + */ + nlocal = 0; + for (i = nlocal; i < ni->naddrs; i++) { + if ((ni->addrs[i].s_addr == myaddr) || + (ni->addrs[i].s_addr == htonl(INADDR_LOOPBACK))) + { + ni_swap(ni, nlocal, i); + nlocal++; + } + } + + /* + * move servers on this network to follow local servers + */ + nnetwork = nlocal; + for (i = nnetwork; i < ni->naddrs; i++) { + if (((ni->addrs[i].s_addr & mynetmask) == mynetwork) || + IS_BROADCASTADDR(ni->addrs[i].s_addr)) + { + ni_swap(ni, nnetwork, i); + nnetwork++; + } + } + + stuff.ni = ni; + for (;;) { + /* + * call local servers first + */ + if (nlocal > 0) { + for (i = 0; i < nlocal; i++) { + syslog(LOG_DEBUG, "NetInfo connect call to: %s/%s (local %d)", + inet_ntoa(ni->addrs[i]), ni->tags[i], i); + } + stat = multi_call(nlocal, ni->addrs, + NIBIND_PROG, NIBIND_VERS, NIBIND_GETREGISTER, + xdr_ni_name, ni->tags, + sizeof(ni_name), + xdr_nibind_getregister_res, + &stuff, eachresult, + NI_TIMEOUT_SHORT); + if (stat == RPC_SUCCESS) { + break; + } + } + + /* + * call local servers and this network's servers + */ + if (nnetwork > nlocal) { + for (i = 0; i < nnetwork; i++) { + syslog(LOG_DEBUG, "NetInfo connect call to: %s/%s (network %d)", + inet_ntoa(ni->addrs[i]), ni->tags[i], i); + } + stat = multi_call(nnetwork, ni->addrs, + NIBIND_PROG, NIBIND_VERS, NIBIND_GETREGISTER, + xdr_ni_name, ni->tags, + sizeof(ni_name), + xdr_nibind_getregister_res, + &stuff, eachresult, + NI_TIMEOUT_SHORT); + if (stat == RPC_SUCCESS) { + break; + } + } + + /* + * call all servers + */ + for (i = 0; i < ni->naddrs; i++) { + syslog(LOG_DEBUG, "NetInfo connect call to: %s/%s (world %d)", + inet_ntoa(ni->addrs[i]), ni->tags[i], i); + } + stat = multi_call(ni->naddrs, + ni->addrs, NIBIND_PROG, NIBIND_VERS, + NIBIND_GETREGISTER, + xdr_ni_name, ni->tags, + sizeof(ni_name), + xdr_nibind_getregister_res, + &stuff, eachresult, + ni->rtv_sec == 0 ? NI_TIMEOUT_SHORT : ni->rtv_sec); + if (stat == RPC_SUCCESS) { + break; + } + + if (ni->abort) { + return (0); + } + if (!printed) { + if (ni->whichwrite >= 0) { + syslog(LOG_ERR, + "NetInfo connect timeout (domain with master %s/%s), sleeping", + inet_ntoa(ni->addrs[ni->whichwrite]), ni->tags[ni->whichwrite]); + } + else { + syslog(LOG_ERR, "NetInfo connect timeout (domain with server %s/%s), sleeping", + inet_ntoa(ni->addrs[0]), ni->tags[0]); + } + printed++; + } + sleep(sleeptime); + if (sleeptime < NI_MAXSLEEPTIME) { + sleeptime *= 2; /* backoff */ + } + } + + syslog(LOG_INFO, "NetInfo connected to %s/%s", inet_ntoa(ni->addrs[0]), ni->tags[0]); + + if (printed) { + syslog(LOG_ERR, "NetInfo connected to %s/%s", inet_ntoa(ni->addrs[0]), ni->tags[0]); + } + return (1); +} + + +/* + * Confirm that our tcp socket is still valid + */ +static int +confirm_tcp( + ni_private *ni, + int needwrite + ) +{ + if (ni->tsock != -1) { + if (getmyport(ni->tsock) == ni->tport) { + return (1); + } + /* + * Somebody closed our socket. Do not close it, it could + * be owned by somebody else now. + */ + auth_destroy(ni->tc->cl_auth); + clnt_destroy(ni->tc); + ni->tc = NULL; + } + if (!needwrite && !rebind(ni) && ni->abort) { + return (0); + } + return (connectit(ni)); +} + + +static int +setmaster( + ni_private *ni + ) +{ + ni_id root; + ni_namelist nl; + ni_name sep; + ni_idlist idl; + ni_name master; + ni_index i; + ni_index j; + ni_id id; + struct in_addr addr; + int needwrite; + + if (ni->naddrs == 1) { + /* + * One server - must be the master + */ + ni->whichwrite = 0; + return (1); + } + needwrite = ni->needwrite; + ni->needwrite = 0; + if (ni_root(ni, &root) != NI_OK) { + ni->needwrite = needwrite; + return (0); + } + if (ni_lookupprop(ni, &root, NAME_MASTER, &nl) != NI_OK) { + ni->needwrite = needwrite; + return (0); + } + if (nl.ninl_len == 0) { + ni->needwrite = needwrite; + return (0); + } + sep = index(nl.ninl_val[0], '/'); + if (sep == NULL) { + ni->needwrite = needwrite; + return (0); + } + *sep++ = 0; + master = nl.ninl_val[0]; + if (ni_lookup(ni, &root, NAME_NAME, NAME_MACHINES, &idl) != NI_OK) { + ni->needwrite = needwrite; + ni_namelist_free(&nl); + return (0); + } + if (idl.niil_len < 1) { + ni->needwrite = needwrite; + return (0); + } + id.nii_object = idl.niil_val[0]; + ni_idlist_free(&idl); + if (ni_lookup(ni, &id, NAME_NAME, master, &idl) != NI_OK) { + ni_namelist_free(&nl); + ni->needwrite = needwrite; + return (0); + } + ni_namelist_free(&nl); + if (idl.niil_len < 1) { + ni->needwrite = needwrite; + return (0); + } + id.nii_object = idl.niil_val[0]; + ni_idlist_free(&idl); + if (ni_lookupprop(ni, &id, NAME_IP_ADDRESS, &nl) != NI_OK) { + return (0); + } + for (i = 0; i < nl.ninl_len; i++) { + addr.s_addr = inet_addr(nl.ninl_val[i]); + for (j = 0; j < ni->naddrs; j++) { + if (addr.s_addr == ni->addrs[j].s_addr) { + ni->whichwrite = j; + ni_namelist_free(&nl); + ni->needwrite = needwrite; + return (1); + } + } + } + ni->needwrite = needwrite; + ni_namelist_free(&nl); + return (0); +} + + +static void * +callit( + ni_private *ni, + void *(*stub)(), + void *args, + int needwrite + ) +{ + void *resp; + struct rpc_err err; + int i; + int sleeptime = 0; + int printed = 0; + + if (getpid() != ni->pid) { + reinit(ni); + } + if (needwrite || ni->needwrite) { + if (ni->whichwrite >= 0) { + ni_switch(ni, ni->whichwrite); + } else { + if (!setmaster(ni)) { + return (NULL); + } + ni_switch(ni, ni->whichwrite); + } + if (!needwrite) { + ni_settimeout(ni, (ni->rtv_sec == 0 ? + NI_TIMEOUT_SHORT : ni->rtv_sec)); + needwrite = 1; + } else { + ni_settimeout(ni, (ni->wtv_sec == 0 ? + NI_TIMEOUT_LONG : ni->wtv_sec)); + } + } else { + ni_settimeout(ni, (ni->rtv_sec == 0 ? + NI_TIMEOUT_SHORT : ni->rtv_sec)); + } + for (;;) { + /* + * Try more than once, in case server closed connection. + */ + for (i = 0; i < NI_MAXCONNTRIES; i++) { + if (!confirm_tcp(ni, needwrite)) { + break; + } + if ((resp = (*stub)(args, ni->tc)) != NULL) { + if (printed) { + syslog(LOG_ERR, "NetInfo connected to %s/%s", + inet_ntoa(ni->addrs[0]), ni->tags[0]); + } + return (resp); + } + clnt_geterr(ni->tc, &err); + if (err.re_status != RPC_CANTRECV) { + break; + } + if (i + 1 < NI_MAXCONNTRIES) { + /* + * Server closed connection. Reinit and try + * again. + */ + reinit(ni); + } + } + if (err.re_status == RPC_PROCUNAVAIL) { + return (NULL); + } + if (needwrite || ni->abort) { + /* + * We time out for writes or if it is explicitly + * requested. + */ + if (ni->abort) { + reinit(ni); + } + syslog(LOG_ERR, + "NetInfo connection failed for server %s/%s", + inet_ntoa(ni->addrs[0]), ni->tags[0]); + return (NULL); + } + if (!printed) { + if (ni->tc != NULL) { + if (!(sleeptime == 0 && + err.re_status == RPC_TIMEDOUT)) { + /* + * Do not print message on + * first timeout. It is likely + * we will find another server soon. + * Let's not needlessly alarm the + * poor user! + */ + syslog(LOG_ERR, "%s on connection to %s/%s", + clnt_sperror(ni->tc,"NetInfo connection timeout"), + inet_ntoa(ni->addrs[0]), ni->tags[0]); + printed++; + } + else { + /* first attempt failed */ + syslog(LOG_ERR, "%s on initial connection to %s/%s", + clnt_sperror(ni->tc,"NetInfo connection timeout"), + inet_ntoa(ni->addrs[0]), ni->tags[0]); + } + } else { + syslog(LOG_ERR, + "NetInfo connection failed for server %s/%s", + inet_ntoa(ni->addrs[0]), ni->tags[0]); + printed++; + } + } + if (sleeptime > 0) { + sleep(sleeptime); + if (sleeptime < NI_MAXSLEEPTIME) { + sleeptime *= 2; /* backoff */ + } + } else { + /* + * Do not sleep on the first timeout. + * It is likely we will find another server quickly. + */ + sleeptime = NI_SLEEPTIME; + } + reinit(ni); + (void)rebind(ni); + } +} + + +#define RCALLIT(a, b, c) callit((ni_private *)(a), (void *(*)())(b), \ + (void *)c, 0) + + +#define WCALLIT(a, b, c) callit((ni_private *)(a), (void *(*)())(b), \ + (void *)c, 1) + + +static void +ni_clear( + ni_private *ni + ) +{ + ni->needwrite = 0; + ni->naddrs = 0; + ni->addrs = NULL; + ni->tags = NULL; + ni->tc = NULL; + ni->tsock = -1; + ni->tport = -1; + ni->whichwrite = -1; + ni->passwd = NULL; +} + + +static void * +ni_alloc( + void + ) +{ + ni_private *ni; + + ni = (ni_private *)malloc(sizeof(*ni)); + ni->naddrs = 0; + ni->whichwrite = -1; + ni->pid = getpid(); + ni->tsock = -1; + ni->tport = -1; + ni->tc = NULL; + ni->tv_sec = NI_TIMEOUT_SHORT; + ni->rtv_sec = 0; + ni->wtv_sec = 0; + ni->abort = 0; + ni->passwd = NULL; + ni->uid = getuid(); + ni->needwrite = 0; + return ((void *)ni); +} + + +void * +_ni_dup( + void *ni + ) +{ + ni_private *dupni; + ni_index i; + + dupni = (ni_private *)ni_alloc(); + *dupni = *NIP(ni); + ni_clear(dupni); + dupni->naddrs = NIP(ni)->naddrs; + dupni->whichwrite = NIP(ni)->whichwrite; + if (dupni->naddrs > 0) { + dupni->addrs = ((struct in_addr *) + malloc(NIP(ni)->naddrs * sizeof(struct in_addr))); + bcopy(NIP(ni)->addrs, dupni->addrs, + NIP(ni)->naddrs * sizeof(struct in_addr)); + dupni->tags = ((ni_name *) + malloc(NIP(ni)->naddrs * sizeof(ni_name))); + for (i = 0; i < NIP(ni)->naddrs; i++) { + dupni->tags[i] = ni_name_dup(NIP(ni)->tags[i]); + } + } + if (NIP(ni)->passwd != NULL) { + dupni->passwd = ni_name_dup(NIP(ni)->passwd); + } + return ((void *)dupni); +} + + +static int +match( + ni_name domain, + ni_name domtag, + ni_name *tag + ) +{ + int len = strlen(domain); + ni_name sep; + + sep = index(domtag, '/'); + if (sep == NULL) { + return (0); + } + if (strncmp(domain, domtag, len) == 0 && + domtag[len] == '/') { + *tag = ni_name_dup(sep + 1); + return (1); + } + return (0); +} + + +static int +addaddr( + void *ni, + ni_index ido, + ni_name tag, + ni_private *target_ni + ) +{ + ni_id id; + ni_namelist nl; + struct in_addr addr; + int i; + + id.nii_object = ido; + if (ni_lookupprop(ni, &id, NAME_IP_ADDRESS, &nl) != NI_OK) { + return (0); + } + if (nl.ninl_len == 0) { + return(0); + } + + if (target_ni->naddrs == 0) { + target_ni->addrs = + (struct in_addr *)malloc(nl.ninl_len * sizeof(struct in_addr)); + target_ni->tags = + (ni_name *)malloc(nl.ninl_len * sizeof(ni_name)); + } else { + target_ni->addrs = + (struct in_addr *)realloc(target_ni->addrs, + ((target_ni->naddrs + nl.ninl_len) * sizeof(struct in_addr))); + target_ni->tags = + (ni_name *)realloc(target_ni->tags, + ((target_ni->naddrs + nl.ninl_len) * sizeof(ni_name))); + } + + for (i=0; iaddrs[target_ni->naddrs] = addr; + target_ni->tags[target_ni->naddrs] = ni_name_dup(tag); + target_ni->naddrs++; + } + + ni_namelist_free(&nl); + return (1); +} + + +static int +get_daddr( + ni_private *ni, + ni_name dom, + ni_private *target_ni + ) +{ + ni_id id; + ni_idlist ids; + ni_namelist nl; + ni_entrylist entries; + ni_index i; + ni_index j; + ni_name tag; + + if (ni_root(ni, &id) != NI_OK) { + return(0); + } + + if (ni_lookup(ni, &id, NAME_NAME, NAME_MACHINES, &ids) != NI_OK) { + return (0); + } + + id.nii_object = ids.niil_val[0]; + ni_idlist_free(&ids); + + if (ni_list(ni, &id, NAME_SERVES, &entries) != NI_OK) { + return (0); + } + + for (i = 0; i < entries.niel_len; i++) { + if (entries.niel_val[i].names != NULL) { + nl = *entries.niel_val[i].names; + for (j = 0; j < nl.ninl_len; j++) { + if (match(dom, nl.ninl_val[j], &tag)) { + if (addaddr(ni, + entries.niel_val[i].id, + tag, + target_ni)) { + ni_name_free(&tag); + break; + } + ni_name_free(&tag); + } + } + } + + } + ni_entrylist_free(&entries); + return (target_ni->naddrs > 0); +} + + +#ifdef notdef +static int +get_haddr( + ni_private *ni, + ni_name hname, + ni_name tag, + ni_private *target_ni + ) +{ + ni_id id; + ni_idlist ids; + + if (ni_root(ni, &id) != NI_OK) { + return(0); + } + if (ni_lookup(ni, &id, NAME_NAME, NAME_MACHINES, &ids) != NI_OK) { + return (0); + } + id.nii_object = ids.niil_val[0]; + ni_idlist_free(&ids); + + if (ni_lookup(ni, &id, NAME_NAME, hname, &ids) != NI_OK) { + return (0); + } + id.nii_object = ids.niil_val[0]; + ni_idlist_free(&ids); + if (!addaddr(ni, id.nii_object, tag, target_ni)) { + return (0); + } + return (1); +} +#endif + + +static ni_status +getparent(ni_private *oldni, ni_private **newni) +{ + ni_rparent_res *resp; + ni_private *ni; + ni_private *dupni; + int found; + ni_index i; + struct in_addr raddr; + int printed = 0; + int inlist = 0; + + found = 0; + while (!found) { + /* + * First, find our parent, any parent + */ + for (;;) { + resp = RCALLIT(oldni, _ni_rparent_2, NULL); + if (resp == NULL) { + return (NI_FAILED); + } + if (resp->status != NI_NORESPONSE) { + break; + } + if (!printed) { + syslog(LOG_ERR, "NetInfo timeout finding server for parent of %s/%s, sleeping", + inet_ntoa(oldni->addrs[0]), oldni->tags[0]); + printed++; + } + sleep(NI_SLEEPTIME); + } + if (printed) { + raddr.s_addr = htonl(resp->ni_rparent_res_u.binding.addr); + + syslog(LOG_ERR, "NetInfo %s/%s found parent %s/%s", + inet_ntoa(oldni->addrs[0]), oldni->tags[0], + inet_ntoa(raddr), resp->ni_rparent_res_u.binding.tag); + } + if (resp->status != NI_OK) { + return (resp->status); + } + ni = ni_alloc(); + *ni = *oldni; + ni_clear(ni); + ni->naddrs = 1; + ni->addrs = (struct in_addr *)malloc(sizeof(struct in_addr)); + ni->addrs[0].s_addr=htonl(resp->ni_rparent_res_u.binding.addr); + ni->tags = (ni_name *)malloc(sizeof(ni_name)); + ni->tags[0] = ni_name_dup(resp->ni_rparent_res_u.binding.tag); + + xdr_free(xdr_ni_rparent_res, resp); + + dupni = ni; + ni = ni_alloc(); + *ni = *dupni; + ni_clear(ni); + if (get_daddr(dupni, ".", ni)) { + + /* + * Now make sure returned parent is head of + * list + */ + for (i = 0; i < ni->naddrs; i++) { + if (ni->addrs[i].s_addr == + dupni->addrs[0].s_addr) { + ni_switch(ni, i); + inlist++; + break; + } + } + + /* + * Reuse dupni client info + */ + ni->tsock = dupni->tsock; + ni->tport = dupni->tport; + ni->tc = dupni->tc; + dupni->tsock = -1; + dupni->tport = -1; + dupni->tc = NULL; + found++; + + /* + * If returned parent wasn't in list, it's a rogue. + * Log an error and drop the connection. + */ + if (inlist == 0) { + syslog(LOG_ERR, "Rogue NetInfo server detected: %s/%s", + inet_ntoa(dupni->addrs[0]), dupni->tags[0]); + reinit(ni); + } + + } + ni_free(dupni); + } + if (found) { + *newni = ni; + return (NI_OK); + } else { + ni_free(ni); + return (NI_FAILED); + } +} + + +void * +ni_connect( + struct sockaddr_in *sin, + const char *tag + ) +{ + void *ni; + + ni = ni_alloc(); + NIP(ni)->naddrs = 1; + NIP(ni)->addrs = (struct in_addr * + )malloc(sizeof(struct in_addr)); + NIP(ni)->addrs[0] = sin->sin_addr; + NIP(ni)->tags = (ni_name *)malloc(sizeof(ni_name)); + NIP(ni)->tags[0] = ni_name_dup(tag); + return (ni); +} + + +ni_status +ni_addrtag( + void *ni, + struct sockaddr_in *addr, + ni_name *tag + ) +{ + + if (!confirm_tcp(ni, 0)) { + return (NI_FAILED); + } + *tag = ni_name_dup(NIP(ni)->tags[0]); + addr->sin_addr = NIP(ni)->addrs[0]; + addr->sin_port = htons(NIP(ni)->tport); + addr->sin_family = AF_INET; + bzero(addr->sin_zero, sizeof(addr->sin_zero)); + return (NI_OK); +} + + +void * +ni_new( + void *oldni, + const char *domain + ) +{ + ni_private *ni; + ni_status status; + ni_name sep, addr, tag; + struct sockaddr_in sin; + struct hostent *he; + + if (oldni == NULL) { + ni = ni_alloc(); + if (!connectlocal(ni)) { + free(ni); + return (NULL); + } + if (strcmp(domain, "..") == 0) { + oldni = ni; + status = getparent((ni_private *)oldni, &ni); + ni_free(oldni); + if (status != NI_OK) { + return (NULL); + } + } else if ((sep = index(domain, '@')) != NULL) { + free(ni); + tag = strncpy((char *)malloc(sep-domain+1), domain, sep-domain); + tag[sep-domain] = '\0'; + addr = strcpy ((char *)malloc(strlen(sep+1)), sep+1); + sin.sin_addr.s_addr = inet_addr(addr); + if (sin.sin_addr.s_addr == INADDR_NONE) { + he = gethostbyname(addr); + if (he == NULL) { + free(addr); + free(tag); + return (NULL); + } + bcopy(he->h_addr_list[0], &sin.sin_addr.s_addr, he->h_length); + } + ni = ni_connect(&sin, tag); + free(addr); + free(tag); + } else if (strcmp(domain, ".") != 0) { + /* + * nothing else makes sense + */ + free(ni); + return (NULL); + } + } else { + if (strcmp(domain, "..") == 0) { + status = getparent((ni_private *)oldni, &ni); + if (status != NI_OK) { + return (NULL); + } + } else if ((sep = index(domain, '@')) != NULL) { + tag = strncpy((char *)malloc(sep-domain+1), domain, sep-domain); + tag[sep-domain] = '\0'; + addr = strcpy ((char *)malloc(strlen(sep+1)), sep+1); + sin.sin_addr.s_addr = inet_addr(addr); + if (sin.sin_addr.s_addr == INADDR_NONE) { + he = gethostbyname(addr); + if (he == NULL) { + free(addr); + free(tag); + return (NULL); + } + bcopy(he->h_addr_list[0], &sin.sin_addr.s_addr, he->h_length); + } + ni = ni_connect(&sin, tag); + free(addr); + free(tag); + } else { + ni = ni_alloc(); + *ni = *NIP(oldni); + ni_clear(ni); + if (!get_daddr(oldni, (ni_name)domain, ni)) { + ni_free(ni); + ni = NULL; + } + } + } + return ((void *)ni); +} + + +void +ni_free( + void *ni + ) +{ + ni_index i; + + if (NIP(ni)->tc != NULL) { + clnt_kill(NIP(ni)->tc, NIP(ni)->tsock, NIP(ni)->tport); + } + if (NIP(ni)->naddrs > 0) { + free(NIP(ni)->addrs); + for (i = 0; i < NIP(ni)->naddrs; i++) { + ni_name_free(&NIP(ni)->tags[i]); + } + free(NIP(ni)->tags); + } + if (NIP(ni)->passwd != NULL) { + ni_name_free(&NIP(ni)->passwd); + } + free(ni); +} + + +/* + * The rest of these are just wrappers that end up doing + * RPC calls to the local NetInfo server. + */ +ni_status +ni_statistics( + void *ni, + ni_proplist *pl + ) +{ + ni_proplist *resp; + + if ((resp = (ni_proplist *)RCALLIT(ni, _ni_statistics_2, NULL)) + == NULL) { + return (NI_FAILED); + } + *pl = *resp; + return (NI_OK); +} + + +ni_status +ni_root( + void *ni, + ni_id *id + ) +{ + ni_id_res *resp; + + if ((resp = RCALLIT(ni, _ni_root_2, id)) == NULL) { + clnt_debug(ni, "_ni_root"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *id = resp->ni_id_res_u.id; + } + return (resp->status); +} + + +ni_status +ni_self( + void *ni, + ni_id *id + ) +{ + ni_id_res *resp; + + if ((resp = RCALLIT(ni, _ni_self_2, id)) == NULL) { + clnt_debug(ni, "_ni_self"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *id = resp->ni_id_res_u.id; + } + return (resp->status); +} + + +ni_status +ni_parent( + void *ni, + ni_id *id, + ni_index *parent_id_p + ) +{ + ni_parent_res *resp; + + if ((resp = RCALLIT(ni, _ni_parent_2, id)) == NULL) { + clnt_debug(ni, "_ni_parent"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *parent_id_p = resp->ni_parent_res_u.stuff.object_id; + *id = resp->ni_parent_res_u.stuff.self_id; + } + return (resp->status); +} + + +ni_status +ni_children( + void *ni, + ni_id *id, + ni_idlist *children + ) +{ + ni_children_res *resp; + + if ((resp = RCALLIT(ni, _ni_children_2, id)) == NULL) { + clnt_debug(ni, "_ni_children"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *children = resp->ni_children_res_u.stuff.children; + *id = resp->ni_children_res_u.stuff.self_id; + } + return (resp->status); +} + + +ni_status +ni_create( + void *ni, + ni_id *parent_id, + ni_proplist pl, + ni_id *child_id_p, + ni_index where + ) +{ + ni_create_args args; + ni_create_res *resp; + + args.id = *parent_id; + args.props = pl; + args.where = where; + args.target_id = NULL; + if ((resp = WCALLIT(ni, _ni_create_2, &args)) == NULL) { + clnt_debug(ni, "_ni_create"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *child_id_p = resp->ni_create_res_u.stuff.id; + *parent_id = resp->ni_create_res_u.stuff.self_id; + } + return (resp->status); +} + + +ni_status +ni_destroy( + void *ni, + ni_id *parent_id, + ni_id self_id + ) +{ + ni_id_res *resp; + ni_destroy_args args; + + args.parent_id = *parent_id; + args.self_id = self_id; + if ((resp = WCALLIT(ni, _ni_destroy_2, &args)) == NULL) { + clnt_debug(ni, "_ni_destroy"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *parent_id = resp->ni_id_res_u.id; + } + return (resp->status); +} + + +ni_status +ni_write( + void *ni, + ni_id *self_id, + ni_proplist pl + ) +{ + ni_proplist_stuff args; + ni_id_res *resp; + + args.id = *self_id; + args.props = pl; + if ((resp = WCALLIT(ni, _ni_write_2, &args)) == NULL) { + clnt_debug(ni, "_ni_write"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *self_id = resp->ni_id_res_u.id; + } + return (resp->status); +} + + +ni_status +ni_read( + void *ni, + ni_id *self_id, + ni_proplist *pl + ) +{ + ni_proplist_res *resp; + + if ((resp = RCALLIT(ni, _ni_read_2, self_id)) == NULL) { + clnt_debug(ni, "_ni_read"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *self_id = resp->ni_proplist_res_u.stuff.id; + *pl = resp->ni_proplist_res_u.stuff.props; + } + return (resp->status); +} + + +ni_status +ni_lookup( + void *ni, + ni_id *id, + ni_name_const pname, + ni_name_const pval, + ni_idlist *hits + ) +{ + ni_lookup_res *resp; + ni_lookup_args args; + + args.id = *id; + args.key = (ni_name)pname; + args.value = (ni_name)pval; + if ((resp = RCALLIT(ni, _ni_lookup_2, &args)) == NULL) { + clnt_debug(ni, "_ni_lookup"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *hits = resp->ni_lookup_res_u.stuff.idlist; + *id = resp->ni_lookup_res_u.stuff.self_id; + } + return (resp->status); +} + + +ni_status +ni_lookupread( + void *ni, + ni_id *id, + ni_name_const pname, + ni_name_const pval, + ni_proplist *props + ) +{ + ni_proplist_res *resp; + ni_lookup_args args; + + args.id = *id; + args.key = (ni_name)pname; + args.value = (ni_name)pval; + if ((resp = RCALLIT(ni, _ni_lookupread_2, &args)) == NULL) { + clnt_debug(ni, "_ni_lookupread"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *props = resp->ni_proplist_res_u.stuff.props; + *id = resp->ni_proplist_res_u.stuff.id; + } + return (resp->status); +} + + +ni_status +ni_list( + void *ni, + ni_id *id, + ni_name_const pname, + ni_entrylist *entries + ) +{ + ni_list_res *resp; + ni_name_args args; + + args.id = *id; + args.name = (ni_name)pname; + if ((resp = RCALLIT(ni, _ni_list_2, &args)) == NULL) { + clnt_debug(ni, "_ni_list"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *entries = resp->ni_list_res_u.stuff.entries; + *id = resp->ni_list_res_u.stuff.self_id; + } + return (resp->status); +} + + +ni_status +ni_listall( + void *ni, + ni_id *id, + ni_proplist_list *entries + ) +{ + ni_listall_res *resp; + + if ((resp = RCALLIT(ni, _ni_listall_2, id)) == NULL) { + clnt_debug(ni, "_ni_listall"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *entries = resp->ni_listall_res_u.stuff.entries; + *id = resp->ni_listall_res_u.stuff.self_id; + } + return (resp->status); +} + + +ni_status +ni_readprop( + void *ni, + ni_id *id, + ni_index which, + ni_namelist *propval_p + ) +{ + ni_namelist_res *resp; + ni_prop_args args; + + args.id = *id; + args.prop_index = which; + if ((resp = RCALLIT(ni, _ni_readprop_2, &args)) == NULL) { + clnt_debug(ni, "_ni_readprop"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *propval_p = resp->ni_namelist_res_u.stuff.values; + *id = resp->ni_namelist_res_u.stuff.self_id; + } + return (resp->status); +} + + +ni_status +ni_writeprop( + void *ni, + ni_id *id, + ni_index which, + ni_namelist propval + ) +{ + ni_id_res *resp; + ni_writeprop_args args; + + args.id = *id; + args.prop_index = which; + args.values = propval; + if ((resp = WCALLIT(ni, _ni_writeprop_2, &args)) == NULL) { + clnt_debug(ni, "_ni_writeprop"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *id = resp->ni_id_res_u.id; + } + return (resp->status); +} + + +ni_status +ni_listprops( + void *ni, + ni_id *id, + ni_namelist *propnames + ) +{ + ni_namelist_res *resp; + + if ((resp = RCALLIT(ni, _ni_listprops_2, id)) == NULL) { + clnt_debug(ni, "_ni_listprops"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *propnames = resp->ni_namelist_res_u.stuff.values; + *id = resp->ni_namelist_res_u.stuff.self_id; + } + return (resp->status); +} + + +ni_status +ni_createprop( + void *ni, + ni_id *id, + ni_property prop, + ni_index where + ) +{ + ni_id_res *resp; + ni_createprop_args args; + + args.id = *id; + args.prop = prop; + args.where = where; + if ((resp = WCALLIT(ni, _ni_createprop_2, &args)) == NULL) { + clnt_debug(ni, "_ni_createprop"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *id = resp->ni_id_res_u.id; + } + return (resp->status); +} + + +ni_status +ni_destroyprop( + void *ni, + ni_id *id, + ni_index which + ) +{ + ni_id_res *resp; + ni_prop_args args; + + args.id = *id; + args.prop_index = which; + if ((resp = WCALLIT(ni, _ni_destroyprop_2, &args)) == NULL) { + clnt_debug(ni, "_ni_destroyprop"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *id = resp->ni_id_res_u.id; + } + return (resp->status); +} + + +ni_status +ni_renameprop( + void *ni, + ni_id *id, + ni_index prop_index, + ni_name_const name + ) +{ + ni_id_res *resp; + ni_propname_args args; + + args.id = *id; + args.prop_index = prop_index; + args.name = (ni_name)name; + if ((resp = WCALLIT(ni, _ni_renameprop_2, &args)) == NULL) { + clnt_debug(ni, "_ni_renameprop"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *id = resp->ni_id_res_u.id; + } + return (resp->status); +} + + +ni_status +ni_createname( + void *ni, + ni_id *id, + ni_index prop_index, + ni_name_const name, + ni_index where + ) +{ + ni_id_res *resp; + ni_createname_args args; + + args.id = *id; + args.prop_index = prop_index; + args.name = (ni_name)name; + args.where = where; + if ((resp = WCALLIT(ni, _ni_createname_2, &args)) == NULL) { + clnt_debug(ni, "_ni_createname"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *id = resp->ni_id_res_u.id; + } + return (resp->status); +} + + +ni_status +ni_destroyname( + void *ni, + ni_id *id, + ni_index prop_index, + ni_index name_index + ) +{ + ni_id_res *resp; + ni_nameindex_args args; + + args.id = *id; + args.prop_index = prop_index; + args.name_index = name_index; + if ((resp = WCALLIT(ni, _ni_destroyname_2, &args)) == NULL) { + clnt_debug(ni, "_ni_destroyname"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *id = resp->ni_id_res_u.id; + } + return (resp->status); +} + + +ni_status +ni_writename( + void *ni, + ni_id *id, + ni_index prop_index, + ni_index name_index, + ni_name_const name + ) +{ + ni_id_res *resp; + ni_writename_args args; + + args.id = *id; + args.prop_index = prop_index; + args.name_index = name_index; + args.name = (ni_name)name; + if ((resp = WCALLIT(ni, _ni_writename_2, &args)) == NULL) { + clnt_debug(ni, "_ni_writename"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *id = resp->ni_id_res_u.id; + } + return (resp->status); +} + + +ni_status +ni_readname( + void *ni, + ni_id *id, + ni_index prop_index, + ni_index name_index, + ni_name *name + ) +{ + ni_readname_res *resp; + ni_nameindex_args args; + + args.id = *id; + args.prop_index = prop_index; + args.name_index = name_index; + if ((resp = RCALLIT(ni, _ni_readname_2, &args)) == NULL) { + clnt_debug(ni, "_ni_readname"); + return (NI_FAILED); + } + if (resp->status == NI_OK) { + *id = resp->ni_readname_res_u.stuff.id; + *name = resp->ni_readname_res_u.stuff.name; + } + return (resp->status); +} + + +ni_status +ni_resync( + void *ni + ) +{ + ni_status *resp; + + if ((resp = (ni_status *)RCALLIT(ni, _ni_resync_2, NULL)) == NULL) { + return (NI_FAILED); + } + return (*resp); +} + + +ni_status +ni_setuser( + void *ni, + ni_name_const user + ) +{ + ni_id id; + ni_idlist ids; + ni_namelist nl; + char *p; + + if (user == NULL) { + NIP(ni)->uid = getuid(); + return (ni_setpassword(ni, NULL)); + } + + if (ni_root(ni, &id) != NI_OK) { + return(NI_NOUSER); + } + if (ni_lookup(ni, &id, NAME_NAME, NAME_USERS, &ids) != NI_OK) { + return (NI_NOUSER); + } + id.nii_object = ids.niil_val[0]; + ni_idlist_free(&ids); + + if (ni_lookup(ni, &id, NAME_NAME, user, &ids) != NI_OK) { + return (NI_NOUSER); + } + id.nii_object = ids.niil_val[0]; + ni_idlist_free(&ids); + if (ni_lookupprop(ni, &id, NAME_UID, &nl) != NI_OK) { + return (NI_NOUSER); + } + if (nl.ninl_len == 0) { + return (NI_NOUSER); + } + for (p = nl.ninl_val[0]; *p; p++) { + if (!isdigit(*p)) { + ni_namelist_free(&nl); + return (NI_NOUSER); + } + } + NIP(ni)->uid = atoi(nl.ninl_val[0]); + if (NIP(ni)->passwd == NULL) { + NIP(ni)->passwd = ni_name_dup(""); + } + createauth(NIP(ni)); + return (NI_OK); +} + + +ni_status +ni_setpassword( + void *ni, + ni_name_const passwd + ) +{ + char *p; + + if (NIP(ni)->passwd != NULL) { + ni_name_free(&NIP(ni)->passwd); + } + if (passwd == NULL) { + NIP(ni)->passwd = NULL; + if (NIP(ni)->tc != NULL) { + auth_destroy(NIP(ni)->tc->cl_auth); + NIP(ni)->tc->cl_auth = authnone_create(); + } + return (NI_OK); + } + NIP(ni)->passwd = ni_name_dup(passwd); + /* + * Our trivial encryption scheme + */ + for (p = NIP(ni)->passwd; *p; p++) { + *p = ~(*p); + } + createauth(NIP(ni)); + return (NI_OK); +} + + +extern int bindresvport(int, struct sockaddr_in *); + + +/* + * NeXT note: + * The procedure pmap_getport_to below is derived + * from Sun Microsystems RPC source code. As such the following + * statement applies to it.: + * + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* + * Client interface to pmap rpc service. + * + * Find the mapped port for program,version. + * Calls the pmap service remotely to do the lookup. + * Returns 0 if no map exists. + */ +static u_short +pmap_getport_to(address, program, version, protocol, timeout_secs, ntries) + struct sockaddr_in *address; + u_long program; + u_long version; + u_int protocol; + int timeout_secs; + int ntries; +{ + u_short port = 0; + int sock = -1; + register CLIENT *client; + struct pmap parms; + struct timeval timeout; + + sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (sock < 0) { + return (0); + } + address->sin_port = htons(PMAPPORT); + timeout.tv_usec = ((timeout_secs % ntries) * 1000000) / ntries; + timeout.tv_sec = (timeout_secs / ntries); + client = clntudp_bufcreate(address, PMAPPROG, + PMAPVERS, timeout, &sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); + if (client != (CLIENT *)NULL) { + parms.pm_prog = program; + parms.pm_vers = version; + parms.pm_prot = protocol; + parms.pm_port = 0; /* not needed or used */ + timeout.tv_usec = 0; + timeout.tv_sec = timeout_secs; + if (CLNT_CALL(client, PMAPPROC_GETPORT, xdr_pmap, &parms, + xdr_u_short, &port, timeout) != RPC_SUCCESS){ + rpc_createerr.cf_stat = RPC_PMAPFAILURE; + clnt_geterr(client, &rpc_createerr.cf_error); + port = 0; + } else if (port == 0) { + rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; + } + } + if (client != NULL) { + clnt_destroy(client); + } + (void)close(sock); + address->sin_port = 0; + return (port); +} + + +/* + * Open a socket, but do not use the default portmap timeout + */ +static int +socket_open( + struct sockaddr_in *raddr, + int prog, + int vers, + int timeout, + int ntries, + int proto + ) +{ + int sock; + + /* + * If no port number given ask the pmap for one + */ + if (raddr->sin_port == 0) { + u_short port; + if ((port = pmap_getport_to(raddr, prog, vers, + IPPROTO_UDP, timeout, + ntries)) == 0) { + return (-1); + } + raddr->sin_port = htons(port); + } + + sock = socket(AF_INET, proto == IPPROTO_UDP ? SOCK_DGRAM : SOCK_STREAM, + proto); + if (sock < 0) { + return (-1); + } + (void)bindresvport(sock, (struct sockaddr_in *)0); + if (proto == IPPROTO_TCP) { + if (connect(sock, (struct sockaddr *)raddr, + sizeof(*raddr)) < 0) { + (void)close(sock); + return (-1); + } + } + return (sock); +} diff --git a/netinfo.subproj/ni_prot.x b/netinfo.subproj/ni_prot.x new file mode 100644 index 0000000..a83e0fe --- /dev/null +++ b/netinfo.subproj/ni_prot.x @@ -0,0 +1,502 @@ +/* + * 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@ + */ +/* + * NetInfo protocol specification + * Copyright (C) 1989 by NeXT, Inc. + */ + +/* Preamble appearing on all generated output */ +#ifndef NOPREAMBLE +%/* +% * Output of the RPC protocol compiler: DO NOT EDIT +% * Copyright (C) 1989 by NeXT, Inc. +% */ +#endif + +#ifndef RPC_HDR +%#include +#endif + +const NI_NAME_MAXLEN = 65535; +const NI_NAMELIST_MAXLEN = 65535; +const NI_PROPLIST_MAXLEN = 65535; +const NI_IDLIST_MAXLEN = 1048576; + +/* + * Every object has a unique ID. One part of the ID identifies the object + * itself. The other identifies the instance of the object. Every time + * an object is written or an object is destroyed and then reallocated, + * its instance is incremented. + * + * All read operations ignore the instance field. All write operations + * refuse to operate on the object if there is an instance mismatch. + */ + +/* + * Don't go through unnecessary overhead for xdr_ni_index using typedef + * rpcgen needs an optimizer so we don't have to do this! + */ +#ifdef RPC_HDR +%typedef unsigned long ni_index; +#endif +#define ni_index unsigned long + +struct ni_id { + ni_index nii_object; + ni_index nii_instance; +}; + + +/* + * Names are assumed to contain human-readable ASCII characters. + */ +typedef string ni_name; + + +typedef ni_name ni_namelist; + +/* + * A property + */ +struct ni_property { + ni_name nip_name; + ni_namelist nip_val; +}; + +/* + * A list of properties + */ +typedef ni_property ni_proplist; + +/* + * A list of IDs (yet another variable-length array) + */ +typedef ni_index ni_idlist; + + +/* + * A name object + */ +struct ni_object { + ni_id nio_id; + ni_proplist nio_props; + ni_index nio_parent; + ni_idlist nio_children; +}; + + +/* + * All operations return a status indicating either that the requested + * operation succeeded or why it failed. + */ +enum ni_status { + NI_OK, /* Operation succeeded */ + NI_BADID, /* ID is invalid */ + NI_STALE, /* Write attempted on stale version of object */ + NI_NOSPACE, /* No space available for write operation */ + NI_PERM, /* Permission denied */ + NI_NODIR, /* No such directory */ + NI_NOPROP, /* No such property */ + NI_NONAME, /* No such name */ + NI_NOTEMPTY, /* Cannot delete name object with children */ + NI_UNRELATED, /* Object is not child of parent: cannot destroy */ + NI_SERIAL, /* Serialization error */ + NI_NETROOT, /* Hit network root domain */ + NI_NORESPONSE, /* No response from remote parent */ + NI_RDONLY, /* No writes allowed: all objects are read-only */ + NI_SYSTEMERR, /* generic remote error */ + NI_ALIVE, /* Can't regenerate: already in use */ + NI_NOTMASTER, /* Operation makes no sense on clone */ + NI_CANTFINDADDRESS, /* Can't find address of server */ + NI_DUPTAG, /* Duplicate domain tag: can't serve it */ + NI_NOTAG, /* No such tag */ + NI_AUTHERROR, /* Authentication error */ + NI_NOUSER, /* No such user */ + NI_MASTERBUSY, /* Master server is busy */ + NI_INVALIDDOMAIN, /* Invalid Domain */ + NI_BADOP, /* Invalid operation on master */ + NI_FAILED = 9999 /* generic local error */ +}; + +/* + * Wrappers needed to handle arguments and results + */ +union ni_id_res switch (ni_status status) { +case NI_OK: + ni_id id; +default: + void; +}; + +struct ni_parent_stuff { + ni_index object_id; + ni_id self_id; +}; + +union ni_parent_res switch (ni_status status) { +case NI_OK: + struct ni_parent_stuff stuff; +default: + void; +}; + +struct ni_children_stuff { + ni_idlist children; + ni_id self_id; +}; + +union ni_children_res switch (ni_status status) { +case NI_OK: + ni_children_stuff stuff; +default: + void; +}; + +struct ni_entry { + ni_index id; + ni_namelist *names; +}; + +typedef ni_entry ni_entrylist; + +struct ni_list_stuff { + ni_entrylist entries; + ni_id self_id; +}; + +union ni_list_res switch (ni_status status) { +case NI_OK: + ni_list_stuff stuff; +default: + void; +}; + +struct ni_proplist_stuff { + ni_id id; + ni_proplist props; +}; + +struct ni_create_args { + ni_id id; + ni_proplist props; + ni_index where; + ni_id *target_id; +}; + +union ni_proplist_res switch (ni_status status) { +case NI_OK: + ni_proplist_stuff stuff; +default: + void; +}; + +struct ni_create_stuff { + ni_id id; + ni_id self_id; +}; + +union ni_create_res switch (ni_status status) { +case NI_OK: + ni_create_stuff stuff; +default: + void; +}; + +struct ni_destroy_args { + ni_id parent_id; + ni_id self_id; +}; + +struct ni_lookup_args { + ni_id id; + ni_name key; + ni_name value; +}; + +struct ni_lookup_stuff { + ni_idlist idlist; + ni_id self_id; +}; + +union ni_lookup_res switch (ni_status status) { +case NI_OK: + ni_lookup_stuff stuff; +default: + void; +}; + + +struct ni_name_args { + ni_id id; + ni_name name; +}; + +struct ni_createprop_args { + ni_id id; + ni_property prop; + ni_index where; +}; + +struct ni_writeprop_args { + ni_id id; + ni_index prop_index; + ni_namelist values; +}; + +struct ni_prop_args { + ni_id id; + ni_index prop_index; +}; + +struct ni_namelist_stuff { + ni_namelist values; + ni_id self_id; +}; + +union ni_namelist_res switch (ni_status status) { +case NI_OK: + ni_namelist_stuff stuff; +default: + void; +}; + +struct ni_propname_args { + ni_id id; + ni_index prop_index; + ni_name name; +}; + +struct ni_createname_args { + ni_id id; + ni_index prop_index; + ni_name name; + ni_index where; +}; + +struct ni_nameindex_args { + ni_id id; + ni_index prop_index; + ni_index name_index; +}; + +struct ni_writename_args { + ni_id id; + ni_index prop_index; + ni_index name_index; + ni_name name; +}; + +struct ni_readname_stuff { + ni_id id; + ni_name name; +}; + +union ni_readname_res switch (ni_status status) { +case NI_OK: + ni_readname_stuff stuff; +default: + void; +}; + +struct ni_binding { + ni_name tag; + unsigned addr; +}; + +union ni_rparent_res switch (ni_status status) { +case NI_OK: + ni_binding binding; +default: + void; +}; + +typedef struct ni_object_node *ni_object_list; +struct ni_object_node { + ni_object object; + ni_object_list next; +}; + +struct ni_readall_stuff { + unsigned checksum; + ni_index highestid; + ni_object_list list; +}; + +union ni_readall_res switch (ni_status status) { +case NI_OK: + ni_readall_stuff stuff; +default: + void; +}; + +typedef ni_proplist ni_proplist_list; + +struct ni_listall_stuff { + ni_id self_id; + ni_proplist_list entries; +}; + +union ni_listall_res switch (ni_status status) { +case NI_OK: + ni_listall_stuff stuff; +default: + void; +}; + + +program NI_PROG { + version NI_VERS { + void + _NI_PING(void) = 0; + /* + * Get various server statistics + */ + ni_proplist + _NI_STATISTICS(void) = 1; + + /* + * Procedures dealing with nodes + */ + ni_id_res + _NI_ROOT(void) = 2; + + ni_id_res + _NI_SELF(ni_id) = 3; + + ni_parent_res + _NI_PARENT(ni_id) = 4; + + ni_create_res + _NI_CREATE(ni_create_args) = 5; + + ni_id_res + _NI_DESTROY(ni_destroy_args) = 6; + + ni_proplist_res + _NI_READ(ni_id) = 7; + + ni_id_res + _NI_WRITE(ni_proplist_stuff) = 8; + + ni_children_res + _NI_CHILDREN(ni_id) = 9; + + ni_lookup_res + _NI_LOOKUP(ni_lookup_args) = 10; + + ni_list_res + _NI_LIST(ni_name_args) = 11; + + /* + * Procedures dealing with properties + */ + ni_id_res + _NI_CREATEPROP(ni_createprop_args) = 12; + + ni_id_res + _NI_DESTROYPROP(ni_prop_args) = 13; + + ni_namelist_res + _NI_READPROP(ni_prop_args) = 14; + + ni_id_res + _NI_WRITEPROP(ni_writeprop_args) = 15; + + ni_id_res + _NI_RENAMEPROP(ni_propname_args) = 16; + + ni_namelist_res + _NI_LISTPROPS(ni_id) = 17; + + /* + * Procedures dealing with names + */ + ni_id_res + _NI_CREATENAME(ni_createname_args) = 18; + + ni_id_res + _NI_DESTROYNAME(ni_nameindex_args) = 19; + + ni_readname_res + _NI_READNAME(ni_nameindex_args) = 20; + + ni_id_res + _NI_WRITENAME(ni_writename_args) = 21; + + /* + * Returns the address of this domain's remote parent + */ + ni_rparent_res + _NI_RPARENT(void) = 22; + + /* + * List all properties of each subdirectory, not just + * just a single named property. + * + * WARNING: this routine is dangerous and may be + * removed from future implementations of the protocol. + * While it is good the the network in that there is + * less data on it because a lot is done in a single call, + * it is bad for the server because it ties it up and locks + * others out. + */ + ni_listall_res + _NI_LISTALL(ni_id) = 23; + + /* + * Answers only if the given binding is served + */ + void + _NI_BIND(ni_binding) = 24; + + /* + * Read the entire database if the checksum is different + * Implemented by master only. + */ + ni_readall_res + _NI_READALL(unsigned) = 25; + + /* + * Informs server that master has crashed. Hands out + * latest checksum. + */ + void + _NI_CRASHED(unsigned) = 26; + + /* + * If master, force clones to resync. + * If clone, resync with master. + */ + ni_status + _NI_RESYNC(void) = 27; + + + /* + * Extra procedure added for performance + * Terminates on first hit, returns proplist + */ + ni_proplist_res + _NI_LOOKUPREAD(ni_lookup_args) = 28; + } = 2; +} = 200100000; diff --git a/netinfo.subproj/ni_pwdomain.c b/netinfo.subproj/ni_pwdomain.c new file mode 100644 index 0000000..c872cc8 --- /dev/null +++ b/netinfo.subproj/ni_pwdomain.c @@ -0,0 +1,345 @@ +/* + * 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) 1990 by NeXT, Inc. All rights reserved. + */ + +/* + * ni_pwdomain function: present working domain for a netinfo handle + * + * usage: + * ni_status ni_pwdomain(void *ni, ni_name *buf) + * + * pwd is returned in buf, which can be freed with ni_name_free + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern char *inet_ntoa(); + +static const char NAME_NAME[] = "name"; +static const char NAME_MACHINES[] = "machines"; +static const char NAME_IP_ADDRESS[] = "ip_address"; +static const char NAME_SERVES[] = "serves"; +static const char NAME_UNKNOWN[] = "###UNKNOWN###"; + +typedef struct +{ + char name[IFNAMSIZ]; + short flags; + struct in_addr addr; + struct in_addr mask; + struct in_addr netaddr; + struct in_addr bcast; +} interface_t; + +typedef struct +{ + unsigned int count; + interface_t *interface; +} interface_list_t; + +static interface_list_t *my_interfaces = NULL; + +static interface_list_t * +sys_interfaces(void) +{ + struct ifconf ifc; + struct ifreq *ifr; + char buf[1024]; /* XXX */ + int offset, addrlen, extra, delta; + int sock; + interface_t *iface; + + if (my_interfaces != NULL) return my_interfaces; + + sock = socket(AF_INET, SOCK_DGRAM, 0); + + if (sock < 0) return NULL; + + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = buf; + + if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) + { + close(sock); + return NULL; + } + + my_interfaces = (interface_list_t *)malloc(sizeof(interface_list_t)); + my_interfaces->count = 0; + my_interfaces->interface = NULL; + + delta = sizeof(struct ifreq); + addrlen = delta - IFNAMSIZ; + extra = 0; + + offset = 0; + + while (offset <= ifc.ifc_len) + { + ifr = (struct ifreq *)(ifc.ifc_buf + offset); + +#ifndef _NO_SOCKADDR_LENGTH_ + extra = ifr->ifr_addr.sa_len - addrlen; + if (extra < 0) extra = 0; +#endif + + offset = offset + delta + extra; + + if (ifr->ifr_addr.sa_family != AF_INET) continue; + if (ioctl(sock, SIOCGIFFLAGS, (char *)ifr) < 0) continue; + + my_interfaces->count++; + if (my_interfaces->count == 1) + { + my_interfaces->interface = (interface_t *)malloc(sizeof(interface_t)); + } + else + { + my_interfaces->interface = (interface_t *)realloc(my_interfaces->interface, my_interfaces->count * sizeof(interface_t)); + } + + iface = &(my_interfaces->interface[my_interfaces->count - 1]); + memset(iface, 0, sizeof(interface_t)); + + memmove(iface->name, ifr->ifr_name, IFNAMSIZ); + iface->flags = ifr->ifr_ifru.ifru_flags; + iface->addr.s_addr = ((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr; + ioctl(sock, SIOCGIFNETMASK, (char *)ifr); + iface->mask.s_addr = ((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr; + iface->netaddr.s_addr = iface->addr.s_addr & iface->mask.s_addr; + iface->bcast.s_addr = iface->netaddr.s_addr | (~iface->mask.s_addr); + } + + close(sock); + return my_interfaces; +} + +static ni_name +escape_domain(ni_name name) +{ + int extra; + char *p; + char *s; + ni_name newname; + + extra = 0; + for (p = name; *p; p++) + { + if ((*p == '/') || (*p == '\\')) extra++; + } + + newname = malloc(strlen(name) + extra + 1); + s = newname; + for (p = name; *p; p++) + { + if ((*p == '/') || (*p == '\\')) *s++ = '\\'; + *s++ = *p; + } + + *s = 0; + return newname; + +} + +static char * +finddomain(void *ni, struct in_addr addr, ni_name tag) +{ + ni_id nid; + ni_idlist idl; + ni_namelist nl; + ni_index i; + ni_name slash; + ni_name domain; + ni_status status; + + status = ni_root(ni, &nid); + if (status != NI_OK) return NULL; + + status = ni_lookup(ni, &nid, NAME_NAME, NAME_MACHINES, &idl); + if (status != NI_OK) return NULL; + + nid.nii_object = idl.niil_val[0]; + ni_idlist_free(&idl); + + status = ni_lookup(ni, &nid, NAME_IP_ADDRESS, inet_ntoa(addr), &idl); + if (status != NI_OK) return NULL; + + nid.nii_object = idl.niil_val[0]; + ni_idlist_free(&idl); + + status = ni_lookupprop(ni, &nid, NAME_SERVES, &nl); + if (status != NI_OK) return NULL; + + for (i = 0; i < nl.ninl_len; i++) + { + slash = rindex(nl.ninl_val[i], '/'); + if (slash == NULL) continue; + + if (ni_name_match(slash + 1, tag)) + { + *slash = 0; + domain = escape_domain(nl.ninl_val[i]); + ni_namelist_free(&nl); + return domain; + } + } + + ni_namelist_free(&nl); + + return NULL; +} + +static int +sys_is_my_address(struct in_addr *a) +{ + int i; + interface_list_t *l; + + l = sys_interfaces(); + if (l == NULL) return 0; + + for (i = 0; i < l->count; i++) + { + if (a->s_addr == l->interface[i].addr.s_addr) return 1; + } + return 0; +} + +static char * +ni_domainof(void *ni, void *parent) +{ + struct sockaddr_in addr; + ni_name tag; + ni_name dom; + ni_status status; + interface_list_t *ilist; + int i; + + status = ni_addrtag(ni, &addr, &tag); + if (status != NI_OK) return ni_name_dup(NAME_UNKNOWN); + + dom = finddomain(parent, addr.sin_addr, tag); + if (dom != NULL) + { + ni_name_free(&tag); + return dom; + } + + if (sys_is_my_address(&(addr.sin_addr))) + { + /* Try all my non-loopback interfaces */ + ilist = sys_interfaces(); + if (ilist == NULL) return ni_name_dup(NAME_UNKNOWN); + + for (i = 0; i < ilist->count; i++) + { + if (ilist->interface[i].addr.s_addr == htonl(INADDR_LOOPBACK)) continue; + + addr.sin_addr.s_addr = ilist->interface[i].addr.s_addr; + dom = finddomain(parent, addr.sin_addr, tag); + if (dom != NULL) + { + ni_name_free(&tag); + return dom; + } + } + } + + dom = malloc(strlen(tag) + 256); + sprintf(dom, "%s@%s", tag, inet_ntoa(addr.sin_addr.s_addr)); + ni_name_free(&tag); + return dom; +} + +static ni_status +_ni_pwdomain(void *ni, ni_name *buf) +{ + void *nip; + ni_status status; + int len; + char *dom; + + /* Open domain name */ + nip = ni_new(ni, ".."); + if (nip == NULL) + { + (*buf) = malloc(2); + (*buf)[0] = 0; + return NI_OK; + } + + /* Get parent's name */ + status = _ni_pwdomain(nip, buf); + if (status != NI_OK) return status; + + /* Get my name relative to my parent */ + dom = ni_domainof(ni, nip); + + /* Append my relative name to my parent's name */ + len = strlen(*buf); + *buf = realloc(*buf, len + 1 + strlen(dom) + 1); + (*buf)[len] = '/'; + strcpy(&(*buf)[len + 1], dom); + ni_name_free(&dom); + ni_free(nip); + + return NI_OK; +} + +/* + * Just call the recursive ni_pwdomain above, and then fix for case of root + * domain or error + */ +ni_status +ni_pwdomain(void *ni, ni_name *buf) +{ + ni_status status; + + *buf = NULL; + status = _ni_pwdomain(ni, buf); + if (status != NI_OK) + { + if (*buf != NULL) ni_name_free(buf); + return status; + } + + if ((*buf)[0] == 0) + { + (*buf)[0] = '/'; + (*buf)[1] = 0; + } + + return NI_OK; +} diff --git a/netinfo.subproj/ni_useful.c b/netinfo.subproj/ni_useful.c new file mode 100644 index 0000000..a3d3df6 --- /dev/null +++ b/netinfo.subproj/ni_useful.c @@ -0,0 +1,745 @@ +/* + * 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@ + */ +/* + * Useful stuff for programming netinfo + * Copyright (C) 1989 by NeXT, Inc. + */ +#include +#include +#include +#include +#include +#include +#include + +extern void *_ni_dup(void *); + +static const char * +eatslash( + const char *path + ) +{ + while (*path == '/') { + path++; + } + return (path); +} + +static void +unescape( + ni_name *name + ) +{ + ni_name newname; + ni_name p; + int len; + int i; + + p = *name; + len = strlen(p); + newname = malloc(len + 1); + for (i = 0; *p != 0; i++) { + if (*p == '\\') { + p++; + } + newname[i] = *p++; + } + ni_name_free(name); + newname[i] = 0; + *name = newname; +} + +static const char * +escindex( + const char *str, + char ch + ) +{ + char *p; + + p = index(str, ch); + if (p == NULL) { + return (NULL); + } + if (p == str) { + return (p); + } + if (p[-1] == '\\') { + return (escindex(p + 1, ch)); + } + return (p); +} + +static void +setstuff( + void *ni, + ni_fancyopenargs *args + ) +{ + if (args != NULL) { + ni_setabort(ni, args->abort); + if (args->rtimeout) { + ni_setreadtimeout(ni, args->rtimeout); + } + if (args->wtimeout) { + ni_setwritetimeout(ni, args->wtimeout); + } + } +} + +static void * +ni_relopen( + void *ni, + const char *domain, + int freeold, + ni_fancyopenargs *args + ) +{ + void *newni; + void *tmpni; + char *start; + char *slash; + char *component; + + /* look for @
in last component of domain */ + start = domain; + while ((slash = escindex(start, '/')) != NULL) { + /* found a slash, keep looking for the last one */ + start = slash + 1; + } + if (index(start, '@') != NULL) { + /* + * last component in @
form, skip + * all of the leading components. + */ + component = ni_name_dup(start); + newni = ni_new(NULL, component); + free(component); + if (newni != NULL && args != NULL) + setstuff(newni, args); + if (ni != NULL && freeold) + ni_free(ni); + return (newni); + } + + component = ni_name_dup(domain); + slash = (char *)escindex(component, '/'); + if (slash != NULL) { + *slash = 0; + } + unescape(&component); + + tmpni = NULL; + if (ni != NULL && args != NULL) { + tmpni = _ni_dup(ni); + if (freeold) { + ni_free(ni); + } + ni = tmpni; + setstuff(ni, args); + } + + newni = ni_new(ni, component); + free(component); + + if (tmpni != NULL) { + ni_free(ni); + ni = NULL; + } + + if (ni != NULL && freeold) { + ni_free(ni); + } + + + if (newni == NULL) { + return (NULL); + } + setstuff(newni, args); + ni = newni; + if (slash != NULL) { + slash = (char *)escindex(domain, '/'); + domain = eatslash(slash + 1); + return (ni_relopen(ni, domain, TRUE, NULL)); + } else { + return (ni); + } +} + +static void * +ni_rootopen( + ni_fancyopenargs *args + ) +{ + void *ni; + void *newni; + + ni = ni_new(NULL, "."); + if (ni == NULL) { + return (NULL); + } + setstuff(ni, args); + for (;;) { + newni = ni_new(ni, ".."); + if (newni == NULL) { + break; + } + ni_free(ni); + ni = newni; + } + return (ni); +} + +static ni_name +ni_name_dupn( + ni_name_const start, + ni_name_const stop + ) +{ + int len; + ni_name new; + + if (stop != NULL) { + len = stop - start; + } else { + len = strlen(start); + } + new = malloc(len + 1); + bcopy(start, new, len); + new[len] = 0; + return (new); +} + + +static ni_status +ni_relsearch( + void *ni, + const char *path, + ni_id *id + ) +{ + char *slash; + char *equal; + ni_name key; + ni_name val; + ni_idlist idl; + ni_status status; + + slash = (char *)escindex(path, '/'); + equal = (char *)escindex(path, '='); + if (equal != NULL && (slash == NULL || equal < slash)) { + key = ni_name_dupn(path, equal); + val = ni_name_dupn(equal + 1, slash); + } else { + if (equal == NULL || (slash != NULL && slash < equal)) { + key = ni_name_dup("name"); + val = ni_name_dupn(path, slash); + } else { + key = ni_name_dupn(path, equal); + val = ni_name_dupn(equal + 1, slash); + } + } + unescape(&key); + unescape(&val); + status = ni_lookup(ni, id, key, val, &idl); + if (status != NI_OK) { + ni_name_free(&key); + ni_name_free(&val); + return (status); + } + id->nii_object = idl.niil_val[0]; + ni_name_free(&key); + ni_name_free(&val); + ni_idlist_free(&idl); + if (slash == NULL) { + ni_self(ni, id); + return (NI_OK); + } + path = eatslash(slash); + return (ni_relsearch(ni, path, id)); +} + +ni_status +ni_open( + void *ni, + const char *domain, + void **newni + ) +{ + return (ni_fancyopen(ni, domain, newni, NULL)); +} + +ni_status +ni_fancyopen( + void *ni, + const char *domain, + void **newni, + ni_fancyopenargs *args + ) +{ + void *tmp = NULL; + int rootopen = 0; + + if (*domain == '/') { + tmp = ni_rootopen(args); + if (tmp == NULL) { + return (NI_FAILED); /* XXX: should return real error */ + } + domain = eatslash(domain); + ni = tmp; + rootopen++; + } + if (*domain != 0) { + tmp = ni_relopen(ni, domain, FALSE, args); + if (rootopen) { + ni_free(ni); + } + } + if (tmp == NULL) { + return (NI_FAILED); + } + *newni = tmp; + ni_needwrite(*newni, args == NULL ? 0 : args->needwrite); + return (NI_OK); +} + +ni_status +ni_pathsearch( + void *ni, + ni_id *id, + const char *path + ) +{ + ni_status status; + + if (*path == '/') { + status = ni_root(ni, id); + if (status != NI_OK) { + return (status); + } + } + path = eatslash(path); + if (*path != 0) { + status = ni_relsearch(ni, path, id); + if (status != NI_OK) { + return (status); + } + } + return (NI_OK); +} + +static char ** +_ni_append_string(char *s, char **l) +{ + int i, len; + + if (s == NULL) return l; + if (l == NULL) + { + l = (char **)malloc(2 * sizeof(char *)); + l[0] = strdup(s); + l[1] = NULL; + return l; + } + + for (i = 0; l[i] != NULL; i++); + len = i + 1; /* count the NULL on the end of the list too! */ + + l = (char **)realloc(l, (len + 1) * sizeof(char *)); + + l[len - 1] = strdup(s); + l[len] = NULL; + return l; +} + +static char ** +_ni_explode_string(char *s, char c) +{ + char **l = NULL; + char *p, *t; + int i, n; + + if (s == NULL) return NULL; + + p = s; + while (p[0] != '\0') + { + for (i = 0; ((p[i] != '\0') && p[i] != c); i++); + n = i; + t = malloc(n + 1); + for (i = 0; i < n; i++) t[i] = p[i]; + t[n] = '\0'; + l = _ni_append_string(t, l); + free(t); + t = NULL; + if (p[i] == '\0') return l; + if (p[i + 1] == '\0') l = _ni_append_string("", l); + p = p + i + 1; + } + return l; +} + +static void +_ni_free_list(char **l) +{ + int i; + + if (l == NULL) return; + for (i = 0; l[i] != NULL; i++) + { + if (l[i] != NULL) free(l[i]); + l[i] = NULL; + } + if (l != NULL) free(l); +} + +ni_status +ni_host_domain(char *host, char *domspec, void **domain) +{ + void *d0, *d1; + struct sockaddr_in server; + ni_name tag; + int i, is_tag, is_local, is_relative; + ni_status status; + char **path; + struct hostent *h; + + is_local = 1; + + /* NULL host implies localhost */ + if (host == NULL) + { + server.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + } + else + { + is_local = 0; + server.sin_addr.s_addr = inet_addr(host); + if (server.sin_addr.s_addr == -1) + { + h = gethostbyname(host); + if (h == NULL) + { + *domain = (void *)NULL; + return NI_CANTFINDADDRESS; + } + bcopy(h->h_addr_list[0], &server.sin_addr.s_addr, h->h_length); + } + } + + is_relative = 1; + is_tag = 1; + + if (domspec == NULL) + { + is_tag = 0; + is_relative = 0; + } + else if (domspec[0] == '/') + { + is_tag = 0; + is_relative = 0; + } + else if (!strcmp(domspec, ".")) is_tag = 0; + else if (!strcmp(domspec, "..")) is_tag = 0; + else if (!strncmp(domspec, "./", 2)) is_tag = 0; + else if (!strncmp(domspec, "../", 3)) is_tag = 0; + + if (is_tag == 1) + { + d0 = ni_connect(&server, domspec); + status = ni_addrtag(d0, &server, &tag); + ni_name_free(&tag); + if (status != NI_OK) + { + *domain = (void *)NULL; + return NI_FAILED; + } + + *domain = d0; + return NI_OK; + } + + if (is_local) + { + if (domspec == NULL) status = ni_open(NULL, ".", domain); + else status = ni_open(NULL, domspec, domain); + return status; + } + + d0 = ni_connect(&server, "local"); + status = ni_addrtag(d0, &server, &tag); + ni_name_free(&tag); + if (status != NI_OK) + { + *domain = (void *)NULL; + return NI_FAILED; + } + + if ((domspec == NULL) || (!strcmp(domspec, "."))) + { + *domain = d0; + return NI_OK; + } + + if (is_relative == 1) + { + path = _ni_explode_string(domspec, '/'); + } + else + { + path = _ni_explode_string(domspec + 1, '/'); + + status = NI_OK; + while (status == NI_OK) + { + status = ni_open(d0, "..", &d1); + if (status == NI_OK) + { + ni_free(d0); + d0 = d1; + } + } + + if (!strcmp(domspec, "/")) + { + *domain = d0; + return NI_OK; + } + } + + for (i = 0; path[i] != NULL; i++) + { + status = ni_open(d0, path[i], &d1); + if (status != NI_OK) + { + _ni_free_list(path); + *domain = (void *)NULL; + return NI_FAILED; + } + ni_free(d0); + d0 = d1; + } + + _ni_free_list(path); + *domain = d0; + return NI_OK; +} + +static void +_ni_parse_url_hostspec(char *s, char **u, char **p, char **h) +{ + + char *p_at, *p_colon; + int ulen, plen, hlen; + + if (s == NULL) return; + if (s[0] == '\0') return; + + /* Check for [[[user][:[passwd]]]@]host */ + p_at = strchr(s, '@'); + if (p_at == NULL) + { + hlen = strlen(s); + if (hlen == 0) return; + + *h = malloc(hlen + 1); + strcpy(*h, s); + return; + } + + *p_at = '\0'; + p_at++; + hlen = strlen(p_at); + if (hlen > 0) + { + *h = malloc(hlen + 1); + strcpy(*h, p_at); + } + + if (s[0] == '\0') return; + + p_colon = strchr(s, ':'); + if (p_colon == NULL) + { + ulen = strlen(s); + if (ulen == 0) return; + + *u = malloc(ulen + 1); + strcpy(*u, s); + return; + } + + *p_colon = '\0'; + p_colon++; + plen = strlen(p_colon); + if (plen > 0) + { + *p = malloc(plen + 1); + strcpy(*p, p_colon); + } + + ulen = strlen(s); + if (ulen > 0) + { + *u = malloc(ulen + 1); + strcpy(*u, s); + } +} + +void +ni_parse_url(char *url, char **user, char **password, char **host, + char **domspec, char **dirspec) +{ + int i, x, len; + char *str; + + *host = NULL; + *user = NULL; + *password = NULL; + *domspec = NULL; + *dirspec = NULL; + + /* + * url ::= "netinfo://" [/[][:[]]] + * hostspec ::= [[[user][:[password]]]@]hostref + * hostref ::= | + * domainspec ::= | + * dirspec ::= | + */ + + x = strlen("netinfo://"); + + if (strncmp(url, "netinfo://", x)) return; + + /* + * Look for part + * Defults to NULL user, password and host + * NULL host implies localhost + */ + len = 0; + for (i = x; (url[i] != '\0') && (url[i] != '/'); i++) len++; + + if (len != 0) + { + str = malloc(len + 1); + bcopy(url + x, str, len); + str[len] = '\0'; + + _ni_parse_url_hostspec(str, user, password, host); + + free(str); + } + + /* + * Look for part + * NULL domainspec implies "." + */ + if (url[i] != '\0') i++; + x = i; + len = 0; + for (; (url[i] != '\0') && (url[i] != ':'); i++) len++; + + if (len > 0) + { + *domspec = malloc(len + 1); + bcopy(url + x, *domspec, len); + (*domspec)[len] = '\0'; + } + + /* + * Look for part + * NULL implies "/" + */ + if (url[i] != '\0') i++; + x = i; + len = 0; + for (; url[i] != '\0'; i++) len++; + if (len > 0) + { + *dirspec = malloc(len + 1); + bcopy(url + x, *dirspec, len); + (*dirspec)[len] = '\0'; + } +} + +ni_status +ni_url(char *url, void **domain, ni_id *dir) +{ + int nilen; + char *user, *password, *host; + char *domspec, *dirspec; + ni_status status; + + nilen = strlen("netinfo://"); + + if (strncmp(url, "netinfo://", nilen)) + { + *domain = (void *)NULL; + return NI_CANTFINDADDRESS; + } + + ni_parse_url(url, &user, &password, &host, &domspec, &dirspec); + + status = ni_host_domain(host, domspec, domain); + if (host != NULL) free(host); + if (domspec != NULL) free(domspec); + if (status != NI_OK) + { + if (user != NULL) free(user); + if (password != NULL) free(password); + if (dirspec != NULL) free(dirspec); + return status; + } + + if (user != NULL) + { + ni_setuser(*domain, user); + free(user); + } + + if (password != NULL) + { + ni_setpassword(*domain, password); + free(password); + } + + if (dirspec == NULL) + { + status = ni_root(*domain, dir); + return status; + } + + if ((dirspec[0] >= '0') && (dirspec[0] <= '9')) + { + dir->nii_object = atoi(dirspec); + free(dirspec); + status = ni_self(*domain, dir); + return status; + } + + status = ni_pathsearch(*domain, dir, dirspec); + free(dirspec); + return status; +} diff --git a/netinfo.subproj/ni_util.c b/netinfo.subproj/ni_util.c new file mode 100644 index 0000000..c279510 --- /dev/null +++ b/netinfo.subproj/ni_util.c @@ -0,0 +1,527 @@ +/* + * 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@ + */ +/* + * Utility routines for netinfo data structures + * Copyright (C) 1989 by NeXT, Inc. + */ +#include +#include +#include +#include +#include +#include "mm.h" + +void +ni_idlist_insert( + ni_idlist *cl, + ni_index id, + ni_index where + ) +{ + ni_index i; + + MM_GROW_ARRAY(cl->niil_val, cl->niil_len); + for (i = cl->niil_len; i > where; i--) { + cl->niil_val[i] = cl->niil_val[i - 1]; + } + cl->niil_val[i] = id; + cl->niil_len++; +} + +int +ni_idlist_delete( + ni_idlist *idlist, + ni_index id + ) +{ + ni_index j; + ni_index i; + + for (i = 0; i < idlist->niil_len; i++) { + if (idlist->niil_val[i] == id) { + for (j = i + 1; j < idlist->niil_len; j++) { + idlist->niil_val[j - 1] = idlist->niil_val[j]; + } + MM_SHRINK_ARRAY(idlist->niil_val, idlist->niil_len--); + return(1); + } + } + return (0); +} + + +void +ni_idlist_free( + ni_idlist *idlist + ) +{ + if (idlist->niil_val != NULL) { + MM_FREE_ARRAY(idlist->niil_val, idlist->niil_len); + } + NI_INIT(idlist); +} + +ni_idlist +ni_idlist_dup( + const ni_idlist idlist + ) +{ + ni_idlist newlist; + ni_index i; + + newlist.niil_len = idlist.niil_len; + MM_ALLOC_ARRAY(newlist.niil_val, idlist.niil_len); + for (i = 0; i < idlist.niil_len; i++) { + newlist.niil_val[i] = idlist.niil_val[i]; + } + return (newlist); +} + +void +ni_proplist_insert( + ni_proplist *pl, + const ni_property prop, + ni_index where + ) +{ + ni_index i; + + MM_GROW_ARRAY(pl->nipl_val, pl->nipl_len); + for (i = pl->nipl_len; i > where; i--) { + pl->nipl_val[i] = pl->nipl_val[i - 1]; + } + pl->nipl_val[i] = ni_prop_dup(prop); + pl->nipl_len++; +} + +void +ni_proplist_delete( + ni_proplist *pl, + ni_index which + ) +{ + int i; + + ni_prop_free(&pl->nipl_val[which]); + for (i = which + 1; i < pl->nipl_len; i++) { + pl->nipl_val[i - 1] = pl->nipl_val[i]; + } + MM_SHRINK_ARRAY(pl->nipl_val, pl->nipl_len--); +} + +void +ni_proplist_free( + ni_proplist *pl + ) +{ + ni_index i; + + if (pl->nipl_val == NULL) { + return; + } + for (i = 0; i < pl->nipl_len; i++) { + ni_prop_free(&pl->nipl_val[i]); + } + MM_FREE_ARRAY(pl->nipl_val, pl->nipl_len); + NI_INIT(pl); +} + +void +ni_proplist_list_free( + ni_proplist_list *pll + ) +{ + ni_index i; + + if (pll->nipll_val == NULL) { + return; + } + for (i = 0; i < pll->nipll_len; i++) { + ni_proplist_free(&pll->nipll_val[i]); + } + MM_FREE_ARRAY(pll->nipll_val, pll->nipll_len); + NI_INIT(pll); +} + +ni_proplist +ni_proplist_dup( + const ni_proplist pl + ) +{ + ni_proplist newlist; + ni_index i; + + newlist.nipl_len = pl.nipl_len; + MM_ALLOC_ARRAY(newlist.nipl_val, pl.nipl_len); + for (i = 0; i < pl.nipl_len; i++) { + newlist.nipl_val[i].nip_name = ni_name_dup(pl.nipl_val[i].nip_name); + newlist.nipl_val[i].nip_val = ni_namelist_dup(pl.nipl_val[i].nip_val); + } + return (newlist); +} + +ni_index +ni_proplist_match( + const ni_proplist pl, + ni_name_const pname, + ni_name_const pval + ) +{ + ni_index i; + ni_index j; + ni_namelist nl; + + for (i = 0; i < pl.nipl_len; i++) { + if (ni_name_match(pname, pl.nipl_val[i].nip_name)) { + if (pval == NULL) { + return (i); + } + nl = pl.nipl_val[i].nip_val; + for (j = 0; j < nl.ninl_len; j++) { + if (ni_name_match(pval, nl.ninl_val[j])) { + return (i); + } + } + break; + } + } + return (NI_INDEX_NULL); +} + + +ni_property +ni_prop_dup( + const ni_property prop + ) +{ + ni_property newprop; + + newprop.nip_name = ni_name_dup(prop.nip_name); + newprop.nip_val = ni_namelist_dup(prop.nip_val); + return (newprop); +} + +void +ni_prop_free( + ni_property *prop + ) +{ + ni_name_free(&prop->nip_name); + ni_namelist_free(&prop->nip_val); +} + +int +ni_name_match( + ni_name_const nm1, + ni_name_const nm2 + ) +{ + return (strcmp(nm1, nm2) == 0); +} + +ni_name +ni_name_dup( + ni_name_const nm + ) +{ + return (strcpy(malloc(strlen(nm) + 1), nm)); +} + + +void +ni_name_free( + ni_name *nm + ) +{ + if (*nm != NULL) { + free(*nm); + *nm = NULL; + } +} + +ni_namelist +ni_namelist_dup( + const ni_namelist nl + ) +{ + ni_namelist newlist; + ni_index i; + + newlist.ninl_len = nl.ninl_len; + MM_ALLOC_ARRAY(newlist.ninl_val, newlist.ninl_len); + for (i = 0; i < nl.ninl_len; i++) { + newlist.ninl_val[i] = ni_name_dup(nl.ninl_val[i]); + } + return (newlist); +} + +void +ni_namelist_free( + ni_namelist *nl + ) +{ + ni_index i; + + if (nl->ninl_val == NULL) { + return; + } + for (i = 0; i < nl->ninl_len; i++) { + ni_name_free(&nl->ninl_val[i]); + } + MM_FREE_ARRAY(nl->ninl_val, nl->ninl_len); + NI_INIT(nl); +} + +void +ni_namelist_insert( + ni_namelist *nl, + ni_name_const nm, + ni_index where + ) +{ + ni_index i; + + MM_GROW_ARRAY(nl->ninl_val, nl->ninl_len); + for (i = nl->ninl_len; i > where; i--) { + nl->ninl_val[i] = nl->ninl_val[i - 1]; + } + nl->ninl_val[i] = ni_name_dup(nm); + nl->ninl_len++; +} + +void +ni_namelist_delete( + ni_namelist *nl, + ni_index which + ) +{ + int i; + + ni_name_free(&nl->ninl_val[which]); + for (i = which + 1; i < nl-> ninl_len; i++) { + nl->ninl_val[i - 1] = nl->ninl_val[i]; + } + MM_SHRINK_ARRAY(nl->ninl_val, nl->ninl_len--); +} + +ni_index +ni_namelist_match( + const ni_namelist nl, + ni_name_const nm + ) +{ + ni_index i; + + for (i = 0; i < nl.ninl_len; i++) { + if (ni_name_match(nl.ninl_val[i], nm)) { + return (i); + } + } + return (NI_INDEX_NULL); +} + +void +ni_entrylist_insert( + ni_entrylist *el, + const ni_entry en + ) +{ + ni_entry entry; + + MM_GROW_ARRAY(el->niel_val, el->niel_len); + entry.id = en.id; + if (en.names != NULL) { + MM_ALLOC(entry.names); + *entry.names = ni_namelist_dup(*en.names); + } else { + entry.names = NULL; + } + el->niel_val[el->niel_len++] = entry; +} + +void +ni_entrylist_delete( + ni_entrylist *el, + ni_index which + ) +{ + int i; + + if (el->niel_val[which].names != NULL) { + ni_namelist_free(el->niel_val[which].names); + } + for (i = which + 1; i < el-> niel_len; i++) { + el->niel_val[i - 1] = el->niel_val[i]; + } + MM_SHRINK_ARRAY(el->niel_val, el->niel_len--); +} + +void +ni_entrylist_free( + ni_entrylist *el + ) +{ + ni_index i; + + if (el->niel_val == NULL) { + return; + } + for (i = 0; i < el->niel_len; i++) { + if (el->niel_val[i].names != NULL) { + ni_namelist_free(el->niel_val[i].names); + MM_FREE(el->niel_val[i].names); + } + } + MM_FREE_ARRAY(el->niel_val, el->niel_len); + NI_INIT(el); +} + + + +/* + * We can do this without an addition to the protocol + */ +ni_status +ni_lookupprop( + void *ni, + ni_id *id, + ni_name_const pname, + ni_namelist *nl + ) +{ + ni_status status; + ni_namelist list; + ni_index which; + + NI_INIT(&list); + status = ni_listprops(ni, id, &list); + if (status != NI_OK) { + return (status); + } + which = ni_namelist_match(list, pname); + ni_namelist_free(&list); + if (which == NI_INDEX_NULL) { + return (NI_NOPROP); + } + return (ni_readprop(ni, id, which, nl)); +} + +/* + * Search from local domain to root domain to locate a path. + */ +ni_status +ni_find(void **dom, ni_id *nid, ni_name dirname, unsigned int timeout) +{ + void *d, *p; + ni_id n; + ni_status status; + + *dom = NULL; + nid->nii_object = NI_INDEX_NULL; + nid->nii_instance = NI_INDEX_NULL; + + status = ni_open(NULL, ".", &d); + if (status != NI_OK) return status; + + if (timeout > 0) + { + ni_setreadtimeout(d, timeout); + ni_setabort(d, 1); + } + + while (d != NULL) + { + status = ni_pathsearch(d, &n, dirname); + if (status == NI_OK) + { + *dom = d; + *nid = n; + return NI_OK; + } + + status = ni_open(d, "..", &p); + ni_free(d); + d = NULL; + if (status == NI_OK) d = p; + } + + return NI_NODIR; +} + +ni_status +ni_search(void *handle, ni_id *dir, ni_name name, ni_name expr, int flags, ni_entrylist *entries) +{ + regex_t *cexp; + int i, j, found; + ni_entrylist el; + ni_namelist *nl; + ni_status status; + + /* get subdirectory list */ + NI_INIT(&el); + status = ni_list(handle, dir, name, &el); + if (status != NI_OK) return status; + + cexp = (regex_t *)malloc(sizeof(regex_t)); + memset(cexp, 0, sizeof(regex_t)); + i = regcomp(cexp, expr, flags); + if (i != 0) return NI_FAILED; + + for (i = 0; i < el.ni_entrylist_len; i++) + { + if (el.ni_entrylist_val[i].names == NULL) continue; + + nl = el.ni_entrylist_val[i].names; + + for (j = 0; j < nl->ni_namelist_len; j++) + { + found = 0; + if (regexec(cexp, nl->ni_namelist_val[j], 0, NULL, 0) != 0) continue; + + found = 1; + break; + } + + if (found == 0) continue; + + if (entries->ni_entrylist_len == 0) + { + entries->ni_entrylist_val = malloc(sizeof(ni_entry)); + } + else + { + entries->ni_entrylist_val = (ni_entry *)realloc(entries->ni_entrylist_val, (entries->ni_entrylist_len + 1) * sizeof(ni_entry)); + } + + entries->ni_entrylist_val[entries->ni_entrylist_len].id = el.ni_entrylist_val[i].id; + entries->ni_entrylist_val[entries->ni_entrylist_len].names = el.ni_entrylist_val[i].names; + el.ni_entrylist_val[i].names = NULL; + entries->ni_entrylist_len++; + } + + ni_entrylist_free(&el); + free(cexp); + + return NI_OK; +} diff --git a/netinfo.subproj/ni_util.h b/netinfo.subproj/ni_util.h new file mode 100644 index 0000000..6cb2c56 --- /dev/null +++ b/netinfo.subproj/ni_util.h @@ -0,0 +1,98 @@ +/* + * 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@ + */ +/* + * Utility routines for NetInfo + * Copyright (C) 1989 by NeXT, Inc. + */ + +#ifndef _NI_UTIL_H_ +#define _NI_UTIL_H_ + +#include + +#define NI_INDEX_NULL ((ni_index)-1) +#define NI_INIT(objp) bzero((void *)(objp), sizeof(*(objp))) + +ni_name ni_name_dup(ni_name_const); +void ni_name_free(ni_name *); +int ni_name_match(ni_name_const, ni_name_const); + +ni_namelist ni_namelist_dup(const ni_namelist); +void ni_namelist_free(ni_namelist *); +void ni_namelist_insert(ni_namelist *, ni_name_const, ni_index); +void ni_namelist_delete(ni_namelist *, ni_index); +ni_index ni_namelist_match(const ni_namelist, ni_name_const); + +ni_property ni_prop_dup(const ni_property); +void ni_prop_free(ni_property *); + +void ni_proplist_insert(ni_proplist *, const ni_property, ni_index); +void ni_proplist_delete(ni_proplist *, ni_index); +ni_index ni_proplist_match(const ni_proplist, ni_name_const, ni_name_const); +ni_proplist ni_proplist_dup(const ni_proplist); +void ni_proplist_free(ni_proplist *); + +void ni_proplist_list_free(ni_proplist_list *); + +void ni_idlist_insert(ni_idlist *, ni_index, ni_index); +int ni_idlist_delete(ni_idlist *, ni_index); +ni_idlist ni_idlist_dup(const ni_idlist); +void ni_idlist_free(ni_idlist *); + +void ni_entrylist_insert(ni_entrylist *, ni_entry); +void ni_entrylist_delete(ni_entrylist *, ni_index); +void ni_entrylist_free(ni_entrylist *); + +int innetgr(const char *, const char *, const char *, const char *); + +/* + * Search for a directory for all subdirs with key=val, when val is + * a regular expression. Usage: + * status = ni_search(domain, directory, key, val, flags, &list); + * val and flags are passed to regcomp (see regex(3)). + */ +ni_status ni_search(void *, ni_id *, ni_name, ni_name, int, ni_entrylist *); + +/* + * Searches from local domain to root to find the first directory with a + * given pathname. Last argument is a timeout. Usage: + * status = ni_find(&domain, &dir, path, timeout); + */ +ni_status ni_find(void **, ni_id *, ni_name, unsigned int); + +/* + * Parses a NetInfo URL, and returns the domain and directory referenced + * by the URL. Usage: + * status = ni_url(ustring, &domain, &dir); + * + * BNF for NetInfo URLs: + * url ::= "netinfo://" [/[][:[]]] + * hostspec ::= [[[user][:[password]]]@]hostref + * hostref ::= | + * domainspec ::= | + * dirspec ::= | + */ +ni_status ni_url(char *, void **, ni_id *); + +#endif !_NI_UTIL_H_ \ No newline at end of file diff --git a/netinfo.subproj/nibind_prot.x b/netinfo.subproj/nibind_prot.x new file mode 100644 index 0000000..19ef737 --- /dev/null +++ b/netinfo.subproj/nibind_prot.x @@ -0,0 +1,116 @@ +/* + * 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@ + */ +/* + * NetInfo binder protocol specification + * Copyright (C) 1989 by NeXT, Inc. + */ + +/* Preamble appearing on all generated output */ +#ifndef NOPREAMBLE +%/* +% * Output of the RPC protocol compiler: DO NOT EDIT +% * Copyright (C) 1989 by NeXT, Inc. +% */ +#endif + +#ifdef RPC_HDR +%#ifndef NI_PROG +%#include +%#endif +#else +%#include +#endif + +const NIBIND_MAXREGS = 32; + +struct nibind_addrinfo { + unsigned udp_port; + unsigned tcp_port; +}; + +struct nibind_registration { + ni_name tag; + nibind_addrinfo addrs; +}; + +union nibind_getregister_res switch (ni_status status) { +case NI_OK: + nibind_addrinfo addrs; +default: + void; +}; + +union nibind_listreg_res switch (ni_status status) { +case NI_OK: + nibind_registration regs; +default: + void; +}; + +struct nibind_clone_args { + ni_name tag; + ni_name master_name; + unsigned master_addr; + ni_name master_tag; +}; + +struct nibind_bind_args { + unsigned client_addr; + ni_name client_tag; + ni_name server_tag; +}; + +program NIBIND_PROG { + version NIBIND_VERS { + void + NIBIND_PING(void) = 0; + + ni_status + NIBIND_REGISTER(nibind_registration) = 1; + + ni_status + NIBIND_UNREGISTER(ni_name) = 2; + + nibind_getregister_res + NIBIND_GETREGISTER(ni_name) = 3; + + nibind_listreg_res + NIBIND_LISTREG(void) = 4; + + ni_status + NIBIND_CREATEMASTER(ni_name) = 5; + + ni_status + NIBIND_CREATECLONE(nibind_clone_args) = 6; + + ni_status + NIBIND_DESTROYDOMAIN(ni_name) = 7; + + /* + * Answers only if the given binding is served + */ + void + NIBIND_BIND(nibind_bind_args) = 8; + } = 1; +} = 200100001; diff --git a/nis.subproj/Makefile b/nis.subproj/Makefile new file mode 100644 index 0000000..fd7babb --- /dev/null +++ b/nis.subproj/Makefile @@ -0,0 +1,58 @@ +# +# Generated by the NeXT Project Builder. +# +# NOTE: Do NOT change this file -- Project Builder maintains it. +# +# Put all of your customizations in files called Makefile.preamble +# and Makefile.postamble (both optional), and Makefile will include them. +# + +NAME = nis + +PROJECTVERSION = 2.8 +PROJECT_TYPE = Component + +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 + +OTHERSRCS = Makefile.preamble Makefile + + +MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles +CODE_GEN_STYLE = DYNAMIC +MAKEFILE = subproj.make +LIBS = +DEBUG_LIBS = $(LIBS) +PROF_LIBS = $(LIBS) + + +PUBLIC_HEADERS = ypclnt.h yp_prot.h + + + +NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc +WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc +PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc +NEXTSTEP_JAVA_COMPILER = /usr/bin/javac +WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe +PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac + +include $(MAKEFILEDIR)/platform.make + +-include Makefile.preamble + +include $(MAKEFILEDIR)/$(MAKEFILE) + +-include Makefile.postamble + +-include Makefile.dependencies diff --git a/nis.subproj/Makefile.preamble b/nis.subproj/Makefile.preamble new file mode 100644 index 0000000..eb86120 --- /dev/null +++ b/nis.subproj/Makefile.preamble @@ -0,0 +1 @@ +PUBLIC_HEADER_DIR_SUFFIX = /rpcsvc diff --git a/nis.subproj/PB.project b/nis.subproj/PB.project new file mode 100644 index 0000000..6d2b72e --- /dev/null +++ b/nis.subproj/PB.project @@ -0,0 +1,58 @@ +{ + DYNAMIC_CODE_GEN = YES; + FILESTABLE = { + H_FILES = (ypclnt.h, ypinternal.h, yp_prot.h); + OTHER_LINKED = ( + 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 + ); + OTHER_SOURCES = (Makefile.preamble, Makefile); + PUBLIC_HEADERS = (ypclnt.h, yp_prot.h); + }; + LANGUAGE = English; + MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; + NEXTSTEP_BUILDTOOL = /bin/gnumake; + NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; + NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; + PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; + PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; + PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; + PROJECTNAME = nis; + PROJECTTYPE = Component; + PROJECTVERSION = 2.8; + WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; + WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; + WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; +} diff --git a/nis.subproj/getdomainname.c b/nis.subproj/getdomainname.c new file mode 100644 index 0000000..e0e4dc8 --- /dev/null +++ b/nis.subproj/getdomainname.c @@ -0,0 +1,39 @@ +/* + * 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@ + */ +/* + * cover for getdomainname() + * Copyright (C) 1995 by NeXT Computer, Inc. + */ +#include +#include + +int +getdomainname(char *val, size_t len) +{ + int mib[2]; + + mib[0] = CTL_KERN; + mib[1] = KERN_DOMAINNAME; + return sysctl(mib, 2, (void *)val, &len, NULL, 0); +} diff --git a/nis.subproj/getnetgrent.c b/nis.subproj/getnetgrent.c new file mode 100644 index 0000000..3894676 --- /dev/null +++ b/nis.subproj/getnetgrent.c @@ -0,0 +1,236 @@ +/* + * 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@ + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)getnetgrent.c 1.2 90/07/20 4.1NFSSRC; from 1.22 88/02/08 Copyr 1985 Sun Micro"; +#endif + +/* + * Copyright (c) 1985 by Sun Microsystems, Inc. + */ + +#include +#include +#include +#include +#include + +#define MAXGROUPLEN 1024 + +/* + * access members of a netgroup + */ + +static struct grouplist { /* also used by pwlib */ + char *gl_machine; + char *gl_name; + char *gl_domain; + struct grouplist *gl_nxt; +} *grouplist, *grlist; + + +struct list { /* list of names to check for loops */ + char *name; + struct list *nxt; +}; + +static void doit(); +static char *fill(); +static char *match(); + +static char *domain; +static char *oldgrp; + +char *NETGROUP = "netgroup"; + +void _old_endnetgrent(void); +void _old_setnetgrent(char *); + +void _old_setnetgrent(grp) + char *grp; +{ + + if (oldgrp == NULL) + oldgrp = (char *)calloc(1,256); + if (strcmp(oldgrp, grp) == 0) + grlist = grouplist; + else { + if (grouplist != NULL) + _old_endnetgrent(); + doit(grp, (struct list *) NULL); + grlist = grouplist; + (void) strcpy(oldgrp, grp); + } +} + +void _old_endnetgrent() +{ + register struct grouplist *gl; + + for (gl = grouplist; gl != NULL; gl = gl->gl_nxt) { + if (gl->gl_name) + free(gl->gl_name); + if (gl->gl_domain) + free(gl->gl_domain); + if (gl->gl_machine) + free(gl->gl_machine); + free((char *) gl); + } + grouplist = NULL; + grlist = NULL; + if (oldgrp) { + free(oldgrp); + oldgrp = 0; + } +} + +int _old_getnetgrent(machinep, namep, domainp) + char **machinep, **namep, **domainp; +{ + + if (grlist == 0) + return (0); + *machinep = grlist->gl_machine; + *namep = grlist->gl_name; + *domainp = grlist->gl_domain; + grlist = grlist->gl_nxt; + return (1); +} + +/* + * recursive function to find the members of netgroup "group". "list" is + * the path followed through the netgroups so far, to check for cycles. + */ +static void +doit(group,list) + char *group; + struct list *list; +{ + register char *p, *q; + register struct list *ls; + struct list this_group; + char *val; + struct grouplist *gpls; + + /* + * check for non-existing groups + */ + if ((val = match(group)) == NULL) + return; + + /* + * check for cycles + */ + for (ls = list; ls != NULL; ls = ls->nxt) + if (strcmp(ls->name, group) == 0) { + (void) fprintf(stderr, + "Cycle detected in /etc/netgroup: %s.\n", group); + return; + } + + ls = &this_group; + ls->name = group; + ls->nxt = list; + list = ls; + + p = val; + while (p != NULL) { + while (*p == ' ' || *p == '\t') + p++; + if (*p == 0 || *p =='#') + break; + if (*p == '(') { + gpls = (struct grouplist *) + malloc(sizeof(struct grouplist)); + p++; + if (!(p = fill(p,&gpls->gl_machine,','))) + goto syntax_error; + if (!(p = fill(p,&gpls->gl_name,','))) + goto syntax_error; + if (!(p = fill(p,&gpls->gl_domain,')'))) + goto syntax_error; + gpls->gl_nxt = grouplist; + grouplist = gpls; + } else { + q = strpbrk(p, " \t\n#"); + if (q && *q == '#') + break; + *q = 0; + doit(p,list); + *q = ' '; + } + p = strpbrk(p, " \t"); + } + return; + +syntax_error: + (void) fprintf(stderr,"syntax error in /etc/netgroup\n"); + (void) fprintf(stderr,"--- %s\n",val); + return; +} + +/* + * Fill a buffer "target" selectively from buffer "start". + * "termchar" terminates the information in start, and preceding + * or trailing white space is ignored. The location just after the + * terminating character is returned. + */ +static char * +fill(start,target,termchar) + char *start, **target, termchar; +{ + register char *p, *q; + char *r; + unsigned size; + + for (p = start; *p == ' ' || *p == '\t'; p++) + ; + r = index(p, termchar); + if (r == NULL) + return (NULL); + if (p == r) + *target = NULL; + else { + for (q = r-1; *q == ' ' || *q == '\t'; q--) + ; + size = q - p + 1; + *target = malloc(size+1); + (void) strncpy(*target,p,(int) size); + (*target)[size] = 0; + } + return (r+1); +} + +static char * +match(group) + char *group; +{ + char *val; + int vallen; + + if (domain == NULL) + (void) yp_get_default_domain(&domain ); + if (yp_match(domain, NETGROUP, group, strlen(group), &val, &vallen)) + return (NULL); + return (val); +} diff --git a/nis.subproj/innetgr.c b/nis.subproj/innetgr.c new file mode 100644 index 0000000..d146233 --- /dev/null +++ b/nis.subproj/innetgr.c @@ -0,0 +1,337 @@ +/* + * 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@ + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)innetgr.c 1.2 90/07/20 4.1NFSSRC; from 1.17 88/02/08 SMI Copyr 1985 Sun Micro"; +#endif + +/* + * Copyright (c) 1990 by Sun Microsystems, Inc. + */ + +#include +#include +#include +#include +#include + +/* + * innetgr: test whether I'm in /etc/netgroup + * + */ + + +struct innetgrdata { + char *name; + char *machine; + char *domain; + char **list; +#define LISTSIZE 200 /* recursion limit */ + char **listp; /* pointer into list */ + char *thisdomain; +}; + +static int lookup(char *, char *, char *, char *, char *, int *); +static int doit(register struct innetgrdata *, char *); +static void makekey(char *, char *, char *); + +int _old_innetgr(group, machine, name, domain) + char *group, *machine, *name, *domain; +{ + int res; + register struct innetgrdata *d; + char *thisdomain; + + (void) yp_get_default_domain(&thisdomain); + if (domain) { + if (name && !machine) { + if (lookup(thisdomain, + "netgroup.byuser",group,name,domain,&res)) { + return(res); + } + } else if (machine && !name) { + if (lookup(thisdomain, + "netgroup.byhost",group,machine,domain,&res)) { + return(res); + } + } + } + d = (struct innetgrdata *)malloc(sizeof (struct innetgrdata)); + if (d == 0) + return (0); + d->machine = machine; + d->name = name; + d->domain = domain; + d->thisdomain = thisdomain; + d->list = (char **)calloc(LISTSIZE, sizeof (char *)); + d->listp = d->list; + if (d->list == 0) { + free(d); + return (0); + } + res = doit(d, group); + free(d->list); + free(d); + return (res); +} + +/* + * calls itself recursively + */ +static int +doit(d, group) + register struct innetgrdata *d; + char *group; +{ + char *key, *val; + int vallen,keylen; + char *r; + int match; + register char *p, *q; + register char **lp; + int err; + + *d->listp++ = group; + if (d->listp > d->list + LISTSIZE) { + (void) fprintf(stderr, "innetgr: recursive overflow\r\n"); + d->listp--; + return (0); + } + key = group; + keylen = strlen(group); + err = yp_match(d->thisdomain, "netgroup", key, keylen, &val, &vallen); + if (err) { +#ifdef DEBUG + if (err == YPERR_KEY) + (void) fprintf(stderr, + "innetgr: no such netgroup as %s\n", group); + else + (void) fprintf(stderr, "innetgr: yp_match, %s\n",yperr_string(err)); +#endif + d->listp--; + return(0); + } + /* + * check for recursive loops + */ + for (lp = d->list; lp < d->listp-1; lp++) + if (strcmp(*lp, group) == 0) { + (void) fprintf(stderr, + "innetgr: netgroup %s called recursively\r\n", + group); + d->listp--; + free(val); + return(0); + } + + p = val; + p[vallen] = 0; + while (p != NULL) { + match = 0; + while (*p == ' ' || *p == '\t') + p++; + if (*p == 0 || *p == '#') + break; + if (*p == '(') { + p++; + while (*p == ' ' || *p == '\t') + p++; + r = q = index(p, ','); + if (q == NULL) { + (void) fprintf(stderr, + "innetgr: syntax error in /etc/netgroup\r\n"); + d->listp--; + free(val); + return(0); + } + if (p == q || d->machine == NULL) + match++; + else { + while (*(q-1) == ' ' || *(q-1) == '\t') + q--; + if (strncmp(d->machine, p, q-p) == 0) + match++; + } + p = r+1; + + while (*p == ' ' || *p == '\t') + p++; + r = q = index(p, ','); + if (q == NULL) { + (void) fprintf(stderr, + "innetgr: syntax error in /etc/netgroup\r\n"); + d->listp--; + free(val); + return(0); + } + if (p == q || d->name == NULL) + match++; + else { + while (*(q-1) == ' ' || *(q-1) == '\t') + q--; + if (strncmp(d->name, p, q-p) == 0) + match++; + } + p = r+1; + + while (*p == ' ' || *p == '\t') + p++; + r = q = index(p, ')'); + if (q == NULL) { + (void) fprintf(stderr, + "innetgr: syntax error in /etc/netgroup\r\n"); + d->listp--; + free(val); + return(0); + } + if (p == q || d->domain == NULL) + match++; + else { + while (*(q-1) == ' ' || *(q-1) == '\t') + q--; + if (strncmp(d->domain, p, q-p) == 0) + match++; + } + p = r+1; + if (match == 3) { + free(val); + d->listp--; + return 1; + } + } + else { + q = strpbrk(p, " \t\n#"); + if (q && *q == '#') + break; + if (q) + *q = 0; + if (doit(d, p)) { + free(val); + d->listp--; + return 1; + } + if (q) + *q = ' '; + } + p = strpbrk(p, " \t"); + } + free(val); + d->listp--; + return 0; +} + +/* + * return 1 if "what" is in the comma-separated, newline-terminated "d->list" + */ +static int +inlist(what,list) + char *what; + char *list; +{ +# define TERMINATOR(c) (c == ',' || c == '\n') + + register char *p; + int len; + + len = strlen(what); + p = list; + do { + if (strncmp(what,p,len) == 0 && TERMINATOR(p[len])) { + return(1); + } + while (!TERMINATOR(*p)) { + p++; + } + p++; + } while (*p); + return(0); +} + + + + +/* + * Lookup a host or user name in a NIS map. Set result to 1 if group in the + * lookup list of groups. Return 1 if the map was found. + */ +static int +lookup(thisdomain,map,group,name,domain,res) + char *thisdomain; + char *map; + char *group; + char *name; + char *domain; + int *res; +{ + int err; + char *val; + int vallen; + char key[256]; + char *wild = "*"; + int i; + + for (i = 0; i < 4; i++) { + switch (i) { + case 0: makekey(key,name,domain); break; + case 1: makekey(key,wild,domain); break; + case 2: makekey(key,name,wild); break; + case 3: makekey(key,wild,wild); break; + } + err = yp_match(thisdomain,map,key,strlen(key),&val,&vallen); + if (!err) { + *res = inlist(group,val); + free(val); + if (*res) { + return(1); + } + } else { +#ifdef DEBUG + (void) fprintf(stderr, + "yp_match(%s,%s) failed: %s.\n",map,key,yperr_string(err)); +#endif + if (err != YPERR_KEY) { + return(0); + } + } + } + *res = 0; + return(1); +} + + + +/* + * Generate a key for a netgroup.byXXXX NIS map + */ +static void +makekey(key,name,domain) + register char *key; + register char *name; + register char *domain; +{ + while (*key++ = *name++) + ; + *(key-1) = '.'; + while (*key++ = *domain++) + ; +} diff --git a/nis.subproj/setdomainname.c b/nis.subproj/setdomainname.c new file mode 100644 index 0000000..1541c01 --- /dev/null +++ b/nis.subproj/setdomainname.c @@ -0,0 +1,39 @@ +/* + * 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@ + */ +/* + * cover for getdomainname() + * Copyright (C) 1995 by NeXT Computer, Inc. + */ +#include +#include + +int +setdomainname(const char *name, size_t namelen) +{ + int mib[2]; + + mib[0] = CTL_KERN; + mib[1] = KERN_DOMAINNAME; + return sysctl(mib, 2, NULL, NULL, (void *)name, namelen); +} diff --git a/nis.subproj/xdr_domainname.c b/nis.subproj/xdr_domainname.c new file mode 100644 index 0000000..5308c1e --- /dev/null +++ b/nis.subproj/xdr_domainname.c @@ -0,0 +1,77 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: xdr_domainname.c,v 1.3 1996/08/19 08:34:58 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool_t +xdr_domainname(xdrs, objp) +XDR *xdrs; +domainname *objp; +{ + return xdr_string(xdrs, objp, YPMAXDOMAIN); +} diff --git a/nis.subproj/xdr_keydat.c b/nis.subproj/xdr_keydat.c new file mode 100644 index 0000000..9e0c6f0 --- /dev/null +++ b/nis.subproj/xdr_keydat.c @@ -0,0 +1,78 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: xdr_keydat.c,v 1.4 1996/08/19 08:34:58 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool_t +xdr_keydat(xdrs, objp) +XDR *xdrs; +keydat *objp; +{ + return xdr_bytes(xdrs, (char **)&objp->keydat_val, + (u_int *)&objp->keydat_len, YPMAXRECORD); +} diff --git a/nis.subproj/xdr_mapname.c b/nis.subproj/xdr_mapname.c new file mode 100644 index 0000000..6c4323a --- /dev/null +++ b/nis.subproj/xdr_mapname.c @@ -0,0 +1,77 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: xdr_mapname.c,v 1.3 1996/08/19 08:34:59 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool_t +xdr_mapname(xdrs, objp) +XDR *xdrs; +mapname *objp; +{ + return xdr_string(xdrs, objp, YPMAXMAP); +} diff --git a/nis.subproj/xdr_peername.c b/nis.subproj/xdr_peername.c new file mode 100644 index 0000000..7c4726d --- /dev/null +++ b/nis.subproj/xdr_peername.c @@ -0,0 +1,77 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: xdr_peername.c,v 1.3 1996/08/19 08:34:59 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool_t +xdr_peername(xdrs, objp) +XDR *xdrs; +peername *objp; +{ + return xdr_string(xdrs, objp, YPMAXPEER); +} diff --git a/nis.subproj/xdr_valdat.c b/nis.subproj/xdr_valdat.c new file mode 100644 index 0000000..1ab9024 --- /dev/null +++ b/nis.subproj/xdr_valdat.c @@ -0,0 +1,78 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: xdr_valdat.c,v 1.4 1996/08/19 08:35:00 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool_t +xdr_valdat(xdrs, objp) +XDR *xdrs; +valdat *objp; +{ + return xdr_bytes(xdrs, (char **)&objp->valdat_val, + (u_int *)&objp->valdat_len, YPMAXRECORD); +} diff --git a/nis.subproj/xdr_ypbind_binding.c b/nis.subproj/xdr_ypbind_binding.c new file mode 100644 index 0000000..53b82fa --- /dev/null +++ b/nis.subproj/xdr_ypbind_binding.c @@ -0,0 +1,80 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: xdr_ypbind_binding.c,v 1.3 1996/08/19 08:35:00 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool_t +xdr_ypbind_binding(xdrs, objp) +XDR *xdrs; +struct ypbind_binding *objp; +{ + if (!xdr_opaque(xdrs, objp->ypbind_binding_addr, 4)) { + return (FALSE); + } + return xdr_opaque(xdrs, objp->ypbind_binding_port, 2); +} diff --git a/nis.subproj/xdr_ypbind_resp.c b/nis.subproj/xdr_ypbind_resp.c new file mode 100644 index 0000000..832973f --- /dev/null +++ b/nis.subproj/xdr_ypbind_resp.c @@ -0,0 +1,91 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: xdr_ypbind_resp.c,v 1.3 1996/08/19 08:35:01 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool_t +xdr_ypbind_resp(xdrs, objp) +XDR *xdrs; +struct ypbind_resp *objp; +{ + if (!xdr_ypbind_resptype(xdrs, &objp->ypbind_status)) { + return FALSE; + } + + switch (objp->ypbind_status) { + case YPBIND_FAIL_VAL: + return xdr_u_int(xdrs, + (u_int *)&objp->ypbind_resp_u.ypbind_error); + case YPBIND_SUCC_VAL: + return xdr_ypbind_binding(xdrs, + &objp->ypbind_resp_u.ypbind_bindinfo); + default: + return FALSE; + } + /* NOTREACHED */ +} diff --git a/nis.subproj/xdr_ypbind_resptype.c b/nis.subproj/xdr_ypbind_resptype.c new file mode 100644 index 0000000..12096e2 --- /dev/null +++ b/nis.subproj/xdr_ypbind_resptype.c @@ -0,0 +1,77 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: xdr_ypbind_resptype.c,v 1.3 1996/08/19 08:35:01 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool_t +xdr_ypbind_resptype(xdrs, objp) +XDR *xdrs; +enum ypbind_resptype *objp; +{ + return xdr_enum(xdrs, (enum_t *)objp); +} diff --git a/nis.subproj/xdr_ypbind_setdom.c b/nis.subproj/xdr_ypbind_setdom.c new file mode 100644 index 0000000..be681a2 --- /dev/null +++ b/nis.subproj/xdr_ypbind_setdom.c @@ -0,0 +1,83 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: xdr_ypbind_setdom.c,v 1.3 1996/08/19 08:35:02 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool_t +xdr_ypbind_setdom(xdrs, objp) +XDR *xdrs; +struct ypbind_setdom *objp; +{ + if (!xdr_domainname(xdrs, (domainname *)&objp->ypsetdom_domain)) { + return FALSE; + } + if (!xdr_ypbind_binding(xdrs, &objp->ypsetdom_binding)) { + return FALSE; + } + return xdr_u_int(xdrs, (u_int *)&objp->ypsetdom_vers); +} diff --git a/nis.subproj/xdr_ypmaplist.c b/nis.subproj/xdr_ypmaplist.c new file mode 100644 index 0000000..137ea49 --- /dev/null +++ b/nis.subproj/xdr_ypmaplist.c @@ -0,0 +1,81 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: xdr_ypmaplist.c,v 1.3 1996/08/19 08:35:02 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool_t +xdr_ypmaplist(xdrs, objp) +XDR *xdrs; +struct ypmaplist *objp; +{ + if (!xdr_mapname(xdrs, (mapname *)&objp->map)) { + return FALSE; + } + return xdr_pointer(xdrs, (caddr_t *)&objp->next, + sizeof(struct ypmaplist), xdr_ypmaplist); +} diff --git a/nis.subproj/xdr_ypreq_key.c b/nis.subproj/xdr_ypreq_key.c new file mode 100644 index 0000000..eababd8 --- /dev/null +++ b/nis.subproj/xdr_ypreq_key.c @@ -0,0 +1,83 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: xdr_ypreq_key.c,v 1.3 1996/08/19 08:35:03 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool_t +xdr_ypreq_key(xdrs, objp) +XDR *xdrs; +struct ypreq_key *objp; +{ + if (!xdr_domainname(xdrs, (domainname *)&objp->domain)) { + return FALSE; + } + if (!xdr_mapname(xdrs, (mapname *)&objp->map)) { + return FALSE; + } + return xdr_keydat(xdrs, &objp->key); +} diff --git a/nis.subproj/xdr_ypreq_nokey.c b/nis.subproj/xdr_ypreq_nokey.c new file mode 100644 index 0000000..b3e1552 --- /dev/null +++ b/nis.subproj/xdr_ypreq_nokey.c @@ -0,0 +1,80 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: xdr_ypreq_nokey.c,v 1.3 1996/08/19 08:35:03 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool_t +xdr_ypreq_nokey(xdrs, objp) +XDR *xdrs; +struct ypreq_nokey *objp; +{ + if (!xdr_domainname(xdrs, (domainname *)&objp->domain)) { + return FALSE; + } + return xdr_mapname(xdrs, (mapname *)&objp->map); +} diff --git a/nis.subproj/xdr_ypresp_all.c b/nis.subproj/xdr_ypresp_all.c new file mode 100644 index 0000000..cee7c8a --- /dev/null +++ b/nis.subproj/xdr_ypresp_all.c @@ -0,0 +1,88 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: xdr_ypresp_all.c,v 1.3 1996/08/19 08:35:04 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool_t +xdr_ypresp_all(xdrs, objp) +XDR *xdrs; +struct ypresp_all *objp; +{ + if (!xdr_bool(xdrs, &objp->more)) { + return FALSE; + } + switch (objp->more) { + case TRUE: + return xdr_ypresp_key_val(xdrs, &objp->ypresp_all_u.val); + case FALSE: + return (TRUE); + default: + return FALSE; + } + /* NOTREACHED */ +} diff --git a/nis.subproj/xdr_ypresp_key_val.c b/nis.subproj/xdr_ypresp_key_val.c new file mode 100644 index 0000000..dfb11b8 --- /dev/null +++ b/nis.subproj/xdr_ypresp_key_val.c @@ -0,0 +1,83 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: xdr_ypresp_key_val.c,v 1.3 1996/08/19 08:35:04 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool_t +xdr_ypresp_key_val(xdrs, objp) +XDR *xdrs; +struct ypresp_key_val *objp; +{ + if (!xdr_ypstat(xdrs, (ypstat *)&objp->stat)) { + return FALSE; + } + if (!xdr_valdat(xdrs, &objp->val)) { + return FALSE; + } + return xdr_keydat(xdrs, &objp->key); +} diff --git a/nis.subproj/xdr_ypresp_maplist.c b/nis.subproj/xdr_ypresp_maplist.c new file mode 100644 index 0000000..cce1529 --- /dev/null +++ b/nis.subproj/xdr_ypresp_maplist.c @@ -0,0 +1,81 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: xdr_ypresp_maplist.c,v 1.3 1996/08/19 08:35:05 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool_t +xdr_ypresp_maplist(xdrs, objp) +XDR *xdrs; +struct ypresp_maplist *objp; +{ + if (!xdr_ypstat(xdrs, (ypstat *)&objp->stat)) { + return FALSE; + } + return xdr_pointer(xdrs, (caddr_t *)&objp->maps, + sizeof(struct ypmaplist), xdr_ypmaplist); +} diff --git a/nis.subproj/xdr_ypresp_master.c b/nis.subproj/xdr_ypresp_master.c new file mode 100644 index 0000000..b844a40 --- /dev/null +++ b/nis.subproj/xdr_ypresp_master.c @@ -0,0 +1,80 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: xdr_ypresp_master.c,v 1.3 1996/08/19 08:35:05 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool_t +xdr_ypresp_master(xdrs, objp) +XDR *xdrs; +struct ypresp_master *objp; +{ + if (!xdr_ypstat(xdrs, (ypstat *)&objp->stat)) { + return FALSE; + } + return xdr_peername(xdrs, (peername *)&objp->peer); +} diff --git a/nis.subproj/xdr_ypresp_order.c b/nis.subproj/xdr_ypresp_order.c new file mode 100644 index 0000000..4660014 --- /dev/null +++ b/nis.subproj/xdr_ypresp_order.c @@ -0,0 +1,80 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: xdr_ypresp_order.c,v 1.3 1996/08/19 08:35:06 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool_t +xdr_ypresp_order(xdrs, objp) +XDR *xdrs; +struct ypresp_order *objp; +{ + if (!xdr_ypstat(xdrs, (ypstat *)&objp->stat)) { + return FALSE; + } + return xdr_u_int(xdrs, (u_int *)&objp->ordernum); +} diff --git a/nis.subproj/xdr_ypresp_val.c b/nis.subproj/xdr_ypresp_val.c new file mode 100644 index 0000000..26226e0 --- /dev/null +++ b/nis.subproj/xdr_ypresp_val.c @@ -0,0 +1,80 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: xdr_ypresp_val.c,v 1.3 1996/08/19 08:35:06 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool_t +xdr_ypresp_val(xdrs, objp) +XDR *xdrs; +struct ypresp_val *objp; +{ + if (!xdr_ypstat(xdrs, (ypstat *)&objp->stat)) { + return FALSE; + } + return xdr_valdat(xdrs, &objp->val); +} diff --git a/nis.subproj/xdr_ypstat.c b/nis.subproj/xdr_ypstat.c new file mode 100644 index 0000000..15a4842 --- /dev/null +++ b/nis.subproj/xdr_ypstat.c @@ -0,0 +1,77 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: xdr_ypstat.c,v 1.4 1996/12/14 06:49:45 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +bool_t +xdr_ypstat(xdrs, objp) +XDR *xdrs; +ypstat *objp; +{ + return xdr_enum(xdrs, (enum_t *)objp); +} diff --git a/nis.subproj/yp_all.c b/nis.subproj/yp_all.c new file mode 100644 index 0000000..55778c8 --- /dev/null +++ b/nis.subproj/yp_all.c @@ -0,0 +1,193 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: yp_all.c,v 1.5 1996/12/14 06:49:46 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ypinternal.h" + +int (*ypresp_allfn) __P((u_long, char *, int, char *, int, void *)); +void *ypresp_data; + +bool_t +xdr_ypresp_all_seq(xdrs, objp) +XDR *xdrs; +u_long *objp; +{ + struct ypresp_all out; + u_long status; + char *key, *val; + int size; + int r; + + memset(&out, 0, sizeof out); + while(1) { + if( !xdr_ypresp_all(xdrs, &out)) { + xdr_free(xdr_ypresp_all, (char *)&out); + *objp = (u_long)YP_YPERR; + return FALSE; + } + if(out.more == 0) { + xdr_free(xdr_ypresp_all, (char *)&out); + return FALSE; + } + status = out.ypresp_all_u.val.stat; + switch(status) { + case YP_TRUE: + size = out.ypresp_all_u.val.key.keydat_len; + if ((key = malloc(size + 1)) != NULL) { + (void)memcpy(key, + out.ypresp_all_u.val.key.keydat_val, + size); + key[size] = '\0'; + } + size = out.ypresp_all_u.val.val.valdat_len; + if ((val = malloc(size + 1)) != NULL) { + (void)memcpy(val, + out.ypresp_all_u.val.val.valdat_val, + size); + val[size] = '\0'; + } + else { + free(key); + key = NULL; + } + xdr_free(xdr_ypresp_all, (char *)&out); + + if (key == NULL || val == NULL) + return FALSE; + + r = (*ypresp_allfn)(status, key, + out.ypresp_all_u.val.key.keydat_len, val, + out.ypresp_all_u.val.val.valdat_len, ypresp_data); + *objp = status; + free(key); + free(val); + if(r) + return TRUE; + break; + case YP_NOMORE: + xdr_free(xdr_ypresp_all, (char *)&out); + return TRUE; + default: + xdr_free(xdr_ypresp_all, (char *)&out); + *objp = status; + return TRUE; + } + } +} + +int +yp_all(indomain, inmap, incallback) + const char *indomain; + const char *inmap; + struct ypall_callback *incallback; +{ + struct ypreq_nokey yprnk; + struct dom_binding *ysd; + struct timeval tv; + struct sockaddr_in clnt_sin; + CLIENT *clnt; + u_long status; + int clnt_sock; + int r = 0; + + if (indomain == NULL || *indomain == '\0' || + strlen(indomain) > YPMAXDOMAIN || inmap == NULL || + *inmap == '\0' || strlen(inmap) > YPMAXMAP || incallback == NULL) + return YPERR_BADARGS; + + if (_yp_dobind(indomain, &ysd) != 0) + return YPERR_DOMAIN; + + tv.tv_sec = _yplib_timeout; + tv.tv_usec = 0; + clnt_sock = RPC_ANYSOCK; + clnt_sin = ysd->dom_server_addr; + clnt_sin.sin_port = 0; + clnt = clnttcp_create(&clnt_sin, YPPROG, YPVERS, &clnt_sock, 0, 0); + if (clnt == NULL) { + printf("clnttcp_create failed\n"); + r = YPERR_PMAP; + goto out; + } + yprnk.domain = (char *)indomain; + yprnk.map = (char *)inmap; + ypresp_allfn = incallback->foreach; + ypresp_data = (void *) incallback->data; + + (void) clnt_call(clnt, YPPROC_ALL, + xdr_ypreq_nokey, &yprnk, xdr_ypresp_all_seq, &status, tv); + clnt_destroy(clnt); + if(status != YP_FALSE) + r = ypprot_err(status); +out: + _yp_unbind(ysd); + return r; +} diff --git a/nis.subproj/yp_bind.c b/nis.subproj/yp_bind.c new file mode 100644 index 0000000..a8b9c9d --- /dev/null +++ b/nis.subproj/yp_bind.c @@ -0,0 +1,315 @@ +/* + * 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) 1996 Theo de Raadt + * Copyright (c) 1992, 1993 Theo de Raadt + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: yp_bind.c,v 1.9 1997/04/29 21:25:20 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ypinternal.h" + +struct dom_binding *_ypbindlist = NULL; +char _yp_domain[MAXHOSTNAMELEN] = { '\0' }; + +int _yplib_timeout = 10; + +int +_yp_dobind(dom, ypdb) + const char *dom; + struct dom_binding **ypdb; +{ + static int pid = -1; + char path[MAXPATHLEN]; + struct dom_binding *ysd, *ysd2; + struct ypbind_resp ypbr; + struct timeval tv; + struct sockaddr_in clnt_sin; + struct ypbind_binding *bn; + int clnt_sock, fd, gpid; + CLIENT *client; + int new = 0, r; + int count = 0; + u_short port; + + /* + * test if YP is running or not + */ + if ((fd = open(YPBINDLOCK, O_RDONLY)) == -1) + return YPERR_YPBIND; + if (!(flock(fd, LOCK_EX | LOCK_NB) == -1 && errno == EWOULDBLOCK)) { + (void)close(fd); + return YPERR_YPBIND; + } + (void)close(fd); + + gpid = getpid(); + if (!(pid == -1 || pid == gpid)) { + ysd = _ypbindlist; + while (ysd) { + if (ysd->dom_client) + clnt_destroy(ysd->dom_client); + ysd2 = ysd->dom_pnext; + free(ysd); + ysd = ysd2; + } + _ypbindlist = NULL; + } + pid = gpid; + + if (ypdb != NULL) + *ypdb = NULL; + + if (dom == NULL || strlen(dom) == 0) + return YPERR_BADARGS; + + for (ysd = _ypbindlist; ysd; ysd = ysd->dom_pnext) + if (strcmp(dom, ysd->dom_domain) == 0) + break; + if (ysd == NULL) { + if ((ysd = malloc(sizeof *ysd)) == NULL) + return YPERR_YPERR; + (void)memset(ysd, 0, sizeof *ysd); + ysd->dom_socket = -1; + ysd->dom_vers = 0; + new = 1; + } +again: + if (ysd->dom_vers == 0) { + (void) snprintf(path, sizeof(path), "%s/%s.%d", + BINDINGDIR, dom, 2); + if ((fd = open(path, O_RDONLY)) == -1) { + /* + * no binding file, YP is dead, or not yet fully + * alive. + */ + goto trynet; + } + if (flock(fd, LOCK_EX | LOCK_NB) == -1 && + errno == EWOULDBLOCK) { + struct iovec iov[2]; + u_short ypb_port; + + /* + * we fetch the ypbind port number, but do + * nothing with it. + */ + iov[0].iov_base = (caddr_t) &ypb_port; + iov[0].iov_len = sizeof ypb_port; + iov[1].iov_base = (caddr_t) &ypbr; + iov[1].iov_len = sizeof ypbr; + + r = readv(fd, iov, 2); + if (r != iov[0].iov_len + iov[1].iov_len) { + (void)close(fd); + ysd->dom_vers = -1; + goto again; + } + (void)close(fd); + goto gotdata; + } else { + /* no lock on binding file, YP is dead. */ + (void)close(fd); + if (new) + free(ysd); + return YPERR_YPBIND; + } + } +trynet: + if (ysd->dom_vers == -1 || ysd->dom_vers == 0) { + (void)memset(&clnt_sin, 0, sizeof clnt_sin); + clnt_sin.sin_len = sizeof(struct sockaddr_in); + clnt_sin.sin_family = AF_INET; + clnt_sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + clnt_sock = RPC_ANYSOCK; + client = clnttcp_create(&clnt_sin, YPBINDPROG, YPBINDVERS, + &clnt_sock, 0, 0); + if (client == NULL) { + clnt_pcreateerror("clnttcp_create"); + if (new) + free(ysd); + return YPERR_YPBIND; + } + if (ntohs(clnt_sin.sin_port) >= IPPORT_RESERVED || + ntohs(clnt_sin.sin_port) == 20) { + /* + * YP was not running, but someone has registered + * ypbind with portmap -- this simply means YP is + * not running. + */ + clnt_destroy(client); + if (new) + free(ysd); + return YPERR_YPBIND; + } + tv.tv_sec = _yplib_timeout; + tv.tv_usec = 0; + r = clnt_call(client, YPBINDPROC_DOMAIN, xdr_domainname, + &dom, xdr_ypbind_resp, &ypbr, tv); + if (r != RPC_SUCCESS) { + if (new == 0 || count) + fprintf(stderr, + "YP server for domain %s not responding, still trying\n", + dom); + count++; + clnt_destroy(client); + ysd->dom_vers = -1; + goto again; + } + clnt_destroy(client); +gotdata: + bn = &ypbr.ypbind_resp_u.ypbind_bindinfo; + memcpy(&port, &bn->ypbind_binding_port, sizeof port); + if (ntohs(port) >= IPPORT_RESERVED || + ntohs(port) == 20) { + /* + * This is bogus -- the ypbind wants me to + * communicate to an insecure ypserv. We are + * within rights to syslog this as an attack, + * but for now we'll simply ignore it; real YP + * is obviously not running. + */ + if (new) + free(ysd); + return YPERR_YPBIND; + } + (void)memset(&ysd->dom_server_addr, 0, + sizeof ysd->dom_server_addr); + ysd->dom_server_addr.sin_len = sizeof(struct sockaddr_in); + ysd->dom_server_addr.sin_family = AF_INET; + memcpy(&ysd->dom_server_addr.sin_port, + &bn->ypbind_binding_port, + sizeof(ysd->dom_server_addr.sin_port)); + memcpy(&ysd->dom_server_addr.sin_addr.s_addr, + &bn->ypbind_binding_addr, + sizeof(ysd->dom_server_addr.sin_addr.s_addr)); + ysd->dom_server_port = ysd->dom_server_addr.sin_port; + ysd->dom_vers = YPVERS; + (void)strncpy(ysd->dom_domain, dom, sizeof ysd->dom_domain-1); + ysd->dom_domain[sizeof ysd->dom_domain-1] = '\0'; + } + tv.tv_sec = _yplib_timeout / 2; + tv.tv_usec = 0; + if (ysd->dom_client) + clnt_destroy(ysd->dom_client); + ysd->dom_socket = RPC_ANYSOCK; + ysd->dom_client = clntudp_create(&ysd->dom_server_addr, + YPPROG, YPVERS, tv, &ysd->dom_socket); + if (ysd->dom_client == NULL) { + clnt_pcreateerror("clntudp_create"); + ysd->dom_vers = -1; + goto again; + } + if (fcntl(ysd->dom_socket, F_SETFD, 1) == -1) + perror("fcntl: F_SETFD"); + + if (new) { + ysd->dom_pnext = _ypbindlist; + _ypbindlist = ysd; + } + if (ypdb != NULL) + *ypdb = ysd; + return 0; +} + +void +_yp_unbind(ypb) + struct dom_binding *ypb; +{ + if (ypb->dom_client) clnt_destroy(ypb->dom_client); + ypb->dom_client = NULL; + ypb->dom_socket = -1; +} + +int +yp_bind(dom) + const char *dom; +{ + return _yp_dobind(dom, NULL); +} + +void +yp_unbind(dom) + const char *dom; +{ + struct dom_binding *ypb, *ypbp; + + ypbp = NULL; + for (ypb = _ypbindlist; ypb; ypb = ypb->dom_pnext) { + if (strcmp(dom, ypb->dom_domain) == 0) { + if (ypb->dom_client) clnt_destroy(ypb->dom_client); + if (ypbp) + ypbp->dom_pnext = ypb->dom_pnext; + else + _ypbindlist = ypb->dom_pnext; + free(ypb); + return; + } + ypbp = ypb; + } +} diff --git a/nis.subproj/yp_first.c b/nis.subproj/yp_first.c new file mode 100644 index 0000000..5bdcf11 --- /dev/null +++ b/nis.subproj/yp_first.c @@ -0,0 +1,136 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: yp_first.c,v 1.5 1996/12/03 08:20:03 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ypinternal.h" + +int +yp_first(indomain, inmap, outkey, outkeylen, outval, outvallen) + const char *indomain; + const char *inmap; + char **outkey; + int *outkeylen; + char **outval; + int *outvallen; +{ + struct ypresp_key_val yprkv; + struct ypreq_nokey yprnk; + struct dom_binding *ysd; + struct timeval tv; + int tries = 0, r; + + if (indomain == NULL || *indomain == '\0' || + strlen(indomain) > YPMAXDOMAIN || inmap == NULL || + *inmap == '\0' || strlen(inmap) > YPMAXMAP) + return YPERR_BADARGS; + + *outkey = *outval = NULL; + *outkeylen = *outvallen = 0; + +again: + if (_yp_dobind(indomain, &ysd) != 0) + return YPERR_DOMAIN; + + tv.tv_sec = _yplib_timeout; + tv.tv_usec = 0; + + yprnk.domain = (char *)indomain; + yprnk.map = (char *)inmap; + (void)memset(&yprkv, 0, sizeof yprkv); + + r = clnt_call(ysd->dom_client, YPPROC_FIRST, + xdr_ypreq_nokey, &yprnk, xdr_ypresp_key_val, &yprkv, tv); + if (r != RPC_SUCCESS) { + if (tries++) + clnt_perror(ysd->dom_client, "yp_first: clnt_call"); + ysd->dom_vers = -1; + goto again; + } + if (!(r = ypprot_err(yprkv.stat))) { + *outkeylen = yprkv.key.keydat_len; + if ((*outkey = malloc(*outkeylen + 1)) == NULL) + r = YPERR_RESRC; + else { + (void)memcpy(*outkey, yprkv.key.keydat_val, *outkeylen); + (*outkey)[*outkeylen] = '\0'; + } + *outvallen = yprkv.val.valdat_len; + if ((*outval = malloc(*outvallen + 1)) == NULL) + r = YPERR_RESRC; + else { + (void)memcpy(*outval, yprkv.val.valdat_val, *outvallen); + (*outval)[*outvallen] = '\0'; + } + } + xdr_free(xdr_ypresp_key_val, (char *) &yprkv); + _yp_unbind(ysd); + return r; +} diff --git a/nis.subproj/yp_get_default_domain.c b/nis.subproj/yp_get_default_domain.c new file mode 100644 index 0000000..373d1a4 --- /dev/null +++ b/nis.subproj/yp_get_default_domain.c @@ -0,0 +1,87 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: yp_get_default_domain.c,v 1.3 1996/08/19 08:35:09 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ypinternal.h" + +int +yp_get_default_domain(domp) + char **domp; +{ + *domp = NULL; + + if (_yp_domain[0] == '\0') + /* bug in sysctl() ? */ + if (getdomainname(_yp_domain, sizeof _yp_domain) < 0) + return YPERR_NODOM; + *domp = _yp_domain; + return 0; +} diff --git a/nis.subproj/yp_maplist.c b/nis.subproj/yp_maplist.c new file mode 100644 index 0000000..e795ad2 --- /dev/null +++ b/nis.subproj/yp_maplist.c @@ -0,0 +1,106 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: yp_maplist.c,v 1.5 1996/12/03 08:20:04 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ypinternal.h" + +int +yp_maplist(indomain, outmaplist) + const char *indomain; + struct ypmaplist **outmaplist; +{ + struct dom_binding *ysd; + struct ypresp_maplist ypml; + struct timeval tv; + int tries = 0, r; + +again: + if (_yp_dobind(indomain, &ysd) != 0) + return YPERR_DOMAIN; + + tv.tv_sec = _yplib_timeout; + tv.tv_usec = 0; + + memset(&ypml, 0, sizeof ypml); + + r = clnt_call(ysd->dom_client, YPPROC_MAPLIST, + xdr_domainname, &indomain, xdr_ypresp_maplist, &ypml, tv); + if (r != RPC_SUCCESS) { + if (tries++) + clnt_perror(ysd->dom_client, "yp_maplist: clnt_call"); + ysd->dom_vers = -1; + goto again; + } + *outmaplist = ypml.maps; + /* NO: xdr_free(xdr_ypresp_maplist, &ypml); */ + _yp_unbind(ysd); + return ypprot_err(ypml.stat); +} diff --git a/nis.subproj/yp_master.c b/nis.subproj/yp_master.c new file mode 100644 index 0000000..b3a0795 --- /dev/null +++ b/nis.subproj/yp_master.c @@ -0,0 +1,119 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: yp_master.c,v 1.5 1996/12/03 08:20:05 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ypinternal.h" + +int +yp_master(indomain, inmap, outname) + const char *indomain; + const char *inmap; + char **outname; +{ + struct dom_binding *ysd; + struct ypresp_master yprm; + struct ypreq_nokey yprnk; + struct timeval tv; + int tries = 0, r; + + if (indomain == NULL || *indomain == '\0' || + strlen(indomain) > YPMAXDOMAIN || inmap == NULL || + *inmap == '\0' || strlen(inmap) > YPMAXMAP || outname == NULL) + return YPERR_BADARGS; + +again: + if (_yp_dobind(indomain, &ysd) != 0) + return YPERR_DOMAIN; + + tv.tv_sec = _yplib_timeout; + tv.tv_usec = 0; + + yprnk.domain = (char *)indomain; + yprnk.map = (char *)inmap; + + (void)memset(&yprm, 0, sizeof yprm); + + r = clnt_call(ysd->dom_client, YPPROC_MASTER, + xdr_ypreq_nokey, &yprnk, xdr_ypresp_master, &yprm, tv); + if (r != RPC_SUCCESS) { + if (tries++) + clnt_perror(ysd->dom_client, "yp_master: clnt_call"); + ysd->dom_vers = -1; + goto again; + } + if (!(r = ypprot_err(yprm.stat))) { + if ((*outname = strdup(yprm.peer)) == NULL) + r = YPERR_RESRC; + } + xdr_free(xdr_ypresp_master, (char *) &yprm); + _yp_unbind(ysd); + return r; +} diff --git a/nis.subproj/yp_order.c b/nis.subproj/yp_order.c new file mode 100644 index 0000000..44b7a7c --- /dev/null +++ b/nis.subproj/yp_order.c @@ -0,0 +1,125 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: yp_order.c,v 1.5 1996/08/19 08:35:11 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "ypinternal.h" + +int +yp_order(indomain, inmap, outorder) + const char *indomain; + const char *inmap; + int *outorder; +{ + struct dom_binding *ysd; + struct ypresp_order ypro; + struct ypreq_nokey yprnk; + struct timeval tv; + int r = 0; + + if (indomain == NULL || *indomain == '\0' || + strlen(indomain) > YPMAXDOMAIN || inmap == NULL || + *inmap == '\0' || strlen(inmap) > YPMAXMAP || outorder == NULL) + return YPERR_BADARGS; + +again: + if (_yp_dobind(indomain, &ysd) != 0) + return YPERR_DOMAIN; + + tv.tv_sec = _yplib_timeout; + tv.tv_usec = 0; + + yprnk.domain = (char *)indomain; + yprnk.map = (char *)inmap; + + (void)memset(&ypro, 0, sizeof ypro); + + r = clnt_call(ysd->dom_client, YPPROC_ORDER, + xdr_ypreq_nokey, &yprnk, xdr_ypresp_order, &ypro, tv); + /* + * XXX + * NIS+ YP emulation package does not impliment YPPROC_ORDER + */ + if (r == RPC_PROCUNAVAIL) { + r = YPERR_YPERR; + goto bail; + } + if (r != RPC_SUCCESS) { + clnt_perror(ysd->dom_client, "yp_order: clnt_call"); + ysd->dom_vers = -1; + goto again; + } + *outorder = ypro.ordernum; + xdr_free(xdr_ypresp_order, (char *) &ypro); + r = ypprot_err(ypro.stat); +bail: + _yp_unbind(ysd); + return r; +} diff --git a/nis.subproj/yp_prot.h b/nis.subproj/yp_prot.h new file mode 100644 index 0000000..1be2a2e --- /dev/null +++ b/nis.subproj/yp_prot.h @@ -0,0 +1,365 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#ifndef _RPCSVC_YP_PROT_H_ +#define _RPCSVC_YP_PROT_H_ + +/* + * YPSERV PROTOCOL: + * + * 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). + * true if ypserv serves the named domain. + * YPPROC_DOMAIN_NOACK takes (char *), returns (bool_t). + * true if ypserv serves the named domain. + * used for broadcasts, does not ack if ypserv + * doesn't handle named domain. + * YPPROC_MATCH takes (struct ypreq_key), returns (struct ypresp_val) + * does a lookup. + * YPPROC_FIRST takes (struct ypreq_nokey) returns (ypresp_key_val). + * gets the first key/datum from the map. + * YPPROC_NEXT takes (struct ypreq_key) returns (ypresp_key_val). + * gets the next key/datum from the map. + * YPPROC_XFR takes (struct ypreq_xfr), returns (void). + * tells ypserv to check if there is a new version of + * the map. + * YPPROC_CLEAR takes (void), returns (void). + * tells ypserv to flush it's file cache, so that + * newly transferred files will get read. + * YPPROC_ALL takes (struct ypreq_nokey), returns (bool_t and + * struct ypresp_key_val). + * returns an array of data, with the bool_t being + * false on the last datum. read the source, it's + * convoluted. + * YPPROC_MASTER takes (struct ypreq_nokey), returns (ypresp_master). + * YPPROC_ORDER takes (struct ypreq_nokey), returns (ypresp_order). + * YPPROC_MAPLIST takes (char *), returns (struct ypmaplist *). + */ + +#ifndef BOOL_DEFINED +typedef u_int bool; +#define BOOL_DEFINED +#endif + + +/* Program and version symbols, magic numbers */ +#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 + * simply defined it so that their own code wouldn't try to send + * packets over the ethernet MTU. This YP code doesn't use it. + */ +#define YPMSGSZ 1600 + +#ifndef DATUM +typedef struct { + const char *dptr; + int dsize; +} datum; +#define DATUM +#endif + +struct ypmap_parms { + const char *domain; + const char *map; + u_long ordernum; + char *owner; +}; + +struct ypreq_key { + const char *domain; + const char *map; + datum keydat; +}; + +struct ypreq_nokey { + const char *domain; + const char *map; +}; + +struct ypreq_xfr { + struct ypmap_parms map_parms; + u_long transid; + u_long proto; + u_short port; +}; +#define ypxfr_domain map_parms.domain +#define ypxfr_map map_parms.map +#define ypxfr_ordernum map_parms.ordernum +#define ypxfr_owner map_parms.owner + +struct ypresp_val { + u_long status; + datum valdat; +}; + +struct ypresp_key_val { + u_long status; + datum keydat; + datum valdat; +}; + +struct ypresp_master { + u_long status; + char *master; +}; + +struct ypresp_order { + u_long status; + u_long ordernum; +}; + +struct ypresp_all { + bool_t more; + union { + struct ypresp_key_val val; + } ypresp_all_u; +}; + +struct ypmaplist { + char ypml_name[YPMAXMAP + 1]; + struct ypmaplist *ypml_next; +}; + +struct ypresp_maplist { + u_long status; + struct ypmaplist *list; +}; + +/* ypserv procedure numbers */ +#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 */ +#define YP_NOMORE ((long)2) /* no more entries in map */ +#define YP_FALSE ((long)0) /* general purpose failure code */ +#define YP_NOMAP ((long)-1) /* no such map in domain */ +#define YP_NODOM ((long)-2) /* domain not supported */ +#define YP_NOKEY ((long)-3) /* no such key in map */ +#define YP_BADOP ((long)-4) /* invalid operation */ +#define YP_BADDB ((long)-5) /* server data base is bad */ +#define YP_YPERR ((long)-6) /* YP server error */ +#define YP_BADARGS ((long)-7) /* request arguments bad */ +#define YP_VERS ((long)-8) /* YP server version mismatch */ + +/* + * Sun's header file says: + * "Domain binding data structure, used by ypclnt package and ypserv modules. + * 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.. + * we provide this.. exactly as Sun wants it. + */ +struct dom_binding { + struct dom_binding *dom_pnext; + char dom_domain[YPMAXDOMAIN + 1]; + struct sockaddr_in dom_server_addr; + u_short dom_server_port; + int dom_socket; + CLIENT *dom_client; + u_short dom_local_port; + long dom_vers; +}; + +/* + * YPBIND PROTOCOL: + * + * ypbind supports the following procedures: + * + * YPBINDPROC_NULL takes (void), returns (void). + * to check if ypbind is running. + * YPBINDPROC_DOMAIN takes (char *), returns (struct ypbind_resp). + * requests that ypbind start to serve the + * named domain (if it doesn't already) + * YPBINDPROC_SETDOM takes (struct ypbind_setdom), returns (void). + * used by ypset. + */ + +#define YPBINDPROG ((u_long)100007) +#define YPBINDVERS ((u_long)2) +#define YPBINDVERS_ORIG ((u_long)1) + +/* ypbind procedure numbers */ +#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 { + YPBIND_SUCC_VAL = 1, + YPBIND_FAIL_VAL = 2 +}; + +/* network order, of course */ +struct ypbind_binding { + struct in_addr ypbind_binding_addr; + u_short ypbind_binding_port; +}; + +struct ypbind_resp { + enum ypbind_resptype ypbind_status; + union { + u_long ypbind_error; + struct ypbind_binding ypbind_bindinfo; + } ypbind_respbody; +}; + +/* error code in ypbind_resp.ypbind_respbody.ypbind_error */ +#define YPBIND_ERR_ERR 1 /* internal error */ +#define YPBIND_ERR_NOSERV 2 /* no bound server for passed domain */ +#define YPBIND_ERR_RESC 3 /* system resource allocation failure */ + +/* + * Request data structure for ypbind "Set domain" procedure. + */ +struct ypbind_setdom { + char ypsetdom_domain[YPMAXDOMAIN + 1]; + struct ypbind_binding ypsetdom_binding; + u_short ypsetdom_vers; +}; +#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." + * + * This protocol is not implimented, naturally, because this YP + * implimentation only does the client side. + */ +#define YPPUSHVERS ((u_long)1) +#define YPPUSHVERS_ORIG ((u_long)1) + +/* yppush procedure numbers */ +#define YPPUSHPROC_NULL ((u_long)0) +#define YPPUSHPROC_XFRRESP ((u_long)1) + +struct yppushresp_xfr { + u_long transid; + u_long status; +}; + +/* yppush status value in yppushresp_xfr.status */ +#define YPPUSH_SUCC ((long)1) /* Success */ +#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_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_BADARGS ((long)-7) /* Request arguments bad */ +#define YPPUSH_DBM ((long)-8) /* Local dbm operation failed */ +#define YPPUSH_FILE ((long)-9) /* Local file I/O operation failed */ +#define YPPUSH_SKEW ((long)-10) /* Map version skew during transfer */ +#define YPPUSH_CLEAR ((long)-11) /* Can't send "Clear" req to local ypserv */ +#define YPPUSH_FORCE ((long)-12) /* No local order number in map - use -f */ +#define YPPUSH_XFRERR ((long)-13) /* ypxfr error */ +#define YPPUSH_REFUSED ((long)-14) /* Transfer request refused by ypserv */ + +__BEGIN_DECLS +bool_t xdr_domainname __P((XDR *, char *)); +bool_t xdr_peername __P((XDR *, char *)); +bool_t xdr_datum __P((XDR *, datum *)); +bool_t xdr_mapname __P((XDR *, char *)); +bool_t xdr_ypreq_key __P((XDR *, struct ypreq_key *)); +bool_t xdr_ypreq_nokey __P((XDR *, struct ypreq_nokey *)); +bool_t xdr_yp_inaddr __P((XDR *, struct in_addr *)); +bool_t xdr_ypbind_binding __P((XDR *, struct ypbind_binding *)); +bool_t xdr_ypbind_resptype __P((XDR *, enum ypbind_resptype *)); +bool_t xdr_ypstat __P((XDR *, enum ypbind_resptype *)); +bool_t xdr_ypbind_resp __P((XDR *, struct ypbind_resp *)); +bool_t xdr_ypresp_val __P((XDR *, struct ypresp_val *)); +bool_t xdr_ypbind_setdom __P((XDR *, struct ypbind_setdom *)); +bool_t xdr_ypresp_key_val __P((XDR *, struct ypresp_key_val *)); +bool_t xdr_ypresp_all __P((XDR *, struct ypresp_all *)); +bool_t xdr_ypresp_all_seq __P((XDR *, u_long *)); +bool_t xdr_ypresp_master __P((XDR *, struct ypresp_master *)); +bool_t xdr_ypmaplist_str __P((XDR *, char *)); +bool_t xdr_ypmaplist __P((XDR *, struct ypmaplist *)); +bool_t xdr_ypresp_maplist __P((XDR *, struct ypresp_maplist *)); +bool_t xdr_ypresp_order __P((XDR *, struct ypresp_order *)); +__END_DECLS + +#endif /* _RPCSVC_YP_PROT_H_ */ diff --git a/nis.subproj/ypclnt.h b/nis.subproj/ypclnt.h new file mode 100644 index 0000000..c09e8b1 --- /dev/null +++ b/nis.subproj/ypclnt.h @@ -0,0 +1,111 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#ifndef _RPCSVC_YPCLNT_H_ +#define _RPCSVC_YPCLNT_H_ + +#define YPERR_BADARGS 1 /* args to function are bad */ +#define YPERR_RPC 2 /* RPC failure */ +#define YPERR_DOMAIN 3 /* can't bind to a server for domain */ +#define YPERR_MAP 4 /* no such map in server's domain */ +#define YPERR_KEY 5 /* no such key in map */ +#define YPERR_YPERR 6 /* some internal YP server or client error */ +#define YPERR_RESRC 7 /* local resource allocation failure */ +#define YPERR_NOMORE 8 /* no more records in map database */ +#define YPERR_PMAP 9 /* can't communicate with portmapper */ +#define YPERR_YPBIND 10 /* can't communicate with ypbind */ +#define YPERR_YPSERV 11 /* can't communicate with ypserv */ +#define YPERR_NODOM 12 /* local domain name not set */ +#define YPERR_BADDB 13 /* YP data base is bad */ +#define YPERR_VERS 14 /* YP version mismatch */ +#define YPERR_ACCESS 15 /* access violation */ +#define YPERR_BUSY 16 /* database is busy */ + +/* + * Types of update operations + */ +#define YPOP_CHANGE 1 /* change, do not add */ +#define YPOP_INSERT 2 /* add, do not change */ +#define YPOP_DELETE 3 /* delete this entry */ +#define YPOP_STORE 4 /* add, or change */ + +struct ypall_callback { + /* return non-0 to stop getting called */ + int (*foreach) __P((u_long, char *, int, char *, int, void *)); + char *data; /* opaque pointer for use of callback fn */ +}; + +__BEGIN_DECLS +int yp_bind __P((const char *)); +struct dom_binding; +int _yp_dobind __P((const char *, struct dom_binding **)); +void yp_unbind __P((const char *)); +int yp_get_default_domain __P((char **)); +int yp_match __P((const char *, const char *, const char *, + int , char **, int *)); +int yp_first __P((const char *, const char *, char **, int *, + char **, int *)); +int yp_next __P((const char *, const char *, const char *, + int, char **, int *, char **, int *)); +int yp_master __P((const char *, const char *, char **)); +int yp_order __P((const char *, const char *, int *)); +int yp_all __P((const char *, const char *, + struct ypall_callback *)); +char * yperr_string __P((int)); +int ypprot_err __P((unsigned int)); +struct ypmaplist; +int yp_maplist __P((const char *, struct ypmaplist **)); +__END_DECLS + +#endif /* _RPCSVC_YPCLNT_H_ */ diff --git a/nis.subproj/yperr_string.c b/nis.subproj/yperr_string.c new file mode 100644 index 0000000..4b98ee6 --- /dev/null +++ b/nis.subproj/yperr_string.c @@ -0,0 +1,118 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: yperr_string.c,v 1.3 1996/08/19 08:35:12 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +char * +yperr_string(incode) + int incode; +{ + static char err[80]; + + switch (incode) { + case 0: + return "Success"; + case YPERR_BADARGS: + return "Request arguments bad"; + case YPERR_RPC: + return "RPC failure"; + case YPERR_DOMAIN: + return "Can't bind to server which serves this domain"; + case YPERR_MAP: + return "No such map in server's domain"; + case YPERR_KEY: + return "No such key in map"; + case YPERR_YPERR: + return "YP server error"; + case YPERR_RESRC: + return "Local resource allocation failure"; + case YPERR_NOMORE: + return "No more records in map database"; + case YPERR_PMAP: + return "Can't communicate with portmapper"; + case YPERR_YPBIND: + return "Can't communicate with ypbind"; + case YPERR_YPSERV: + return "Can't communicate with ypserv"; + case YPERR_NODOM: + return "Local domain name not set"; + case YPERR_BADDB: + return "Server data base is bad"; + case YPERR_VERS: + return "YP server version mismatch - server can't supply service."; + case YPERR_ACCESS: + return "Access violation"; + case YPERR_BUSY: + return "Database is busy"; + } + (void) snprintf(err, sizeof(err), "YP unknown error %d\n", incode); + return err; +} diff --git a/nis.subproj/ypinternal.h b/nis.subproj/ypinternal.h new file mode 100644 index 0000000..03e40fc --- /dev/null +++ b/nis.subproj/ypinternal.h @@ -0,0 +1,100 @@ +/* + * 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@ + */ +/* $OpenBSD: ypinternal.h,v 1.2 1996/09/15 09:32:00 tholo Exp $ */ + +/* + * Copyright (c) 1992, 1993, 1996 Theo de Raadt + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +/* + * XXX We have to define these here due to clashes between + * yp_prot.h and yp.h. + */ +struct dom_binding { + struct dom_binding *dom_pnext; + char dom_domain[YPMAXDOMAIN + 1]; + struct sockaddr_in dom_server_addr; + u_short dom_server_port; + int dom_socket; + CLIENT *dom_client; + u_short dom_local_port; + long dom_vers; +}; + +#define BINDINGDIR "/var/yp/binding" +#define YPBINDLOCK "/var/run/ypbind.lock" + +extern struct dom_binding *_ypbindlist; +extern char _yp_domain[MAXHOSTNAMELEN]; +extern int _yplib_timeout; + +void _yp_unbind __P((struct dom_binding *)); +int _yp_check __P((char **)); + +int getdomainname(char *val, size_t len); + +#ifdef YPMATCHCACHE + +static bool_t ypmatch_add __P((const char *, const char *, + u_int, char *, u_int)); +static bool_t ypmatch_find __P((const char *, const char *, + u_int, char **, u_int *)); + +static struct ypmatch_ent { + struct ypmatch_ent *next; + char *map, *key; + char *val; + int keylen, vallen; + time_t expire_t; +} *ypmc; +extern int _yplib_cache; + +#endif diff --git a/nis.subproj/ypmatch_cache.c b/nis.subproj/ypmatch_cache.c new file mode 100644 index 0000000..e689913 --- /dev/null +++ b/nis.subproj/ypmatch_cache.c @@ -0,0 +1,324 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: ypmatch_cache.c,v 1.6 1996/12/03 08:20:06 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/* #define YPMATCHCACHE */ +#include "ypinternal.h" + +int _yplib_cache = 5; + +#ifdef YPMATCHCACHE +static bool_t +ypmatch_add(map, key, keylen, val, vallen) + const char *map; + const char *key; + u_int keylen; + char *val; + u_int vallen; +{ + struct ypmatch_ent *ep; + time_t t; + + (void)time(&t); + + for (ep = ypmc; ep; ep = ep->next) + if (ep->expire_t < t) + break; + if (ep == NULL) { + if ((ep = malloc(sizeof *ep)) == NULL) + return 0; + (void)memset(ep, 0, sizeof *ep); + if (ypmc) + ep->next = ypmc; + ypmc = ep; + } + + if (ep->key) { + free(ep->key); + ep->key = NULL; + } + if (ep->val) { + free(ep->val); + ep->val = NULL; + } + + if ((ep->key = malloc(keylen)) == NULL) + return 0; + + if ((ep->val = malloc(vallen)) == NULL) { + free(ep->key); + ep->key = NULL; + return 0; + } + + ep->keylen = keylen; + ep->vallen = vallen; + + (void)memcpy(ep->key, key, ep->keylen); + (void)memcpy(ep->val, val, ep->vallen); + + if (ep->map) { + if (strcmp(ep->map, map)) { + free(ep->map); + if ((ep->map = strdup(map)) == NULL) + return 0; + } + } else { + if ((ep->map = strdup(map)) == NULL) + return 0; + } + + ep->expire_t = t + _yplib_cache; + return 1; +} + +static bool_t +ypmatch_find(map, key, keylen, val, vallen) + const char *map; + const char *key; + u_int keylen; + char **val; + u_int *vallen; +{ + struct ypmatch_ent *ep; + time_t t; + + if (ypmc == NULL) + return 0; + + (void) time(&t); + + for (ep = ypmc; ep; ep = ep->next) { + if (ep->keylen != keylen) + continue; + if (strcmp(ep->map, map)) + continue; + if (memcmp(ep->key, key, keylen)) + continue; + if (t > ep->expire_t) + continue; + + *val = ep->val; + *vallen = ep->vallen; + return 1; + } + return 0; +} +#endif + +int +yp_match(indomain, inmap, inkey, inkeylen, outval, outvallen) + const char *indomain; + const char *inmap; + const char *inkey; + int inkeylen; + char **outval; + int *outvallen; +{ + struct dom_binding *ysd; + struct ypresp_val yprv; + struct timeval tv; + struct ypreq_key yprk; + int tries = 0, r; + + if (indomain == NULL || *indomain == '\0' || + strlen(indomain) > YPMAXDOMAIN || inmap == NULL || + *inmap == '\0' || strlen(inmap) > YPMAXMAP || + inkey == NULL || inkeylen == 0) + return YPERR_BADARGS; + + *outval = NULL; + *outvallen = 0; + +again: + if (_yp_dobind(indomain, &ysd) != 0) + return YPERR_DOMAIN; + +#ifdef YPMATCHCACHE + if (!strcmp(_yp_domain, indomain) && ypmatch_find(inmap, inkey, + inkeylen, &yprv.val.valdat_val, &yprv.val.valdat_len)) { + *outvallen = yprv.val.valdat_len; + if ((*outval = malloc(*outvallen + 1)) == NULL) { + _yp_unbind(ysd); + return YPERR_YPERR; + } + (void)memcpy(*outval, yprv.val.valdat_val, *outvallen); + (*outval)[*outvallen] = '\0'; + _yp_unbind(ysd); + return 0; + } +#endif + + tv.tv_sec = _yplib_timeout; + tv.tv_usec = 0; + + yprk.domain = (char *)indomain; + yprk.map = (char *)inmap; + yprk.key.keydat_val = (char *) inkey; + yprk.key.keydat_len = inkeylen; + + memset(&yprv, 0, sizeof yprv); + + r = clnt_call(ysd->dom_client, YPPROC_MATCH, + xdr_ypreq_key, &yprk, xdr_ypresp_val, &yprv, tv); + if (r != RPC_SUCCESS) { + if (tries++) + clnt_perror(ysd->dom_client, "yp_match: clnt_call"); + ysd->dom_vers = -1; + goto again; + } + if (!(r = ypprot_err(yprv.stat))) { + *outvallen = yprv.val.valdat_len; + if ((*outval = malloc(*outvallen + 1)) == NULL) { + r = YPERR_YPERR; + goto out; + } + (void)memcpy(*outval, yprv.val.valdat_val, *outvallen); + (*outval)[*outvallen] = '\0'; +#ifdef YPMATCHCACHE + if (strcmp(_yp_domain, indomain) == 0) + if (!ypmatch_add(inmap, inkey, inkeylen, + *outval, *outvallen)) + r = YPERR_RESRC; +#endif + } +out: + xdr_free(xdr_ypresp_val, (char *) &yprv); + _yp_unbind(ysd); + return r; +} + +int +yp_next(indomain, inmap, inkey, inkeylen, outkey, outkeylen, outval, outvallen) + const char *indomain; + const char *inmap; + const char *inkey; + int inkeylen; + char **outkey; + int *outkeylen; + char **outval; + int *outvallen; +{ + struct ypresp_key_val yprkv; + struct ypreq_key yprk; + struct dom_binding *ysd; + struct timeval tv; + int tries = 0, r; + + if (indomain == NULL || *indomain == '\0' || + strlen(indomain) > YPMAXDOMAIN || inmap == NULL || + *inmap == '\0' || strlen(inmap) > YPMAXMAP) + return YPERR_BADARGS; + + *outkey = *outval = NULL; + *outkeylen = *outvallen = 0; + +again: + if (_yp_dobind(indomain, &ysd) != 0) + return YPERR_DOMAIN; + + tv.tv_sec = _yplib_timeout; + tv.tv_usec = 0; + + yprk.domain = (char *)indomain; + yprk.map = (char *)inmap; + yprk.key.keydat_val = (char *)inkey; + yprk.key.keydat_len = inkeylen; + (void)memset(&yprkv, 0, sizeof yprkv); + + r = clnt_call(ysd->dom_client, YPPROC_NEXT, + xdr_ypreq_key, &yprk, xdr_ypresp_key_val, &yprkv, tv); + if (r != RPC_SUCCESS) { + if (tries++) + clnt_perror(ysd->dom_client, "yp_next: clnt_call"); + ysd->dom_vers = -1; + goto again; + } + if (!(r = ypprot_err(yprkv.stat))) { + *outkeylen = yprkv.key.keydat_len; + if ((*outkey = malloc(*outkeylen + 1)) == NULL) + r = YPERR_RESRC; + else { + (void)memcpy(*outkey, yprkv.key.keydat_val, *outkeylen); + (*outkey)[*outkeylen] = '\0'; + } + *outvallen = yprkv.val.valdat_len; + if ((*outval = malloc(*outvallen + 1)) == NULL) + r = YPERR_RESRC; + else { + (void)memcpy(*outval, yprkv.val.valdat_val, *outvallen); + (*outval)[*outvallen] = '\0'; + } + } + xdr_free(xdr_ypresp_key_val, (char *) &yprkv); + _yp_unbind(ysd); + return r; +} diff --git a/nis.subproj/yppasswdd_xdr.c b/nis.subproj/yppasswdd_xdr.c new file mode 100644 index 0000000..d285182 --- /dev/null +++ b/nis.subproj/yppasswdd_xdr.c @@ -0,0 +1,105 @@ +/* + * 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@ + */ +/* $OpenBSD: yppasswdd_xdr.c,v 1.4 1997/08/19 07:00:52 niklas Exp $ */ + +/* + * Copyright (c) 1994 Mats O Jansson + * 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 Mats O Jansson + * 4. 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 + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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. + */ + +#ifndef LINT +static char rcsid[] = "$OpenBSD: yppasswdd_xdr.c,v 1.4 1997/08/19 07:00:52 niklas Exp $"; +#endif + +#include +#include + +bool_t +xdr_x_passwd(xdrs, objp) + XDR *xdrs; + x_passwd *objp; +{ + if (!xdr_string(xdrs, &objp->pw_name, ~0)) { + return (FALSE); + } + if (!xdr_string(xdrs, &objp->pw_passwd, ~0)) { + return (FALSE); + } + if (!xdr_int(xdrs, &objp->pw_uid)) { + return (FALSE); + } + if (!xdr_int(xdrs, &objp->pw_gid)) { + return (FALSE); + } + if (!xdr_string(xdrs, &objp->pw_gecos, ~0)) { + return (FALSE); + } + if (!xdr_string(xdrs, &objp->pw_dir, ~0)) { + return (FALSE); + } + if (!xdr_string(xdrs, &objp->pw_shell, ~0)) { + return (FALSE); + } + return (TRUE); +} + +bool_t +xdr_yppasswd(xdrs, objp) + XDR *xdrs; + yppasswd *objp; +{ + if (!xdr_string(xdrs, &objp->oldpass, ~0)) { + return (FALSE); + } + if (!xdr_x_passwd(xdrs, &objp->newpw)) { + return (FALSE); + } + return (TRUE); +} diff --git a/nis.subproj/ypprot_err.c b/nis.subproj/ypprot_err.c new file mode 100644 index 0000000..7c955fb --- /dev/null +++ b/nis.subproj/ypprot_err.c @@ -0,0 +1,103 @@ +/* + * 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 + * 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 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. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: ypprot_err.c,v 1.4 1996/12/14 06:49:47 tholo Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int +ypprot_err(incode) + unsigned int incode; +{ + switch ((int)incode) { + case YP_TRUE: + return 0; + case YP_FALSE: + return YPERR_YPBIND; + case YP_NOMORE: + return YPERR_NOMORE; + case YP_NOMAP: + return YPERR_MAP; + case YP_NODOM: + return YPERR_NODOM; + case YP_NOKEY: + return YPERR_KEY; + case YP_BADOP: + return YPERR_YPERR; + case YP_BADDB: + return YPERR_BADDB; + case YP_YPERR: + return YPERR_YPERR; + case YP_BADARGS: + return YPERR_BADARGS; + case YP_VERS: + return YPERR_VERS; + } + return YPERR_YPERR; +} diff --git a/rpc.subproj/Makefile b/rpc.subproj/Makefile new file mode 100644 index 0000000..4bf2c53 --- /dev/null +++ b/rpc.subproj/Makefile @@ -0,0 +1,60 @@ +# +# Generated by the NeXT Project Builder. +# +# NOTE: Do NOT change this file -- Project Builder maintains it. +# +# Put all of your customizations in files called Makefile.preamble +# and Makefile.postamble (both optional), and Makefile will include them. +# + +NAME = rpc + +PROJECTVERSION = 2.8 +PROJECT_TYPE = Component + +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 + +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_stdio.c getrpcport.c + +OTHERSRCS = Makefile.preamble Makefile + + +MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles +CODE_GEN_STYLE = DYNAMIC +MAKEFILE = subproj.make +LIBS = +DEBUG_LIBS = $(LIBS) +PROF_LIBS = $(LIBS) + + +PUBLIC_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 + + + +NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc +WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc +PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc +NEXTSTEP_JAVA_COMPILER = /usr/bin/javac +WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe +PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac + +include $(MAKEFILEDIR)/platform.make + +-include Makefile.preamble + +include $(MAKEFILEDIR)/$(MAKEFILE) + +-include Makefile.postamble + +-include Makefile.dependencies diff --git a/rpc.subproj/Makefile.preamble b/rpc.subproj/Makefile.preamble new file mode 100644 index 0000000..1d84ceb --- /dev/null +++ b/rpc.subproj/Makefile.preamble @@ -0,0 +1,8 @@ +OTHER_CFLAGS = \ + -Dsetrpcent=_old_setrpcent \ + -Dgetrpcent=_old_getrpcent \ + -Dendrpcent=_old_endrpcent \ + -Dgetrpcbyname=_old_getrpcbyname \ + -Dgetrpcbynumber=_old_getrpcbynumber + +PUBLIC_HEADER_DIR_SUFFIX = /rpc diff --git a/rpc.subproj/PB.project b/rpc.subproj/PB.project new file mode 100644 index 0000000..859704b --- /dev/null +++ b/rpc.subproj/PB.project @@ -0,0 +1,88 @@ +{ + DYNAMIC_CODE_GEN = YES; + FILESTABLE = { + H_FILES = ( + 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 + ); + OTHER_LINKED = ( + 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_stdio.c, + getrpcport.c + ); + OTHER_SOURCES = (Makefile.preamble, Makefile); + PUBLIC_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 + ); + }; + LANGUAGE = English; + MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; + NEXTSTEP_BUILDTOOL = /bin/gnumake; + NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; + NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; + PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; + PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; + PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; + PROJECTNAME = rpc; + PROJECTTYPE = Component; + PROJECTVERSION = 2.8; + WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; + WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; + WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; +} diff --git a/rpc.subproj/auth.h b/rpc.subproj/auth.h new file mode 100644 index 0000000..bc5f843 --- /dev/null +++ b/rpc.subproj/auth.h @@ -0,0 +1,201 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)auth.h 1.17 88/02/08 SMI + * from: @(#)auth.h 2.3 88/08/07 4.0 RPCSRC + * $Id: auth.h,v 1.2 1999/10/14 21:56:52 wsanchez Exp $ + */ + +/* + * auth.h, Authentication interface. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The data structures are completely opaque to the client. The client + * is required to pass a AUTH * to routines that create rpc + * "sessions". + */ + +#ifndef _RPC_AUTH_H +#define _RPC_AUTH_H +#include + +#define MAX_AUTH_BYTES 400 +#define MAXNETNAMELEN 255 /* maximum length of network user's name */ + +/* + * Status returned from authentication check + */ +enum auth_stat { + AUTH_OK=0, + /* + * failed at remote end + */ + AUTH_BADCRED=1, /* bogus credentials (seal broken) */ + AUTH_REJECTEDCRED=2, /* client should begin new session */ + AUTH_BADVERF=3, /* bogus verifier (seal broken) */ + AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */ + AUTH_TOOWEAK=5, /* rejected due to security reasons */ + /* + * failed locally + */ + AUTH_INVALIDRESP=6, /* bogus response verifier */ + AUTH_FAILED=7 /* some unknown reason */ +}; + +typedef u_long u_int32; /* 32-bit unsigned integers */ + +union des_block { + struct { + u_int32 high; + u_int32 low; + } key; + char c[8]; +}; +typedef union des_block des_block; +__BEGIN_DECLS +extern bool_t xdr_des_block __P((XDR *, des_block *)); +__END_DECLS + +/* + * Authentication info. Opaque to client. + */ +struct opaque_auth { + enum_t oa_flavor; /* flavor of auth */ + caddr_t oa_base; /* address of more auth stuff */ + u_int oa_length; /* not to exceed MAX_AUTH_BYTES */ +}; + + +/* + * Auth handle, interface to client side authenticators. + */ +typedef struct { + struct opaque_auth ah_cred; + struct opaque_auth ah_verf; + union des_block ah_key; + struct auth_ops { + void (*ah_nextverf)(); + int (*ah_marshal)(); /* nextverf & serialize */ + int (*ah_validate)(); /* validate varifier */ + int (*ah_refresh)(); /* refresh credentials */ + void (*ah_destroy)(); /* destroy this structure */ + } *ah_ops; + caddr_t ah_private; +} AUTH; + + +/* + * Authentication ops. + * The ops and the auth handle provide the interface to the authenticators. + * + * AUTH *auth; + * XDR *xdrs; + * struct opaque_auth verf; + */ +#define AUTH_NEXTVERF(auth) \ + ((*((auth)->ah_ops->ah_nextverf))(auth)) +#define auth_nextverf(auth) \ + ((*((auth)->ah_ops->ah_nextverf))(auth)) + +#define AUTH_MARSHALL(auth, xdrs) \ + ((*((auth)->ah_ops->ah_marshal))(auth, xdrs)) +#define auth_marshall(auth, xdrs) \ + ((*((auth)->ah_ops->ah_marshal))(auth, xdrs)) + +#define AUTH_VALIDATE(auth, verfp) \ + ((*((auth)->ah_ops->ah_validate))((auth), verfp)) +#define auth_validate(auth, verfp) \ + ((*((auth)->ah_ops->ah_validate))((auth), verfp)) + +#define AUTH_REFRESH(auth) \ + ((*((auth)->ah_ops->ah_refresh))(auth)) +#define auth_refresh(auth) \ + ((*((auth)->ah_ops->ah_refresh))(auth)) + +#define AUTH_DESTROY(auth) \ + ((*((auth)->ah_ops->ah_destroy))(auth)) +#define auth_destroy(auth) \ + ((*((auth)->ah_ops->ah_destroy))(auth)) + + +extern struct opaque_auth _null_auth; + + +/* + * These are the various implementations of client side authenticators. + */ + +/* + * Unix style authentication + * AUTH *authunix_create(machname, uid, gid, len, aup_gids) + * char *machname; + * int uid; + * int gid; + * int len; + * int *aup_gids; + */ +__BEGIN_DECLS +extern AUTH *authunix_create __P((char *, int, int, int, int *)); +extern AUTH *authunix_create_default __P((void)); +extern AUTH *authnone_create __P((void)); +extern AUTH *authdes_create __P((char *, u_int, + struct sockaddr_in *, + des_block *)); +__END_DECLS + +#define AUTH_NONE 0 /* no authentication */ +#define AUTH_NULL 0 /* backward compatibility */ +#define AUTH_UNIX 1 /* unix style (uid, gids) */ +#define AUTH_SHORT 2 /* short hand unix style */ +#define AUTH_DES 3 /* des style (encrypted timestamps) */ + +#endif /* !_RPC_AUTH_H */ diff --git a/rpc.subproj/auth_none.c b/rpc.subproj/auth_none.c new file mode 100644 index 0000000..220a8ca --- /dev/null +++ b/rpc.subproj/auth_none.c @@ -0,0 +1,158 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)auth_none.c 2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: auth_none.c,v 1.2 1999/10/14 21:56:52 wsanchez Exp $"; +#endif + +/* + * auth_none.c + * Creates a client authentication handle for passing "null" + * credentials and verifiers to remote systems. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include +#include +#include +#define MAX_MARSHEL_SIZE 20 + +/* + * Authenticator operations routines + */ +static void authnone_verf(); +static void authnone_destroy(); +static bool_t authnone_marshal(); +static bool_t authnone_validate(); +static bool_t authnone_refresh(); + +static struct auth_ops ops = { + authnone_verf, + authnone_marshal, + authnone_validate, + authnone_refresh, + authnone_destroy +}; + +static struct authnone_private { + AUTH no_client; + char marshalled_client[MAX_MARSHEL_SIZE]; + u_int mcnt; +} *authnone_private; + +AUTH * +authnone_create() +{ + register struct authnone_private *ap = authnone_private; + XDR xdr_stream; + register XDR *xdrs; + + if (ap == 0) { + ap = (struct authnone_private *)calloc(1, sizeof (*ap)); + if (ap == 0) + return (0); + authnone_private = ap; + } + if (!ap->mcnt) { + ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth; + ap->no_client.ah_ops = &ops; + xdrs = &xdr_stream; + xdrmem_create(xdrs, ap->marshalled_client, (u_int)MAX_MARSHEL_SIZE, + XDR_ENCODE); + (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_cred); + (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_verf); + ap->mcnt = XDR_GETPOS(xdrs); + XDR_DESTROY(xdrs); + } + return (&ap->no_client); +} + +/*ARGSUSED*/ +static bool_t +authnone_marshal(client, xdrs) + AUTH *client; + XDR *xdrs; +{ + register struct authnone_private *ap = authnone_private; + + if (ap == 0) + return (0); + return ((*xdrs->x_ops->x_putbytes)(xdrs, + ap->marshalled_client, ap->mcnt)); +} + +static void +authnone_verf() +{ +} + +static bool_t +authnone_validate() +{ + + return (TRUE); +} + +static bool_t +authnone_refresh() +{ + + return (FALSE); +} + +static void +authnone_destroy() +{ +} diff --git a/rpc.subproj/auth_unix.c b/rpc.subproj/auth_unix.c new file mode 100644 index 0000000..448654d --- /dev/null +++ b/rpc.subproj/auth_unix.c @@ -0,0 +1,364 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC";*/ +static char *rcsid = "$Id: auth_unix.c,v 1.3 2001/01/17 19:05:42 majka Exp $"; +#endif + +/* + * auth_unix.c, Implements UNIX style authentication parameters. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The system is very weak. The client uses no encryption for it's + * credentials and only sends null verifiers. The server sends backs + * null verifiers or optionally a verifier that suggests a new short hand + * for the credentials. + * + */ + +#include +#include +#include + +#include +#include +#include +#include + +/* + * Unix authenticator operations vector + */ +static void authunix_nextverf(); +static bool_t authunix_marshal(); +static bool_t authunix_validate(); +static bool_t authunix_refresh(); +static void authunix_destroy(); + +static struct auth_ops auth_unix_ops = { + authunix_nextverf, + authunix_marshal, + authunix_validate, + authunix_refresh, + authunix_destroy +}; + +/* + * This struct is pointed to by the ah_private field of an auth_handle. + */ +struct audata { + struct opaque_auth au_origcred; /* original credentials */ + struct opaque_auth au_shcred; /* short hand cred */ + u_long au_shfaults; /* short hand cache faults */ + char au_marshed[MAX_AUTH_BYTES]; + u_int au_mpos; /* xdr pos at end of marshed */ +}; +#define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private) + +static bool_t marshal_new_auth(); + + +/* + * Create a unix style authenticator. + * Returns an auth handle with the given stuff in it. + */ +AUTH * +authunix_create(machname, uid, gid, len, aup_gids) + char *machname; + int uid; + int gid; + register int len; + int *aup_gids; +{ + struct authunix_parms aup; + char mymem[MAX_AUTH_BYTES]; + struct timeval now; + XDR xdrs; + register AUTH *auth; + register struct audata *au; + + /* + * Allocate and set up auth handle + */ + auth = (AUTH *)mem_alloc(sizeof(*auth)); +#ifndef KERNEL + if (auth == NULL) { + (void)fprintf(stderr, "authunix_create: out of memory\n"); + return (NULL); + } +#endif + au = (struct audata *)mem_alloc(sizeof(*au)); +#ifndef KERNEL + if (au == NULL) { + (void)fprintf(stderr, "authunix_create: out of memory\n"); + return (NULL); + } +#endif + auth->ah_ops = &auth_unix_ops; + auth->ah_private = (caddr_t)au; + auth->ah_verf = au->au_shcred = _null_auth; + au->au_shfaults = 0; + + /* + * fill in param struct from the given params + */ + (void)gettimeofday(&now, (struct timezone *)0); + aup.aup_time = now.tv_sec; + aup.aup_machname = machname; + aup.aup_uid = uid; + aup.aup_gid = gid; + aup.aup_len = (u_int)len; + aup.aup_gids = aup_gids; + + /* + * Serialize the parameters into origcred + */ + xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE); + if (! xdr_authunix_parms(&xdrs, &aup)) + abort(); + au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs); + au->au_origcred.oa_flavor = AUTH_UNIX; +#ifdef KERNEL + au->au_origcred.oa_base = mem_alloc((u_int) len); +#else + if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) { + (void)fprintf(stderr, "authunix_create: out of memory\n"); + return (NULL); + } +#endif + bcopy(mymem, au->au_origcred.oa_base, (u_int)len); + + /* + * set auth handle to reflect new cred. + */ + auth->ah_cred = au->au_origcred; + marshal_new_auth(auth); + return (auth); +} + +/* +* Some servers will refuse mounts if the group list is larger +* than it expects (like 8). This allows the application to set +* the maximum size of the group list that will be sent. +*/ + +static maxgrplist = NGROUPS; + +set_rpc_maxgrouplist(num) + int num; +{ + if (num < NGROUPS) + maxgrplist = num; +} + +/* + * Returns an auth handle with parameters determined by doing lots of + * syscalls. + */ +AUTH * +authunix_create_default() +{ + register int len; + char machname[MAX_MACHINE_NAME + 1]; + register int uid; + register int gid; + int gids[NGROUPS]; + + if (gethostname(machname, MAX_MACHINE_NAME) == -1) + abort(); + machname[MAX_MACHINE_NAME] = 0; + uid = geteuid(); + gid = getegid(); + if ((len = getgroups(NGROUPS, gids)) < 0) + abort(); + if (len > maxgrplist) { + len = maxgrplist; + } + return (authunix_create(machname, uid, gid, len, gids)); +} + +/* + * authunix operations + */ + +static void +authunix_nextverf(auth) + AUTH *auth; +{ + /* no action necessary */ +} + +static bool_t +authunix_marshal(auth, xdrs) + AUTH *auth; + XDR *xdrs; +{ + register struct audata *au = AUTH_PRIVATE(auth); + + return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos)); +} + +static bool_t +authunix_validate(auth, verf) + register AUTH *auth; + struct opaque_auth verf; +{ + register struct audata *au; + XDR xdrs; + + if (verf.oa_flavor == AUTH_SHORT) { + au = AUTH_PRIVATE(auth); + xdrmem_create(&xdrs, verf.oa_base, verf.oa_length, XDR_DECODE); + + if (au->au_shcred.oa_base != NULL) { + mem_free(au->au_shcred.oa_base, + au->au_shcred.oa_length); + au->au_shcred.oa_base = NULL; + } + if (xdr_opaque_auth(&xdrs, &au->au_shcred)) { + auth->ah_cred = au->au_shcred; + } else { + xdrs.x_op = XDR_FREE; + (void)xdr_opaque_auth(&xdrs, &au->au_shcred); + au->au_shcred.oa_base = NULL; + auth->ah_cred = au->au_origcred; + } + marshal_new_auth(auth); + } + return (TRUE); +} + +static bool_t +authunix_refresh(auth) + register AUTH *auth; +{ + register struct audata *au = AUTH_PRIVATE(auth); + struct authunix_parms aup; + struct timeval now; + XDR xdrs; + register int stat; + + if (auth->ah_cred.oa_base == au->au_origcred.oa_base) { + /* there is no hope. Punt */ + return (FALSE); + } + au->au_shfaults ++; + + /* first deserialize the creds back into a struct authunix_parms */ + aup.aup_machname = NULL; + aup.aup_gids = (int *)NULL; + xdrmem_create(&xdrs, au->au_origcred.oa_base, + au->au_origcred.oa_length, XDR_DECODE); + stat = xdr_authunix_parms(&xdrs, &aup); + if (! stat) + goto done; + + /* update the time and serialize in place */ + (void)gettimeofday(&now, (struct timezone *)0); + aup.aup_time = now.tv_sec; + xdrs.x_op = XDR_ENCODE; + XDR_SETPOS(&xdrs, 0); + stat = xdr_authunix_parms(&xdrs, &aup); + if (! stat) + goto done; + auth->ah_cred = au->au_origcred; + marshal_new_auth(auth); +done: + /* free the struct authunix_parms created by deserializing */ + xdrs.x_op = XDR_FREE; + (void)xdr_authunix_parms(&xdrs, &aup); + XDR_DESTROY(&xdrs); + return (stat); +} + +static void +authunix_destroy(auth) + register AUTH *auth; +{ + register struct audata *au = AUTH_PRIVATE(auth); + + mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length); + + if (au->au_shcred.oa_base != NULL) + mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length); + + mem_free(auth->ah_private, sizeof(struct audata)); + + if (auth->ah_verf.oa_base != NULL) + mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length); + + mem_free((caddr_t)auth, sizeof(*auth)); +} + +/* + * Marshals (pre-serializes) an auth struct. + * sets private data, au_marshed and au_mpos + */ +static bool_t +marshal_new_auth(auth) + register AUTH *auth; +{ + XDR xdr_stream; + register XDR *xdrs = &xdr_stream; + register struct audata *au = AUTH_PRIVATE(auth); + + xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE); + if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) || + (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) { + perror("auth_none.c - Fatal marshalling problem"); + } else { + au->au_mpos = XDR_GETPOS(xdrs); + } + XDR_DESTROY(xdrs); +} diff --git a/rpc.subproj/auth_unix.h b/rpc.subproj/auth_unix.h new file mode 100644 index 0000000..a26f59a --- /dev/null +++ b/rpc.subproj/auth_unix.h @@ -0,0 +1,102 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)auth_unix.h 1.8 88/02/08 SMI + * from: @(#)auth_unix.h 2.2 88/07/29 4.0 RPCSRC + * $Id: auth_unix.h,v 1.3 2001/01/17 19:05:42 majka Exp $ + */ + +/* + * auth_unix.h, Protocol for UNIX style authentication parameters for RPC + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +/* + * The system is very weak. The client uses no encryption for it + * credentials and only sends null verifiers. The server sends backs + * null verifiers or optionally a verifier that suggests a new short hand + * for the credentials. + */ + +#ifndef _RPC_AUTH_UNIX_H +#define _RPC_AUTH_UNIX_H +#include + +/* The machine name is part of a credential; it may not exceed 255 bytes */ +#define MAX_MACHINE_NAME 255 + +/* + * Unix style credentials. + */ +struct authunix_parms { + u_long aup_time; + char *aup_machname; + int aup_uid; + int aup_gid; + u_int aup_len; + int *aup_gids; +}; + +__BEGIN_DECLS +extern bool_t xdr_authunix_parms __P((XDR *, struct authunix_parms *)); +__END_DECLS + +/* + * If a response verifier has flavor AUTH_SHORT, + * then the body of the response verifier encapsulates the following structure; + * again it is serialized in the obvious fashion. + */ +struct short_hand_verf { + struct opaque_auth new_cred; +}; + +#endif /* !_RPC_AUTH_UNIX_H */ diff --git a/rpc.subproj/authunix_prot.c b/rpc.subproj/authunix_prot.c new file mode 100644 index 0000000..dce59b3 --- /dev/null +++ b/rpc.subproj/authunix_prot.c @@ -0,0 +1,92 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)authunix_prot.c 1.15 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)authunix_prot.c 2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: authunix_prot.c,v 1.3 2001/01/17 19:05:42 majka Exp $"; +#endif + +/* + * authunix_prot.c + * XDR for UNIX style authentication parameters for RPC + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + + +#include +#include +#include +#include +#include + +/* + * XDR for unix authentication parameters. + */ +bool_t +xdr_authunix_parms(xdrs, p) + register XDR *xdrs; + register struct authunix_parms *p; +{ + + if (xdr_u_long(xdrs, &(p->aup_time)) + && xdr_string(xdrs, &(p->aup_machname), MAX_MACHINE_NAME) + && xdr_int(xdrs, &(p->aup_uid)) + && xdr_int(xdrs, &(p->aup_gid)) + && xdr_array(xdrs, (caddr_t *)&(p->aup_gids), + &(p->aup_len), NGROUPS, sizeof(int), xdr_int) ) { + return (TRUE); + } + return (FALSE); +} + diff --git a/rpc.subproj/bindresvport.c b/rpc.subproj/bindresvport.c new file mode 100644 index 0000000..14261d1 --- /dev/null +++ b/rpc.subproj/bindresvport.c @@ -0,0 +1,107 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)bindresvport.c 1.8 88/02/08 SMI";*/ +/*static char *sccsid = "from: @(#)bindresvport.c 2.2 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: bindresvport.c,v 1.2 1999/10/14 21:56:52 wsanchez Exp $"; +#endif + +/* + * Copyright (c) 1987 by Sun Microsystems, Inc. + */ + +#include +#include +#include +#include + +/* + * Bind a socket to a privileged IP port + */ +bindresvport(sd, sin) + int sd; + struct sockaddr_in *sin; +{ + int res; + static short port; + struct sockaddr_in myaddr; + extern int errno; + int i; + +#define STARTPORT 600 +#define ENDPORT (IPPORT_RESERVED - 1) +#define NPORTS (ENDPORT - STARTPORT + 1) + + if (sin == (struct sockaddr_in *)0) { + sin = &myaddr; + bzero(sin, sizeof (*sin)); + sin->sin_family = AF_INET; + } else if (sin->sin_family != AF_INET) { + errno = EPFNOSUPPORT; + return (-1); + } + if (port == 0) { + port = (getpid() % NPORTS) + STARTPORT; + } + res = -1; + errno = EADDRINUSE; + for (i = 0; i < NPORTS && res < 0 && errno == EADDRINUSE; i++) { + sin->sin_port = htons(port++); + if (port > ENDPORT) { + port = STARTPORT; + } + res = bind(sd, + (struct sockaddr *)sin, sizeof(struct sockaddr_in)); + } + return (res); +} diff --git a/rpc.subproj/clnt.h b/rpc.subproj/clnt.h new file mode 100644 index 0000000..1efee44 --- /dev/null +++ b/rpc.subproj/clnt.h @@ -0,0 +1,387 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)clnt.h 1.31 88/02/08 SMI + * from: @(#)clnt.h 2.1 88/07/29 4.0 RPCSRC + * $Id: clnt.h,v 1.2 1999/10/14 21:56:52 wsanchez Exp $ + */ + +/* + * clnt.h - Client side remote procedure call interface. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef _RPC_CLNT_H_ +#define _RPC_CLNT_H_ +#include + +/* + * Rpc calls return an enum clnt_stat. This should be looked at more, + * since each implementation is required to live with this (implementation + * independent) list of errors. + */ + +/* Avoid collision with mach definition */ +#if defined(RPC_SUCCESS) +#undef RPC_SUCCESS +#endif + +enum clnt_stat { + RPC_SUCCESS=0, /* call succeeded */ + /* + * local errors + */ + RPC_CANTENCODEARGS=1, /* can't encode arguments */ + RPC_CANTDECODERES=2, /* can't decode results */ + RPC_CANTSEND=3, /* failure in sending call */ + RPC_CANTRECV=4, /* failure in receiving result */ + RPC_TIMEDOUT=5, /* call timed out */ + /* + * remote errors + */ + RPC_VERSMISMATCH=6, /* rpc versions not compatible */ + RPC_AUTHERROR=7, /* authentication error */ + RPC_PROGUNAVAIL=8, /* program not available */ + RPC_PROGVERSMISMATCH=9, /* program version mismatched */ + RPC_PROCUNAVAIL=10, /* procedure unavailable */ + RPC_CANTDECODEARGS=11, /* decode arguments error */ + RPC_SYSTEMERROR=12, /* generic "other problem" */ + + /* + * callrpc & clnt_create errors + */ + RPC_UNKNOWNHOST=13, /* unknown host name */ + RPC_UNKNOWNPROTO=17, /* unkown protocol */ + + /* + * _ create errors + */ + RPC_PMAPFAILURE=14, /* the pmapper failed in its call */ + RPC_PROGNOTREGISTERED=15, /* remote program is not registered */ + /* + * unspecified error + */ + RPC_FAILED=16 +}; + + +/* + * Error info. + */ +struct rpc_err { + enum clnt_stat re_status; + union { + int RE_errno; /* realated system error */ + enum auth_stat RE_why; /* why the auth error occurred */ + struct { + u_long low; /* lowest verion supported */ + u_long high; /* highest verion supported */ + } RE_vers; + struct { /* maybe meaningful if RPC_FAILED */ + long s1; + long s2; + } RE_lb; /* life boot & debugging only */ + } ru; +#define re_errno ru.RE_errno +#define re_why ru.RE_why +#define re_vers ru.RE_vers +#define re_lb ru.RE_lb +}; + + +/* + * Client rpc handle. + * Created by individual implementations, see e.g. rpc_udp.c. + * Client is responsible for initializing auth, see e.g. auth_none.c. + */ +typedef struct { + AUTH *cl_auth; /* authenticator */ + struct clnt_ops { + enum clnt_stat (*cl_call)(); /* call remote procedure */ + void (*cl_abort)(); /* abort a call */ + void (*cl_geterr)(); /* get specific error code */ + bool_t (*cl_freeres)(); /* frees results */ + void (*cl_destroy)();/* destroy this structure */ + bool_t (*cl_control)();/* the ioctl() of rpc */ + } *cl_ops; + caddr_t cl_private; /* private stuff */ +} CLIENT; + + +/* + * client side rpc interface ops + * + * Parameter types are: + * + */ + +/* + * enum clnt_stat + * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout) + * CLIENT *rh; + * u_long proc; + * xdrproc_t xargs; + * caddr_t argsp; + * xdrproc_t xres; + * caddr_t resp; + * struct timeval timeout; + */ +#define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs) \ + ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs)) +#define clnt_call(rh, proc, xargs, argsp, xres, resp, secs) \ + ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs)) + +/* + * void + * CLNT_ABORT(rh); + * CLIENT *rh; + */ +#define CLNT_ABORT(rh) ((*(rh)->cl_ops->cl_abort)(rh)) +#define clnt_abort(rh) ((*(rh)->cl_ops->cl_abort)(rh)) + +/* + * struct rpc_err + * CLNT_GETERR(rh); + * CLIENT *rh; + */ +#define CLNT_GETERR(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp)) +#define clnt_geterr(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp)) + + +/* + * bool_t + * CLNT_FREERES(rh, xres, resp); + * CLIENT *rh; + * xdrproc_t xres; + * caddr_t resp; + */ +#define CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp)) +#define clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp)) + +/* + * bool_t + * CLNT_CONTROL(cl, request, info) + * CLIENT *cl; + * u_int request; + * char *info; + */ +#define CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in)) +#define clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in)) + +/* + * control operations that apply to both udp and tcp transports + */ +#define CLSET_TIMEOUT 1 /* set timeout (timeval) */ +#define CLGET_TIMEOUT 2 /* get timeout (timeval) */ +#define CLGET_SERVER_ADDR 3 /* get server's address (sockaddr) */ +/* + * udp only control operations + */ +#define CLSET_RETRY_TIMEOUT 4 /* set retry timeout (timeval) */ +#define CLGET_RETRY_TIMEOUT 5 /* get retry timeout (timeval) */ + +/* + * void + * CLNT_DESTROY(rh); + * CLIENT *rh; + */ +#define CLNT_DESTROY(rh) ((*(rh)->cl_ops->cl_destroy)(rh)) +#define clnt_destroy(rh) ((*(rh)->cl_ops->cl_destroy)(rh)) + + +/* + * RPCTEST is a test program which is accessable on every rpc + * transport/port. It is used for testing, performance evaluation, + * and network administration. + */ + +#define RPCTEST_PROGRAM ((u_long)1) +#define RPCTEST_VERSION ((u_long)1) +#define RPCTEST_NULL_PROC ((u_long)2) +#define RPCTEST_NULL_BATCH_PROC ((u_long)3) + +/* + * By convention, procedure 0 takes null arguments and returns them + */ + +#define NULLPROC ((u_long)0) + +/* + * Below are the client handle creation routines for the various + * implementations of client side rpc. They can return NULL if a + * creation failure occurs. + */ + +/* + * Memory based rpc (for speed check and testing) + * CLIENT * + * clntraw_create(prog, vers) + * u_long prog; + * u_long vers; + */ +__BEGIN_DECLS +extern CLIENT *clntraw_create __P((u_long, u_long)); +__END_DECLS + + +/* + * Generic client creation routine. Supported protocols are "udp" and "tcp" + * CLIENT * + * clnt_create(host, prog, vers, prot); + * char *host; -- hostname + * u_long prog; -- program number + * u_long vers; -- version number + * char *prot; -- protocol + */ +__BEGIN_DECLS +extern CLIENT *clnt_create __P((char *, u_long, u_long, char *)); +__END_DECLS + + +/* + * TCP based rpc + * CLIENT * + * clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz) + * struct sockaddr_in *raddr; + * u_long prog; + * u_long version; + * register int *sockp; + * u_int sendsz; + * u_int recvsz; + */ +__BEGIN_DECLS +extern CLIENT *clnttcp_create __P((struct sockaddr_in *, + u_long, + u_long, + int *, + u_int, + u_int)); +__END_DECLS + + +/* + * UDP based rpc. + * CLIENT * + * clntudp_create(raddr, program, version, wait, sockp) + * struct sockaddr_in *raddr; + * u_long program; + * u_long version; + * struct timeval wait; + * int *sockp; + * + * Same as above, but you specify max packet sizes. + * CLIENT * + * clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz) + * struct sockaddr_in *raddr; + * u_long program; + * u_long version; + * struct timeval wait; + * int *sockp; + * u_int sendsz; + * u_int recvsz; + */ +__BEGIN_DECLS +extern CLIENT *clntudp_create __P((struct sockaddr_in *, + u_long, + u_long, + struct timeval, + int *)); +extern CLIENT *clntudp_bufcreate __P((struct sockaddr_in *, + u_long, + u_long, + struct timeval, + int *, + u_int, + u_int)); +__END_DECLS + + +/* + * Print why creation failed + */ +__BEGIN_DECLS +extern void clnt_pcreateerror __P((char *)); /* stderr */ +extern char *clnt_spcreateerror __P((char *)); /* string */ +__END_DECLS + +/* + * Like clnt_perror(), but is more verbose in its output + */ +__BEGIN_DECLS +extern void clnt_perrno __P((enum clnt_stat)); /* stderr */ +extern char *clnt_sperrno __P((enum clnt_stat)); /* string */ +__END_DECLS + +/* + * Print an English error message, given the client error code + */ +__BEGIN_DECLS +extern void clnt_perror __P((CLIENT *, char *)); /* stderr */ +extern char *clnt_sperror __P((CLIENT *, char *)); /* string */ +__END_DECLS + + +/* + * If a creation fails, the following allows the user to figure out why. + */ +struct rpc_createerr { + enum clnt_stat cf_stat; + struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */ +}; + +extern struct rpc_createerr rpc_createerr; + + +#define UDPMSGSIZE 8800 /* rpc imposed limit on udp msg size */ +#define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */ + +#endif /* !_RPC_CLNT_H */ diff --git a/rpc.subproj/clnt_generic.c b/rpc.subproj/clnt_generic.c new file mode 100644 index 0000000..cd966ef --- /dev/null +++ b/rpc.subproj/clnt_generic.c @@ -0,0 +1,131 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)clnt_generic.c 1.4 87/08/11 (C) 1987 SMI";*/ +/*static char *sccsid = "from: @(#)clnt_generic.c 2.2 88/08/01 4.0 RPCSRC";*/ +static char *rcsid = "$Id: clnt_generic.c,v 1.2 1999/10/14 21:56:52 wsanchez Exp $"; +#endif + +/* + * Copyright (C) 1987, Sun Microsystems, Inc. + */ +#include +#include +#include +#include + +/* + * Generic client creation: takes (hostname, program-number, protocol) and + * returns client handle. Default options are set, which the user can + * change using the rpc equivalent of ioctl()'s. + */ +CLIENT * +clnt_create(hostname, prog, vers, proto) + char *hostname; + u_long prog; + u_long vers; + char *proto; +{ + struct hostent *h; + struct protoent *p; + struct sockaddr_in sin; + int sock; + struct timeval tv; + CLIENT *client; + + h = gethostbyname(hostname); + if (h == NULL) { + rpc_createerr.cf_stat = RPC_UNKNOWNHOST; + return (NULL); + } + if (h->h_addrtype != AF_INET) { + /* + * Only support INET for now + */ + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = EAFNOSUPPORT; + return (NULL); + } + bzero((char *)&sin, sizeof sin); + sin.sin_family = h->h_addrtype; + sin.sin_port = 0; + bcopy(h->h_addr, (char*)&sin.sin_addr, h->h_length); + p = getprotobyname(proto); + if (p == NULL) { + rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; + rpc_createerr.cf_error.re_errno = EPFNOSUPPORT; + return (NULL); + } + sock = RPC_ANYSOCK; + switch (p->p_proto) { + case IPPROTO_UDP: + tv.tv_sec = 5; + tv.tv_usec = 0; + client = clntudp_create(&sin, prog, vers, tv, &sock); + if (client == NULL) { + return (NULL); + } + break; + case IPPROTO_TCP: + client = clnttcp_create(&sin, prog, vers, &sock, 0, 0); + if (client == NULL) { + return (NULL); + } + break; + default: + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = EPFNOSUPPORT; + return (NULL); + } + return (client); +} diff --git a/rpc.subproj/clnt_perror.c b/rpc.subproj/clnt_perror.c new file mode 100644 index 0000000..7ad8e75 --- /dev/null +++ b/rpc.subproj/clnt_perror.c @@ -0,0 +1,326 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)clnt_perror.c 2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: clnt_perror.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $"; +#endif + +/* + * clnt_perror.c + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + */ +#include +#include +#include +#include +#include +#include + +static char *auth_errmsg(); + +static char *buf; + +static char * +_buf() +{ + + if (buf == 0) + buf = (char *)malloc(256); + return (buf); +} + +/* + * Print reply error info + */ +char * +clnt_sperror(rpch, s) + CLIENT *rpch; + char *s; +{ + struct rpc_err e; + void clnt_perrno(); + char *err; + char *str = _buf(); + char *strstart = str; + + if (str == 0) + return (0); + CLNT_GETERR(rpch, &e); + + (void) sprintf(str, "%s: ", s); + str += strlen(str); + + (void) strcpy(str, clnt_sperrno(e.re_status)); + str += strlen(str); + + switch (e.re_status) { + case RPC_SUCCESS: + case RPC_CANTENCODEARGS: + case RPC_CANTDECODERES: + case RPC_TIMEDOUT: + case RPC_PROGUNAVAIL: + case RPC_PROCUNAVAIL: + case RPC_CANTDECODEARGS: + case RPC_SYSTEMERROR: + case RPC_UNKNOWNHOST: + case RPC_UNKNOWNPROTO: + case RPC_PMAPFAILURE: + case RPC_PROGNOTREGISTERED: + case RPC_FAILED: + break; + + case RPC_CANTSEND: + case RPC_CANTRECV: + (void) sprintf(str, "; errno = %s", + strerror(e.re_errno)); + str += strlen(str); + break; + + case RPC_VERSMISMATCH: + (void) sprintf(str, + "; low version = %lu, high version = %lu", + e.re_vers.low, e.re_vers.high); + str += strlen(str); + break; + + case RPC_AUTHERROR: + err = auth_errmsg(e.re_why); + (void) sprintf(str,"; why = "); + str += strlen(str); + if (err != NULL) { + (void) sprintf(str, "%s",err); + } else { + (void) sprintf(str, + "(unknown authentication error - %d)", + (int) e.re_why); + } + str += strlen(str); + break; + + case RPC_PROGVERSMISMATCH: + (void) sprintf(str, + "; low version = %lu, high version = %lu", + e.re_vers.low, e.re_vers.high); + str += strlen(str); + break; + + default: /* unknown */ + (void) sprintf(str, + "; s1 = %lu, s2 = %lu", + e.re_lb.s1, e.re_lb.s2); + str += strlen(str); + break; + } + (void) sprintf(str, "\n"); + return(strstart) ; +} + +void +clnt_perror(rpch, s) + CLIENT *rpch; + char *s; +{ + (void) fprintf(stderr,"%s",clnt_sperror(rpch,s)); +} + + +struct rpc_errtab { + enum clnt_stat status; + char *message; +}; + +static struct rpc_errtab rpc_errlist[] = { + { RPC_SUCCESS, + "RPC: Success" }, + { RPC_CANTENCODEARGS, + "RPC: Can't encode arguments" }, + { RPC_CANTDECODERES, + "RPC: Can't decode result" }, + { RPC_CANTSEND, + "RPC: Unable to send" }, + { RPC_CANTRECV, + "RPC: Unable to receive" }, + { RPC_TIMEDOUT, + "RPC: Timed out" }, + { RPC_VERSMISMATCH, + "RPC: Incompatible versions of RPC" }, + { RPC_AUTHERROR, + "RPC: Authentication error" }, + { RPC_PROGUNAVAIL, + "RPC: Program unavailable" }, + { RPC_PROGVERSMISMATCH, + "RPC: Program/version mismatch" }, + { RPC_PROCUNAVAIL, + "RPC: Procedure unavailable" }, + { RPC_CANTDECODEARGS, + "RPC: Server can't decode arguments" }, + { RPC_SYSTEMERROR, + "RPC: Remote system error" }, + { RPC_UNKNOWNHOST, + "RPC: Unknown host" }, + { RPC_UNKNOWNPROTO, + "RPC: Unknown protocol" }, + { RPC_PMAPFAILURE, + "RPC: Port mapper failure" }, + { RPC_PROGNOTREGISTERED, + "RPC: Program not registered"}, + { RPC_FAILED, + "RPC: Failed (unspecified error)"} +}; + + +/* + * This interface for use by clntrpc + */ +char * +clnt_sperrno(stat) + enum clnt_stat stat; +{ + int i; + + for (i = 0; i < sizeof(rpc_errlist)/sizeof(struct rpc_errtab); i++) { + if (rpc_errlist[i].status == stat) { + return (rpc_errlist[i].message); + } + } + return ("RPC: (unknown error code)"); +} + +void +clnt_perrno(num) + enum clnt_stat num; +{ + (void) fprintf(stderr,"%s",clnt_sperrno(num)); +} + + +char * +clnt_spcreateerror(s) + char *s; +{ + extern int sys_nerr; + char *str = _buf(); + + if (str == 0) + return(0); + (void) sprintf(str, "%s: ", s); + (void) strcat(str, clnt_sperrno(rpc_createerr.cf_stat)); + switch (rpc_createerr.cf_stat) { + case RPC_PMAPFAILURE: + (void) strcat(str, " - "); + (void) strcat(str, + clnt_sperrno(rpc_createerr.cf_error.re_status)); + break; + + case RPC_SYSTEMERROR: + (void) strcat(str, " - "); + if (rpc_createerr.cf_error.re_errno > 0 + && rpc_createerr.cf_error.re_errno < sys_nerr) + (void) strcat(str, + strerror(rpc_createerr.cf_error.re_errno)); + else + (void) sprintf(&str[strlen(str)], "Error %d", + rpc_createerr.cf_error.re_errno); + break; + } + (void) strcat(str, "\n"); + return (str); +} + +void +clnt_pcreateerror(s) + char *s; +{ + (void) fprintf(stderr,"%s",clnt_spcreateerror(s)); +} + +struct auth_errtab { + enum auth_stat status; + char *message; +}; + +static struct auth_errtab auth_errlist[] = { + { AUTH_OK, + "Authentication OK" }, + { AUTH_BADCRED, + "Invalid client credential" }, + { AUTH_REJECTEDCRED, + "Server rejected credential" }, + { AUTH_BADVERF, + "Invalid client verifier" }, + { AUTH_REJECTEDVERF, + "Server rejected verifier" }, + { AUTH_TOOWEAK, + "Client credential too weak" }, + { AUTH_INVALIDRESP, + "Invalid server verifier" }, + { AUTH_FAILED, + "Failed (unspecified error)" }, +}; + +static char * +auth_errmsg(stat) + enum auth_stat stat; +{ + int i; + + for (i = 0; i < sizeof(auth_errlist)/sizeof(struct auth_errtab); i++) { + if (auth_errlist[i].status == stat) { + return(auth_errlist[i].message); + } + } + return(NULL); +} diff --git a/rpc.subproj/clnt_raw.c b/rpc.subproj/clnt_raw.c new file mode 100644 index 0000000..100b870 --- /dev/null +++ b/rpc.subproj/clnt_raw.c @@ -0,0 +1,263 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC";*/ +static char *rcsid = "$Id: clnt_raw.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $"; +#endif + +/* + * clnt_raw.c + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * Memory based rpc for simple testing and timing. + * Interface to create an rpc client and server in the same process. + * This lets us similate rpc and get round trip overhead, without + * any interference from the kernal. + */ + +#include + +#define MCALL_MSG_SIZE 24 + +/* + * This is the "network" we will be moving stuff over. + */ +static struct clntraw_private { + CLIENT client_object; + XDR xdr_stream; + char _raw_buf[UDPMSGSIZE]; + char mashl_callmsg[MCALL_MSG_SIZE]; + u_int mcnt; +} *clntraw_private; + +static enum clnt_stat clntraw_call(); +static void clntraw_abort(); +static void clntraw_geterr(); +static bool_t clntraw_freeres(); +static bool_t clntraw_control(); +static void clntraw_destroy(); + +static struct clnt_ops client_ops = { + clntraw_call, + clntraw_abort, + clntraw_geterr, + clntraw_freeres, + clntraw_destroy, + clntraw_control +}; + +void svc_getreq(); + +/* + * Create a client handle for memory based rpc. + */ +CLIENT * +clntraw_create(prog, vers) + u_long prog; + u_long vers; +{ + register struct clntraw_private *clp = clntraw_private; + struct rpc_msg call_msg; + XDR *xdrs = &clp->xdr_stream; + CLIENT *client = &clp->client_object; + + if (clp == 0) { + clp = (struct clntraw_private *)calloc(1, sizeof (*clp)); + if (clp == 0) + return (0); + clntraw_private = clp; + } + /* + * pre-serialize the staic part of the call msg and stash it away + */ + call_msg.rm_direction = CALL; + call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; + call_msg.rm_call.cb_prog = prog; + call_msg.rm_call.cb_vers = vers; + xdrmem_create(xdrs, clp->mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE); + if (! xdr_callhdr(xdrs, &call_msg)) { + perror("clnt_raw.c - Fatal header serialization error."); + } + clp->mcnt = XDR_GETPOS(xdrs); + XDR_DESTROY(xdrs); + + /* + * Set xdrmem for client/server shared buffer + */ + xdrmem_create(xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE); + + /* + * create client handle + */ + client->cl_ops = &client_ops; + client->cl_auth = authnone_create(); + return (client); +} + +static enum clnt_stat +clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout) + CLIENT *h; + u_long proc; + xdrproc_t xargs; + caddr_t argsp; + xdrproc_t xresults; + caddr_t resultsp; + struct timeval timeout; +{ + register struct clntraw_private *clp = clntraw_private; + register XDR *xdrs = &clp->xdr_stream; + struct rpc_msg msg; + enum clnt_stat status; + struct rpc_err error; + + if (clp == 0) + return (RPC_FAILED); +call_again: + /* + * send request + */ + xdrs->x_op = XDR_ENCODE; + XDR_SETPOS(xdrs, 0); + ((struct rpc_msg *)clp->mashl_callmsg)->rm_xid ++ ; + if ((! XDR_PUTBYTES(xdrs, clp->mashl_callmsg, clp->mcnt)) || + (! XDR_PUTLONG(xdrs, (long *)&proc)) || + (! AUTH_MARSHALL(h->cl_auth, xdrs)) || + (! (*xargs)(xdrs, argsp))) { + return (RPC_CANTENCODEARGS); + } + (void)XDR_GETPOS(xdrs); /* called just to cause overhead */ + + /* + * We have to call server input routine here because this is + * all going on in one process. Yuk. + */ + svc_getreq(1); + + /* + * get results + */ + xdrs->x_op = XDR_DECODE; + XDR_SETPOS(xdrs, 0); + msg.acpted_rply.ar_verf = _null_auth; + msg.acpted_rply.ar_results.where = resultsp; + msg.acpted_rply.ar_results.proc = xresults; + if (! xdr_replymsg(xdrs, &msg)) + return (RPC_CANTDECODERES); + _seterr_reply(&msg, &error); + status = error.re_status; + + if (status == RPC_SUCCESS) { + if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) { + status = RPC_AUTHERROR; + } + } /* end successful completion */ + else { + if (AUTH_REFRESH(h->cl_auth)) + goto call_again; + } /* end of unsuccessful completion */ + + if (status == RPC_SUCCESS) { + if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) { + status = RPC_AUTHERROR; + } + if (msg.acpted_rply.ar_verf.oa_base != NULL) { + xdrs->x_op = XDR_FREE; + (void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf)); + } + } + + return (status); +} + +static void +clntraw_geterr() +{ +} + + +static bool_t +clntraw_freeres(cl, xdr_res, res_ptr) + CLIENT *cl; + xdrproc_t xdr_res; + caddr_t res_ptr; +{ + register struct clntraw_private *clp = clntraw_private; + register XDR *xdrs = &clp->xdr_stream; + bool_t rval; + + if (clp == 0) + { + rval = (bool_t) RPC_FAILED; + return (rval); + } + xdrs->x_op = XDR_FREE; + return ((*xdr_res)(xdrs, res_ptr)); +} + +static void +clntraw_abort() +{ +} + +static bool_t +clntraw_control() +{ + return (FALSE); +} + +static void +clntraw_destroy() +{ +} diff --git a/rpc.subproj/clnt_simple.c b/rpc.subproj/clnt_simple.c new file mode 100644 index 0000000..ec99490 --- /dev/null +++ b/rpc.subproj/clnt_simple.c @@ -0,0 +1,139 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)clnt_simple.c 2.2 88/08/01 4.0 RPCSRC";*/ +static char *rcsid = "$Id: clnt_simple.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $"; +#endif + +/* + * clnt_simple.c + * Simplified front end to rpc. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include +#include +#include +#include +#include +#include + +static struct callrpc_private { + CLIENT *client; + int socket; + int oldprognum, oldversnum, valid; + char *oldhost; +} *callrpc_private; + +callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out) + char *host; + xdrproc_t inproc, outproc; + char *in, *out; +{ + register struct callrpc_private *crp = callrpc_private; + struct sockaddr_in server_addr; + enum clnt_stat clnt_stat; + struct hostent *hp; + struct timeval timeout, tottimeout; + + if (crp == 0) { + crp = (struct callrpc_private *)calloc(1, sizeof (*crp)); + if (crp == 0) + return (0); + callrpc_private = crp; + } + if (crp->oldhost == NULL) { + crp->oldhost = malloc(256); + crp->oldhost[0] = 0; + crp->socket = RPC_ANYSOCK; + } + if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum + && strcmp(crp->oldhost, host) == 0) { + /* reuse old client */ + } else { + crp->valid = 0; + (void)close(crp->socket); + crp->socket = RPC_ANYSOCK; + if (crp->client) { + clnt_destroy(crp->client); + crp->client = NULL; + } + if ((hp = gethostbyname(host)) == NULL) + return ((int) RPC_UNKNOWNHOST); + timeout.tv_usec = 0; + timeout.tv_sec = 5; + bzero((char *)&server_addr, sizeof server_addr); + bcopy(hp->h_addr, (char *)&server_addr.sin_addr, hp->h_length); + server_addr.sin_family = AF_INET; + server_addr.sin_port = 0; + if ((crp->client = clntudp_create(&server_addr, (u_long)prognum, + (u_long)versnum, timeout, &crp->socket)) == NULL) + return ((int) rpc_createerr.cf_stat); + crp->valid = 1; + crp->oldprognum = prognum; + crp->oldversnum = versnum; + (void) strcpy(crp->oldhost, host); + } + tottimeout.tv_sec = 25; + tottimeout.tv_usec = 0; + clnt_stat = clnt_call(crp->client, procnum, inproc, in, + outproc, out, tottimeout); + /* + * if call failed, empty cache + */ + if (clnt_stat != RPC_SUCCESS) + crp->valid = 0; + return ((int) clnt_stat); +} diff --git a/rpc.subproj/clnt_tcp.c b/rpc.subproj/clnt_tcp.c new file mode 100644 index 0000000..22f6616 --- /dev/null +++ b/rpc.subproj/clnt_tcp.c @@ -0,0 +1,482 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC";*/ +static char *rcsid = "$Id: clnt_tcp.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $"; +#endif + +/* + * clnt_tcp.c, Implements a TCP/IP based, client side RPC. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * TCP based RPC supports 'batched calls'. + * A sequence of calls may be batched-up in a send buffer. The rpc call + * return immediately to the client even though the call was not necessarily + * sent. The batching occurs if the results' xdr routine is NULL (0) AND + * the rpc timeout value is zero (see clnt.h, rpc). + * + * Clients should NOT casually batch calls that in fact return results; that is, + * the server side should be aware that a call is batched and not produce any + * return message. Batched calls that produce many result messages can + * deadlock (netlock) the client and the server.... + * + * Now go hang yourself. + */ + +#include +#include +#include +#include +#include +#include + +#define MCALL_MSG_SIZE 24 + +extern int errno; + +static int readtcp(); +static int writetcp(); + +static enum clnt_stat clnttcp_call(); +static void clnttcp_abort(); +static void clnttcp_geterr(); +static bool_t clnttcp_freeres(); +static bool_t clnttcp_control(); +static void clnttcp_destroy(); + +static struct clnt_ops tcp_ops = { + clnttcp_call, + clnttcp_abort, + clnttcp_geterr, + clnttcp_freeres, + clnttcp_destroy, + clnttcp_control +}; + +struct ct_data { + int ct_sock; + bool_t ct_closeit; + struct timeval ct_wait; + bool_t ct_waitset; /* wait set by clnt_control? */ + struct sockaddr_in ct_addr; + struct rpc_err ct_error; + char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg */ + u_int ct_mpos; /* pos after marshal */ + XDR ct_xdrs; +}; + +/* + * Create a client handle for a tcp/ip connection. + * If *sockp<0, *sockp is set to a newly created TCP socket and it is + * connected to raddr. If *sockp non-negative then + * raddr is ignored. The rpc/tcp package does buffering + * similar to stdio, so the client must pick send and receive buffer sizes,]; + * 0 => use the default. + * If raddr->sin_port is 0, then a binder on the remote machine is + * consulted for the right port number. + * NB: *sockp is copied into a private area. + * NB: It is the clients responsibility to close *sockp. + * NB: The rpch->cl_auth is set null authentication. Caller may wish to set this + * something more useful. + */ +CLIENT * +clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz) + struct sockaddr_in *raddr; + u_long prog; + u_long vers; + register int *sockp; + u_int sendsz; + u_int recvsz; +{ + CLIENT *h; + register struct ct_data *ct; + struct timeval now; + struct rpc_msg call_msg; + + h = (CLIENT *)mem_alloc(sizeof(*h)); + if (h == NULL) { + (void)fprintf(stderr, "clnttcp_create: out of memory\n"); + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + goto fooy; + } + ct = (struct ct_data *)mem_alloc(sizeof(*ct)); + if (ct == NULL) { + (void)fprintf(stderr, "clnttcp_create: out of memory\n"); + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + goto fooy; + } + + /* + * If no port number given ask the pmap for one + */ + if (raddr->sin_port == 0) { + u_short port; + if ((port = pmap_getport(raddr, prog, vers, IPPROTO_TCP)) == 0) { + mem_free((caddr_t)ct, sizeof(struct ct_data)); + mem_free((caddr_t)h, sizeof(CLIENT)); + return ((CLIENT *)NULL); + } + raddr->sin_port = htons(port); + } + + /* + * If no socket given, open one + */ + if (*sockp < 0) { + *sockp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + (void)bindresvport(*sockp, (struct sockaddr_in *)0); + if ((*sockp < 0) + || (connect(*sockp, (struct sockaddr *)raddr, + sizeof(*raddr)) < 0)) { + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + (void)close(*sockp); + goto fooy; + } + ct->ct_closeit = TRUE; + } else { + ct->ct_closeit = FALSE; + } + + /* + * Set up private data struct + */ + ct->ct_sock = *sockp; + ct->ct_wait.tv_usec = 0; + ct->ct_waitset = FALSE; + ct->ct_addr = *raddr; + + /* + * Initialize call message + */ + (void)gettimeofday(&now, (struct timezone *)0); + call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec; + call_msg.rm_direction = CALL; + call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; + call_msg.rm_call.cb_prog = prog; + call_msg.rm_call.cb_vers = vers; + + /* + * pre-serialize the staic part of the call msg and stash it away + */ + xdrmem_create(&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE, + XDR_ENCODE); + if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) { + if (ct->ct_closeit) { + (void)close(*sockp); + } + goto fooy; + } + ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs)); + XDR_DESTROY(&(ct->ct_xdrs)); + + /* + * Create a client handle which uses xdrrec for serialization + * and authnone for authentication. + */ + xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz, + (caddr_t)ct, readtcp, writetcp); + h->cl_ops = &tcp_ops; + h->cl_private = (caddr_t) ct; + h->cl_auth = authnone_create(); + return (h); + +fooy: + /* + * Something goofed, free stuff and barf + */ + mem_free((caddr_t)ct, sizeof(struct ct_data)); + mem_free((caddr_t)h, sizeof(CLIENT)); + return ((CLIENT *)NULL); +} + +static enum clnt_stat +clnttcp_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout) + register CLIENT *h; + u_long proc; + xdrproc_t xdr_args; + caddr_t args_ptr; + xdrproc_t xdr_results; + caddr_t results_ptr; + struct timeval timeout; +{ + register struct ct_data *ct = (struct ct_data *) h->cl_private; + register XDR *xdrs = &(ct->ct_xdrs); + struct rpc_msg reply_msg; + u_long x_id; + u_long *msg_x_id = (u_long *)(ct->ct_mcall); /* yuk */ + register bool_t shipnow; + int refreshes = 2; + + if (!ct->ct_waitset) { + ct->ct_wait = timeout; + } + + shipnow = + (xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0 + && timeout.tv_usec == 0) ? FALSE : TRUE; + +call_again: + xdrs->x_op = XDR_ENCODE; + ct->ct_error.re_status = RPC_SUCCESS; + x_id = ntohl(--(*msg_x_id)); + if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) || + (! XDR_PUTLONG(xdrs, (long *)&proc)) || + (! AUTH_MARSHALL(h->cl_auth, xdrs)) || + (! (*xdr_args)(xdrs, args_ptr))) { + if (ct->ct_error.re_status == RPC_SUCCESS) + ct->ct_error.re_status = RPC_CANTENCODEARGS; + (void)xdrrec_endofrecord(xdrs, TRUE); + return (ct->ct_error.re_status); + } + if (! xdrrec_endofrecord(xdrs, shipnow)) + return (ct->ct_error.re_status = RPC_CANTSEND); + if (! shipnow) + return (RPC_SUCCESS); + /* + * Hack to provide rpc-based message passing + */ + if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { + return(ct->ct_error.re_status = RPC_TIMEDOUT); + } + + + /* + * Keep receiving until we get a valid transaction id + */ + xdrs->x_op = XDR_DECODE; + while (TRUE) { + reply_msg.acpted_rply.ar_verf = _null_auth; + reply_msg.acpted_rply.ar_results.where = NULL; + reply_msg.acpted_rply.ar_results.proc = xdr_void; + if (! xdrrec_skiprecord(xdrs)) + return (ct->ct_error.re_status); + /* now decode and validate the response header */ + if (! xdr_replymsg(xdrs, &reply_msg)) { + if (ct->ct_error.re_status == RPC_SUCCESS) + continue; + return (ct->ct_error.re_status); + } + if (reply_msg.rm_xid == x_id) + break; + } + + /* + * process header + */ + _seterr_reply(&reply_msg, &(ct->ct_error)); + if (ct->ct_error.re_status == RPC_SUCCESS) { + if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) { + ct->ct_error.re_status = RPC_AUTHERROR; + ct->ct_error.re_why = AUTH_INVALIDRESP; + } else if (! (*xdr_results)(xdrs, results_ptr)) { + if (ct->ct_error.re_status == RPC_SUCCESS) + ct->ct_error.re_status = RPC_CANTDECODERES; + } + /* free verifier ... */ + if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) { + xdrs->x_op = XDR_FREE; + (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf)); + } + } /* end successful completion */ + else { + /* maybe our credentials need to be refreshed ... */ + if (refreshes-- && AUTH_REFRESH(h->cl_auth)) + goto call_again; + } /* end of unsuccessful completion */ + return (ct->ct_error.re_status); +} + +static void +clnttcp_geterr(h, errp) + CLIENT *h; + struct rpc_err *errp; +{ + register struct ct_data *ct = + (struct ct_data *) h->cl_private; + + *errp = ct->ct_error; +} + +static bool_t +clnttcp_freeres(cl, xdr_res, res_ptr) + CLIENT *cl; + xdrproc_t xdr_res; + caddr_t res_ptr; +{ + register struct ct_data *ct = (struct ct_data *)cl->cl_private; + register XDR *xdrs = &(ct->ct_xdrs); + + xdrs->x_op = XDR_FREE; + return ((*xdr_res)(xdrs, res_ptr)); +} + +static void +clnttcp_abort() +{ +} + +static bool_t +clnttcp_control(cl, request, info) + CLIENT *cl; + int request; + char *info; +{ + register struct ct_data *ct = (struct ct_data *)cl->cl_private; + + switch (request) { + case CLSET_TIMEOUT: + ct->ct_wait = *(struct timeval *)info; + ct->ct_waitset = TRUE; + break; + case CLGET_TIMEOUT: + *(struct timeval *)info = ct->ct_wait; + break; + case CLGET_SERVER_ADDR: + *(struct sockaddr_in *)info = ct->ct_addr; + break; + default: + return (FALSE); + } + return (TRUE); +} + + +static void +clnttcp_destroy(h) + CLIENT *h; +{ + register struct ct_data *ct = + (struct ct_data *) h->cl_private; + + if (ct->ct_closeit) { + (void)close(ct->ct_sock); + } + XDR_DESTROY(&(ct->ct_xdrs)); + mem_free((caddr_t)ct, sizeof(struct ct_data)); + mem_free((caddr_t)h, sizeof(CLIENT)); +} + +/* + * Interface between xdr serializer and tcp connection. + * Behaves like the system calls, read & write, but keeps some error state + * around for the rpc level. + */ +static int +readtcp(ct, buf, len) + register struct ct_data *ct; + caddr_t buf; + register int len; +{ + fd_set mask; + fd_set readfds; + + if (len == 0) + return (0); + FD_ZERO(&mask); + FD_SET(ct->ct_sock, &mask); + while (TRUE) { + readfds = mask; + switch (select(ct->ct_sock+1, &readfds, (int*)NULL, (int*)NULL, + &(ct->ct_wait))) { + case 0: + ct->ct_error.re_status = RPC_TIMEDOUT; + return (-1); + + case -1: + if (errno == EINTR) + continue; + ct->ct_error.re_status = RPC_CANTRECV; + ct->ct_error.re_errno = errno; + return (-1); + } + break; + } + switch (len = read(ct->ct_sock, buf, len)) { + + case 0: + /* premature eof */ + ct->ct_error.re_errno = ECONNRESET; + ct->ct_error.re_status = RPC_CANTRECV; + len = -1; /* it's really an error */ + break; + + case -1: + ct->ct_error.re_errno = errno; + ct->ct_error.re_status = RPC_CANTRECV; + break; + } + return (len); +} + +static int +writetcp(ct, buf, len) + struct ct_data *ct; + caddr_t buf; + int len; +{ + register int i, cnt; + + for (cnt = len; cnt > 0; cnt -= i, buf += i) { + if ((i = write(ct->ct_sock, buf, cnt)) == -1) { + ct->ct_error.re_errno = errno; + ct->ct_error.re_status = RPC_CANTSEND; + return (-1); + } + } + return (len); +} diff --git a/rpc.subproj/clnt_udp.c b/rpc.subproj/clnt_udp.c new file mode 100644 index 0000000..38a03fe --- /dev/null +++ b/rpc.subproj/clnt_udp.c @@ -0,0 +1,458 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)clnt_udp.c 2.2 88/08/01 4.0 RPCSRC";*/ +static char *rcsid = "$Id: clnt_udp.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $"; +#endif + +/* + * clnt_udp.c, Implements a UDP/IP based, client side RPC. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +extern int errno; + +/* + * UDP bases client side rpc operations + */ +static enum clnt_stat clntudp_call(); +static void clntudp_abort(); +static void clntudp_geterr(); +static bool_t clntudp_freeres(); +static bool_t clntudp_control(); +static void clntudp_destroy(); + +static struct clnt_ops udp_ops = { + clntudp_call, + clntudp_abort, + clntudp_geterr, + clntudp_freeres, + clntudp_destroy, + clntudp_control +}; + +/* + * Private data kept per client handle + */ +struct cu_data { + int cu_sock; + bool_t cu_closeit; + struct sockaddr_in cu_raddr; + int cu_rlen; + struct timeval cu_wait; + struct timeval cu_total; + struct rpc_err cu_error; + XDR cu_outxdrs; + u_int cu_xdrpos; + u_int cu_sendsz; + char *cu_outbuf; + u_int cu_recvsz; + char cu_inbuf[1]; +}; + +/* + * Create a UDP based client handle. + * If *sockp<0, *sockp is set to a newly created UPD socket. + * If raddr->sin_port is 0 a binder on the remote machine + * is consulted for the correct port number. + * NB: It is the clients responsibility to close *sockp. + * NB: The rpch->cl_auth is initialized to null authentication. + * Caller may wish to set this something more useful. + * + * wait is the amount of time used between retransmitting a call if + * no response has been heard; retransmition occurs until the actual + * rpc call times out. + * + * sendsz and recvsz are the maximum allowable packet sizes that can be + * sent and received. + */ +CLIENT * +clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz) + struct sockaddr_in *raddr; + u_long program; + u_long version; + struct timeval wait; + register int *sockp; + u_int sendsz; + u_int recvsz; +{ + CLIENT *cl; + register struct cu_data *cu; + struct timeval now; + struct rpc_msg call_msg; + + cl = (CLIENT *)mem_alloc(sizeof(CLIENT)); + if (cl == NULL) { + (void) fprintf(stderr, "clntudp_create: out of memory\n"); + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + goto fooy; + } + sendsz = ((sendsz + 3) / 4) * 4; + recvsz = ((recvsz + 3) / 4) * 4; + cu = (struct cu_data *)mem_alloc(sizeof(*cu) + sendsz + recvsz); + if (cu == NULL) { + (void) fprintf(stderr, "clntudp_create: out of memory\n"); + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + goto fooy; + } + cu->cu_outbuf = &cu->cu_inbuf[recvsz]; + + (void)gettimeofday(&now, (struct timezone *)0); + if (raddr->sin_port == 0) { + u_short port; + if ((port = + pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) { + goto fooy; + } + raddr->sin_port = htons(port); + } + cl->cl_ops = &udp_ops; + cl->cl_private = (caddr_t)cu; + cu->cu_raddr = *raddr; + cu->cu_rlen = sizeof (cu->cu_raddr); + cu->cu_wait = wait; + cu->cu_total.tv_sec = -1; + cu->cu_total.tv_usec = -1; + cu->cu_sendsz = sendsz; + cu->cu_recvsz = recvsz; + call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec; + call_msg.rm_direction = CALL; + call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; + call_msg.rm_call.cb_prog = program; + call_msg.rm_call.cb_vers = version; + xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf, + sendsz, XDR_ENCODE); + if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) { + goto fooy; + } + cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs)); + if (*sockp < 0) { + int dontblock = 1; + + *sockp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (*sockp < 0) { + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + goto fooy; + } + /* attempt to bind to prov port */ + (void)bindresvport(*sockp, (struct sockaddr_in *)0); + /* the sockets rpc controls are non-blocking */ + (void)ioctl(*sockp, FIONBIO, (char *) &dontblock); + cu->cu_closeit = TRUE; + } else { + cu->cu_closeit = FALSE; + } + cu->cu_sock = *sockp; + cl->cl_auth = authnone_create(); + return (cl); +fooy: + if (cu) + mem_free((caddr_t)cu, sizeof(*cu) + sendsz + recvsz); + if (cl) + mem_free((caddr_t)cl, sizeof(CLIENT)); + return ((CLIENT *)NULL); +} + +CLIENT * +clntudp_create(raddr, program, version, wait, sockp) + struct sockaddr_in *raddr; + u_long program; + u_long version; + struct timeval wait; + register int *sockp; +{ + + return(clntudp_bufcreate(raddr, program, version, wait, sockp, + UDPMSGSIZE, UDPMSGSIZE)); +} + +static enum clnt_stat +clntudp_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout) + register CLIENT *cl; /* client handle */ + u_long proc; /* procedure number */ + xdrproc_t xargs; /* xdr routine for args */ + caddr_t argsp; /* pointer to args */ + xdrproc_t xresults; /* xdr routine for results */ + caddr_t resultsp; /* pointer to results */ + struct timeval utimeout; /* seconds to wait before giving up */ +{ + register struct cu_data *cu = (struct cu_data *)cl->cl_private; + register XDR *xdrs; + register int outlen; + register int inlen; + int fromlen; + fd_set readfds; + fd_set mask; + struct sockaddr_in from; + struct rpc_msg reply_msg; + XDR reply_xdrs; + struct timeval time_waited; + bool_t ok; + int nrefreshes = 2; /* number of times to refresh cred */ + struct timeval timeout; + + if (cu->cu_total.tv_usec == -1) { + timeout = utimeout; /* use supplied timeout */ + } else { + timeout = cu->cu_total; /* use default timeout */ + } + + time_waited.tv_sec = 0; + time_waited.tv_usec = 0; +call_again: + xdrs = &(cu->cu_outxdrs); + xdrs->x_op = XDR_ENCODE; + XDR_SETPOS(xdrs, cu->cu_xdrpos); + /* + * the transaction is the first thing in the out buffer + */ + (*(u_short *)(cu->cu_outbuf))++; + if ((! XDR_PUTLONG(xdrs, (long *)&proc)) || + (! AUTH_MARSHALL(cl->cl_auth, xdrs)) || + (! (*xargs)(xdrs, argsp))) + return (cu->cu_error.re_status = RPC_CANTENCODEARGS); + outlen = (int)XDR_GETPOS(xdrs); + +send_again: + if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0, + (struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen) + != outlen) { + cu->cu_error.re_errno = errno; + return (cu->cu_error.re_status = RPC_CANTSEND); + } + + /* + * Hack to provide rpc-based message passing + */ + if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { + return (cu->cu_error.re_status = RPC_TIMEDOUT); + } + /* + * sub-optimal code appears here because we have + * some clock time to spare while the packets are in flight. + * (We assume that this is actually only executed once.) + */ + reply_msg.acpted_rply.ar_verf = _null_auth; + reply_msg.acpted_rply.ar_results.where = resultsp; + reply_msg.acpted_rply.ar_results.proc = xresults; + FD_ZERO(&mask); + FD_SET(cu->cu_sock, &mask); + for (;;) { + readfds = mask; + switch (select(cu->cu_sock+1, &readfds, (int *)NULL, + (int *)NULL, &(cu->cu_wait))) { + + case 0: + time_waited.tv_sec += cu->cu_wait.tv_sec; + time_waited.tv_usec += cu->cu_wait.tv_usec; + while (time_waited.tv_usec >= 1000000) { + time_waited.tv_sec++; + time_waited.tv_usec -= 1000000; + } + if ((time_waited.tv_sec < timeout.tv_sec) || + ((time_waited.tv_sec == timeout.tv_sec) && + (time_waited.tv_usec < timeout.tv_usec))) + goto send_again; + return (cu->cu_error.re_status = RPC_TIMEDOUT); + + /* + * buggy in other cases because time_waited is not being + * updated. + */ + case -1: + if (errno == EINTR) + continue; + cu->cu_error.re_errno = errno; + return (cu->cu_error.re_status = RPC_CANTRECV); + } + do { + fromlen = sizeof(struct sockaddr); + inlen = recvfrom(cu->cu_sock, cu->cu_inbuf, + (int) cu->cu_recvsz, 0, + (struct sockaddr *)&from, &fromlen); + } while (inlen < 0 && errno == EINTR); + if (inlen < 0) { + if (errno == EWOULDBLOCK) + continue; + cu->cu_error.re_errno = errno; + return (cu->cu_error.re_status = RPC_CANTRECV); + } + if (inlen < sizeof(u_long)) + continue; + /* see if reply transaction id matches sent id */ + if (*((u_long *)(cu->cu_inbuf)) != *((u_long *)(cu->cu_outbuf))) + continue; + /* we now assume we have the proper reply */ + break; + } + + /* + * now decode and validate the response + */ + xdrmem_create(&reply_xdrs, cu->cu_inbuf, (u_int)inlen, XDR_DECODE); + ok = xdr_replymsg(&reply_xdrs, &reply_msg); + /* XDR_DESTROY(&reply_xdrs); save a few cycles on noop destroy */ + if (ok) { + _seterr_reply(&reply_msg, &(cu->cu_error)); + if (cu->cu_error.re_status == RPC_SUCCESS) { + if (! AUTH_VALIDATE(cl->cl_auth, + &reply_msg.acpted_rply.ar_verf)) { + cu->cu_error.re_status = RPC_AUTHERROR; + cu->cu_error.re_why = AUTH_INVALIDRESP; + } + if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) { + xdrs->x_op = XDR_FREE; + (void)xdr_opaque_auth(xdrs, + &(reply_msg.acpted_rply.ar_verf)); + } + } /* end successful completion */ + else { + /* maybe our credentials need to be refreshed ... */ + if (nrefreshes > 0 && AUTH_REFRESH(cl->cl_auth)) { + nrefreshes--; + goto call_again; + } + } /* end of unsuccessful completion */ + } /* end of valid reply message */ + else { + cu->cu_error.re_status = RPC_CANTDECODERES; + } + return (cu->cu_error.re_status); +} + +static void +clntudp_geterr(cl, errp) + CLIENT *cl; + struct rpc_err *errp; +{ + register struct cu_data *cu = (struct cu_data *)cl->cl_private; + + *errp = cu->cu_error; +} + + +static bool_t +clntudp_freeres(cl, xdr_res, res_ptr) + CLIENT *cl; + xdrproc_t xdr_res; + caddr_t res_ptr; +{ + register struct cu_data *cu = (struct cu_data *)cl->cl_private; + register XDR *xdrs = &(cu->cu_outxdrs); + + xdrs->x_op = XDR_FREE; + return ((*xdr_res)(xdrs, res_ptr)); +} + +static void +clntudp_abort(/*h*/) + /*CLIENT *h;*/ +{ +} + +static bool_t +clntudp_control(cl, request, info) + CLIENT *cl; + int request; + char *info; +{ + register struct cu_data *cu = (struct cu_data *)cl->cl_private; + + switch (request) { + case CLSET_TIMEOUT: + cu->cu_total = *(struct timeval *)info; + break; + case CLGET_TIMEOUT: + *(struct timeval *)info = cu->cu_total; + break; + case CLSET_RETRY_TIMEOUT: + cu->cu_wait = *(struct timeval *)info; + break; + case CLGET_RETRY_TIMEOUT: + *(struct timeval *)info = cu->cu_wait; + break; + case CLGET_SERVER_ADDR: + *(struct sockaddr_in *)info = cu->cu_raddr; + break; + default: + return (FALSE); + } + return (TRUE); +} + +static void +clntudp_destroy(cl) + CLIENT *cl; +{ + register struct cu_data *cu = (struct cu_data *)cl->cl_private; + + if (cu->cu_closeit) { + (void)close(cu->cu_sock); + } + XDR_DESTROY(&(cu->cu_outxdrs)); + mem_free((caddr_t)cu, (sizeof(*cu) + cu->cu_sendsz + cu->cu_recvsz)); + mem_free((caddr_t)cl, sizeof(CLIENT)); +} diff --git a/rpc.subproj/get_myaddress.c b/rpc.subproj/get_myaddress.c new file mode 100644 index 0000000..944a0e8 --- /dev/null +++ b/rpc.subproj/get_myaddress.c @@ -0,0 +1,139 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)get_myaddress.c 1.4 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)get_myaddress.c 2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: get_myaddress.c,v 1.3 2000/08/03 20:25:14 ajn Exp $"; +#endif + +/* + * get_myaddress.c + * + * Get client's IP address via ioctl. This avoids using the yellowpages. + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * Re-worked for 4.4BSD by Marc Majka at Apple. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int +get_myaddress(struct sockaddr_in *addr) +{ + struct ifconf ifc; + struct ifreq *ifr; + char buf[BUFSIZ]; + int offset, x, addrlen, s; + + bzero(addr, sizeof(struct sockaddr_in)); + addr->sin_family = AF_INET; + + s = socket(AF_INET, SOCK_DGRAM, 0); + + if (s < 0) + { + addr->sin_addr.s_addr = htonl(INADDR_LOOPBACK); + return 0; + } + + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = buf; + + if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) + { + addr->sin_addr.s_addr = htonl(INADDR_LOOPBACK); + close(s); + return 0; + } + + addrlen = sizeof(struct ifreq) - IFNAMSIZ; + offset = 0; + + while (offset <= ifc.ifc_len) + { + ifr = (struct ifreq *)(ifc.ifc_buf + offset); + offset += IFNAMSIZ; + if (ifr->ifr_addr.sa_len > addrlen) offset += ifr->ifr_addr.sa_len; + else offset += addrlen; + + if (ifr->ifr_addr.sa_family != AF_INET) continue; + if (ioctl(s, SIOCGIFFLAGS, ifr) < 0) continue; + + x = ((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr; + if + ( + (ifr->ifr_flags & IFF_UP) && + (!(ifr->ifr_flags & IFF_LOOPBACK)) && + (x != 0) && + (x != -1) + ) + { + addr->sin_addr.s_addr = x; + close(s); + return 0; + } + } + + close(s); + addr->sin_addr.s_addr = htonl(INADDR_LOOPBACK); + return 0; +} diff --git a/rpc.subproj/getrpcent.c b/rpc.subproj/getrpcent.c new file mode 100644 index 0000000..1b57d99 --- /dev/null +++ b/rpc.subproj/getrpcent.c @@ -0,0 +1,231 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user or with the express written consent of + * Sun Microsystems, Inc. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro";*/ +static char *rcsid = "$Id: getrpcent.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $"; +#endif + +/* + * Copyright (c) 1984 by Sun Microsystems, Inc. + */ + +#include +#include +#include +#include + +/* + * Internet version. + */ +struct rpcdata { + FILE *rpcf; + int stayopen; +#define MAXALIASES 35 + char *rpc_aliases[MAXALIASES]; + struct rpcent rpc; + char line[BUFSIZ+1]; +} *rpcdata; + +static struct rpcent *interpret(); +struct hostent *gethostent(); +char *inet_ntoa(); + +static char RPCDB[] = "/etc/rpc"; + +static struct rpcdata * +_rpcdata() +{ + register struct rpcdata *d = rpcdata; + + if (d == 0) { + d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata)); + rpcdata = d; + } + return (d); +} + +struct rpcent * +getrpcbynumber(number) + register long number; +{ + register struct rpcdata *d = _rpcdata(); + register struct rpcent *p; + + if (d == 0) + return (0); + setrpcent(0); + while (p = getrpcent()) { + if (p->r_number == number) + break; + } + endrpcent(); + return (p); +} + +struct rpcent * +getrpcbyname(name) +#if defined(__APPLE__) + const char *name; +#else + char *name; +#endif +{ + struct rpcent *rpc; + char **rp; + + setrpcent(0); + while (rpc = getrpcent()) { + if (strcmp(rpc->r_name, name) == 0) + return (rpc); + for (rp = rpc->r_aliases; *rp != NULL; rp++) { + if (strcmp(*rp, name) == 0) + return (rpc); + } + } + endrpcent(); + return (NULL); +} + +void +setrpcent(f) + int f; +{ + register struct rpcdata *d = _rpcdata(); + + if (d == 0) + return; + if (d->rpcf == NULL) + d->rpcf = fopen(RPCDB, "r"); + else + rewind(d->rpcf); + d->stayopen |= f; +} + +void +endrpcent() +{ + register struct rpcdata *d = _rpcdata(); + + if (d == 0) + return; + if (d->rpcf && !d->stayopen) { + fclose(d->rpcf); + d->rpcf = NULL; + } +} + +struct rpcent * +getrpcent() +{ + struct rpcent *hp; + int reason; + register struct rpcdata *d = _rpcdata(); + + if (d == 0) + return(NULL); + if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL) + return (NULL); + if (fgets(d->line, BUFSIZ, d->rpcf) == NULL) + return (NULL); + return (interpret(d->line, strlen(d->line))); +} + +static struct rpcent * +interpret(val, len) + char *val; + int len; +{ + register struct rpcdata *d = _rpcdata(); + char *p; + register char *cp, **q; + + if (d == 0) + return (0); + (void) strncpy(d->line, val, len); + p = d->line; + d->line[len] = '\n'; + if (*p == '#') + return (getrpcent()); + cp = strpbrk(p, "#\n"); + if (cp == NULL) + return (getrpcent()); + *cp = '\0'; + cp = strpbrk(p, " \t"); + if (cp == NULL) + return (getrpcent()); + *cp++ = '\0'; + /* THIS STUFF IS INTERNET SPECIFIC */ + d->rpc.r_name = d->line; + while (*cp == ' ' || *cp == '\t') + cp++; + d->rpc.r_number = atoi(cp); + q = d->rpc.r_aliases = d->rpc_aliases; + cp = strpbrk(cp, " \t"); + if (cp != NULL) + *cp++ = '\0'; + while (cp && *cp) { + if (*cp == ' ' || *cp == '\t') { + cp++; + continue; + } + if (q < &(d->rpc_aliases[MAXALIASES - 1])) + *q++ = cp; + cp = strpbrk(cp, " \t"); + if (cp != NULL) + *cp++ = '\0'; + } + *q = NULL; + return (&d->rpc); +} + diff --git a/rpc.subproj/getrpcport.c b/rpc.subproj/getrpcport.c new file mode 100644 index 0000000..af368dd --- /dev/null +++ b/rpc.subproj/getrpcport.c @@ -0,0 +1,81 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)getrpcport.c 1.3 87/08/11 SMI";*/ +/*static char *sccsid = "from: @(#)getrpcport.c 2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: getrpcport.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $"; +#endif + +/* + * Copyright (c) 1985 by Sun Microsystems, Inc. + */ + +#include +#include +#include +#include + +getrpcport(host, prognum, versnum, proto) + char *host; +{ + struct sockaddr_in addr; + struct hostent *hp; + + if ((hp = gethostbyname(host)) == NULL) + return (0); + bzero((char *)&addr, sizeof addr); + bcopy(hp->h_addr, (char *) &addr.sin_addr, hp->h_length); + addr.sin_family = AF_INET; + addr.sin_port = 0; + return (pmap_getport(&addr, prognum, versnum, proto)); +} diff --git a/rpc.subproj/pmap_clnt.c b/rpc.subproj/pmap_clnt.c new file mode 100644 index 0000000..cdd3261 --- /dev/null +++ b/rpc.subproj/pmap_clnt.c @@ -0,0 +1,152 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)pmap_clnt.c 2.2 88/08/01 4.0 RPCSRC";*/ +static char *rcsid = "$Id: pmap_clnt.c,v 1.3 2000/08/03 20:25:14 ajn Exp $"; +#endif + +/* + * pmap_clnt.c + * Client interface to pmap rpc service. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct timeval timeout = { 5, 0 }; +static struct timeval tottimeout = { 60, 0 }; + +void clnt_perror(); + + +/* + * Set a mapping between program,version and port. + * Calls the pmap service remotely to do the mapping. + */ +bool_t +pmap_set(program, version, protocol, port) + u_long program; + u_long version; + int protocol; + u_short port; +{ + struct sockaddr_in myaddress; + int socket = -1; + register CLIENT *client; + struct pmap parms; + bool_t rslt; + + memset(&myaddress, 0, sizeof(struct sockaddr_in)); + myaddress.sin_family = AF_INET; + myaddress.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS, + timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); + if (client == (CLIENT *)NULL) + return (FALSE); + parms.pm_prog = program; + parms.pm_vers = version; + parms.pm_prot = protocol; + parms.pm_port = port; + if (CLNT_CALL(client, PMAPPROC_SET, xdr_pmap, &parms, xdr_bool, &rslt, + tottimeout) != RPC_SUCCESS) { + clnt_perror(client, "Cannot register service"); + return (FALSE); + } + CLNT_DESTROY(client); + (void)close(socket); + return (rslt); +} + +/* + * Remove the mapping between program,version and port. + * Calls the pmap service remotely to do the un-mapping. + */ +bool_t +pmap_unset(program, version) + u_long program; + u_long version; +{ + struct sockaddr_in myaddress; + int socket = -1; + register CLIENT *client; + struct pmap parms; + bool_t rslt; + + memset(&myaddress, 0, sizeof(struct sockaddr_in)); + myaddress.sin_family = AF_INET; + myaddress.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + + client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS, + timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); + if (client == (CLIENT *)NULL) + return (FALSE); + parms.pm_prog = program; + parms.pm_vers = version; + parms.pm_port = parms.pm_prot = 0; + CLNT_CALL(client, PMAPPROC_UNSET, xdr_pmap, &parms, xdr_bool, &rslt, + tottimeout); + CLNT_DESTROY(client); + (void)close(socket); + return (rslt); +} diff --git a/rpc.subproj/pmap_clnt.h b/rpc.subproj/pmap_clnt.h new file mode 100644 index 0000000..16e7fed --- /dev/null +++ b/rpc.subproj/pmap_clnt.h @@ -0,0 +1,107 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)pmap_clnt.h 1.11 88/02/08 SMI + * from: @(#)pmap_clnt.h 2.1 88/07/29 4.0 RPCSRC + * $Id: pmap_clnt.h,v 1.2 1999/10/14 21:56:53 wsanchez Exp $ + */ + +/* + * pmap_clnt.h + * Supplies C routines to get to portmap services. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +/* + * Usage: + * success = pmap_set(program, version, protocol, port); + * success = pmap_unset(program, version); + * port = pmap_getport(address, program, version, protocol); + * head = pmap_getmaps(address); + * clnt_stat = pmap_rmtcall(address, program, version, procedure, + * xdrargs, argsp, xdrres, resp, tout, port_ptr) + * (works for udp only.) + * clnt_stat = clnt_broadcast(program, version, procedure, + * xdrargs, argsp, xdrres, resp, eachresult) + * (like pmap_rmtcall, except the call is broadcasted to all + * locally connected nets. For each valid response received, + * the procedure eachresult is called. Its form is: + * done = eachresult(resp, raddr) + * bool_t done; + * caddr_t resp; + * struct sockaddr_in raddr; + * where resp points to the results of the call and raddr is the + * address if the responder to the broadcast. + */ + +#ifndef _RPC_PMAPCLNT_H +#define _RPC_PMAPCLNT_H +#include + +__BEGIN_DECLS +extern bool_t pmap_set __P((u_long, u_long, int, int)); +extern bool_t pmap_unset __P((u_long, u_long)); +extern struct pmaplist *pmap_getmaps __P((struct sockaddr_in *)); +extern enum clnt_stat pmap_rmtcall __P((struct sockaddr_in *, + u_long, u_long, u_long, + xdrproc_t, caddr_t, + xdrproc_t, caddr_t, + struct timeval, u_long *)); +extern enum clnt_stat clnt_broadcast __P((u_long, u_long, u_long, + xdrproc_t, char *, + xdrproc_t, char *, + bool_t (*)())); +extern u_short pmap_getport __P((struct sockaddr_in *, + u_long, u_long, u_int)); +__END_DECLS + +#endif /* !_RPC_PMAPCLNT_H */ diff --git a/rpc.subproj/pmap_getmaps.c b/rpc.subproj/pmap_getmaps.c new file mode 100644 index 0000000..7946572 --- /dev/null +++ b/rpc.subproj/pmap_getmaps.c @@ -0,0 +1,109 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)pmap_getmaps.c 2.2 88/08/01 4.0 RPCSRC";*/ +static char *rcsid = "$Id: pmap_getmaps.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $"; +#endif + +/* + * pmap_getmap.c + * Client interface to pmap rpc service. + * contains pmap_getmaps, which is only tcp service involved + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define NAMELEN 255 +#define MAX_BROADCAST_SIZE 1400 + +extern int errno; + +/* + * Get a copy of the current port maps. + * Calls the pmap service remotely to do get the maps. + */ +struct pmaplist * +pmap_getmaps(address) + struct sockaddr_in *address; +{ + struct pmaplist *head = (struct pmaplist *)NULL; + int socket = -1; + struct timeval minutetimeout; + register CLIENT *client; + + minutetimeout.tv_sec = 60; + minutetimeout.tv_usec = 0; + address->sin_port = htons(PMAPPORT); + client = clnttcp_create(address, PMAPPROG, + PMAPVERS, &socket, 50, 500); + if (client != (CLIENT *)NULL) { + if (CLNT_CALL(client, PMAPPROC_DUMP, xdr_void, NULL, xdr_pmaplist, + &head, minutetimeout) != RPC_SUCCESS) { + clnt_perror(client, "pmap_getmaps rpc problem"); + } + CLNT_DESTROY(client); + } + (void)close(socket); + address->sin_port = 0; + return (head); +} diff --git a/rpc.subproj/pmap_getport.c b/rpc.subproj/pmap_getport.c new file mode 100644 index 0000000..b4b6eb5 --- /dev/null +++ b/rpc.subproj/pmap_getport.c @@ -0,0 +1,112 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)pmap_getport.c 2.2 88/08/01 4.0 RPCSRC";*/ +static char *rcsid = "$Id: pmap_getport.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $"; +#endif + +/* + * pmap_getport.c + * Client interface to pmap rpc service. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include +#include +#include +#include +#include + +static struct timeval timeout = { 5, 0 }; +static struct timeval tottimeout = { 60, 0 }; + +/* + * Find the mapped port for program,version. + * Calls the pmap service remotely to do the lookup. + * Returns 0 if no map exists. + */ +u_short +pmap_getport(address, program, version, protocol) + struct sockaddr_in *address; + u_long program; + u_long version; + u_int protocol; +{ + u_short port = 0; + int socket = -1; + register CLIENT *client; + struct pmap parms; + + address->sin_port = htons(PMAPPORT); + client = clntudp_bufcreate(address, PMAPPROG, + PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); + if (client != (CLIENT *)NULL) { + parms.pm_prog = program; + parms.pm_vers = version; + parms.pm_prot = protocol; + parms.pm_port = 0; /* not needed or used */ + if (CLNT_CALL(client, PMAPPROC_GETPORT, xdr_pmap, &parms, + xdr_u_short, &port, tottimeout) != RPC_SUCCESS){ + rpc_createerr.cf_stat = RPC_PMAPFAILURE; + clnt_geterr(client, &rpc_createerr.cf_error); + } else if (port == 0) { + rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; + } + CLNT_DESTROY(client); + } + (void)close(socket); + address->sin_port = 0; + return (port); +} diff --git a/rpc.subproj/pmap_prot.c b/rpc.subproj/pmap_prot.c new file mode 100644 index 0000000..b3d4a02 --- /dev/null +++ b/rpc.subproj/pmap_prot.c @@ -0,0 +1,82 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)pmap_prot.c 2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: pmap_prot.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $"; +#endif + +/* + * pmap_prot.c + * Protocol for the local binder service, or pmap. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include +#include +#include + + +bool_t +xdr_pmap(xdrs, regs) + XDR *xdrs; + struct pmap *regs; +{ + + if (xdr_u_long(xdrs, ®s->pm_prog) && + xdr_u_long(xdrs, ®s->pm_vers) && + xdr_u_long(xdrs, ®s->pm_prot)) + return (xdr_u_long(xdrs, ®s->pm_port)); + return (FALSE); +} diff --git a/rpc.subproj/pmap_prot.h b/rpc.subproj/pmap_prot.h new file mode 100644 index 0000000..1565f5e --- /dev/null +++ b/rpc.subproj/pmap_prot.h @@ -0,0 +1,127 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)pmap_prot.h 1.14 88/02/08 SMI + * from: @(#)pmap_prot.h 2.1 88/07/29 4.0 RPCSRC + * $Id: pmap_prot.h,v 1.2 1999/10/14 21:56:53 wsanchez Exp $ + */ + +/* + * pmap_prot.h + * Protocol for the local binder service, or pmap. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The following procedures are supported by the protocol: + * + * PMAPPROC_NULL() returns () + * takes nothing, returns nothing + * + * PMAPPROC_SET(struct pmap) returns (bool_t) + * TRUE is success, FALSE is failure. Registers the tuple + * [prog, vers, prot, port]. + * + * PMAPPROC_UNSET(struct pmap) returns (bool_t) + * TRUE is success, FALSE is failure. Un-registers pair + * [prog, vers]. prot and port are ignored. + * + * PMAPPROC_GETPORT(struct pmap) returns (long unsigned). + * 0 is failure. Otherwise returns the port number where the pair + * [prog, vers] is registered. It may lie! + * + * PMAPPROC_DUMP() RETURNS (struct pmaplist *) + * + * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>) + * RETURNS (port, string<>); + * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs); + * Calls the procedure on the local machine. If it is not registered, + * this procedure is quite; ie it does not return error information!!! + * This procedure only is supported on rpc/udp and calls via + * rpc/udp. This routine only passes null authentication parameters. + * This file has no interface to xdr routines for PMAPPROC_CALLIT. + * + * The service supports remote procedure calls on udp/ip or tcp/ip socket 111. + */ + +#ifndef _RPC_PMAPPROT_H +#define _RPC_PMAPPROT_H +#include + +#define PMAPPORT ((u_short)111) +#define PMAPPROG ((u_long)100000) +#define PMAPVERS ((u_long)2) +#define PMAPVERS_PROTO ((u_long)2) +#define PMAPVERS_ORIG ((u_long)1) +#define PMAPPROC_NULL ((u_long)0) +#define PMAPPROC_SET ((u_long)1) +#define PMAPPROC_UNSET ((u_long)2) +#define PMAPPROC_GETPORT ((u_long)3) +#define PMAPPROC_DUMP ((u_long)4) +#define PMAPPROC_CALLIT ((u_long)5) + +struct pmap { + long unsigned pm_prog; + long unsigned pm_vers; + long unsigned pm_prot; + long unsigned pm_port; +}; + +struct pmaplist { + struct pmap pml_map; + struct pmaplist *pml_next; +}; + +__BEGIN_DECLS +extern bool_t xdr_pmap __P((XDR *, struct pmap *)); +extern bool_t xdr_pmaplist __P((XDR *, struct pmaplist **)); +__END_DECLS + +#endif /* !_RPC_PMAPPROT_H */ diff --git a/rpc.subproj/pmap_prot2.c b/rpc.subproj/pmap_prot2.c new file mode 100644 index 0000000..986c2c8 --- /dev/null +++ b/rpc.subproj/pmap_prot2.c @@ -0,0 +1,141 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)pmap_prot2.c 2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: pmap_prot2.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $"; +#endif + +/* + * pmap_prot2.c + * Protocol for the local binder service, or pmap. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include +#include +#include + + +/* + * What is going on with linked lists? (!) + * First recall the link list declaration from pmap_prot.h: + * + * struct pmaplist { + * struct pmap pml_map; + * struct pmaplist *pml_map; + * }; + * + * Compare that declaration with a corresponding xdr declaration that + * is (a) pointer-less, and (b) recursive: + * + * typedef union switch (bool_t) { + * + * case TRUE: struct { + * struct pmap; + * pmaplist_t foo; + * }; + * + * case FALSE: struct {}; + * } pmaplist_t; + * + * Notice that the xdr declaration has no nxt pointer while + * the C declaration has no bool_t variable. The bool_t can be + * interpreted as ``more data follows me''; if FALSE then nothing + * follows this bool_t; if TRUE then the bool_t is followed by + * an actual struct pmap, and then (recursively) by the + * xdr union, pamplist_t. + * + * This could be implemented via the xdr_union primitive, though this + * would cause a one recursive call per element in the list. Rather than do + * that we can ``unwind'' the recursion + * into a while loop and do the union arms in-place. + * + * The head of the list is what the C programmer wishes to past around + * the net, yet is the data that the pointer points to which is interesting; + * this sounds like a job for xdr_reference! + */ +bool_t +xdr_pmaplist(xdrs, rp) + register XDR *xdrs; + register struct pmaplist **rp; +{ + /* + * more_elements is pre-computed in case the direction is + * XDR_ENCODE or XDR_FREE. more_elements is overwritten by + * xdr_bool when the direction is XDR_DECODE. + */ + bool_t more_elements; + register int freeing = (xdrs->x_op == XDR_FREE); + register struct pmaplist **next; + + while (TRUE) { + more_elements = (bool_t)(*rp != NULL); + if (! xdr_bool(xdrs, &more_elements)) + return (FALSE); + if (! more_elements) + return (TRUE); /* we are done */ + /* + * the unfortunate side effect of non-recursion is that in + * the case of freeing we must remember the next object + * before we free the current object ... + */ + if (freeing) + next = &((*rp)->pml_next); + if (! xdr_reference(xdrs, (caddr_t *)rp, + (u_int)sizeof(struct pmaplist), xdr_pmap)) + return (FALSE); + rp = (freeing) ? next : &((*rp)->pml_next); + } +} diff --git a/rpc.subproj/pmap_rmt.c b/rpc.subproj/pmap_rmt.c new file mode 100644 index 0000000..cbfffa6 --- /dev/null +++ b/rpc.subproj/pmap_rmt.c @@ -0,0 +1,411 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)pmap_rmt.c 2.2 88/08/01 4.0 RPCSRC";*/ +static char *rcsid = "$Id: pmap_rmt.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $"; +#endif + +/* + * pmap_rmt.c + * Client interface to pmap rpc service. + * remote call and broadcast service + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define MAX_BROADCAST_SIZE 1400 + +extern int errno; +static struct timeval timeout = { 3, 0 }; + + +/* + * pmapper remote-call-service interface. + * This routine is used to call the pmapper remote call service + * which will look up a service program in the port maps, and then + * remotely call that routine with the given parameters. This allows + * programs to do a lookup and call in one step. +*/ +enum clnt_stat +pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_ptr) + struct sockaddr_in *addr; + u_long prog, vers, proc; + xdrproc_t xdrargs, xdrres; + caddr_t argsp, resp; + struct timeval tout; + u_long *port_ptr; +{ + int socket = -1; + register CLIENT *client; + struct rmtcallargs a; + struct rmtcallres r; + enum clnt_stat stat; + + addr->sin_port = htons(PMAPPORT); + client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &socket); + if (client != (CLIENT *)NULL) { + a.prog = prog; + a.vers = vers; + a.proc = proc; + a.args_ptr = argsp; + a.xdr_args = xdrargs; + r.port_ptr = port_ptr; + r.results_ptr = resp; + r.xdr_results = xdrres; + stat = CLNT_CALL(client, PMAPPROC_CALLIT, xdr_rmtcall_args, &a, + xdr_rmtcallres, &r, tout); + CLNT_DESTROY(client); + } else { + stat = RPC_FAILED; + } + (void)close(socket); + addr->sin_port = 0; + return (stat); +} + + +/* + * XDR remote call arguments + * written for XDR_ENCODE direction only + */ +bool_t +xdr_rmtcall_args(xdrs, cap) + register XDR *xdrs; + register struct rmtcallargs *cap; +{ + u_int lenposition, argposition, position; + + if (xdr_u_long(xdrs, &(cap->prog)) && + xdr_u_long(xdrs, &(cap->vers)) && + xdr_u_long(xdrs, &(cap->proc))) { + lenposition = XDR_GETPOS(xdrs); + if (! xdr_u_long(xdrs, &(cap->arglen))) + return (FALSE); + argposition = XDR_GETPOS(xdrs); + if (! (*(cap->xdr_args))(xdrs, cap->args_ptr)) + return (FALSE); + position = XDR_GETPOS(xdrs); + cap->arglen = (u_long)position - (u_long)argposition; + XDR_SETPOS(xdrs, lenposition); + if (! xdr_u_long(xdrs, &(cap->arglen))) + return (FALSE); + XDR_SETPOS(xdrs, position); + return (TRUE); + } + return (FALSE); +} + +/* + * XDR remote call results + * written for XDR_DECODE direction only + */ +bool_t +xdr_rmtcallres(xdrs, crp) + register XDR *xdrs; + register struct rmtcallres *crp; +{ + caddr_t port_ptr; + + port_ptr = (caddr_t)crp->port_ptr; + if (xdr_reference(xdrs, &port_ptr, sizeof (u_long), + xdr_u_long) && xdr_u_long(xdrs, &crp->resultslen)) { + crp->port_ptr = (u_long *)port_ptr; + return ((*(crp->xdr_results))(xdrs, crp->results_ptr)); + } + return (FALSE); +} + + +/* + * The following is kludged-up support for simple rpc broadcasts. + * Someday a large, complicated system will replace these trivial + * routines which only support udp/ip . + */ + +static int +getbroadcastnets(addrs, sock, buf) + struct in_addr *addrs; + int sock; /* any valid socket will do */ + char *buf; /* why allocxate more when we can use existing... */ +{ + struct ifconf ifc; + struct ifreq ifreq, *ifr; + struct sockaddr_in *sin; + char *cp, *cplim; + int n, i = 0; + + ifc.ifc_len = UDPMSGSIZE; + ifc.ifc_buf = buf; + if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) { + perror("broadcast: ioctl (get interface configuration)"); + return (0); + } +#define max(a, b) (a > b ? a : b) +#define size(p) max((p).sa_len, sizeof(p)) + cplim = buf + ifc.ifc_len; /*skip over if's with big ifr_addr's */ + for (cp = buf; cp < cplim; + cp += sizeof (ifr->ifr_name) + size(ifr->ifr_addr)) { + ifr = (struct ifreq *)cp; + if (ifr->ifr_addr.sa_family != AF_INET) + continue; + ifreq = *ifr; + if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) { + perror("broadcast: ioctl (get interface flags)"); + continue; + } + if ((ifreq.ifr_flags & IFF_BROADCAST) && + (ifreq.ifr_flags & IFF_UP)) { + sin = (struct sockaddr_in *)&ifr->ifr_addr; +#ifdef SIOCGIFBRDADDR /* 4.3BSD */ + if (ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) { + addrs[i++] = + inet_makeaddr(inet_netof(sin->sin_addr), + INADDR_ANY); + } else { + addrs[i++] = ((struct sockaddr_in*) + &ifreq.ifr_addr)->sin_addr; + } +#else /* 4.2 BSD */ + addrs[i++] = inet_makeaddr(inet_netof(sin->sin_addr), + INADDR_ANY); +#endif + } + } + return (i); +} + +typedef bool_t (*resultproc_t)(); + +enum clnt_stat +clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult) + u_long prog; /* program number */ + u_long vers; /* version number */ + u_long proc; /* procedure number */ + xdrproc_t xargs; /* xdr routine for args */ + caddr_t argsp; /* pointer to args */ + xdrproc_t xresults; /* xdr routine for results */ + caddr_t resultsp; /* pointer to results */ + resultproc_t eachresult; /* call with each result obtained */ +{ + enum clnt_stat stat; + AUTH *unix_auth = authunix_create_default(); + XDR xdr_stream; + register XDR *xdrs = &xdr_stream; + int outlen, inlen, fromlen, nets; + register int sock; + int on = 1; + fd_set mask; + fd_set readfds; + register int i; + bool_t done = FALSE; + register u_long xid; + u_long port; + struct in_addr addrs[20]; + struct sockaddr_in baddr, raddr; /* broadcast and response addresses */ + struct rmtcallargs a; + struct rmtcallres r; + struct rpc_msg msg; + struct timeval t; + char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE]; + + /* + * initialization: create a socket, a broadcast address, and + * preserialize the arguments into a send buffer. + */ + if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + perror("Cannot create socket for broadcast rpc"); + stat = RPC_CANTSEND; + goto done_broad; + } +#ifdef SO_BROADCAST + if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { + perror("Cannot set socket option SO_BROADCAST"); + stat = RPC_CANTSEND; + goto done_broad; + } +#endif /* def SO_BROADCAST */ + FD_ZERO(&mask); + FD_SET(sock, &mask); + nets = getbroadcastnets(addrs, sock, inbuf); + bzero((char *)&baddr, sizeof (baddr)); + baddr.sin_family = AF_INET; + baddr.sin_port = htons(PMAPPORT); + baddr.sin_addr.s_addr = htonl(INADDR_ANY); +/* baddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); */ + (void)gettimeofday(&t, (struct timezone *)0); + msg.rm_xid = xid = getpid() ^ t.tv_sec ^ t.tv_usec; + t.tv_usec = 0; + msg.rm_direction = CALL; + msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; + msg.rm_call.cb_prog = PMAPPROG; + msg.rm_call.cb_vers = PMAPVERS; + msg.rm_call.cb_proc = PMAPPROC_CALLIT; + msg.rm_call.cb_cred = unix_auth->ah_cred; + msg.rm_call.cb_verf = unix_auth->ah_verf; + a.prog = prog; + a.vers = vers; + a.proc = proc; + a.xdr_args = xargs; + a.args_ptr = argsp; + r.port_ptr = &port; + r.xdr_results = xresults; + r.results_ptr = resultsp; + xdrmem_create(xdrs, outbuf, MAX_BROADCAST_SIZE, XDR_ENCODE); + if ((! xdr_callmsg(xdrs, &msg)) || (! xdr_rmtcall_args(xdrs, &a))) { + stat = RPC_CANTENCODEARGS; + goto done_broad; + } + outlen = (int)xdr_getpos(xdrs); + xdr_destroy(xdrs); + /* + * Basic loop: broadcast a packet and wait a while for response(s). + * The response timeout grows larger per iteration. + */ + for (t.tv_sec = 4; t.tv_sec <= 14; t.tv_sec += 2) { + for (i = 0; i < nets; i++) { + baddr.sin_addr = addrs[i]; + if (sendto(sock, outbuf, outlen, 0, + (struct sockaddr *)&baddr, + sizeof (struct sockaddr)) != outlen) { + perror("Cannot send broadcast packet"); + stat = RPC_CANTSEND; + goto done_broad; + } + } + if (eachresult == NULL) { + stat = RPC_SUCCESS; + goto done_broad; + } + recv_again: + msg.acpted_rply.ar_verf = _null_auth; + msg.acpted_rply.ar_results.where = (caddr_t)&r; + msg.acpted_rply.ar_results.proc = xdr_rmtcallres; + readfds = mask; + switch (select(sock+1, &readfds, (int *)NULL, + (int *)NULL, &t)) { + + case 0: /* timed out */ + stat = RPC_TIMEDOUT; + continue; + + case -1: /* some kind of error */ + if (errno == EINTR) + goto recv_again; + perror("Broadcast select problem"); + stat = RPC_CANTRECV; + goto done_broad; + + } /* end of select results switch */ + try_again: + fromlen = sizeof(struct sockaddr); + inlen = recvfrom(sock, inbuf, UDPMSGSIZE, 0, + (struct sockaddr *)&raddr, &fromlen); + if (inlen < 0) { + if (errno == EINTR) + goto try_again; + perror("Cannot receive reply to broadcast"); + stat = RPC_CANTRECV; + goto done_broad; + } + if (inlen < sizeof(u_long)) + goto recv_again; + /* + * see if reply transaction id matches sent id. + * If so, decode the results. + */ + xdrmem_create(xdrs, inbuf, (u_int)inlen, XDR_DECODE); + if (xdr_replymsg(xdrs, &msg)) { + if ((msg.rm_xid == xid) && + (msg.rm_reply.rp_stat == MSG_ACCEPTED) && + (msg.acpted_rply.ar_stat == SUCCESS)) { + raddr.sin_port = htons((u_short)port); + done = (*eachresult)(resultsp, &raddr); + } + /* otherwise, we just ignore the errors ... */ + } else { +#ifdef notdef + /* some kind of deserialization problem ... */ + if (msg.rm_xid == xid) + fprintf(stderr, "Broadcast deserialization problem"); + /* otherwise, just random garbage */ +#endif + } + xdrs->x_op = XDR_FREE; + msg.acpted_rply.ar_results.proc = xdr_void; + (void)xdr_replymsg(xdrs, &msg); + (void)(*xresults)(xdrs, resultsp); + xdr_destroy(xdrs); + if (done) { + stat = RPC_SUCCESS; + goto done_broad; + } else { + goto recv_again; + } + } +done_broad: + (void)close(sock); + AUTH_DESTROY(unix_auth); + return (stat); +} + diff --git a/rpc.subproj/pmap_rmt.h b/rpc.subproj/pmap_rmt.h new file mode 100644 index 0000000..a6782a5 --- /dev/null +++ b/rpc.subproj/pmap_rmt.h @@ -0,0 +1,86 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)pmap_rmt.h 1.2 88/02/08 SMI + * from: @(#)pmap_rmt.h 2.1 88/07/29 4.0 RPCSRC + * $Id: pmap_rmt.h,v 1.2 1999/10/14 21:56:53 wsanchez Exp $ + */ + +/* + * Structures and XDR routines for parameters to and replies from + * the portmapper remote-call-service. + * + * Copyright (C) 1986, Sun Microsystems, Inc. + */ + +#ifndef _RPC_PMAPRMT_H +#define _RPC_PMAPRMT_H +#include + +struct rmtcallargs { + u_long prog, vers, proc, arglen; + caddr_t args_ptr; + xdrproc_t xdr_args; +}; + +struct rmtcallres { + u_long *port_ptr; + u_long resultslen; + caddr_t results_ptr; + xdrproc_t xdr_results; +}; + +__BEGIN_DECLS +extern bool_t xdr_rmtcall_args __P((XDR *, struct rmtcallargs *)); +extern bool_t xdr_rmtcallres __P((XDR *, struct rmtcallres *)); +__END_DECLS + +#endif /* !_RPC_PMAPRMT_H */ diff --git a/rpc.subproj/rpc.h b/rpc.subproj/rpc.h new file mode 100644 index 0000000..da89dff --- /dev/null +++ b/rpc.subproj/rpc.h @@ -0,0 +1,93 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)rpc.h 1.9 88/02/08 SMI + * from: @(#)rpc.h 2.4 89/07/11 4.0 RPCSRC + * $Id: rpc.h,v 1.2 1999/10/14 21:56:53 wsanchez Exp $ + */ + +/* + * rpc.h, Just includes the billions of rpc header files necessary to + * do remote procedure calling. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ +#ifndef _RPC_RPC_H +#define _RPC_RPC_H + +#include /* some typedefs */ +#include + +/* external data representation interfaces */ +#include /* generic (de)serializer */ + +/* Client side only authentication */ +#include /* generic authenticator (client side) */ + +/* Client side (mostly) remote procedure call */ +#include /* generic rpc stuff */ + +/* semi-private protocol headers */ +#include /* protocol for rpc messages */ +#include /* protocol for unix style cred */ +/* + * Uncomment-out the next line if you are building the rpc library with + * DES Authentication (see the README file in the secure_rpc/ directory). + */ +/*#include protocol for des style cred */ + +/* Server side only remote procedure callee */ +#include /* service manager and multiplexer */ +#include /* service side authenticator */ + +#include + +#endif /* !_RPC_RPC_H */ diff --git a/rpc.subproj/rpc_callmsg.c b/rpc.subproj/rpc_callmsg.c new file mode 100644 index 0000000..45014db --- /dev/null +++ b/rpc.subproj/rpc_callmsg.c @@ -0,0 +1,215 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)rpc_callmsg.c 2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: rpc_callmsg.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $"; +#endif + +/* + * rpc_callmsg.c + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + */ + +#include + +#include + +/* + * XDR a call message + */ +bool_t +xdr_callmsg(xdrs, cmsg) + register XDR *xdrs; + register struct rpc_msg *cmsg; +{ + register long *buf; + register struct opaque_auth *oa; + + if (xdrs->x_op == XDR_ENCODE) { + if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) { + return (FALSE); + } + if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) { + return (FALSE); + } + buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT + + RNDUP(cmsg->rm_call.cb_cred.oa_length) + + 2 * BYTES_PER_XDR_UNIT + + RNDUP(cmsg->rm_call.cb_verf.oa_length)); + if (buf != NULL) { + IXDR_PUT_LONG(buf, cmsg->rm_xid); + IXDR_PUT_ENUM(buf, cmsg->rm_direction); + if (cmsg->rm_direction != CALL) { + return (FALSE); + } + IXDR_PUT_LONG(buf, cmsg->rm_call.cb_rpcvers); + if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) { + return (FALSE); + } + IXDR_PUT_LONG(buf, cmsg->rm_call.cb_prog); + IXDR_PUT_LONG(buf, cmsg->rm_call.cb_vers); + IXDR_PUT_LONG(buf, cmsg->rm_call.cb_proc); + oa = &cmsg->rm_call.cb_cred; + IXDR_PUT_ENUM(buf, oa->oa_flavor); + IXDR_PUT_LONG(buf, oa->oa_length); + if (oa->oa_length) { + bcopy(oa->oa_base, (caddr_t)buf, oa->oa_length); + buf += RNDUP(oa->oa_length) / sizeof (long); + } + oa = &cmsg->rm_call.cb_verf; + IXDR_PUT_ENUM(buf, oa->oa_flavor); + IXDR_PUT_LONG(buf, oa->oa_length); + if (oa->oa_length) { + bcopy(oa->oa_base, (caddr_t)buf, oa->oa_length); + /* no real need.... + buf += RNDUP(oa->oa_length) / sizeof (long); + */ + } + return (TRUE); + } + } + if (xdrs->x_op == XDR_DECODE) { + buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT); + if (buf != NULL) { + cmsg->rm_xid = IXDR_GET_LONG(buf); + cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type); + if (cmsg->rm_direction != CALL) { + return (FALSE); + } + cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG(buf); + if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) { + return (FALSE); + } + cmsg->rm_call.cb_prog = IXDR_GET_LONG(buf); + cmsg->rm_call.cb_vers = IXDR_GET_LONG(buf); + cmsg->rm_call.cb_proc = IXDR_GET_LONG(buf); + oa = &cmsg->rm_call.cb_cred; + oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); + oa->oa_length = IXDR_GET_LONG(buf); + if (oa->oa_length) { + if (oa->oa_length > MAX_AUTH_BYTES) { + return (FALSE); + } + if (oa->oa_base == NULL) { + oa->oa_base = (caddr_t) + mem_alloc(oa->oa_length); + } + buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); + if (buf == NULL) { + if (xdr_opaque(xdrs, oa->oa_base, + oa->oa_length) == FALSE) { + return (FALSE); + } + } else { + bcopy((caddr_t)buf, oa->oa_base, + oa->oa_length); + /* no real need.... + buf += RNDUP(oa->oa_length) / + sizeof (long); + */ + } + } + oa = &cmsg->rm_call.cb_verf; + buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE || + xdr_u_int(xdrs, &oa->oa_length) == FALSE) { + return (FALSE); + } + } else { + oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); + oa->oa_length = IXDR_GET_LONG(buf); + } + if (oa->oa_length) { + if (oa->oa_length > MAX_AUTH_BYTES) { + return (FALSE); + } + if (oa->oa_base == NULL) { + oa->oa_base = (caddr_t) + mem_alloc(oa->oa_length); + } + buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); + if (buf == NULL) { + if (xdr_opaque(xdrs, oa->oa_base, + oa->oa_length) == FALSE) { + return (FALSE); + } + } else { + bcopy((caddr_t)buf, oa->oa_base, + oa->oa_length); + /* no real need... + buf += RNDUP(oa->oa_length) / + sizeof (long); + */ + } + } + return (TRUE); + } + } + if ( + xdr_u_long(xdrs, &(cmsg->rm_xid)) && + xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) && + (cmsg->rm_direction == CALL) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) && + (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_proc)) && + xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred)) ) + return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf))); + return (FALSE); +} + diff --git a/rpc.subproj/rpc_commondata.c b/rpc.subproj/rpc_commondata.c new file mode 100644 index 0000000..c12c265 --- /dev/null +++ b/rpc.subproj/rpc_commondata.c @@ -0,0 +1,73 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)rpc_commondata.c 2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: rpc_commondata.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $"; +#endif + +#include +/* + * This file should only contain common data (global data) that is exported + * by public interfaces + */ +#if defined(__APPLE__) +struct opaque_auth _null_auth = {0}; +fd_set svc_fdset = {0}; +int svc_maxfd = -1; +struct rpc_createerr rpc_createerr = {0}; +#else +struct opaque_auth _null_auth; +fd_set svc_fdset; +int svc_maxfd = -1; +struct rpc_createerr rpc_createerr; +#endif /* !NeXT */ diff --git a/rpc.subproj/rpc_dtablesize.c b/rpc.subproj/rpc_dtablesize.c new file mode 100644 index 0000000..bfdd00b --- /dev/null +++ b/rpc.subproj/rpc_dtablesize.c @@ -0,0 +1,78 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)rpc_dtablesize.c 1.2 87/08/11 Copyr 1987 Sun Micro";*/ +/*static char *sccsid = "from: @(#)rpc_dtablesize.c 2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: rpc_dtablesize.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $"; +#endif + +#include + +/* + * Cache the result of getdtablesize(), so we don't have to do an + * expensive system call every time. + */ +_rpc_dtablesize() +{ + static int size; + + if (size == 0) { + size = getdtablesize(); +#ifdef FD_SETSIZE + /* prevent select() from breaking */ + if (size > FD_SETSIZE) + size = FD_SETSIZE; +#endif + } + return (size); +} diff --git a/rpc.subproj/rpc_msg.h b/rpc.subproj/rpc_msg.h new file mode 100644 index 0000000..53373d0 --- /dev/null +++ b/rpc.subproj/rpc_msg.h @@ -0,0 +1,218 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)rpc_msg.h 1.7 86/07/16 SMI + * from: @(#)rpc_msg.h 2.1 88/07/29 4.0 RPCSRC + * $Id: rpc_msg.h,v 1.2 1999/10/14 21:56:54 wsanchez Exp $ + */ + +/* + * rpc_msg.h + * rpc message definition + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef _RPC_RPCMSG_H +#define _RPC_RPCMSG_H + +#define RPC_MSG_VERSION ((u_long) 2) +#define RPC_SERVICE_PORT ((u_short) 2048) + +/* + * Bottom up definition of an rpc message. + * NOTE: call and reply use the same overall stuct but + * different parts of unions within it. + */ + +enum msg_type { + CALL=0, + REPLY=1 +}; + +enum reply_stat { + MSG_ACCEPTED=0, + MSG_DENIED=1 +}; + +enum accept_stat { + SUCCESS=0, + PROG_UNAVAIL=1, + PROG_MISMATCH=2, + PROC_UNAVAIL=3, + GARBAGE_ARGS=4, + SYSTEM_ERR=5 +}; + +enum reject_stat { + RPC_MISMATCH=0, + AUTH_ERROR=1 +}; + +/* + * Reply part of an rpc exchange + */ + +/* + * Reply to an rpc request that was accepted by the server. + * Note: there could be an error even though the request was + * accepted. + */ +struct accepted_reply { + struct opaque_auth ar_verf; + enum accept_stat ar_stat; + union { + struct { + u_long low; + u_long high; + } AR_versions; + struct { + caddr_t where; + xdrproc_t proc; + } AR_results; + /* and many other null cases */ + } ru; +#define ar_results ru.AR_results +#define ar_vers ru.AR_versions +}; + +/* + * Reply to an rpc request that was rejected by the server. + */ +struct rejected_reply { + enum reject_stat rj_stat; + union { + struct { + u_long low; + u_long high; + } RJ_versions; + enum auth_stat RJ_why; /* why authentication did not work */ + } ru; +#define rj_vers ru.RJ_versions +#define rj_why ru.RJ_why +}; + +/* + * Body of a reply to an rpc request. + */ +struct reply_body { + enum reply_stat rp_stat; + union { + struct accepted_reply RP_ar; + struct rejected_reply RP_dr; + } ru; +#define rp_acpt ru.RP_ar +#define rp_rjct ru.RP_dr +}; + +/* + * Body of an rpc request call. + */ +struct call_body { + u_long cb_rpcvers; /* must be equal to two */ + u_long cb_prog; + u_long cb_vers; + u_long cb_proc; + struct opaque_auth cb_cred; + struct opaque_auth cb_verf; /* protocol specific - provided by client */ +}; + +/* + * The rpc message + */ +struct rpc_msg { + u_long rm_xid; + enum msg_type rm_direction; + union { + struct call_body RM_cmb; + struct reply_body RM_rmb; + } ru; +#define rm_call ru.RM_cmb +#define rm_reply ru.RM_rmb +}; +#define acpted_rply ru.RM_rmb.ru.RP_ar +#define rjcted_rply ru.RM_rmb.ru.RP_dr + +__BEGIN_DECLS +/* + * XDR routine to handle a rpc message. + * xdr_callmsg(xdrs, cmsg) + * XDR *xdrs; + * struct rpc_msg *cmsg; + */ +extern bool_t xdr_callmsg __P((XDR *, struct rpc_msg *)); + +/* + * XDR routine to pre-serialize the static part of a rpc message. + * xdr_callhdr(xdrs, cmsg) + * XDR *xdrs; + * struct rpc_msg *cmsg; + */ +extern bool_t xdr_callhdr __P((XDR *, struct rpc_msg *)); + +/* + * XDR routine to handle a rpc reply. + * xdr_replymsg(xdrs, rmsg) + * XDR *xdrs; + * struct rpc_msg *rmsg; + */ +extern bool_t xdr_replymsg __P((XDR *, struct rpc_msg *)); + +/* + * Fills in the error part of a reply message. + * _seterr_reply(msg, error) + * struct rpc_msg *msg; + * struct rpc_err *error; + */ +extern void _seterr_reply __P((struct rpc_msg *, struct rpc_err *)); +__END_DECLS + +#endif /* !_RPC_RPCMSG_H */ diff --git a/rpc.subproj/rpc_prot.c b/rpc.subproj/rpc_prot.c new file mode 100644 index 0000000..ab74c4b --- /dev/null +++ b/rpc.subproj/rpc_prot.c @@ -0,0 +1,316 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";*/ +static char *rcsid = "$Id: rpc_prot.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $"; +#endif + +/* + * rpc_prot.c + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * This set of routines implements the rpc message definition, + * its serializer and some common rpc utility routines. + * The routines are meant for various implementations of rpc - + * they are NOT for the rpc client or rpc service implementations! + * Because authentication stuff is easy and is part of rpc, the opaque + * routines are also in this program. + */ + +#include + +#include + +/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */ + +#if defined(__APPLE__) +extern +#endif +struct opaque_auth _null_auth; + +/* + * XDR an opaque authentication struct + * (see auth.h) + */ +bool_t +xdr_opaque_auth(xdrs, ap) + register XDR *xdrs; + register struct opaque_auth *ap; +{ + + if (xdr_enum(xdrs, &(ap->oa_flavor))) + return (xdr_bytes(xdrs, &ap->oa_base, + &ap->oa_length, MAX_AUTH_BYTES)); + return (FALSE); +} + +/* + * XDR a DES block + */ +bool_t +xdr_des_block(xdrs, blkp) + register XDR *xdrs; + register des_block *blkp; +{ + return (xdr_opaque(xdrs, (caddr_t)blkp, sizeof(des_block))); +} + +/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */ + +/* + * XDR the MSG_ACCEPTED part of a reply message union + */ +bool_t +xdr_accepted_reply(xdrs, ar) + register XDR *xdrs; + register struct accepted_reply *ar; +{ + + /* personalized union, rather than calling xdr_union */ + if (! xdr_opaque_auth(xdrs, &(ar->ar_verf))) + return (FALSE); + if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat))) + return (FALSE); + switch (ar->ar_stat) { + + case SUCCESS: + return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where)); + + case PROG_MISMATCH: + if (! xdr_u_long(xdrs, &(ar->ar_vers.low))) + return (FALSE); + return (xdr_u_long(xdrs, &(ar->ar_vers.high))); + } + return (TRUE); /* TRUE => open ended set of problems */ +} + +/* + * XDR the MSG_DENIED part of a reply message union + */ +bool_t +xdr_rejected_reply(xdrs, rr) + register XDR *xdrs; + register struct rejected_reply *rr; +{ + + /* personalized union, rather than calling xdr_union */ + if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat))) + return (FALSE); + switch (rr->rj_stat) { + + case RPC_MISMATCH: + if (! xdr_u_long(xdrs, &(rr->rj_vers.low))) + return (FALSE); + return (xdr_u_long(xdrs, &(rr->rj_vers.high))); + + case AUTH_ERROR: + return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why))); + } + return (FALSE); +} + +static struct xdr_discrim reply_dscrm[3] = { + { (int)MSG_ACCEPTED, xdr_accepted_reply }, + { (int)MSG_DENIED, xdr_rejected_reply }, + { __dontcare__, NULL_xdrproc_t } }; + +/* + * XDR a reply message + */ +bool_t +xdr_replymsg(xdrs, rmsg) + register XDR *xdrs; + register struct rpc_msg *rmsg; +{ + if ( + xdr_u_long(xdrs, &(rmsg->rm_xid)) && + xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) && + (rmsg->rm_direction == REPLY) ) + return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat), + (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t)); + return (FALSE); +} + + +/* + * Serializes the "static part" of a call message header. + * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers. + * The rm_xid is not really static, but the user can easily munge on the fly. + */ +bool_t +xdr_callhdr(xdrs, cmsg) + register XDR *xdrs; + register struct rpc_msg *cmsg; +{ + + cmsg->rm_direction = CALL; + cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION; + if ( + (xdrs->x_op == XDR_ENCODE) && + xdr_u_long(xdrs, &(cmsg->rm_xid)) && + xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) ) + return (xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers))); + return (FALSE); +} + +/* ************************** Client utility routine ************* */ + +static void +accepted(acpt_stat, error) + register enum accept_stat acpt_stat; + register struct rpc_err *error; +{ + + switch (acpt_stat) { + + case PROG_UNAVAIL: + error->re_status = RPC_PROGUNAVAIL; + return; + + case PROG_MISMATCH: + error->re_status = RPC_PROGVERSMISMATCH; + return; + + case PROC_UNAVAIL: + error->re_status = RPC_PROCUNAVAIL; + return; + + case GARBAGE_ARGS: + error->re_status = RPC_CANTDECODEARGS; + return; + + case SYSTEM_ERR: + error->re_status = RPC_SYSTEMERROR; + return; + + case SUCCESS: + error->re_status = RPC_SUCCESS; + return; + } + /* something's wrong, but we don't know what ... */ + error->re_status = RPC_FAILED; + error->re_lb.s1 = (long)MSG_ACCEPTED; + error->re_lb.s2 = (long)acpt_stat; +} + +static void +rejected(rjct_stat, error) + register enum reject_stat rjct_stat; + register struct rpc_err *error; +{ + + switch (rjct_stat) { + + case RPC_VERSMISMATCH: + error->re_status = RPC_VERSMISMATCH; + return; + + case AUTH_ERROR: + error->re_status = RPC_AUTHERROR; + return; + } + /* something's wrong, but we don't know what ... */ + error->re_status = RPC_FAILED; + error->re_lb.s1 = (long)MSG_DENIED; + error->re_lb.s2 = (long)rjct_stat; +} + +/* + * given a reply message, fills in the error + */ +void +_seterr_reply(msg, error) + register struct rpc_msg *msg; + register struct rpc_err *error; +{ + + /* optimized for normal, SUCCESSful case */ + switch (msg->rm_reply.rp_stat) { + + case MSG_ACCEPTED: + if (msg->acpted_rply.ar_stat == SUCCESS) { + error->re_status = RPC_SUCCESS; + return; + }; + accepted(msg->acpted_rply.ar_stat, error); + break; + + case MSG_DENIED: + rejected(msg->rjcted_rply.rj_stat, error); + break; + + default: + error->re_status = RPC_FAILED; + error->re_lb.s1 = (long)(msg->rm_reply.rp_stat); + break; + } + switch (error->re_status) { + + case RPC_VERSMISMATCH: + error->re_vers.low = msg->rjcted_rply.rj_vers.low; + error->re_vers.high = msg->rjcted_rply.rj_vers.high; + break; + + case RPC_AUTHERROR: + error->re_why = msg->rjcted_rply.rj_why; + break; + + case RPC_PROGVERSMISMATCH: + error->re_vers.low = msg->acpted_rply.ar_vers.low; + error->re_vers.high = msg->acpted_rply.ar_vers.high; + break; + } +} diff --git a/rpc.subproj/svc.c b/rpc.subproj/svc.c new file mode 100644 index 0000000..fffefc0 --- /dev/null +++ b/rpc.subproj/svc.c @@ -0,0 +1,475 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)svc.c 2.4 88/08/11 4.0 RPCSRC";*/ +static char *rcsid = "$Id: svc.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $"; +#endif + +/* + * svc.c, Server-side remote procedure call interface. + * + * There are two sets of procedures here. The xprt routines are + * for handling transport handles. The svc routines handle the + * list of service routines. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include +#include +#include + +extern int errno; + +static SVCXPRT **xports; + +#define NULL_SVC ((struct svc_callout *)0) +#define RQCRED_SIZE 400 /* this size is excessive */ + +#define max(a, b) (a > b ? a : b) + +/* + * The services list + * Each entry represents a set of procedures (an rpc program). + * The dispatch routine takes request structs and runs the + * apropriate procedure. + */ +static struct svc_callout { + struct svc_callout *sc_next; + u_long sc_prog; + u_long sc_vers; + void (*sc_dispatch)(); +} *svc_head; + +static struct svc_callout *svc_find(); + +/* *************** SVCXPRT related stuff **************** */ + +extern int svc_maxfd; + +/* + * Activate a transport handle. + */ +void +xprt_register(xprt) + SVCXPRT *xprt; +{ + register int sock = xprt->xp_sock; + + if (xports == NULL) { + xports = (SVCXPRT **) + mem_alloc(FD_SETSIZE * sizeof(SVCXPRT *)); + } + if (sock < FD_SETSIZE) { + xports[sock] = xprt; + FD_SET(sock, &svc_fdset); + svc_maxfd = max(svc_maxfd, sock); + } +} + +/* + * De-activate a transport handle. + */ +void +xprt_unregister(xprt) + SVCXPRT *xprt; +{ + register int sock = xprt->xp_sock; + + if ((sock < FD_SETSIZE) && (xports[sock] == xprt)) { + xports[sock] = (SVCXPRT *)0; + FD_CLR(sock, &svc_fdset); + if (sock == svc_maxfd) { + for (svc_maxfd--; svc_maxfd>=0; svc_maxfd--) + if (xports[svc_maxfd]) + break; + } + } +} + + +/* ********************** CALLOUT list related stuff ************* */ + +/* + * Add a service program to the callout list. + * The dispatch routine will be called when a rpc request for this + * program number comes in. + */ +bool_t +svc_register(xprt, prog, vers, dispatch, protocol) + SVCXPRT *xprt; + u_long prog; + u_long vers; + void (*dispatch)(); + int protocol; +{ + struct svc_callout *prev; + register struct svc_callout *s; + + if ((s = svc_find(prog, vers, &prev)) != NULL_SVC) { + if (s->sc_dispatch == dispatch) + goto pmap_it; /* he is registering another xptr */ + return (FALSE); + } + s = (struct svc_callout *)mem_alloc(sizeof(struct svc_callout)); + if (s == (struct svc_callout *)0) { + return (FALSE); + } + s->sc_prog = prog; + s->sc_vers = vers; + s->sc_dispatch = dispatch; + s->sc_next = svc_head; + svc_head = s; +pmap_it: + /* now register the information with the local binder service */ + if (protocol) { + return (pmap_set(prog, vers, protocol, xprt->xp_port)); + } + return (TRUE); +} + +/* + * Remove a service program from the callout list. + */ +void +svc_unregister(prog, vers) + u_long prog; + u_long vers; +{ + struct svc_callout *prev; + register struct svc_callout *s; + + if ((s = svc_find(prog, vers, &prev)) == NULL_SVC) + return; + if (prev == NULL_SVC) { + svc_head = s->sc_next; + } else { + prev->sc_next = s->sc_next; + } + s->sc_next = NULL_SVC; + mem_free((char *) s, (u_int) sizeof(struct svc_callout)); + /* now unregister the information with the local binder service */ + (void)pmap_unset(prog, vers); +} + +/* + * Search the callout list for a program number, return the callout + * struct. + */ +static struct svc_callout * +svc_find(prog, vers, prev) + u_long prog; + u_long vers; + struct svc_callout **prev; +{ + register struct svc_callout *s, *p; + + p = NULL_SVC; + for (s = svc_head; s != NULL_SVC; s = s->sc_next) { + if ((s->sc_prog == prog) && (s->sc_vers == vers)) + goto done; + p = s; + } +done: + *prev = p; + return (s); +} + +/* ******************* REPLY GENERATION ROUTINES ************ */ + +/* + * Send a reply to an rpc request + */ +bool_t +svc_sendreply(xprt, xdr_results, xdr_location) + register SVCXPRT *xprt; + xdrproc_t xdr_results; + caddr_t xdr_location; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = SUCCESS; + rply.acpted_rply.ar_results.where = xdr_location; + rply.acpted_rply.ar_results.proc = xdr_results; + return (SVC_REPLY(xprt, &rply)); +} + +/* + * No procedure error reply + */ +void +svcerr_noproc(xprt) + register SVCXPRT *xprt; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = PROC_UNAVAIL; + SVC_REPLY(xprt, &rply); +} + +/* + * Can't decode args error reply + */ +void +svcerr_decode(xprt) + register SVCXPRT *xprt; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = GARBAGE_ARGS; + SVC_REPLY(xprt, &rply); +} + +/* + * Some system error + */ +void +svcerr_systemerr(xprt) + register SVCXPRT *xprt; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = SYSTEM_ERR; + SVC_REPLY(xprt, &rply); +} + +/* + * Authentication error reply + */ +void +svcerr_auth(xprt, why) + SVCXPRT *xprt; + enum auth_stat why; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_DENIED; + rply.rjcted_rply.rj_stat = AUTH_ERROR; + rply.rjcted_rply.rj_why = why; + SVC_REPLY(xprt, &rply); +} + +/* + * Auth too weak error reply + */ +void +svcerr_weakauth(xprt) + SVCXPRT *xprt; +{ + + svcerr_auth(xprt, AUTH_TOOWEAK); +} + +/* + * Program unavailable error reply + */ +void +svcerr_noprog(xprt) + register SVCXPRT *xprt; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = PROG_UNAVAIL; + SVC_REPLY(xprt, &rply); +} + +/* + * Program version mismatch error reply + */ +void +svcerr_progvers(xprt, low_vers, high_vers) + register SVCXPRT *xprt; + u_long low_vers; + u_long high_vers; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = PROG_MISMATCH; + rply.acpted_rply.ar_vers.low = low_vers; + rply.acpted_rply.ar_vers.high = high_vers; + SVC_REPLY(xprt, &rply); +} + +/* ******************* SERVER INPUT STUFF ******************* */ + +/* + * Get server side input from some transport. + * + * Statement of authentication parameters management: + * This function owns and manages all authentication parameters, specifically + * the "raw" parameters (msg.rm_call.cb_cred and msg.rm_call.cb_verf) and + * the "cooked" credentials (rqst->rq_clntcred). + * However, this function does not know the structure of the cooked + * credentials, so it make the following assumptions: + * a) the structure is contiguous (no pointers), and + * b) the cred structure size does not exceed RQCRED_SIZE bytes. + * In all events, all three parameters are freed upon exit from this routine. + * The storage is trivially management on the call stack in user land, but + * is mallocated in kernel land. + */ + +void +svc_getreq(rdfds) + int rdfds; +{ + fd_set readfds; + + FD_ZERO(&readfds); + readfds.fds_bits[0] = rdfds; + svc_getreqset(&readfds); +} + +void +svc_getreqset(readfds) + fd_set *readfds; +{ + enum xprt_stat stat; + struct rpc_msg msg; + int prog_found; + u_long low_vers; + u_long high_vers; + struct svc_req r; + register SVCXPRT *xprt; + register u_long mask; + register int bit; + register u_long *maskp; + register int sock; + char cred_area[2*MAX_AUTH_BYTES + RQCRED_SIZE]; + msg.rm_call.cb_cred.oa_base = cred_area; + msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]); + r.rq_clntcred = &(cred_area[2*MAX_AUTH_BYTES]); + + + maskp = (u_long *)readfds->fds_bits; + for (sock = 0; sock < FD_SETSIZE; sock += NFDBITS) { + for (mask = *maskp++; bit = ffs(mask); mask ^= (1 << (bit - 1))) { + /* sock has input waiting */ + xprt = xports[sock + bit - 1]; + if (xprt == NULL) + /* But do we control sock? */ + continue; + /* now receive msgs from xprtprt (support batch calls) */ + do { + if (SVC_RECV(xprt, &msg)) { + + /* now find the exported program and call it */ + register struct svc_callout *s; + enum auth_stat why; + + r.rq_xprt = xprt; + r.rq_prog = msg.rm_call.cb_prog; + r.rq_vers = msg.rm_call.cb_vers; + r.rq_proc = msg.rm_call.cb_proc; + r.rq_cred = msg.rm_call.cb_cred; + /* first authenticate the message */ + if ((why= _authenticate(&r, &msg)) != AUTH_OK) { + svcerr_auth(xprt, why); + goto call_done; + } + /* now match message with a registered service*/ + prog_found = FALSE; + low_vers = 0 - 1; + high_vers = 0; + for (s = svc_head; s != NULL_SVC; s = s->sc_next) { + if (s->sc_prog == r.rq_prog) { + if (s->sc_vers == r.rq_vers) { + (*s->sc_dispatch)(&r, xprt); + goto call_done; + } /* found correct version */ + prog_found = TRUE; + if (s->sc_vers < low_vers) + low_vers = s->sc_vers; + if (s->sc_vers > high_vers) + high_vers = s->sc_vers; + } /* found correct program */ + } + /* + * if we got here, the program or version + * is not served ... + */ + if (prog_found) + svcerr_progvers(xprt, + low_vers, high_vers); + else + svcerr_noprog(xprt); + /* Fall through to ... */ + } + call_done: + if ((stat = SVC_STAT(xprt)) == XPRT_DIED){ + SVC_DESTROY(xprt); + break; + } + } while (stat == XPRT_MOREREQS); + } + } +} diff --git a/rpc.subproj/svc.h b/rpc.subproj/svc.h new file mode 100644 index 0000000..8a3004e --- /dev/null +++ b/rpc.subproj/svc.h @@ -0,0 +1,325 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)svc.h 1.20 88/02/08 SMI + * from: @(#)svc.h 2.2 88/07/29 4.0 RPCSRC + * $Id: svc.h,v 1.2 1999/10/14 21:56:54 wsanchez Exp $ + */ + +/* + * svc.h, Server-side remote procedure call interface. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef _RPC_SVC_H +#define _RPC_SVC_H +#include + +/* + * This interface must manage two items concerning remote procedure calling: + * + * 1) An arbitrary number of transport connections upon which rpc requests + * are received. The two most notable transports are TCP and UDP; they are + * created and registered by routines in svc_tcp.c and svc_udp.c, respectively; + * they in turn call xprt_register and xprt_unregister. + * + * 2) An arbitrary number of locally registered services. Services are + * described by the following four data: program number, version number, + * "service dispatch" function, a transport handle, and a boolean that + * indicates whether or not the exported program should be registered with a + * local binder service; if true the program's number and version and the + * port number from the transport handle are registered with the binder. + * These data are registered with the rpc svc system via svc_register. + * + * A service's dispatch function is called whenever an rpc request comes in + * on a transport. The request's program and version numbers must match + * those of the registered service. The dispatch function is passed two + * parameters, struct svc_req * and SVCXPRT *, defined below. + */ + +enum xprt_stat { + XPRT_DIED, + XPRT_MOREREQS, + XPRT_IDLE +}; + +/* + * Server side transport handle + */ +typedef struct { + int xp_sock; + u_short xp_port; /* associated port number */ + struct xp_ops { + bool_t (*xp_recv)(); /* receive incomming requests */ + enum xprt_stat (*xp_stat)(); /* get transport status */ + bool_t (*xp_getargs)(); /* get arguments */ + bool_t (*xp_reply)(); /* send reply */ + bool_t (*xp_freeargs)();/* free mem allocated for args */ + void (*xp_destroy)(); /* destroy this struct */ + } *xp_ops; + int xp_addrlen; /* length of remote address */ + struct sockaddr_in xp_raddr; /* remote address */ + struct opaque_auth xp_verf; /* raw response verifier */ + caddr_t xp_p1; /* private */ + caddr_t xp_p2; /* private */ +} SVCXPRT; + +/* + * Approved way of getting address of caller + */ +#define svc_getcaller(x) (&(x)->xp_raddr) + +/* + * Operations defined on an SVCXPRT handle + * + * SVCXPRT *xprt; + * struct rpc_msg *msg; + * xdrproc_t xargs; + * caddr_t argsp; + */ +#define SVC_RECV(xprt, msg) \ + (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) +#define svc_recv(xprt, msg) \ + (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) + +#define SVC_STAT(xprt) \ + (*(xprt)->xp_ops->xp_stat)(xprt) +#define svc_stat(xprt) \ + (*(xprt)->xp_ops->xp_stat)(xprt) + +#define SVC_GETARGS(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) +#define svc_getargs(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) + +#define SVC_REPLY(xprt, msg) \ + (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) +#define svc_reply(xprt, msg) \ + (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) + +#define SVC_FREEARGS(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) +#define svc_freeargs(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) + +#define SVC_DESTROY(xprt) \ + (*(xprt)->xp_ops->xp_destroy)(xprt) +#define svc_destroy(xprt) \ + (*(xprt)->xp_ops->xp_destroy)(xprt) + + +/* + * Service request + */ +struct svc_req { + u_long rq_prog; /* service program number */ + u_long rq_vers; /* service protocol version */ + u_long rq_proc; /* the desired procedure */ + struct opaque_auth rq_cred; /* raw creds from the wire */ + caddr_t rq_clntcred; /* read only cooked cred */ + SVCXPRT *rq_xprt; /* associated transport */ +}; + + +/* + * Service registration + * + * svc_register(xprt, prog, vers, dispatch, protocol) + * SVCXPRT *xprt; + * u_long prog; + * u_long vers; + * void (*dispatch)(); + * int protocol; like TCP or UDP, zero means do not register + */ +__BEGIN_DECLS +extern bool_t svc_register __P((SVCXPRT *, u_long, u_long, void (*)(), int)); +__END_DECLS + +/* + * Service un-registration + * + * svc_unregister(prog, vers) + * u_long prog; + * u_long vers; + */ +__BEGIN_DECLS +extern void svc_unregister __P((u_long, u_long)); +__END_DECLS + +/* + * Transport registration. + * + * xprt_register(xprt) + * SVCXPRT *xprt; + */ +__BEGIN_DECLS +extern void xprt_register __P((SVCXPRT *)); +__END_DECLS + +/* + * Transport un-register + * + * xprt_unregister(xprt) + * SVCXPRT *xprt; + */ +__BEGIN_DECLS +extern void xprt_unregister __P((SVCXPRT *)); +__END_DECLS + + + + +/* + * When the service routine is called, it must first check to see if it + * knows about the procedure; if not, it should call svcerr_noproc + * and return. If so, it should deserialize its arguments via + * SVC_GETARGS (defined above). If the deserialization does not work, + * svcerr_decode should be called followed by a return. Successful + * decoding of the arguments should be followed the execution of the + * procedure's code and a call to svc_sendreply. + * + * Also, if the service refuses to execute the procedure due to too- + * weak authentication parameters, svcerr_weakauth should be called. + * Note: do not confuse access-control failure with weak authentication! + * + * NB: In pure implementations of rpc, the caller always waits for a reply + * msg. This message is sent when svc_sendreply is called. + * Therefore pure service implementations should always call + * svc_sendreply even if the function logically returns void; use + * xdr.h - xdr_void for the xdr routine. HOWEVER, tcp based rpc allows + * for the abuse of pure rpc via batched calling or pipelining. In the + * case of a batched call, svc_sendreply should NOT be called since + * this would send a return message, which is what batching tries to avoid. + * It is the service/protocol writer's responsibility to know which calls are + * batched and which are not. Warning: responding to batch calls may + * deadlock the caller and server processes! + */ + +__BEGIN_DECLS +extern bool_t svc_sendreply __P((SVCXPRT *, xdrproc_t, char *)); +extern void svcerr_decode __P((SVCXPRT *)); +extern void svcerr_weakauth __P((SVCXPRT *)); +extern void svcerr_noproc __P((SVCXPRT *)); +extern void svcerr_progvers __P((SVCXPRT *, u_long, u_long)); +extern void svcerr_auth __P((SVCXPRT *, enum auth_stat)); +extern void svcerr_noprog __P((SVCXPRT *)); +extern void svcerr_systemerr __P((SVCXPRT *)); +__END_DECLS + +/* + * Lowest level dispatching -OR- who owns this process anyway. + * Somebody has to wait for incoming requests and then call the correct + * service routine. The routine svc_run does infinite waiting; i.e., + * svc_run never returns. + * Since another (co-existant) package may wish to selectively wait for + * incoming calls or other events outside of the rpc architecture, the + * routine svc_getreq is provided. It must be passed readfds, the + * "in-place" results of a select system call (see select, section 2). + */ + +/* + * Global keeper of rpc service descriptors in use + * dynamic; must be inspected before each call to select + */ +#ifdef FD_SETSIZE +extern fd_set svc_fdset; +#define svc_fds svc_fdset.fds_bits[0] /* compatibility */ +#else +extern int svc_fds; +#endif /* def FD_SETSIZE */ + +/* + * a small program implemented by the svc_rpc implementation itself; + * also see clnt.h for protocol numbers. + */ +extern void rpctest_service(); + +__BEGIN_DECLS +extern void svc_getreq __P((int)); +extern void svc_getreqset __P((fd_set *)); +extern void svc_run __P((void)); +__END_DECLS + +/* + * Socket to use on svcxxx_create call to get default socket + */ +#define RPC_ANYSOCK -1 + +/* + * These are the existing service side transport implementations + */ + +/* + * Memory based rpc for testing and timing. + */ +__BEGIN_DECLS +extern SVCXPRT *svcraw_create __P((void)); +__END_DECLS + + +/* + * Udp based rpc. + */ +__BEGIN_DECLS +extern SVCXPRT *svcudp_create __P((int)); +extern SVCXPRT *svcudp_bufcreate __P((int, u_int, u_int)); +__END_DECLS + + +/* + * Tcp based rpc. + */ +__BEGIN_DECLS +extern SVCXPRT *svctcp_create __P((int, u_int, u_int)); +__END_DECLS + +#endif /* !_RPC_SVC_H */ diff --git a/rpc.subproj/svc_auth.c b/rpc.subproj/svc_auth.c new file mode 100644 index 0000000..6586c98 --- /dev/null +++ b/rpc.subproj/svc_auth.c @@ -0,0 +1,140 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)svc_auth.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)svc_auth.c 2.1 88/08/07 4.0 RPCSRC";*/ +static char *rcsid = "$Id: svc_auth.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $"; +#endif + +/* + * svc_auth_nodes.c, Server-side rpc authenticator interface, + * *WITHOUT* DES authentication. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include + +/* + * svcauthsw is the bdevsw of server side authentication. + * + * Server side authenticators are called from authenticate by + * using the client auth struct flavor field to index into svcauthsw. + * The server auth flavors must implement a routine that looks + * like: + * + * enum auth_stat + * flavorx_auth(rqst, msg) + * register struct svc_req *rqst; + * register struct rpc_msg *msg; + * + */ + +enum auth_stat _svcauth_null(); /* no authentication */ +enum auth_stat _svcauth_unix(); /* unix style (uid, gids) */ +enum auth_stat _svcauth_short(); /* short hand unix style */ + +static struct { + enum auth_stat (*authenticator)(); +} svcauthsw[] = { + _svcauth_null, /* AUTH_NULL */ + _svcauth_unix, /* AUTH_UNIX */ + _svcauth_short, /* AUTH_SHORT */ +}; +#define AUTH_MAX 2 /* HIGHEST AUTH NUMBER */ + + +/* + * The call rpc message, msg has been obtained from the wire. The msg contains + * the raw form of credentials and verifiers. authenticate returns AUTH_OK + * if the msg is successfully authenticated. If AUTH_OK then the routine also + * does the following things: + * set rqst->rq_xprt->verf to the appropriate response verifier; + * sets rqst->rq_client_cred to the "cooked" form of the credentials. + * + * NB: rqst->rq_cxprt->verf must be pre-alloctaed; + * its length is set appropriately. + * + * The caller still owns and is responsible for msg->u.cmb.cred and + * msg->u.cmb.verf. The authentication system retains ownership of + * rqst->rq_client_cred, the cooked credentials. + * + * There is an assumption that any flavour less than AUTH_NULL is + * invalid. + */ +enum auth_stat +_authenticate(rqst, msg) + register struct svc_req *rqst; + struct rpc_msg *msg; +{ + register int cred_flavor; + + rqst->rq_cred = msg->rm_call.cb_cred; + rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor; + rqst->rq_xprt->xp_verf.oa_length = 0; + cred_flavor = rqst->rq_cred.oa_flavor; + if ((cred_flavor <= AUTH_MAX) && (cred_flavor >= AUTH_NULL)) { + return ((*(svcauthsw[cred_flavor].authenticator))(rqst, msg)); + } + + return (AUTH_REJECTEDCRED); +} + +enum auth_stat +_svcauth_null(/*rqst, msg*/) + /*struct svc_req *rqst; + struct rpc_msg *msg;*/ +{ + + return (AUTH_OK); +} diff --git a/rpc.subproj/svc_auth.h b/rpc.subproj/svc_auth.h new file mode 100644 index 0000000..3dc0959 --- /dev/null +++ b/rpc.subproj/svc_auth.h @@ -0,0 +1,73 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)svc_auth.h 1.6 86/07/16 SMI + * from: @(#)svc_auth.h 2.1 88/07/29 4.0 RPCSRC + * $Id: svc_auth.h,v 1.2 1999/10/14 21:56:54 wsanchez Exp $ + */ + +/* + * svc_auth.h, Service side of rpc authentication. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef _RPC_SVCAUTH_H +#define _RPC_SVCAUTH_H + +/* + * Server side authenticator + */ +__BEGIN_DECLS +extern enum auth_stat _authenticate __P((struct svc_req *, struct rpc_msg *)); +__END_DECLS + +#endif /* !_RPC_SVCAUTH_H */ diff --git a/rpc.subproj/svc_auth_unix.c b/rpc.subproj/svc_auth_unix.c new file mode 100644 index 0000000..2f30dd7 --- /dev/null +++ b/rpc.subproj/svc_auth_unix.c @@ -0,0 +1,160 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)svc_auth_unix.c 1.28 88/02/08 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)svc_auth_unix.c 2.3 88/08/01 4.0 RPCSRC";*/ +static char *rcsid = "$Id: svc_auth_unix.c,v 1.3 2001/01/17 19:05:42 majka Exp $"; +#endif + +/* + * svc_auth_unix.c + * Handles UNIX flavor authentication parameters on the service side of rpc. + * There are two svc auth implementations here: AUTH_UNIX and AUTH_SHORT. + * _svcauth_unix does full blown unix style uid,gid+gids auth, + * _svcauth_short uses a shorthand auth to index into a cache of longhand auths. + * Note: the shorthand has been gutted for efficiency. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include +#include +#include + +/* + * Unix longhand authenticator + */ +enum auth_stat +_svcauth_unix(rqst, msg) + register struct svc_req *rqst; + register struct rpc_msg *msg; +{ + register enum auth_stat stat; + XDR xdrs; + register struct authunix_parms *aup; + register long *buf; + struct area { + struct authunix_parms area_aup; + char area_machname[MAX_MACHINE_NAME+1]; + int area_gids[NGROUPS]; + } *area; + u_int auth_len; + int str_len, gid_len; + register int i; + + area = (struct area *) rqst->rq_clntcred; + aup = &area->area_aup; + aup->aup_machname = area->area_machname; + aup->aup_gids = area->area_gids; + auth_len = (u_int)msg->rm_call.cb_cred.oa_length; + xdrmem_create(&xdrs, msg->rm_call.cb_cred.oa_base, auth_len,XDR_DECODE); + buf = XDR_INLINE(&xdrs, auth_len); + if (buf != NULL) { + aup->aup_time = IXDR_GET_LONG(buf); + str_len = IXDR_GET_U_LONG(buf); + if (str_len > MAX_MACHINE_NAME) { + stat = AUTH_BADCRED; + goto done; + } + bcopy((caddr_t)buf, aup->aup_machname, (u_int)str_len); + aup->aup_machname[str_len] = 0; + str_len = RNDUP(str_len); + buf += str_len / sizeof (long); + aup->aup_uid = IXDR_GET_LONG(buf); + aup->aup_gid = IXDR_GET_LONG(buf); + gid_len = IXDR_GET_U_LONG(buf); + if (gid_len > NGROUPS) { + stat = AUTH_BADCRED; + goto done; + } + aup->aup_len = gid_len; + for (i = 0; i < gid_len; i++) { + aup->aup_gids[i] = IXDR_GET_LONG(buf); + } + /* + * five is the smallest unix credentials structure - + * timestamp, hostname len (0), uid, gid, and gids len (0). + */ + if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len) { + (void) printf("bad auth_len gid %d str %d auth %d\n", + gid_len, str_len, auth_len); + stat = AUTH_BADCRED; + goto done; + } + } else if (! xdr_authunix_parms(&xdrs, aup)) { + xdrs.x_op = XDR_FREE; + (void)xdr_authunix_parms(&xdrs, aup); + stat = AUTH_BADCRED; + goto done; + } + rqst->rq_xprt->xp_verf.oa_flavor = AUTH_NULL; + rqst->rq_xprt->xp_verf.oa_length = 0; + stat = AUTH_OK; +done: + XDR_DESTROY(&xdrs); + return (stat); +} + + +/* + * Shorthand unix authenticator + * Looks up longhand in a cache. + */ +/*ARGSUSED*/ +enum auth_stat +_svcauth_short(rqst, msg) + struct svc_req *rqst; + struct rpc_msg *msg; +{ + return (AUTH_REJECTEDCRED); +} diff --git a/rpc.subproj/svc_raw.c b/rpc.subproj/svc_raw.c new file mode 100644 index 0000000..6729e4d --- /dev/null +++ b/rpc.subproj/svc_raw.c @@ -0,0 +1,191 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)svc_raw.c 1.15 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)svc_raw.c 2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: svc_raw.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $"; +#endif + +/* + * svc_raw.c, This a toy for simple testing and timing. + * Interface to create an rpc client and server in the same UNIX process. + * This lets us similate rpc and get rpc (round trip) overhead, without + * any interference from the kernal. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include + + +/* + * This is the "network" that we will be moving data over + */ +static struct svcraw_private { + char _raw_buf[UDPMSGSIZE]; + SVCXPRT server; + XDR xdr_stream; + char verf_body[MAX_AUTH_BYTES]; +} *svcraw_private; + +static bool_t svcraw_recv(); +static enum xprt_stat svcraw_stat(); +static bool_t svcraw_getargs(); +static bool_t svcraw_reply(); +static bool_t svcraw_freeargs(); +static void svcraw_destroy(); + +static struct xp_ops server_ops = { + svcraw_recv, + svcraw_stat, + svcraw_getargs, + svcraw_reply, + svcraw_freeargs, + svcraw_destroy +}; + +SVCXPRT * +svcraw_create() +{ + register struct svcraw_private *srp = svcraw_private; + + if (srp == 0) { + srp = (struct svcraw_private *)calloc(1, sizeof (*srp)); + if (srp == 0) + return (0); + } + srp->server.xp_sock = 0; + srp->server.xp_port = 0; + srp->server.xp_ops = &server_ops; + srp->server.xp_verf.oa_base = srp->verf_body; + xdrmem_create(&srp->xdr_stream, srp->_raw_buf, UDPMSGSIZE, XDR_FREE); + return (&srp->server); +} + +static enum xprt_stat +svcraw_stat() +{ + + return (XPRT_IDLE); +} + +static bool_t +svcraw_recv(xprt, msg) + SVCXPRT *xprt; + struct rpc_msg *msg; +{ + register struct svcraw_private *srp = svcraw_private; + register XDR *xdrs; + + if (srp == 0) + return (0); + xdrs = &srp->xdr_stream; + xdrs->x_op = XDR_DECODE; + XDR_SETPOS(xdrs, 0); + if (! xdr_callmsg(xdrs, msg)) + return (FALSE); + return (TRUE); +} + +static bool_t +svcraw_reply(xprt, msg) + SVCXPRT *xprt; + struct rpc_msg *msg; +{ + register struct svcraw_private *srp = svcraw_private; + register XDR *xdrs; + + if (srp == 0) + return (FALSE); + xdrs = &srp->xdr_stream; + xdrs->x_op = XDR_ENCODE; + XDR_SETPOS(xdrs, 0); + if (! xdr_replymsg(xdrs, msg)) + return (FALSE); + (void)XDR_GETPOS(xdrs); /* called just for overhead */ + return (TRUE); +} + +static bool_t +svcraw_getargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + register struct svcraw_private *srp = svcraw_private; + + if (srp == 0) + return (FALSE); + return ((*xdr_args)(&srp->xdr_stream, args_ptr)); +} + +static bool_t +svcraw_freeargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + register struct svcraw_private *srp = svcraw_private; + register XDR *xdrs; + + if (srp == 0) + return (FALSE); + xdrs = &srp->xdr_stream; + xdrs->x_op = XDR_FREE; + return ((*xdr_args)(xdrs, args_ptr)); +} + +static void +svcraw_destroy() +{ +} diff --git a/rpc.subproj/svc_run.c b/rpc.subproj/svc_run.c new file mode 100644 index 0000000..47b467a --- /dev/null +++ b/rpc.subproj/svc_run.c @@ -0,0 +1,90 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)svc_run.c 2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: svc_run.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $"; +#endif + +/* + * This is the rpc server side idle loop + * Wait for input, call server program. + */ +#include +#include + +extern int svc_maxfd; + +void +svc_run() +{ + fd_set readfds; + extern int errno; + + for (;;) { + readfds = svc_fdset; + switch (select(svc_maxfd+1, &readfds, (int *)0, (int *)0, + (struct timeval *)0)) { + case -1: + if (errno == EINTR) { + continue; + } + perror("svc_run: - select failed"); + return; + case 0: + continue; + default: + svc_getreqset(&readfds); + } + } +} diff --git a/rpc.subproj/svc_simple.c b/rpc.subproj/svc_simple.c new file mode 100644 index 0000000..6174d04 --- /dev/null +++ b/rpc.subproj/svc_simple.c @@ -0,0 +1,168 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)svc_simple.c 1.18 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)svc_simple.c 2.2 88/08/01 4.0 RPCSRC";*/ +static char *rcsid = "$Id: svc_simple.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $"; +#endif + +/* + * svc_simple.c + * Simplified front end to rpc. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include +#include +#include +#include + +static struct proglst { + char *(*p_progname)(); + int p_prognum; + int p_procnum; + xdrproc_t p_inproc, p_outproc; + struct proglst *p_nxt; +} *proglst; +static void universal(); +static SVCXPRT *transp; +struct proglst *pl; + +registerrpc(prognum, versnum, procnum, progname, inproc, outproc) + char *(*progname)(); + xdrproc_t inproc, outproc; +{ + + if (procnum == NULLPROC) { + (void) fprintf(stderr, + "can't reassign procedure number %d\n", NULLPROC); + return (-1); + } + if (transp == 0) { + transp = svcudp_create(RPC_ANYSOCK); + if (transp == NULL) { + (void) fprintf(stderr, "couldn't create an rpc server\n"); + return (-1); + } + } + (void) pmap_unset((u_long)prognum, (u_long)versnum); + if (!svc_register(transp, (u_long)prognum, (u_long)versnum, + universal, IPPROTO_UDP)) { + (void) fprintf(stderr, "couldn't register prog %d vers %d\n", + prognum, versnum); + return (-1); + } + pl = (struct proglst *)malloc(sizeof(struct proglst)); + if (pl == NULL) { + (void) fprintf(stderr, "registerrpc: out of memory\n"); + return (-1); + } + pl->p_progname = progname; + pl->p_prognum = prognum; + pl->p_procnum = procnum; + pl->p_inproc = inproc; + pl->p_outproc = outproc; + pl->p_nxt = proglst; + proglst = pl; + return (0); +} + +static void +universal(rqstp, transp) + struct svc_req *rqstp; + SVCXPRT *transp; +{ + int prog, proc; + char *outdata; + char xdrbuf[UDPMSGSIZE]; + struct proglst *pl; + + /* + * enforce "procnum 0 is echo" convention + */ + if (rqstp->rq_proc == NULLPROC) { + if (svc_sendreply(transp, xdr_void, (char *)NULL) == FALSE) { + (void) fprintf(stderr, "xxx\n"); + exit(1); + } + return; + } + prog = rqstp->rq_prog; + proc = rqstp->rq_proc; + for (pl = proglst; pl != NULL; pl = pl->p_nxt) + if (pl->p_prognum == prog && pl->p_procnum == proc) { + /* decode arguments into a CLEAN buffer */ + bzero(xdrbuf, sizeof(xdrbuf)); /* required ! */ + if (!svc_getargs(transp, pl->p_inproc, xdrbuf)) { + svcerr_decode(transp); + return; + } + outdata = (*(pl->p_progname))(xdrbuf); + if (outdata == NULL && pl->p_outproc != xdr_void) + /* there was an error */ + return; + if (!svc_sendreply(transp, pl->p_outproc, outdata)) { + (void) fprintf(stderr, + "trouble replying to prog %d\n", + pl->p_prognum); + exit(1); + } + /* free the decoded arguments */ + (void)svc_freeargs(transp, pl->p_inproc, xdrbuf); + return; + } + (void) fprintf(stderr, "never registered prog %d\n", prog); + exit(1); +} + diff --git a/rpc.subproj/svc_tcp.c b/rpc.subproj/svc_tcp.c new file mode 100644 index 0000000..8828b63 --- /dev/null +++ b/rpc.subproj/svc_tcp.c @@ -0,0 +1,435 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC";*/ +static char *rcsid = "$Id: svc_tcp.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $"; +#endif + +/* + * svc_tcp.c, Server side for TCP/IP based RPC. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * Actually implements two flavors of transporter - + * a tcp rendezvouser (a listner and connection establisher) + * and a record/tcp stream. + */ + +#include +#include +#include +#include +extern bool_t abort(); +extern errno; + +/* + * Ops vector for TCP/IP based rpc service handle + */ +static bool_t svctcp_recv(); +static enum xprt_stat svctcp_stat(); +static bool_t svctcp_getargs(); +static bool_t svctcp_reply(); +static bool_t svctcp_freeargs(); +static void svctcp_destroy(); + +static struct xp_ops svctcp_op = { + svctcp_recv, + svctcp_stat, + svctcp_getargs, + svctcp_reply, + svctcp_freeargs, + svctcp_destroy +}; + +/* + * Ops vector for TCP/IP rendezvous handler + */ +static bool_t rendezvous_request(); +static enum xprt_stat rendezvous_stat(); + +static struct xp_ops svctcp_rendezvous_op = { + rendezvous_request, + rendezvous_stat, + abort, + abort, + abort, + svctcp_destroy +}; + +static int readtcp(), writetcp(); +static SVCXPRT *makefd_xprt(); + +struct tcp_rendezvous { /* kept in xprt->xp_p1 */ + u_int sendsize; + u_int recvsize; +}; + +struct tcp_conn { /* kept in xprt->xp_p1 */ + enum xprt_stat strm_stat; + u_long x_id; + XDR xdrs; + char verf_body[MAX_AUTH_BYTES]; +}; + +/* + * Usage: + * xprt = svctcp_create(sock, send_buf_size, recv_buf_size); + * + * Creates, registers, and returns a (rpc) tcp based transporter. + * Once *xprt is initialized, it is registered as a transporter + * see (svc.h, xprt_register). This routine returns + * a NULL if a problem occurred. + * + * If sock<0 then a socket is created, else sock is used. + * If the socket, sock is not bound to a port then svctcp_create + * binds it to an arbitrary port. The routine then starts a tcp + * listener on the socket's associated port. In any (successful) case, + * xprt->xp_sock is the registered socket number and xprt->xp_port is the + * associated port number. + * + * Since tcp streams do buffered io similar to stdio, the caller can specify + * how big the send and receive buffers are via the second and third parms; + * 0 => use the system default. + */ +SVCXPRT * +svctcp_create(sock, sendsize, recvsize) + register int sock; + u_int sendsize; + u_int recvsize; +{ + bool_t madesock = FALSE; + register SVCXPRT *xprt; + register struct tcp_rendezvous *r; + struct sockaddr_in addr; + int len = sizeof(struct sockaddr_in); + + if (sock == RPC_ANYSOCK) { + if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + perror("svctcp_.c - udp socket creation problem"); + return ((SVCXPRT *)NULL); + } + madesock = TRUE; + } + bzero((char *)&addr, sizeof (addr)); + addr.sin_family = AF_INET; + if (bindresvport(sock, &addr)) { + addr.sin_port = 0; + (void)bind(sock, (struct sockaddr *)&addr, len); + } + if ((getsockname(sock, (struct sockaddr *)&addr, &len) != 0) || + (listen(sock, 2) != 0)) { + perror("svctcp_.c - cannot getsockname or listen"); + if (madesock) + (void)close(sock); + return ((SVCXPRT *)NULL); + } + r = (struct tcp_rendezvous *)mem_alloc(sizeof(*r)); + if (r == NULL) { + (void) fprintf(stderr, "svctcp_create: out of memory\n"); + return (NULL); + } + r->sendsize = sendsize; + r->recvsize = recvsize; + xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); + if (xprt == NULL) { + (void) fprintf(stderr, "svctcp_create: out of memory\n"); + return (NULL); + } + xprt->xp_p2 = NULL; + xprt->xp_p1 = (caddr_t)r; + xprt->xp_verf = _null_auth; + xprt->xp_ops = &svctcp_rendezvous_op; + xprt->xp_port = ntohs(addr.sin_port); + xprt->xp_sock = sock; + xprt_register(xprt); + return (xprt); +} + +/* + * Like svtcp_create(), except the routine takes any *open* UNIX file + * descriptor as its first input. + */ +SVCXPRT * +svcfd_create(fd, sendsize, recvsize) + int fd; + u_int sendsize; + u_int recvsize; +{ + + return (makefd_xprt(fd, sendsize, recvsize)); +} + +static SVCXPRT * +makefd_xprt(fd, sendsize, recvsize) + int fd; + u_int sendsize; + u_int recvsize; +{ + register SVCXPRT *xprt; + register struct tcp_conn *cd; + + xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); + if (xprt == (SVCXPRT *)NULL) { + (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n"); + goto done; + } + cd = (struct tcp_conn *)mem_alloc(sizeof(struct tcp_conn)); + if (cd == (struct tcp_conn *)NULL) { + (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n"); + mem_free((char *) xprt, sizeof(SVCXPRT)); + xprt = (SVCXPRT *)NULL; + goto done; + } + cd->strm_stat = XPRT_IDLE; + xdrrec_create(&(cd->xdrs), sendsize, recvsize, + (caddr_t)xprt, readtcp, writetcp); + xprt->xp_p2 = NULL; + xprt->xp_p1 = (caddr_t)cd; + xprt->xp_verf.oa_base = cd->verf_body; + xprt->xp_addrlen = 0; + xprt->xp_ops = &svctcp_op; /* truely deals with calls */ + xprt->xp_port = 0; /* this is a connection, not a rendezvouser */ + xprt->xp_sock = fd; + xprt_register(xprt); + done: + return (xprt); +} + +static bool_t +rendezvous_request(xprt) + register SVCXPRT *xprt; +{ + int sock; + struct tcp_rendezvous *r; + struct sockaddr_in addr; + int len; + + r = (struct tcp_rendezvous *)xprt->xp_p1; + again: + len = sizeof(struct sockaddr_in); + if ((sock = accept(xprt->xp_sock, (struct sockaddr *)&addr, + &len)) < 0) { + if (errno == EINTR) + goto again; + return (FALSE); + } + /* + * make a new transporter (re-uses xprt) + */ + xprt = makefd_xprt(sock, r->sendsize, r->recvsize); + xprt->xp_raddr = addr; + xprt->xp_addrlen = len; + return (FALSE); /* there is never an rpc msg to be processed */ +} + +static enum xprt_stat +rendezvous_stat() +{ + + return (XPRT_IDLE); +} + +static void +svctcp_destroy(xprt) + register SVCXPRT *xprt; +{ + register struct tcp_conn *cd = (struct tcp_conn *)xprt->xp_p1; + + xprt_unregister(xprt); + (void)close(xprt->xp_sock); + if (xprt->xp_port != 0) { + /* a rendezvouser socket */ + xprt->xp_port = 0; + } else { + /* an actual connection socket */ + XDR_DESTROY(&(cd->xdrs)); + } + mem_free((caddr_t)cd, sizeof(struct tcp_conn)); + mem_free((caddr_t)xprt, sizeof(SVCXPRT)); +} + +/* + * All read operations timeout after 35 seconds. + * A timeout is fatal for the connection. + */ +static struct timeval wait_per_try = { 35, 0 }; + +/* + * reads data from the tcp conection. + * any error is fatal and the connection is closed. + * (And a read of zero bytes is a half closed stream => error.) + */ +static int +readtcp(xprt, buf, len) + register SVCXPRT *xprt; + caddr_t buf; + register int len; +{ + register int sock = xprt->xp_sock; + fd_set mask; + fd_set readfds; + + FD_ZERO(&mask); + FD_SET(sock, &mask); + do { + readfds = mask; + if (select(sock+1, &readfds, (int*)NULL, (int*)NULL, + &wait_per_try) <= 0) { + if (errno == EINTR) { + continue; + } + goto fatal_err; + } + } while (!FD_ISSET(sock, &readfds)); + if ((len = read(sock, buf, len)) > 0) { + return (len); + } +fatal_err: + ((struct tcp_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED; + return (-1); +} + +/* + * writes data to the tcp connection. + * Any error is fatal and the connection is closed. + */ +static int +writetcp(xprt, buf, len) + register SVCXPRT *xprt; + caddr_t buf; + int len; +{ + register int i, cnt; + + for (cnt = len; cnt > 0; cnt -= i, buf += i) { + if ((i = write(xprt->xp_sock, buf, cnt)) < 0) { + ((struct tcp_conn *)(xprt->xp_p1))->strm_stat = + XPRT_DIED; + return (-1); + } + } + return (len); +} + +static enum xprt_stat +svctcp_stat(xprt) + SVCXPRT *xprt; +{ + register struct tcp_conn *cd = + (struct tcp_conn *)(xprt->xp_p1); + + if (cd->strm_stat == XPRT_DIED) + return (XPRT_DIED); + if (! xdrrec_eof(&(cd->xdrs))) + return (XPRT_MOREREQS); + return (XPRT_IDLE); +} + +static bool_t +svctcp_recv(xprt, msg) + SVCXPRT *xprt; + register struct rpc_msg *msg; +{ + register struct tcp_conn *cd = + (struct tcp_conn *)(xprt->xp_p1); + register XDR *xdrs = &(cd->xdrs); + + xdrs->x_op = XDR_DECODE; + (void)xdrrec_skiprecord(xdrs); + if (xdr_callmsg(xdrs, msg)) { + cd->x_id = msg->rm_xid; + return (TRUE); + } + return (FALSE); +} + +static bool_t +svctcp_getargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + + return ((*xdr_args)(&(((struct tcp_conn *)(xprt->xp_p1))->xdrs), args_ptr)); +} + +static bool_t +svctcp_freeargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + register XDR *xdrs = + &(((struct tcp_conn *)(xprt->xp_p1))->xdrs); + + xdrs->x_op = XDR_FREE; + return ((*xdr_args)(xdrs, args_ptr)); +} + +static bool_t +svctcp_reply(xprt, msg) + SVCXPRT *xprt; + register struct rpc_msg *msg; +{ + register struct tcp_conn *cd = + (struct tcp_conn *)(xprt->xp_p1); + register XDR *xdrs = &(cd->xdrs); + register bool_t stat; + + xdrs->x_op = XDR_ENCODE; + msg->rm_xid = cd->x_id; + stat = xdr_replymsg(xdrs, msg); + (void)xdrrec_endofrecord(xdrs, TRUE); + return (stat); +} diff --git a/rpc.subproj/svc_udp.c b/rpc.subproj/svc_udp.c new file mode 100644 index 0000000..5af3045 --- /dev/null +++ b/rpc.subproj/svc_udp.c @@ -0,0 +1,503 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)svc_udp.c 1.24 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)svc_udp.c 2.2 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: svc_udp.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $"; +#endif + +/* + * svc_udp.c, + * Server side for UDP/IP based RPC. (Does some caching in the hopes of + * achieving execute-at-most-once semantics.) + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include +#include +#include +#include +#include + + +#define rpc_buffer(xprt) ((xprt)->xp_p1) +#define MAX(a, b) ((a > b) ? a : b) + +static bool_t svcudp_recv(); +static bool_t svcudp_reply(); +static enum xprt_stat svcudp_stat(); +static bool_t svcudp_getargs(); +static bool_t svcudp_freeargs(); +static void svcudp_destroy(); + +static struct xp_ops svcudp_op = { + svcudp_recv, + svcudp_stat, + svcudp_getargs, + svcudp_reply, + svcudp_freeargs, + svcudp_destroy +}; + +extern int errno; + +/* + * kept in xprt->xp_p2 + */ +struct svcudp_data { + u_int su_iosz; /* byte size of send.recv buffer */ + u_long su_xid; /* transaction id */ + XDR su_xdrs; /* XDR handle */ + char su_verfbody[MAX_AUTH_BYTES]; /* verifier body */ + char * su_cache; /* cached data, NULL if no cache */ +}; +#define su_data(xprt) ((struct svcudp_data *)(xprt->xp_p2)) + +/* + * Usage: + * xprt = svcudp_create(sock); + * + * If sock<0 then a socket is created, else sock is used. + * If the socket, sock is not bound to a port then svcudp_create + * binds it to an arbitrary port. In any (successful) case, + * xprt->xp_sock is the registered socket number and xprt->xp_port is the + * associated port number. + * Once *xprt is initialized, it is registered as a transporter; + * see (svc.h, xprt_register). + * The routines returns NULL if a problem occurred. + */ +SVCXPRT * +svcudp_bufcreate(sock, sendsz, recvsz) + register int sock; + u_int sendsz, recvsz; +{ + bool_t madesock = FALSE; + register SVCXPRT *xprt; + register struct svcudp_data *su; + struct sockaddr_in addr; + int len = sizeof(struct sockaddr_in); + + if (sock == RPC_ANYSOCK) { + if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + perror("svcudp_create: socket creation problem"); + return ((SVCXPRT *)NULL); + } + madesock = TRUE; + } + bzero((char *)&addr, sizeof (addr)); + addr.sin_family = AF_INET; + if (bindresvport(sock, &addr)) { + addr.sin_port = 0; + (void)bind(sock, (struct sockaddr *)&addr, len); + } + if (getsockname(sock, (struct sockaddr *)&addr, &len) != 0) { + perror("svcudp_create - cannot getsockname"); + if (madesock) + (void)close(sock); + return ((SVCXPRT *)NULL); + } + xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); + if (xprt == NULL) { + (void)fprintf(stderr, "svcudp_create: out of memory\n"); + return (NULL); + } + su = (struct svcudp_data *)mem_alloc(sizeof(*su)); + if (su == NULL) { + (void)fprintf(stderr, "svcudp_create: out of memory\n"); + return (NULL); + } + su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4; + if ((rpc_buffer(xprt) = mem_alloc(su->su_iosz)) == NULL) { + (void)fprintf(stderr, "svcudp_create: out of memory\n"); + return (NULL); + } + xdrmem_create( + &(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE); + su->su_cache = NULL; + xprt->xp_p2 = (caddr_t)su; + xprt->xp_verf.oa_base = su->su_verfbody; + xprt->xp_ops = &svcudp_op; + xprt->xp_port = ntohs(addr.sin_port); + xprt->xp_sock = sock; + xprt_register(xprt); + return (xprt); +} + +SVCXPRT * +svcudp_create(sock) + int sock; +{ + + return(svcudp_bufcreate(sock, UDPMSGSIZE, UDPMSGSIZE)); +} + +static enum xprt_stat +svcudp_stat(xprt) + SVCXPRT *xprt; +{ + + return (XPRT_IDLE); +} + +static bool_t +svcudp_recv(xprt, msg) + register SVCXPRT *xprt; + struct rpc_msg *msg; +{ + register struct svcudp_data *su = su_data(xprt); + register XDR *xdrs = &(su->su_xdrs); + register int rlen; + char *reply; + u_long replylen; + static int cache_get(); + + again: + xprt->xp_addrlen = sizeof(struct sockaddr_in); + rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), (int) su->su_iosz, + 0, (struct sockaddr *)&(xprt->xp_raddr), &(xprt->xp_addrlen)); + if (rlen == -1 && errno == EINTR) + goto again; + if (rlen < 4*sizeof(u_long)) + return (FALSE); + xdrs->x_op = XDR_DECODE; + XDR_SETPOS(xdrs, 0); + if (! xdr_callmsg(xdrs, msg)) + return (FALSE); + su->su_xid = msg->rm_xid; + if (su->su_cache != NULL) { + if (cache_get(xprt, msg, &reply, &replylen)) { + (void) sendto(xprt->xp_sock, reply, (int) replylen, 0, + (struct sockaddr *) &xprt->xp_raddr, xprt->xp_addrlen); + return (TRUE); + } + } + return (TRUE); +} + +static bool_t +svcudp_reply(xprt, msg) + register SVCXPRT *xprt; + struct rpc_msg *msg; +{ + register struct svcudp_data *su = su_data(xprt); + register XDR *xdrs = &(su->su_xdrs); + register int slen; + register bool_t stat = FALSE; + static void cache_set(); + + xdrs->x_op = XDR_ENCODE; + XDR_SETPOS(xdrs, 0); + msg->rm_xid = su->su_xid; + if (xdr_replymsg(xdrs, msg)) { + slen = (int)XDR_GETPOS(xdrs); + if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0, + (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen) + == slen) { + stat = TRUE; + if (su->su_cache && slen >= 0) { + cache_set(xprt, (u_long) slen); + } + } + } + return (stat); +} + +static bool_t +svcudp_getargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + + return ((*xdr_args)(&(su_data(xprt)->su_xdrs), args_ptr)); +} + +static bool_t +svcudp_freeargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + register XDR *xdrs = &(su_data(xprt)->su_xdrs); + + xdrs->x_op = XDR_FREE; + return ((*xdr_args)(xdrs, args_ptr)); +} + +static void +svcudp_destroy(xprt) + register SVCXPRT *xprt; +{ + register struct svcudp_data *su = su_data(xprt); + + xprt_unregister(xprt); + (void)close(xprt->xp_sock); + XDR_DESTROY(&(su->su_xdrs)); + mem_free(rpc_buffer(xprt), su->su_iosz); + mem_free((caddr_t)su, sizeof(struct svcudp_data)); + mem_free((caddr_t)xprt, sizeof(SVCXPRT)); +} + + +/***********this could be a separate file*********************/ + +/* + * Fifo cache for udp server + * Copies pointers to reply buffers into fifo cache + * Buffers are sent again if retransmissions are detected. + */ + +#define SPARSENESS 4 /* 75% sparse */ + +#define CACHE_PERROR(msg) \ + (void) fprintf(stderr,"%s\n", msg) + +#define ALLOC(type, size) \ + (type *) mem_alloc((unsigned) (sizeof(type) * (size))) + +#define BZERO(addr, type, size) \ + bzero((char *) addr, sizeof(type) * (int) (size)) + +/* + * An entry in the cache + */ +typedef struct cache_node *cache_ptr; +struct cache_node { + /* + * Index into cache is xid, proc, vers, prog and address + */ + u_long cache_xid; + u_long cache_proc; + u_long cache_vers; + u_long cache_prog; + struct sockaddr_in cache_addr; + /* + * The cached reply and length + */ + char * cache_reply; + u_long cache_replylen; + /* + * Next node on the list, if there is a collision + */ + cache_ptr cache_next; +}; + + + +/* + * The entire cache + */ +struct udp_cache { + u_long uc_size; /* size of cache */ + cache_ptr *uc_entries; /* hash table of entries in cache */ + cache_ptr *uc_fifo; /* fifo list of entries in cache */ + u_long uc_nextvictim; /* points to next victim in fifo list */ + u_long uc_prog; /* saved program number */ + u_long uc_vers; /* saved version number */ + u_long uc_proc; /* saved procedure number */ + struct sockaddr_in uc_addr; /* saved caller's address */ +}; + + +/* + * the hashing function + */ +#define CACHE_LOC(transp, xid) \ + (xid % (SPARSENESS*((struct udp_cache *) su_data(transp)->su_cache)->uc_size)) + + +/* + * Enable use of the cache. + * Note: there is no disable. + */ +svcudp_enablecache(transp, size) + SVCXPRT *transp; + u_long size; +{ + struct svcudp_data *su = su_data(transp); + struct udp_cache *uc; + + if (su->su_cache != NULL) { + CACHE_PERROR("enablecache: cache already enabled"); + return(0); + } + uc = ALLOC(struct udp_cache, 1); + if (uc == NULL) { + CACHE_PERROR("enablecache: could not allocate cache"); + return(0); + } + uc->uc_size = size; + uc->uc_nextvictim = 0; + uc->uc_entries = ALLOC(cache_ptr, size * SPARSENESS); + if (uc->uc_entries == NULL) { + CACHE_PERROR("enablecache: could not allocate cache data"); + return(0); + } + BZERO(uc->uc_entries, cache_ptr, size * SPARSENESS); + uc->uc_fifo = ALLOC(cache_ptr, size); + if (uc->uc_fifo == NULL) { + CACHE_PERROR("enablecache: could not allocate cache fifo"); + return(0); + } + BZERO(uc->uc_fifo, cache_ptr, size); + su->su_cache = (char *) uc; + return(1); +} + + +/* + * Set an entry in the cache + */ +static void +cache_set(xprt, replylen) + SVCXPRT *xprt; + u_long replylen; +{ + register cache_ptr victim; + register cache_ptr *vicp; + register struct svcudp_data *su = su_data(xprt); + struct udp_cache *uc = (struct udp_cache *) su->su_cache; + u_int loc; + char *newbuf; + + /* + * Find space for the new entry, either by + * reusing an old entry, or by mallocing a new one + */ + victim = uc->uc_fifo[uc->uc_nextvictim]; + if (victim != NULL) { + loc = CACHE_LOC(xprt, victim->cache_xid); + for (vicp = &uc->uc_entries[loc]; + *vicp != NULL && *vicp != victim; + vicp = &(*vicp)->cache_next) + ; + if (*vicp == NULL) { + CACHE_PERROR("cache_set: victim not found"); + return; + } + *vicp = victim->cache_next; /* remote from cache */ + newbuf = victim->cache_reply; + } else { + victim = ALLOC(struct cache_node, 1); + if (victim == NULL) { + CACHE_PERROR("cache_set: victim alloc failed"); + return; + } + newbuf = mem_alloc(su->su_iosz); + if (newbuf == NULL) { + CACHE_PERROR("cache_set: could not allocate new rpc_buffer"); + return; + } + } + + /* + * Store it away + */ + victim->cache_replylen = replylen; + victim->cache_reply = rpc_buffer(xprt); + rpc_buffer(xprt) = newbuf; + xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_ENCODE); + victim->cache_xid = su->su_xid; + victim->cache_proc = uc->uc_proc; + victim->cache_vers = uc->uc_vers; + victim->cache_prog = uc->uc_prog; + victim->cache_addr = uc->uc_addr; + loc = CACHE_LOC(xprt, victim->cache_xid); + victim->cache_next = uc->uc_entries[loc]; + uc->uc_entries[loc] = victim; + uc->uc_fifo[uc->uc_nextvictim++] = victim; + uc->uc_nextvictim %= uc->uc_size; +} + +/* + * Try to get an entry from the cache + * return 1 if found, 0 if not found + */ +static +cache_get(xprt, msg, replyp, replylenp) + SVCXPRT *xprt; + struct rpc_msg *msg; + char **replyp; + u_long *replylenp; +{ + u_int loc; + register cache_ptr ent; + register struct svcudp_data *su = su_data(xprt); + register struct udp_cache *uc = (struct udp_cache *) su->su_cache; + +# define EQADDR(a1, a2) (bcmp((char*)&a1, (char*)&a2, sizeof(a1)) == 0) + + loc = CACHE_LOC(xprt, su->su_xid); + for (ent = uc->uc_entries[loc]; ent != NULL; ent = ent->cache_next) { + if (ent->cache_xid == su->su_xid && + ent->cache_proc == uc->uc_proc && + ent->cache_vers == uc->uc_vers && + ent->cache_prog == uc->uc_prog && + EQADDR(ent->cache_addr, uc->uc_addr)) { + *replyp = ent->cache_reply; + *replylenp = ent->cache_replylen; + return(1); + } + } + /* + * Failed to find entry + * Remember a few things so we can do a set later + */ + uc->uc_proc = msg->rm_call.cb_proc; + uc->uc_vers = msg->rm_call.cb_vers; + uc->uc_prog = msg->rm_call.cb_prog; + uc->uc_addr = xprt->xp_raddr; + return(0); +} + diff --git a/rpc.subproj/types.h b/rpc.subproj/types.h new file mode 100644 index 0000000..b9cd3cf --- /dev/null +++ b/rpc.subproj/types.h @@ -0,0 +1,85 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)types.h 1.18 87/07/24 SMI + * from: @(#)types.h 2.3 88/08/15 4.0 RPCSRC + * $Id: types.h,v 1.2 1999/10/14 21:56:54 wsanchez Exp $ + */ + +/* + * Rpc additions to + */ +#ifndef _RPC_TYPES_H +#define _RPC_TYPES_H + +#define bool_t int +#define enum_t int +#define __dontcare__ -1 + +#ifndef FALSE +# define FALSE (0) +#endif +#ifndef TRUE +# define TRUE (1) +#endif +#ifndef NULL +# define NULL 0 +#endif + +#define mem_alloc(bsize) malloc(bsize) +#define mem_free(ptr, bsize) free(ptr) + +#ifndef makedev /* ie, we haven't already included it */ +#include +#endif +#include + +#endif /* !_RPC_TYPES_H */ diff --git a/rpc.subproj/xdr.c b/rpc.subproj/xdr.c new file mode 100644 index 0000000..b523fee --- /dev/null +++ b/rpc.subproj/xdr.c @@ -0,0 +1,605 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)xdr.c 1.35 87/08/12";*/ +/*static char *sccsid = "from: @(#)xdr.c 2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: xdr.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $"; +#endif + +/* + * xdr.c, Generic XDR routines implementation. + * + * Copyright (C) 1986, Sun Microsystems, Inc. + * + * These are the "generic" xdr routines used to serialize and de-serialize + * most common data items. See xdr.h for more info on the interface to + * xdr. + */ + +#include + +#include +#include + +/* + * constants specific to the xdr "protocol" + */ +#define XDR_FALSE ((long) 0) +#define XDR_TRUE ((long) 1) +#define LASTUNSIGNED ((u_int) 0-1) + +/* + * for unit alignment + */ +static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 }; + +/* + * Free a data structure using XDR + * Not a filter, but a convenient utility nonetheless + */ +void +xdr_free(proc, objp) + xdrproc_t proc; +#if defined(__APPLE__) + void *objp; +#else + char *objp; +#endif /* !NeXT */ +{ + XDR x; + + x.x_op = XDR_FREE; + (*proc)(&x, objp); +} + +/* + * XDR nothing + */ +bool_t +xdr_void(/* xdrs, addr */) + /* XDR *xdrs; */ + /* caddr_t addr; */ +{ + + return (TRUE); +} + +/* + * XDR integers + */ +bool_t +xdr_int(xdrs, ip) + XDR *xdrs; + int *ip; +{ + +#ifdef lint + (void) (xdr_short(xdrs, (short *)ip)); + return (xdr_long(xdrs, (long *)ip)); +#else + if (sizeof (int) == sizeof (long)) { + return (xdr_long(xdrs, (long *)ip)); + } else { + return (xdr_short(xdrs, (short *)ip)); + } +#endif +} + +/* + * XDR unsigned integers + */ +bool_t +xdr_u_int(xdrs, up) + XDR *xdrs; + u_int *up; +{ + +#ifdef lint + (void) (xdr_short(xdrs, (short *)up)); + return (xdr_u_long(xdrs, (u_long *)up)); +#else + if (sizeof (u_int) == sizeof (u_long)) { + return (xdr_u_long(xdrs, (u_long *)up)); + } else { + return (xdr_short(xdrs, (short *)up)); + } +#endif +} + +/* + * XDR long integers + * same as xdr_u_long - open coded to save a proc call! + */ +bool_t +xdr_long(xdrs, lp) + register XDR *xdrs; + long *lp; +{ + + if (xdrs->x_op == XDR_ENCODE) + return (XDR_PUTLONG(xdrs, lp)); + + if (xdrs->x_op == XDR_DECODE) + return (XDR_GETLONG(xdrs, lp)); + + if (xdrs->x_op == XDR_FREE) + return (TRUE); + + return (FALSE); +} + +/* + * XDR unsigned long integers + * same as xdr_long - open coded to save a proc call! + */ +bool_t +xdr_u_long(xdrs, ulp) + register XDR *xdrs; + u_long *ulp; +{ + + if (xdrs->x_op == XDR_DECODE) + return (XDR_GETLONG(xdrs, (long *)ulp)); + if (xdrs->x_op == XDR_ENCODE) + return (XDR_PUTLONG(xdrs, (long *)ulp)); + if (xdrs->x_op == XDR_FREE) + return (TRUE); + return (FALSE); +} + +/* + * XDR short integers + */ +bool_t +xdr_short(xdrs, sp) + register XDR *xdrs; + short *sp; +{ + long l; + + switch (xdrs->x_op) { + + case XDR_ENCODE: + l = (long) *sp; + return (XDR_PUTLONG(xdrs, &l)); + + case XDR_DECODE: + if (!XDR_GETLONG(xdrs, &l)) { + return (FALSE); + } + *sp = (short) l; + return (TRUE); + + case XDR_FREE: + return (TRUE); + } + return (FALSE); +} + +/* + * XDR unsigned short integers + */ +bool_t +xdr_u_short(xdrs, usp) + register XDR *xdrs; + u_short *usp; +{ + u_long l; + + switch (xdrs->x_op) { + + case XDR_ENCODE: + l = (u_long) *usp; + return (XDR_PUTLONG(xdrs, &l)); + + case XDR_DECODE: + if (!XDR_GETLONG(xdrs, &l)) { + return (FALSE); + } + *usp = (u_short) l; + return (TRUE); + + case XDR_FREE: + return (TRUE); + } + return (FALSE); +} + + +/* + * XDR a char + */ +bool_t +xdr_char(xdrs, cp) + XDR *xdrs; + char *cp; +{ + int i; + + i = (*cp); + if (!xdr_int(xdrs, &i)) { + return (FALSE); + } + *cp = i; + return (TRUE); +} + +/* + * XDR an unsigned char + */ +bool_t +xdr_u_char(xdrs, cp) + XDR *xdrs; + u_char *cp; +{ + u_int u; + + u = (*cp); + if (!xdr_u_int(xdrs, &u)) { + return (FALSE); + } + *cp = u; + return (TRUE); +} + +/* + * XDR booleans + */ +bool_t +xdr_bool(xdrs, bp) + register XDR *xdrs; + bool_t *bp; +{ + long lb; + + switch (xdrs->x_op) { + + case XDR_ENCODE: + lb = *bp ? XDR_TRUE : XDR_FALSE; + return (XDR_PUTLONG(xdrs, &lb)); + + case XDR_DECODE: + if (!XDR_GETLONG(xdrs, &lb)) { + return (FALSE); + } + *bp = (lb == XDR_FALSE) ? FALSE : TRUE; + return (TRUE); + + case XDR_FREE: + return (TRUE); + } + return (FALSE); +} + +/* + * XDR enumerations + */ +bool_t +xdr_enum(xdrs, ep) + XDR *xdrs; + enum_t *ep; +{ +#ifndef lint + enum sizecheck { SIZEVAL }; /* used to find the size of an enum */ + + /* + * enums are treated as ints + */ + if (sizeof (enum sizecheck) == sizeof (long)) { + return (xdr_long(xdrs, (long *)ep)); + } else if (sizeof (enum sizecheck) == sizeof (short)) { + return (xdr_short(xdrs, (short *)ep)); + } else { + return (FALSE); + } +#else + (void) (xdr_short(xdrs, (short *)ep)); + return (xdr_long(xdrs, (long *)ep)); +#endif +} + +/* + * XDR opaque data + * Allows the specification of a fixed size sequence of opaque bytes. + * cp points to the opaque object and cnt gives the byte length. + */ +bool_t +xdr_opaque(xdrs, cp, cnt) + register XDR *xdrs; + caddr_t cp; + register u_int cnt; +{ + register u_int rndup; + static crud[BYTES_PER_XDR_UNIT]; + + /* + * if no data we are done + */ + if (cnt == 0) + return (TRUE); + + /* + * round byte count to full xdr units + */ + rndup = cnt % BYTES_PER_XDR_UNIT; + if (rndup > 0) + rndup = BYTES_PER_XDR_UNIT - rndup; + + if (xdrs->x_op == XDR_DECODE) { + if (!XDR_GETBYTES(xdrs, cp, cnt)) { + return (FALSE); + } + if (rndup == 0) + return (TRUE); + return (XDR_GETBYTES(xdrs, crud, rndup)); + } + + if (xdrs->x_op == XDR_ENCODE) { + if (!XDR_PUTBYTES(xdrs, cp, cnt)) { + return (FALSE); + } + if (rndup == 0) + return (TRUE); + return (XDR_PUTBYTES(xdrs, xdr_zero, rndup)); + } + + if (xdrs->x_op == XDR_FREE) { + return (TRUE); + } + + return (FALSE); +} + +/* + * XDR counted bytes + * *cpp is a pointer to the bytes, *sizep is the count. + * If *cpp is NULL maxsize bytes are allocated + */ +bool_t +xdr_bytes(xdrs, cpp, sizep, maxsize) + register XDR *xdrs; + char **cpp; + register u_int *sizep; + u_int maxsize; +{ + register char *sp = *cpp; /* sp is the actual string pointer */ + register u_int nodesize; + + /* + * first deal with the length since xdr bytes are counted + */ + if (! xdr_u_int(xdrs, sizep)) { + return (FALSE); + } + nodesize = *sizep; + if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) { + return (FALSE); + } + + /* + * now deal with the actual bytes + */ + switch (xdrs->x_op) { + + case XDR_DECODE: + if (nodesize == 0) { + return (TRUE); + } + if (sp == NULL) { + *cpp = sp = (char *)mem_alloc(nodesize); + } + if (sp == NULL) { + (void) fprintf(stderr, "xdr_bytes: out of memory\n"); + return (FALSE); + } + /* fall into ... */ + + case XDR_ENCODE: + return (xdr_opaque(xdrs, sp, nodesize)); + + case XDR_FREE: + if (sp != NULL) { + mem_free(sp, nodesize); + *cpp = NULL; + } + return (TRUE); + } + return (FALSE); +} + +/* + * Implemented here due to commonality of the object. + */ +bool_t +xdr_netobj(xdrs, np) + XDR *xdrs; + struct netobj *np; +{ + + return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ)); +} + +/* + * XDR a descriminated union + * Support routine for discriminated unions. + * You create an array of xdrdiscrim structures, terminated with + * an entry with a null procedure pointer. The routine gets + * the discriminant value and then searches the array of xdrdiscrims + * looking for that value. It calls the procedure given in the xdrdiscrim + * to handle the discriminant. If there is no specific routine a default + * routine may be called. + * If there is no specific or default routine an error is returned. + */ +bool_t +xdr_union(xdrs, dscmp, unp, choices, dfault) + register XDR *xdrs; + enum_t *dscmp; /* enum to decide which arm to work on */ + char *unp; /* the union itself */ + struct xdr_discrim *choices; /* [value, xdr proc] for each arm */ + xdrproc_t dfault; /* default xdr routine */ +{ + register enum_t dscm; + + /* + * we deal with the discriminator; it's an enum + */ + if (! xdr_enum(xdrs, dscmp)) { + return (FALSE); + } + dscm = *dscmp; + + /* + * search choices for a value that matches the discriminator. + * if we find one, execute the xdr routine for that value. + */ + for (; choices->proc != NULL_xdrproc_t; choices++) { + if (choices->value == dscm) + return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED)); + } + + /* + * no match - execute the default xdr routine if there is one + */ + return ((dfault == NULL_xdrproc_t) ? FALSE : + (*dfault)(xdrs, unp, LASTUNSIGNED)); +} + + +/* + * Non-portable xdr primitives. + * Care should be taken when moving these routines to new architectures. + */ + + +/* + * XDR null terminated ASCII strings + * xdr_string deals with "C strings" - arrays of bytes that are + * terminated by a NULL character. The parameter cpp references a + * pointer to storage; If the pointer is null, then the necessary + * storage is allocated. The last parameter is the max allowed length + * of the string as specified by a protocol. + */ +bool_t +xdr_string(xdrs, cpp, maxsize) + register XDR *xdrs; + char **cpp; + u_int maxsize; +{ + register char *sp = *cpp; /* sp is the actual string pointer */ + u_int size; + u_int nodesize; + + /* + * first deal with the length since xdr strings are counted-strings + */ + switch (xdrs->x_op) { + case XDR_FREE: + if (sp == NULL) { + return(TRUE); /* already free */ + } + /* fall through... */ + case XDR_ENCODE: + size = strlen(sp); + break; + } + if (! xdr_u_int(xdrs, &size)) { + return (FALSE); + } + if (size > maxsize) { + return (FALSE); + } + nodesize = size + 1; + + /* + * now deal with the actual bytes + */ + switch (xdrs->x_op) { + + case XDR_DECODE: + if (nodesize == 0) { + return (TRUE); + } + if (sp == NULL) + *cpp = sp = (char *)mem_alloc(nodesize); + if (sp == NULL) { + (void) fprintf(stderr, "xdr_string: out of memory\n"); + return (FALSE); + } + sp[size] = 0; + /* fall into ... */ + + case XDR_ENCODE: + return (xdr_opaque(xdrs, sp, size)); + + case XDR_FREE: + mem_free(sp, nodesize); + *cpp = NULL; + return (TRUE); + } + return (FALSE); +} + +/* + * Wrapper for xdr_string that can be called directly from + * routines like clnt_call + */ +bool_t +xdr_wrapstring(xdrs, cpp) + XDR *xdrs; + char **cpp; +{ + if (xdr_string(xdrs, cpp, LASTUNSIGNED)) { + return (TRUE); + } + return (FALSE); +} diff --git a/rpc.subproj/xdr.h b/rpc.subproj/xdr.h new file mode 100644 index 0000000..6289bc8 --- /dev/null +++ b/rpc.subproj/xdr.h @@ -0,0 +1,318 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + * + * from: @(#)xdr.h 1.19 87/04/22 SMI + * from: @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC + * $Id: xdr.h,v 1.2 1999/10/14 21:56:54 wsanchez Exp $ + */ + +/* + * xdr.h, External Data Representation Serialization Routines. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef _RPC_XDR_H +#define _RPC_XDR_H +#include + +/* + * XDR provides a conventional way for converting between C data + * types and an external bit-string representation. Library supplied + * routines provide for the conversion on built-in C data types. These + * routines and utility routines defined here are used to help implement + * a type encode/decode routine for each user-defined type. + * + * Each data type provides a single procedure which takes two arguments: + * + * bool_t + * xdrproc(xdrs, argresp) + * XDR *xdrs; + * *argresp; + * + * xdrs is an instance of a XDR handle, to which or from which the data + * type is to be converted. argresp is a pointer to the structure to be + * converted. The XDR handle contains an operation field which indicates + * which of the operations (ENCODE, DECODE * or FREE) is to be performed. + * + * XDR_DECODE may allocate space if the pointer argresp is null. This + * data can be freed with the XDR_FREE operation. + * + * We write only one procedure per data type to make it easy + * to keep the encode and decode procedures for a data type consistent. + * In many cases the same code performs all operations on a user defined type, + * because all the hard work is done in the component type routines. + * decode as a series of calls on the nested data types. + */ + +/* + * Xdr operations. XDR_ENCODE causes the type to be encoded into the + * stream. XDR_DECODE causes the type to be extracted from the stream. + * XDR_FREE can be used to release the space allocated by an XDR_DECODE + * request. + */ +enum xdr_op { + XDR_ENCODE=0, + XDR_DECODE=1, + XDR_FREE=2 +}; + +/* + * This is the number of bytes per unit of external data. + */ +#define BYTES_PER_XDR_UNIT (4) +#define RNDUP(x) ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \ + * BYTES_PER_XDR_UNIT) + +/* + * A xdrproc_t exists for each data type which is to be encoded or decoded. + * + * The second argument to the xdrproc_t is a pointer to an opaque pointer. + * The opaque pointer generally points to a structure of the data type + * to be decoded. If this pointer is 0, then the type routines should + * allocate dynamic storage of the appropriate size and return it. + * bool_t (*xdrproc_t)(XDR *, caddr_t *); + */ +typedef bool_t (*xdrproc_t)(); + +/* + * The XDR handle. + * Contains operation which is being applied to the stream, + * an operations vector for the paticular implementation (e.g. see xdr_mem.c), + * and two private fields for the use of the particular impelementation. + */ +typedef struct { + enum xdr_op x_op; /* operation; fast additional param */ + struct xdr_ops { + bool_t (*x_getlong)(); /* get a long from underlying stream */ + bool_t (*x_putlong)(); /* put a long to " */ + bool_t (*x_getbytes)();/* get some bytes from " */ + bool_t (*x_putbytes)();/* put some bytes to " */ + u_int (*x_getpostn)();/* returns bytes off from beginning */ + bool_t (*x_setpostn)();/* lets you reposition the stream */ + long * (*x_inline)(); /* buf quick ptr to buffered data */ + void (*x_destroy)(); /* free privates of this xdr_stream */ + } *x_ops; + caddr_t x_public; /* users' data */ + caddr_t x_private; /* pointer to private data */ + caddr_t x_base; /* private used for position info */ + int x_handy; /* extra private word */ +} XDR; + +/* + * Operations defined on a XDR handle + * + * XDR *xdrs; + * long *longp; + * caddr_t addr; + * u_int len; + * u_int pos; + */ +#define XDR_GETLONG(xdrs, longp) \ + (*(xdrs)->x_ops->x_getlong)(xdrs, longp) +#define xdr_getlong(xdrs, longp) \ + (*(xdrs)->x_ops->x_getlong)(xdrs, longp) + +#define XDR_PUTLONG(xdrs, longp) \ + (*(xdrs)->x_ops->x_putlong)(xdrs, longp) +#define xdr_putlong(xdrs, longp) \ + (*(xdrs)->x_ops->x_putlong)(xdrs, longp) + +#define XDR_GETBYTES(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) +#define xdr_getbytes(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) + +#define XDR_PUTBYTES(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) +#define xdr_putbytes(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) + +#define XDR_GETPOS(xdrs) \ + (*(xdrs)->x_ops->x_getpostn)(xdrs) +#define xdr_getpos(xdrs) \ + (*(xdrs)->x_ops->x_getpostn)(xdrs) + +#define XDR_SETPOS(xdrs, pos) \ + (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) +#define xdr_setpos(xdrs, pos) \ + (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) + +#define XDR_INLINE(xdrs, len) \ + (*(xdrs)->x_ops->x_inline)(xdrs, len) +#define xdr_inline(xdrs, len) \ + (*(xdrs)->x_ops->x_inline)(xdrs, len) + +#define XDR_DESTROY(xdrs) \ + if (xdrs) \ + if ((xdrs)->x_ops) \ + if ((xdrs)->x_ops->x_destroy) \ + (*(xdrs)->x_ops->x_destroy)(xdrs) +#define xdr_destroy(xdrs) \ + if (xdrs) \ + if ((xdrs)->x_ops) \ + if ((xdrs)->x_ops->x_destroy) \ + (*(xdrs)->x_ops->x_destroy)(xdrs) + +/* + * Support struct for discriminated unions. + * You create an array of xdrdiscrim structures, terminated with + * a entry with a null procedure pointer. The xdr_union routine gets + * the discriminant value and then searches the array of structures + * for a matching value. If a match is found the associated xdr routine + * is called to handle that part of the union. If there is + * no match, then a default routine may be called. + * If there is no match and no default routine it is an error. + */ +#define NULL_xdrproc_t ((xdrproc_t)0) +struct xdr_discrim { + int value; + xdrproc_t proc; +}; + +/* + * In-line routines for fast encode/decode of primitve data types. + * Caveat emptor: these use single memory cycles to get the + * data from the underlying buffer, and will fail to operate + * properly if the data is not aligned. The standard way to use these + * is to say: + * if ((buf = XDR_INLINE(xdrs, count)) == NULL) + * return (FALSE); + * <<< macro calls >>> + * where ``count'' is the number of bytes of data occupied + * by the primitive data types. + * + * N.B. and frozen for all time: each data type here uses 4 bytes + * of external representation. + */ +#define IXDR_GET_LONG(buf) ((long)ntohl((u_long)*(buf)++)) +#define IXDR_PUT_LONG(buf, v) (*(buf)++ = (long)htonl((u_long)v)) + +#define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf)) +#define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf)) +#define IXDR_GET_U_LONG(buf) ((u_long)IXDR_GET_LONG(buf)) +#define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf)) +#define IXDR_GET_U_SHORT(buf) ((u_short)IXDR_GET_LONG(buf)) + +#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) + +/* + * These are the "generic" xdr routines. + */ +__BEGIN_DECLS +extern bool_t xdr_void __P((void)); +extern bool_t xdr_int __P((XDR *, int *)); +extern bool_t xdr_u_int __P((XDR *, u_int *)); +extern bool_t xdr_long __P((XDR *, long *)); +extern bool_t xdr_u_long __P((XDR *, u_long *)); +extern bool_t xdr_short __P((XDR *, short *)); +extern bool_t xdr_u_short __P((XDR *, u_short *)); +extern bool_t xdr_bool __P((XDR *, bool_t *)); +extern bool_t xdr_enum __P((XDR *, enum_t *)); +extern bool_t xdr_array __P((XDR *, char **, u_int *, u_int, u_int, xdrproc_t)); +extern bool_t xdr_bytes __P((XDR *, char **, u_int *, u_int)); +extern bool_t xdr_opaque __P((XDR *, caddr_t, u_int)); +extern bool_t xdr_string __P((XDR *, char **, u_int)); +extern bool_t xdr_union __P((XDR *, enum_t *, char *, struct xdr_discrim *, xdrproc_t)); +extern bool_t xdr_char __P((XDR *, char *)); +extern bool_t xdr_u_char __P((XDR *, u_char *)); +extern bool_t xdr_vector __P((XDR *, char *, u_int, u_int, xdrproc_t)); +extern bool_t xdr_float __P((XDR *, float *)); +extern bool_t xdr_double __P((XDR *, double *)); +extern bool_t xdr_reference __P((XDR *, caddr_t *, u_int, xdrproc_t)); +extern bool_t xdr_pointer __P((XDR *, caddr_t *, u_int, xdrproc_t)); +extern bool_t xdr_wrapstring __P((XDR *, char **)); +extern void xdr_free __P((xdrproc_t, void *)); +__END_DECLS + +/* + * Common opaque bytes objects used by many rpc protocols; + * declared here due to commonality. + */ +#define MAX_NETOBJ_SZ 1024 +struct netobj { + u_int n_len; + char *n_bytes; +}; +typedef struct netobj netobj; +extern bool_t xdr_netobj(); + +/* + * These are the public routines for the various implementations of + * xdr streams. + */ +__BEGIN_DECLS +/* XDR using memory buffers */ +extern void xdrmem_create __P((XDR *, void *, u_int, enum xdr_op)); + +#ifdef _STDIO_H_ +/* XDR using stdio library */ +extern void xdrstdio_create __P((XDR *, FILE *, enum xdr_op)); +#endif + +/* XDR pseudo records for tcp */ +extern void xdrrec_create __P((XDR *, u_int, u_int, char *, int (*)(), int (*)())); + +/* make end of xdr record */ +extern bool_t xdrrec_endofrecord __P((XDR *, int)); + +/* move to beginning of next record */ +extern bool_t xdrrec_skiprecord __P((XDR *)); + +/* true if no more input */ +extern bool_t xdrrec_eof __P((XDR *)); +__END_DECLS + +#endif /* !_RPC_XDR_H */ diff --git a/rpc.subproj/xdr_array.c b/rpc.subproj/xdr_array.c new file mode 100644 index 0000000..356b795 --- /dev/null +++ b/rpc.subproj/xdr_array.c @@ -0,0 +1,178 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)xdr_array.c 1.10 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)xdr_array.c 2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: xdr_array.c,v 1.2 1999/10/14 21:56:55 wsanchez Exp $"; +#endif + +/* + * xdr_array.c, Generic XDR routines impelmentation. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * These are the "non-trivial" xdr primitives used to serialize and de-serialize + * arrays. See xdr.h for more info on the interface to xdr. + */ + +#include +#include +#include +#include + +#define LASTUNSIGNED ((u_int)0-1) + + +/* + * XDR an array of arbitrary elements + * *addrp is a pointer to the array, *sizep is the number of elements. + * If addrp is NULL (*sizep * elsize) bytes are allocated. + * elsize is the size (in bytes) of each element, and elproc is the + * xdr procedure to call to handle each element of the array. + */ +bool_t +xdr_array(xdrs, addrp, sizep, maxsize, elsize, elproc) + register XDR *xdrs; + caddr_t *addrp; /* array pointer */ + u_int *sizep; /* number of elements */ + u_int maxsize; /* max numberof elements */ + u_int elsize; /* size in bytes of each element */ + xdrproc_t elproc; /* xdr routine to handle each element */ +{ + register u_int i; + register caddr_t target = *addrp; + register u_int c; /* the actual element count */ + register bool_t stat = TRUE; + register u_int nodesize; + + /* like strings, arrays are really counted arrays */ + if (! xdr_u_int(xdrs, sizep)) { + return (FALSE); + } + c = *sizep; + if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) { + return (FALSE); + } + nodesize = c * elsize; + + /* + * if we are deserializing, we may need to allocate an array. + * We also save time by checking for a null array if we are freeing. + */ + if (target == NULL) + switch (xdrs->x_op) { + case XDR_DECODE: + if (c == 0) + return (TRUE); + *addrp = target = mem_alloc(nodesize); + if (target == NULL) { + (void) fprintf(stderr, + "xdr_array: out of memory\n"); + return (FALSE); + } + bzero(target, nodesize); + break; + + case XDR_FREE: + return (TRUE); + } + + /* + * now we xdr each element of array + */ + for (i = 0; (i < c) && stat; i++) { + stat = (*elproc)(xdrs, target, LASTUNSIGNED); + target += elsize; + } + + /* + * the array may need freeing + */ + if (xdrs->x_op == XDR_FREE) { + mem_free(*addrp, nodesize); + *addrp = NULL; + } + return (stat); +} + +/* + * xdr_vector(): + * + * XDR a fixed length array. Unlike variable-length arrays, + * the storage of fixed length arrays is static and unfreeable. + * > basep: base of the array + * > size: size of the array + * > elemsize: size of each element + * > xdr_elem: routine to XDR each element + */ +bool_t +xdr_vector(xdrs, basep, nelem, elemsize, xdr_elem) + register XDR *xdrs; + register char *basep; + register u_int nelem; + register u_int elemsize; + register xdrproc_t xdr_elem; +{ + register u_int i; + register char *elptr; + + elptr = basep; + for (i = 0; i < nelem; i++) { + if (! (*xdr_elem)(xdrs, elptr, LASTUNSIGNED)) { + return(FALSE); + } + elptr += elemsize; + } + return(TRUE); +} + diff --git a/rpc.subproj/xdr_float.c b/rpc.subproj/xdr_float.c new file mode 100644 index 0000000..775022a --- /dev/null +++ b/rpc.subproj/xdr_float.c @@ -0,0 +1,306 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)xdr_float.c 2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: xdr_float.c,v 1.2 1999/10/14 21:56:55 wsanchez Exp $"; +#endif + +/* + * xdr_float.c, Generic XDR routines impelmentation. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * These are the "floating point" xdr routines used to (de)serialize + * most common data items. See xdr.h for more info on the interface to + * xdr. + */ + +#include +#include +#include +#include +#include + +/* + * NB: Not portable. + * This routine works on Suns (Sky / 68000's), i386's, MIPS, NS32k and Vaxen. + */ + +#if defined(mc68000)||defined(sparc)||defined(i386)||defined(mips)||defined(ns32k)||defined(__APPLE__) +#define IEEEFP +#endif + +#ifdef vax + +/* What IEEE single precision floating point looks like on a Vax */ +struct ieee_single { + unsigned int mantissa: 23; + unsigned int exp : 8; + unsigned int sign : 1; +}; + +/* Vax single precision floating point */ +struct vax_single { + unsigned int mantissa1 : 7; + unsigned int exp : 8; + unsigned int sign : 1; + unsigned int mantissa2 : 16; +}; + +#define VAX_SNG_BIAS 0x81 +#define IEEE_SNG_BIAS 0x7f + +static struct sgl_limits { + struct vax_single s; + struct ieee_single ieee; +} sgl_limits[2] = { + {{ 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */ + { 0x0, 0xff, 0x0 }}, /* Max IEEE */ + {{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */ + { 0x0, 0x0, 0x0 }} /* Min IEEE */ +}; +#endif /* vax */ + +bool_t +xdr_float(xdrs, fp) + register XDR *xdrs; + register float *fp; +{ +#ifndef IEEEFP + struct ieee_single is; + struct vax_single vs, *vsp; + struct sgl_limits *lim; + int i; +#endif + switch (xdrs->x_op) { + + case XDR_ENCODE: +#ifdef IEEEFP + return (XDR_PUTLONG(xdrs, (long *)fp)); +#else + vs = *((struct vax_single *)fp); + for (i = 0, lim = sgl_limits; + i < sizeof(sgl_limits)/sizeof(struct sgl_limits); + i++, lim++) { + if ((vs.mantissa2 == lim->s.mantissa2) && + (vs.exp == lim->s.exp) && + (vs.mantissa1 == lim->s.mantissa1)) { + is = lim->ieee; + goto shipit; + } + } + is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS; + is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2; + shipit: + is.sign = vs.sign; + return (XDR_PUTLONG(xdrs, (long *)&is)); +#endif + + case XDR_DECODE: +#ifdef IEEEFP + return (XDR_GETLONG(xdrs, (long *)fp)); +#else + vsp = (struct vax_single *)fp; + if (!XDR_GETLONG(xdrs, (long *)&is)) + return (FALSE); + for (i = 0, lim = sgl_limits; + i < sizeof(sgl_limits)/sizeof(struct sgl_limits); + i++, lim++) { + if ((is.exp == lim->ieee.exp) && + (is.mantissa == lim->ieee.mantissa)) { + *vsp = lim->s; + goto doneit; + } + } + vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS; + vsp->mantissa2 = is.mantissa; + vsp->mantissa1 = (is.mantissa >> 16); + doneit: + vsp->sign = is.sign; + return (TRUE); +#endif + + case XDR_FREE: + return (TRUE); + } + return (FALSE); +} + +/* + * This routine works on Suns (Sky / 68000's), i386's, MIPS and Vaxen. + */ + +#ifdef vax +/* What IEEE double precision floating point looks like on a Vax */ +struct ieee_double { + unsigned int mantissa1 : 20; + unsigned int exp : 11; + unsigned int sign : 1; + unsigned int mantissa2 : 32; +}; + +/* Vax double precision floating point */ +struct vax_double { + unsigned int mantissa1 : 7; + unsigned int exp : 8; + unsigned int sign : 1; + unsigned int mantissa2 : 16; + unsigned int mantissa3 : 16; + unsigned int mantissa4 : 16; +}; + +#define VAX_DBL_BIAS 0x81 +#define IEEE_DBL_BIAS 0x3ff +#define MASK(nbits) ((1 << nbits) - 1) + +static struct dbl_limits { + struct vax_double d; + struct ieee_double ieee; +} dbl_limits[2] = { + {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */ + { 0x0, 0x7ff, 0x0, 0x0 }}, /* Max IEEE */ + {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */ + { 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */ +}; + +#endif /* vax */ + + +bool_t +xdr_double(xdrs, dp) + register XDR *xdrs; + double *dp; +{ + register long *lp; +#ifndef IEEEFP + struct ieee_double id; + struct vax_double vd; + register struct dbl_limits *lim; + int i; +#endif + + switch (xdrs->x_op) { + + case XDR_ENCODE: +#ifdef IEEEFP + lp = (long *)dp; +#if BYTE_ORDER == BIG_ENDIAN + return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp)); +#else + return (XDR_PUTLONG(xdrs, lp+1) && XDR_PUTLONG(xdrs, lp)); +#endif +#else + vd = *((struct vax_double *)dp); + for (i = 0, lim = dbl_limits; + i < sizeof(dbl_limits)/sizeof(struct dbl_limits); + i++, lim++) { + if ((vd.mantissa4 == lim->d.mantissa4) && + (vd.mantissa3 == lim->d.mantissa3) && + (vd.mantissa2 == lim->d.mantissa2) && + (vd.mantissa1 == lim->d.mantissa1) && + (vd.exp == lim->d.exp)) { + id = lim->ieee; + goto shipit; + } + } + id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS; + id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3); + id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) | + (vd.mantissa3 << 13) | + ((vd.mantissa4 >> 3) & MASK(13)); + shipit: + id.sign = vd.sign; + lp = (long *)&id; + return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp)); +#endif + + case XDR_DECODE: +#ifdef IEEEFP + lp = (long *)dp; +#if BYTE_ORDER == BIG_ENDIAN + return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp)); +#else + return (XDR_GETLONG(xdrs, lp+1) && XDR_GETLONG(xdrs, lp)); +#endif +#else + lp = (long *)&id; + if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp)) + return (FALSE); + for (i = 0, lim = dbl_limits; + i < sizeof(dbl_limits)/sizeof(struct dbl_limits); + i++, lim++) { + if ((id.mantissa2 == lim->ieee.mantissa2) && + (id.mantissa1 == lim->ieee.mantissa1) && + (id.exp == lim->ieee.exp)) { + vd = lim->d; + goto doneit; + } + } + vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS; + vd.mantissa1 = (id.mantissa1 >> 13); + vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) | + (id.mantissa2 >> 29); + vd.mantissa3 = (id.mantissa2 >> 13); + vd.mantissa4 = (id.mantissa2 << 3); + doneit: + vd.sign = id.sign; + *dp = *((double *)&vd); + return (TRUE); +#endif + + case XDR_FREE: + return (TRUE); + } + return (FALSE); +} diff --git a/rpc.subproj/xdr_mem.c b/rpc.subproj/xdr_mem.c new file mode 100644 index 0000000..3bec281 --- /dev/null +++ b/rpc.subproj/xdr_mem.c @@ -0,0 +1,213 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)xdr_mem.c 2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: xdr_mem.c,v 1.2 1999/10/14 21:56:55 wsanchez Exp $"; +#endif + +/* + * xdr_mem.h, XDR implementation using memory buffers. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * If you have some data to be interpreted as external data representation + * or to be converted to external data representation in a memory buffer, + * then this is the package for you. + * + */ + + +#include +#include +#include + +static bool_t xdrmem_getlong(); +static bool_t xdrmem_putlong(); +static bool_t xdrmem_getbytes(); +static bool_t xdrmem_putbytes(); +static u_int xdrmem_getpos(); +static bool_t xdrmem_setpos(); +static long * xdrmem_inline(); +static void xdrmem_destroy(); + +static struct xdr_ops xdrmem_ops = { + xdrmem_getlong, + xdrmem_putlong, + xdrmem_getbytes, + xdrmem_putbytes, + xdrmem_getpos, + xdrmem_setpos, + xdrmem_inline, + xdrmem_destroy +}; + +/* + * The procedure xdrmem_create initializes a stream descriptor for a + * memory buffer. + */ +void +xdrmem_create(xdrs, addr, size, op) + register XDR *xdrs; +#if defined(__APPLE__) + void *addr; +#else + caddr_t addr; +#endif /* !NeXT */ + u_int size; + enum xdr_op op; +{ + + xdrs->x_op = op; + xdrs->x_ops = &xdrmem_ops; + xdrs->x_private = xdrs->x_base = addr; + xdrs->x_handy = size; +} + +static void +xdrmem_destroy(/*xdrs*/) + /*XDR *xdrs;*/ +{ +} + +static bool_t +xdrmem_getlong(xdrs, lp) + register XDR *xdrs; + long *lp; +{ + + if ((xdrs->x_handy -= sizeof(long)) < 0) + return (FALSE); + *lp = (long)ntohl((u_long)(*((long *)(xdrs->x_private)))); + xdrs->x_private += sizeof(long); + return (TRUE); +} + +static bool_t +xdrmem_putlong(xdrs, lp) + register XDR *xdrs; + long *lp; +{ + + if ((xdrs->x_handy -= sizeof(long)) < 0) + return (FALSE); + *(long *)xdrs->x_private = (long)htonl((u_long)(*lp)); + xdrs->x_private += sizeof(long); + return (TRUE); +} + +static bool_t +xdrmem_getbytes(xdrs, addr, len) + register XDR *xdrs; + caddr_t addr; + register u_int len; +{ + + if ((xdrs->x_handy -= len) < 0) + return (FALSE); + bcopy(xdrs->x_private, addr, len); + xdrs->x_private += len; + return (TRUE); +} + +static bool_t +xdrmem_putbytes(xdrs, addr, len) + register XDR *xdrs; + caddr_t addr; + register u_int len; +{ + + if ((xdrs->x_handy -= len) < 0) + return (FALSE); + bcopy(addr, xdrs->x_private, len); + xdrs->x_private += len; + return (TRUE); +} + +static u_int +xdrmem_getpos(xdrs) + register XDR *xdrs; +{ + + return ((u_int)xdrs->x_private - (u_int)xdrs->x_base); +} + +static bool_t +xdrmem_setpos(xdrs, pos) + register XDR *xdrs; + u_int pos; +{ + register caddr_t newaddr = xdrs->x_base + pos; + register caddr_t lastaddr = xdrs->x_private + xdrs->x_handy; + + if ((long)newaddr > (long)lastaddr) + return (FALSE); + xdrs->x_private = newaddr; + xdrs->x_handy = (int)lastaddr - (int)newaddr; + return (TRUE); +} + +static long * +xdrmem_inline(xdrs, len) + register XDR *xdrs; + int len; +{ + long *buf = 0; + + if (xdrs->x_handy >= len) { + xdrs->x_handy -= len; + buf = (long *) xdrs->x_private; + xdrs->x_private += len; + } + return (buf); +} diff --git a/rpc.subproj/xdr_rec.c b/rpc.subproj/xdr_rec.c new file mode 100644 index 0000000..912dbfb --- /dev/null +++ b/rpc.subproj/xdr_rec.c @@ -0,0 +1,607 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)xdr_rec.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)xdr_rec.c 2.2 88/08/01 4.0 RPCSRC";*/ +static char *rcsid = "$Id: xdr_rec.c,v 1.2 1999/10/14 21:56:55 wsanchez Exp $"; +#endif + +/* + * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking" + * layer above tcp (for rpc's use). + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * These routines interface XDRSTREAMS to a tcp/ip connection. + * There is a record marking layer between the xdr stream + * and the tcp transport level. A record is composed on one or more + * record fragments. A record fragment is a thirty-two bit header followed + * by n bytes of data, where n is contained in the header. The header + * is represented as a htonl(u_long). Thegh order bit encodes + * whether or not the fragment is the last fragment of the record + * (1 => fragment is last, 0 => more fragments to follow. + * The other 31 bits encode the byte length of the fragment. + */ + +#include +#include +#include +#include +#include + +static u_int fix_buf_size(); +static bool_t flush_out(); +static bool_t get_input_bytes(); +static bool_t set_input_fragment(); +static bool_t skip_input_bytes(); + +static bool_t xdrrec_getlong(); +static bool_t xdrrec_putlong(); +static bool_t xdrrec_getbytes(); +static bool_t xdrrec_putbytes(); +static u_int xdrrec_getpos(); +static bool_t xdrrec_setpos(); +static long * xdrrec_inline(); +static void xdrrec_destroy(); + +static struct xdr_ops xdrrec_ops = { + xdrrec_getlong, + xdrrec_putlong, + xdrrec_getbytes, + xdrrec_putbytes, + xdrrec_getpos, + xdrrec_setpos, + xdrrec_inline, + xdrrec_destroy +}; + +/* + * A record is composed of one or more record fragments. + * A record fragment is a two-byte header followed by zero to + * 2**32-1 bytes. The header is treated as a long unsigned and is + * encode/decoded to the network via htonl/ntohl. The low order 31 bits + * are a byte count of the fragment. The highest order bit is a boolean: + * 1 => this fragment is the last fragment of the record, + * 0 => this fragment is followed by more fragment(s). + * + * The fragment/record machinery is not general; it is constructed to + * meet the needs of xdr and rpc based on tcp. + */ + +#define LAST_FRAG ((u_long)(1 << 31)) + +typedef struct rec_strm { + caddr_t tcp_handle; + caddr_t the_buffer; + /* + * out-goung bits + */ + int (*writeit)(); + caddr_t out_base; /* output buffer (points to frag header) */ + caddr_t out_finger; /* next output position */ + caddr_t out_boundry; /* data cannot up to this address */ + u_long *frag_header; /* beginning of curren fragment */ + bool_t frag_sent; /* true if buffer sent in middle of record */ + /* + * in-coming bits + */ + int (*readit)(); + u_long in_size; /* fixed size of the input buffer */ + caddr_t in_base; + caddr_t in_finger; /* location of next byte to be had */ + caddr_t in_boundry; /* can read up to this location */ + long fbtbc; /* fragment bytes to be consumed */ + bool_t last_frag; + u_int sendsize; + u_int recvsize; +} RECSTREAM; + + +/* + * Create an xdr handle for xdrrec + * xdrrec_create fills in xdrs. Sendsize and recvsize are + * send and recv buffer sizes (0 => use default). + * tcp_handle is an opaque handle that is passed as the first parameter to + * the procedures readit and writeit. Readit and writeit are read and + * write respectively. They are like the system + * calls expect that they take an opaque handle rather than an fd. + */ +void +xdrrec_create(xdrs, sendsize, recvsize, tcp_handle, readit, writeit) + register XDR *xdrs; + register u_int sendsize; + register u_int recvsize; + caddr_t tcp_handle; + int (*readit)(); /* like read, but pass it a tcp_handle, not sock */ + int (*writeit)(); /* like write, but pass it a tcp_handle, not sock */ +{ + register RECSTREAM *rstrm = + (RECSTREAM *)mem_alloc(sizeof(RECSTREAM)); + + if (rstrm == NULL) { + (void)fprintf(stderr, "xdrrec_create: out of memory\n"); + /* + * This is bad. Should rework xdrrec_create to + * return a handle, and in this case return NULL + */ + return; + } + /* + * adjust sizes and allocate buffer quad byte aligned + */ + rstrm->sendsize = sendsize = fix_buf_size(sendsize); + rstrm->recvsize = recvsize = fix_buf_size(recvsize); + rstrm->the_buffer = mem_alloc(sendsize + recvsize + BYTES_PER_XDR_UNIT); + if (rstrm->the_buffer == NULL) { + (void)fprintf(stderr, "xdrrec_create: out of memory\n"); + return; + } + for (rstrm->out_base = rstrm->the_buffer; + (u_int)rstrm->out_base % BYTES_PER_XDR_UNIT != 0; + rstrm->out_base++); + rstrm->in_base = rstrm->out_base + sendsize; + /* + * now the rest ... + */ + xdrs->x_ops = &xdrrec_ops; + xdrs->x_private = (caddr_t)rstrm; + rstrm->tcp_handle = tcp_handle; + rstrm->readit = readit; + rstrm->writeit = writeit; + rstrm->out_finger = rstrm->out_boundry = rstrm->out_base; + rstrm->frag_header = (u_long *)rstrm->out_base; + rstrm->out_finger += sizeof(u_long); + rstrm->out_boundry += sendsize; + rstrm->frag_sent = FALSE; + rstrm->in_size = recvsize; + rstrm->in_boundry = rstrm->in_base; + rstrm->in_finger = (rstrm->in_boundry += recvsize); + rstrm->fbtbc = 0; + rstrm->last_frag = TRUE; +} + + +/* + * The reoutines defined below are the xdr ops which will go into the + * xdr handle filled in by xdrrec_create. + */ + +static bool_t +xdrrec_getlong(xdrs, lp) + XDR *xdrs; + long *lp; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + register long *buflp = (long *)(rstrm->in_finger); + long mylong; + + /* first try the inline, fast case */ + if ((rstrm->fbtbc >= sizeof(long)) && + (((int)rstrm->in_boundry - (int)buflp) >= sizeof(long))) { + *lp = (long)ntohl((u_long)(*buflp)); + rstrm->fbtbc -= sizeof(long); + rstrm->in_finger += sizeof(long); + } else { + if (! xdrrec_getbytes(xdrs, (caddr_t)&mylong, sizeof(long))) + return (FALSE); + *lp = (long)ntohl((u_long)mylong); + } + return (TRUE); +} + +static bool_t +xdrrec_putlong(xdrs, lp) + XDR *xdrs; + long *lp; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + register long *dest_lp = ((long *)(rstrm->out_finger)); + + if ((rstrm->out_finger += sizeof(long)) > rstrm->out_boundry) { + /* + * this case should almost never happen so the code is + * inefficient + */ + rstrm->out_finger -= sizeof(long); + rstrm->frag_sent = TRUE; + if (! flush_out(rstrm, FALSE)) + return (FALSE); + dest_lp = ((long *)(rstrm->out_finger)); + rstrm->out_finger += sizeof(long); + } + *dest_lp = (long)htonl((u_long)(*lp)); + return (TRUE); +} + +static bool_t /* must manage buffers, fragments, and records */ +xdrrec_getbytes(xdrs, addr, len) + XDR *xdrs; + register caddr_t addr; + register u_int len; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + register int current; + + while (len > 0) { + current = rstrm->fbtbc; + if (current == 0) { + if (rstrm->last_frag) + return (FALSE); + if (! set_input_fragment(rstrm)) + return (FALSE); + continue; + } + current = (len < current) ? len : current; + if (! get_input_bytes(rstrm, addr, current)) + return (FALSE); + addr += current; + rstrm->fbtbc -= current; + len -= current; + } + return (TRUE); +} + +static bool_t +xdrrec_putbytes(xdrs, addr, len) + XDR *xdrs; + register caddr_t addr; + register u_int len; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + register int current; + + while (len > 0) { + current = (u_int)rstrm->out_boundry - (u_int)rstrm->out_finger; + current = (len < current) ? len : current; + bcopy(addr, rstrm->out_finger, current); + rstrm->out_finger += current; + addr += current; + len -= current; + if (rstrm->out_finger == rstrm->out_boundry) { + rstrm->frag_sent = TRUE; + if (! flush_out(rstrm, FALSE)) + return (FALSE); + } + } + return (TRUE); +} + +static u_int +xdrrec_getpos(xdrs) + register XDR *xdrs; +{ + register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; + register long pos; + + pos = lseek((int)rstrm->tcp_handle, 0, 1); + if (pos != -1) + switch (xdrs->x_op) { + + case XDR_ENCODE: + pos += rstrm->out_finger - rstrm->out_base; + break; + + case XDR_DECODE: + pos -= rstrm->in_boundry - rstrm->in_finger; + break; + + default: + pos = (u_int) -1; + break; + } + return ((u_int) pos); +} + +static bool_t +xdrrec_setpos(xdrs, pos) + register XDR *xdrs; + u_int pos; +{ + register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; + u_int currpos = xdrrec_getpos(xdrs); + int delta = currpos - pos; + caddr_t newpos; + + if ((int)currpos != -1) + switch (xdrs->x_op) { + + case XDR_ENCODE: + newpos = rstrm->out_finger - delta; + if ((newpos > (caddr_t)(rstrm->frag_header)) && + (newpos < rstrm->out_boundry)) { + rstrm->out_finger = newpos; + return (TRUE); + } + break; + + case XDR_DECODE: + newpos = rstrm->in_finger - delta; + if ((delta < (int)(rstrm->fbtbc)) && + (newpos <= rstrm->in_boundry) && + (newpos >= rstrm->in_base)) { + rstrm->in_finger = newpos; + rstrm->fbtbc -= delta; + return (TRUE); + } + break; + } + return (FALSE); +} + +static long * +xdrrec_inline(xdrs, len) + register XDR *xdrs; + int len; +{ + register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; + long * buf = NULL; + + switch (xdrs->x_op) { + + case XDR_ENCODE: + if ((rstrm->out_finger + len) <= rstrm->out_boundry) { + buf = (long *) rstrm->out_finger; + rstrm->out_finger += len; + } + break; + + case XDR_DECODE: + if ((len <= rstrm->fbtbc) && + ((rstrm->in_finger + len) <= rstrm->in_boundry)) { + buf = (long *) rstrm->in_finger; + rstrm->fbtbc -= len; + rstrm->in_finger += len; + } + break; + } + return (buf); +} + +static void +xdrrec_destroy(xdrs) + register XDR *xdrs; +{ + register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; + + mem_free(rstrm->the_buffer, + rstrm->sendsize + rstrm->recvsize + BYTES_PER_XDR_UNIT); + mem_free((caddr_t)rstrm, sizeof(RECSTREAM)); +} + + +/* + * Exported routines to manage xdr records + */ + +/* + * Before reading (deserializing from the stream, one should always call + * this procedure to guarantee proper record alignment. + */ +bool_t +xdrrec_skiprecord(xdrs) + XDR *xdrs; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + + while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) { + if (! skip_input_bytes(rstrm, rstrm->fbtbc)) + return (FALSE); + rstrm->fbtbc = 0; + if ((! rstrm->last_frag) && (! set_input_fragment(rstrm))) + return (FALSE); + } + rstrm->last_frag = FALSE; + return (TRUE); +} + +/* + * Look ahead fuction. + * Returns TRUE iff there is no more input in the buffer + * after consuming the rest of the current record. + */ +bool_t +xdrrec_eof(xdrs) + XDR *xdrs; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + + while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) { + if (! skip_input_bytes(rstrm, rstrm->fbtbc)) + return (TRUE); + rstrm->fbtbc = 0; + if ((! rstrm->last_frag) && (! set_input_fragment(rstrm))) + return (TRUE); + } + if (rstrm->in_finger == rstrm->in_boundry) + return (TRUE); + return (FALSE); +} + +/* + * The client must tell the package when an end-of-record has occurred. + * The second paraemters tells whether the record should be flushed to the + * (output) tcp stream. (This let's the package support batched or + * pipelined procedure calls.) TRUE => immmediate flush to tcp connection. + */ +bool_t +xdrrec_endofrecord(xdrs, sendnow) + XDR *xdrs; + bool_t sendnow; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + register u_long len; /* fragment length */ + + if (sendnow || rstrm->frag_sent || + ((u_long)rstrm->out_finger + sizeof(u_long) >= + (u_long)rstrm->out_boundry)) { + rstrm->frag_sent = FALSE; + return (flush_out(rstrm, TRUE)); + } + len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->frag_header) - + sizeof(u_long); + *(rstrm->frag_header) = htonl((u_long)len | LAST_FRAG); + rstrm->frag_header = (u_long *)rstrm->out_finger; + rstrm->out_finger += sizeof(u_long); + return (TRUE); +} + + +/* + * Internal useful routines + */ +static bool_t +flush_out(rstrm, eor) + register RECSTREAM *rstrm; + bool_t eor; +{ + register u_long eormask = (eor == TRUE) ? LAST_FRAG : 0; + register u_long len = (u_long)(rstrm->out_finger) - + (u_long)(rstrm->frag_header) - sizeof(u_long); + + *(rstrm->frag_header) = htonl(len | eormask); + len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->out_base); + if ((*(rstrm->writeit))(rstrm->tcp_handle, rstrm->out_base, (int)len) + != (int)len) + return (FALSE); + rstrm->frag_header = (u_long *)rstrm->out_base; + rstrm->out_finger = (caddr_t)rstrm->out_base + sizeof(u_long); + return (TRUE); +} + +static bool_t /* knows nothing about records! Only about input buffers */ +fill_input_buf(rstrm) + register RECSTREAM *rstrm; +{ + register caddr_t where; + u_int i; + register int len; + + where = rstrm->in_base; + i = (u_int)rstrm->in_boundry % BYTES_PER_XDR_UNIT; + where += i; + len = rstrm->in_size - i; + if ((len = (*(rstrm->readit))(rstrm->tcp_handle, where, len)) == -1) + return (FALSE); + rstrm->in_finger = where; + where += len; + rstrm->in_boundry = where; + return (TRUE); +} + +static bool_t /* knows nothing about records! Only about input buffers */ +get_input_bytes(rstrm, addr, len) + register RECSTREAM *rstrm; + register caddr_t addr; + register int len; +{ + register int current; + + while (len > 0) { + current = (int)rstrm->in_boundry - (int)rstrm->in_finger; + if (current == 0) { + if (! fill_input_buf(rstrm)) + return (FALSE); + continue; + } + current = (len < current) ? len : current; + bcopy(rstrm->in_finger, addr, current); + rstrm->in_finger += current; + addr += current; + len -= current; + } + return (TRUE); +} + +static bool_t /* next two bytes of the input stream are treated as a header */ +set_input_fragment(rstrm) + register RECSTREAM *rstrm; +{ + u_long header; + + if (! get_input_bytes(rstrm, (caddr_t)&header, sizeof(header))) + return (FALSE); + header = (long)ntohl(header); + rstrm->last_frag = ((header & LAST_FRAG) == 0) ? FALSE : TRUE; + rstrm->fbtbc = header & (~LAST_FRAG); + return (TRUE); +} + +static bool_t /* consumes input bytes; knows nothing about records! */ +skip_input_bytes(rstrm, cnt) + register RECSTREAM *rstrm; + long cnt; +{ + register int current; + + while (cnt > 0) { + current = (int)rstrm->in_boundry - (int)rstrm->in_finger; + if (current == 0) { + if (! fill_input_buf(rstrm)) + return (FALSE); + continue; + } + current = (cnt < current) ? cnt : current; + rstrm->in_finger += current; + cnt -= current; + } + return (TRUE); +} + +static u_int +fix_buf_size(s) + register u_int s; +{ + + if (s < 100) + s = 4000; + return (RNDUP(s)); +} diff --git a/rpc.subproj/xdr_reference.c b/rpc.subproj/xdr_reference.c new file mode 100644 index 0000000..bfc82e1 --- /dev/null +++ b/rpc.subproj/xdr_reference.c @@ -0,0 +1,157 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)xdr_reference.c 1.11 87/08/11 SMI";*/ +/*static char *sccsid = "from: @(#)xdr_reference.c 2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: xdr_reference.c,v 1.2 1999/10/14 21:56:55 wsanchez Exp $"; +#endif + +/* + * xdr_reference.c, Generic XDR routines impelmentation. + * + * Copyright (C) 1987, Sun Microsystems, Inc. + * + * These are the "non-trivial" xdr primitives used to serialize and de-serialize + * "pointers". See xdr.h for more info on the interface to xdr. + */ + +#include +#include +#include + +#define LASTUNSIGNED ((u_int)0-1) + +/* + * XDR an indirect pointer + * xdr_reference is for recursively translating a structure that is + * referenced by a pointer inside the structure that is currently being + * translated. pp references a pointer to storage. If *pp is null + * the necessary storage is allocated. + * size is the sizeof the referneced structure. + * proc is the routine to handle the referenced structure. + */ +bool_t +xdr_reference(xdrs, pp, size, proc) + register XDR *xdrs; + caddr_t *pp; /* the pointer to work on */ + u_int size; /* size of the object pointed to */ + xdrproc_t proc; /* xdr routine to handle the object */ +{ + register caddr_t loc = *pp; + register bool_t stat; + + if (loc == NULL) + switch (xdrs->x_op) { + case XDR_FREE: + return (TRUE); + + case XDR_DECODE: + *pp = loc = (caddr_t) mem_alloc(size); + if (loc == NULL) { + (void) fprintf(stderr, + "xdr_reference: out of memory\n"); + return (FALSE); + } + bzero(loc, (int)size); + break; + } + + stat = (*proc)(xdrs, loc, LASTUNSIGNED); + + if (xdrs->x_op == XDR_FREE) { + mem_free(loc, size); + *pp = NULL; + } + return (stat); +} + + +/* + * xdr_pointer(): + * + * XDR a pointer to a possibly recursive data structure. This + * differs with xdr_reference in that it can serialize/deserialiaze + * trees correctly. + * + * What's sent is actually a union: + * + * union object_pointer switch (boolean b) { + * case TRUE: object_data data; + * case FALSE: void nothing; + * } + * + * > objpp: Pointer to the pointer to the object. + * > obj_size: size of the object. + * > xdr_obj: routine to XDR an object. + * + */ +bool_t +xdr_pointer(xdrs,objpp,obj_size,xdr_obj) + register XDR *xdrs; + char **objpp; + u_int obj_size; + xdrproc_t xdr_obj; +{ + + bool_t more_data; + + more_data = (*objpp != NULL); + if (! xdr_bool(xdrs,&more_data)) { + return (FALSE); + } + if (! more_data) { + *objpp = NULL; + return (TRUE); + } + return (xdr_reference(xdrs,objpp,obj_size,xdr_obj)); +} diff --git a/rpc.subproj/xdr_stdio.c b/rpc.subproj/xdr_stdio.c new file mode 100644 index 0000000..d4c6b49 --- /dev/null +++ b/rpc.subproj/xdr_stdio.c @@ -0,0 +1,214 @@ +/* + * 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@ + */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +#if defined(LIBC_SCCS) && !defined(lint) +/*static char *sccsid = "from: @(#)xdr_stdio.c 1.16 87/08/11 Copyr 1984 Sun Micro";*/ +/*static char *sccsid = "from: @(#)xdr_stdio.c 2.1 88/07/29 4.0 RPCSRC";*/ +static char *rcsid = "$Id: xdr_stdio.c,v 1.2 1999/10/14 21:56:55 wsanchez Exp $"; +#endif + +/* + * xdr_stdio.c, XDR implementation on standard i/o file. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * This set of routines implements a XDR on a stdio stream. + * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes + * from the stream. + */ + +#include +#include +#include + +static bool_t xdrstdio_getlong(); +static bool_t xdrstdio_putlong(); +static bool_t xdrstdio_getbytes(); +static bool_t xdrstdio_putbytes(); +static u_int xdrstdio_getpos(); +static bool_t xdrstdio_setpos(); +static long * xdrstdio_inline(); +static void xdrstdio_destroy(); + +/* + * Ops vector for stdio type XDR + */ +static struct xdr_ops xdrstdio_ops = { + xdrstdio_getlong, /* deseraialize a long int */ + xdrstdio_putlong, /* seraialize a long int */ + xdrstdio_getbytes, /* deserialize counted bytes */ + xdrstdio_putbytes, /* serialize counted bytes */ + xdrstdio_getpos, /* get offset in the stream */ + xdrstdio_setpos, /* set offset in the stream */ + xdrstdio_inline, /* prime stream for inline macros */ + xdrstdio_destroy /* destroy stream */ +}; + +/* + * Initialize a stdio xdr stream. + * Sets the xdr stream handle xdrs for use on the stream file. + * Operation flag is set to op. + */ +void +xdrstdio_create(xdrs, file, op) + register XDR *xdrs; + FILE *file; + enum xdr_op op; +{ + + xdrs->x_op = op; + xdrs->x_ops = &xdrstdio_ops; + xdrs->x_private = (caddr_t)file; + xdrs->x_handy = 0; + xdrs->x_base = 0; +} + +/* + * Destroy a stdio xdr stream. + * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create. + */ +static void +xdrstdio_destroy(xdrs) + register XDR *xdrs; +{ + (void)fflush((FILE *)xdrs->x_private); + /* xx should we close the file ?? */ +}; + +static bool_t +xdrstdio_getlong(xdrs, lp) + XDR *xdrs; + register long *lp; +{ + + if (fread((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1) + return (FALSE); +#ifndef mc68000 + *lp = ntohl(*lp); +#endif + return (TRUE); +} + +static bool_t +xdrstdio_putlong(xdrs, lp) + XDR *xdrs; + long *lp; +{ + +#ifndef mc68000 + long mycopy = htonl(*lp); + lp = &mycopy; +#endif + if (fwrite((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1) + return (FALSE); + return (TRUE); +} + +static bool_t +xdrstdio_getbytes(xdrs, addr, len) + XDR *xdrs; + caddr_t addr; + u_int len; +{ + + if ((len != 0) && (fread(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1)) + return (FALSE); + return (TRUE); +} + +static bool_t +xdrstdio_putbytes(xdrs, addr, len) + XDR *xdrs; + caddr_t addr; + u_int len; +{ + + if ((len != 0) && (fwrite(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1)) + return (FALSE); + return (TRUE); +} + +static u_int +xdrstdio_getpos(xdrs) + XDR *xdrs; +{ + + return ((u_int) ftell((FILE *)xdrs->x_private)); +} + +static bool_t +xdrstdio_setpos(xdrs, pos) + XDR *xdrs; + u_int pos; +{ + + return ((fseek((FILE *)xdrs->x_private, (long)pos, 0) < 0) ? + FALSE : TRUE); +} + +static long * +xdrstdio_inline(xdrs, len) + XDR *xdrs; + u_int len; +{ + + /* + * Must do some work to implement this: must insure + * enough data in the underlying stdio buffer, + * that the buffer is aligned so that we can indirect through a + * long *, and stuff this pointer in xdrs->x_buf. Doing + * a fread or fwrite to a scratch buffer would defeat + * most of the gains to be had here and require storage + * management on this buffer, so we don't do this. + */ + return (NULL); +} diff --git a/util.subproj/Makefile b/util.subproj/Makefile new file mode 100644 index 0000000..aede900 --- /dev/null +++ b/util.subproj/Makefile @@ -0,0 +1,46 @@ +# +# Generated by the NeXT Project Builder. +# +# NOTE: Do NOT change this file -- Project Builder maintains it. +# +# Put all of your customizations in files called Makefile.preamble +# and Makefile.postamble (both optional), and Makefile will include them. +# + +NAME = util + +PROJECTVERSION = 2.8 +PROJECT_TYPE = Component + +CFILES = getgrouplist.c glob.c hton.c putpwpasswd.c pwcache.c rcmd.c\ + rcmdsh.c + +OTHERSRCS = Makefile + + +MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles +CODE_GEN_STYLE = DYNAMIC +MAKEFILE = subproj.make +LIBS = +DEBUG_LIBS = $(LIBS) +PROF_LIBS = $(LIBS) + + + + +NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc +WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc +PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc +NEXTSTEP_JAVA_COMPILER = /usr/bin/javac +WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe +PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac + +include $(MAKEFILEDIR)/platform.make + +-include Makefile.preamble + +include $(MAKEFILEDIR)/$(MAKEFILE) + +-include Makefile.postamble + +-include Makefile.dependencies diff --git a/util.subproj/PB.project b/util.subproj/PB.project new file mode 100644 index 0000000..eab47ff --- /dev/null +++ b/util.subproj/PB.project @@ -0,0 +1,21 @@ +{ + DYNAMIC_CODE_GEN = YES; + FILESTABLE = { + OTHER_LINKED = (getgrouplist.c, glob.c, hton.c, putpwpasswd.c, pwcache.c, rcmd.c, rcmdsh.c); + OTHER_SOURCES = (Makefile); + }; + LANGUAGE = English; + MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; + NEXTSTEP_BUILDTOOL = /bin/gnumake; + NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; + NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; + PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; + PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; + PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; + PROJECTNAME = util; + PROJECTTYPE = Component; + PROJECTVERSION = 2.8; + WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; + WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; + WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; +} diff --git a/util.subproj/getgrouplist.c b/util.subproj/getgrouplist.c new file mode 100644 index 0000000..305f1b8 --- /dev/null +++ b/util.subproj/getgrouplist.c @@ -0,0 +1,112 @@ +/* + * 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) 1991, 1993 + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)getgrouplist.c 8.2 (Berkeley) 12/8/94"; +#endif /* LIBC_SCCS and not lint */ + +/* + * get credential + */ +#include +#include +#include + +int +getgrouplist(uname, agroup, groups, grpcnt) + const char *uname; + int agroup; + register int *groups; + int *grpcnt; +{ + register struct group *grp; + register struct passwd *pw; + register int i, ngroups; + int ret, maxgroups; + + ret = 0; + ngroups = 0; + maxgroups = *grpcnt; + /* + * When installing primary group, duplicate it; + * the first element of groups is the effective gid + * and will be overwritten when a setgid file is executed. + */ + groups[ngroups++] = agroup; + if (maxgroups > 1) + groups[ngroups++] = agroup; + /* + * Scan the group file to find additional groups. + */ + setgrent(); + while (grp = getgrent()) { + if (grp->gr_gid == agroup) + continue; + for (i = 0; grp->gr_mem[i]; i++) { + if (!strcmp(grp->gr_mem[i], uname)) { + if (ngroups >= maxgroups) { + ret = -1; + break; + } + groups[ngroups++] = grp->gr_gid; + break; + } + } + } + endgrent(); + *grpcnt = ngroups; + return (ret); +} diff --git a/util.subproj/glob.c b/util.subproj/glob.c new file mode 100644 index 0000000..f19459e --- /dev/null +++ b/util.subproj/glob.c @@ -0,0 +1,845 @@ +/* + * 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) 1995 NeXT Computer, Inc. All Rights Reserved + * + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Guido van Rossum. + * + * The NEXTSTEP Software License Agreement specifies the terms + * and conditions for redistribution. + * + * @(#)glob.c 8.3 (Berkeley) 10/13/93 + */ + + +/* + * glob(3) -- a superset of the one defined in POSIX 1003.2. + * + * The [!...] convention to negate a range is supported (SysV, Posix, ksh). + * + * Optional extra services, controlled by flags not defined by POSIX: + * + * GLOB_QUOTE: + * Escaping convention: \ inhibits any special meaning the following + * character might have (except \ at end of string is retained). + * GLOB_MAGCHAR: + * Set in gl_flags if pattern contained a globbing character. + * GLOB_NOMAGIC: + * Same as GLOB_NOCHECK, but it will only append pattern if it did + * not contain any magic characters. [Used in csh style globbing] + * GLOB_ALTDIRFUNC: + * Use alternately specified directory access functions. + * GLOB_TILDE: + * expand ~user/foo to the /home/dir/of/user/foo + * GLOB_BRACE: + * expand {1,2}{a,b} to 1a 1b 2a 2b + * gl_matchc: + * Number of matches in the current invocation of glob. + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DOLLAR '$' +#define DOT '.' +#define EOS '\0' +#define LBRACKET '[' +#define NOT '!' +#define QUESTION '?' +#define QUOTE '\\' +#define RANGE '-' +#define RBRACKET ']' +#define SEP '/' +#define STAR '*' +#define TILDE '~' +#define UNDERSCORE '_' +#define LBRACE '{' +#define RBRACE '}' +#define SLASH '/' +#define COMMA ',' + +#ifndef DEBUG + +#define M_QUOTE 0x8000 +#define M_PROTECT 0x4000 +#define M_MASK 0xffff +#define M_ASCII 0x00ff + +typedef u_short Char; + +#else + +#define M_QUOTE 0x80 +#define M_PROTECT 0x40 +#define M_MASK 0xff +#define M_ASCII 0x7f + +typedef char Char; + +#endif + + +#define CHAR(c) ((Char)((c)&M_ASCII)) +#define META(c) ((Char)((c)|M_QUOTE)) +#define M_ALL META('*') +#define M_END META(']') +#define M_NOT META('!') +#define M_ONE META('?') +#define M_RNG META('-') +#define M_SET META('[') +#define ismeta(c) (((c)&M_QUOTE) != 0) + + +static int compare __P((const void *, const void *)); +static void g_Ctoc __P((const Char *, char *)); +static int g_lstat __P((Char *, struct stat *, glob_t *)); +static DIR *g_opendir __P((Char *, glob_t *)); +static Char *g_strchr __P((Char *, int)); +#ifdef notdef +static Char *g_strcat __P((Char *, const Char *)); +#endif +static int g_stat __P((Char *, struct stat *, glob_t *)); +static int glob0 __P((const Char *, glob_t *)); +static int glob1 __P((Char *, glob_t *)); +static int glob2 __P((Char *, Char *, Char *, glob_t *)); +static int glob3 __P((Char *, Char *, Char *, Char *, glob_t *)); +static int globextend __P((const Char *, glob_t *)); +static const Char * globtilde __P((const Char *, Char *, glob_t *)); +static int globexp1 __P((const Char *, glob_t *)); +static int globexp2 __P((const Char *, const Char *, glob_t *, int *)); +static int match __P((Char *, Char *, Char *)); +#ifdef DEBUG +static void qprintf __P((const char *, Char *)); +#endif + +int +glob(pattern, flags, errfunc, pglob) + const char *pattern; + int flags, (*errfunc) __P((const char *, int)); + glob_t *pglob; +{ + const u_char *patnext; + int c; + Char *bufnext, *bufend, patbuf[MAXPATHLEN+1]; + + patnext = (u_char *) pattern; + if (!(flags & GLOB_APPEND)) { + pglob->gl_pathc = 0; + pglob->gl_pathv = NULL; + if (!(flags & GLOB_DOOFFS)) + pglob->gl_offs = 0; + } + pglob->gl_flags = flags & ~GLOB_MAGCHAR; + pglob->gl_errfunc = errfunc; + pglob->gl_matchc = 0; + + bufnext = patbuf; + bufend = bufnext + MAXPATHLEN; + if (flags & GLOB_QUOTE) { + /* Protect the quoted characters. */ + while (bufnext < bufend && (c = *patnext++) != EOS) + if (c == QUOTE) { + if ((c = *patnext++) == EOS) { + c = QUOTE; + --patnext; + } + *bufnext++ = c | M_PROTECT; + } + else + *bufnext++ = c; + } + else + while (bufnext < bufend && (c = *patnext++) != EOS) + *bufnext++ = c; + *bufnext = EOS; + + if (flags & GLOB_BRACE) + return globexp1(patbuf, pglob); + else + return glob0(patbuf, pglob); +} + +/* + * Expand recursively a glob {} pattern. When there is no more expansion + * invoke the standard globbing routine to glob the rest of the magic + * characters + */ +static int globexp1(pattern, pglob) + const Char *pattern; + glob_t *pglob; +{ + const Char* ptr = pattern; + int rv; + + /* Protect a single {}, for find(1), like csh */ + if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) + return glob0(pattern, pglob); + + while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL) + if (!globexp2(ptr, pattern, pglob, &rv)) + return rv; + + return glob0(pattern, pglob); +} + + +/* + * Recursive brace globbing helper. Tries to expand a single brace. + * If it succeeds then it invokes globexp1 with the new pattern. + * If it fails then it tries to glob the rest of the pattern and returns. + */ +static int globexp2(ptr, pattern, pglob, rv) + const Char *ptr, *pattern; + glob_t *pglob; + int *rv; +{ + int i; + Char *lm, *ls; + const Char *pe, *pm, *pl; + Char patbuf[MAXPATHLEN + 1]; + + /* copy part up to the brace */ + for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) + continue; + ls = lm; + + /* Find the balanced brace */ + for (i = 0, pe = ++ptr; *pe; pe++) + if (*pe == LBRACKET) { + /* Ignore everything between [] */ + for (pm = pe++; *pe != RBRACKET && *pe != EOS; pe++) + continue; + if (*pe == EOS) { + /* + * We could not find a matching RBRACKET. + * Ignore and just look for RBRACE + */ + pe = pm; + } + } + else if (*pe == LBRACE) + i++; + else if (*pe == RBRACE) { + if (i == 0) + break; + i--; + } + + /* Non matching braces; just glob the pattern */ + if (i != 0 || *pe == EOS) { + *rv = glob0(patbuf, pglob); + return 0; + } + + for (i = 0, pl = pm = ptr; pm <= pe; pm++) + switch (*pm) { + case LBRACKET: + /* Ignore everything between [] */ + for (pl = pm++; *pm != RBRACKET && *pm != EOS; pm++) + continue; + if (*pm == EOS) { + /* + * We could not find a matching RBRACKET. + * Ignore and just look for RBRACE + */ + pm = pl; + } + break; + + case LBRACE: + i++; + break; + + case RBRACE: + if (i) { + i--; + break; + } + /* FALLTHROUGH */ + case COMMA: + if (i && *pm == COMMA) + break; + else { + /* Append the current string */ + for (lm = ls; (pl < pm); *lm++ = *pl++) + continue; + /* + * Append the rest of the pattern after the + * closing brace + */ + for (pl = pe + 1; (*lm++ = *pl++) != EOS;) + continue; + + /* Expand the current pattern */ +#ifdef DEBUG + qprintf("globexp2:", patbuf); +#endif + *rv = globexp1(patbuf, pglob); + + /* move after the comma, to the next string */ + pl = pm + 1; + } + break; + + default: + break; + } + *rv = 0; + return 0; +} + + + +/* + * expand tilde from the passwd file. + */ +static const Char * +globtilde(pattern, patbuf, pglob) + const Char *pattern; + Char *patbuf; + glob_t *pglob; +{ + struct passwd *pwd; + char *h; + const Char *p; + Char *b; + + if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) + return pattern; + + /* Copy up to the end of the string or / */ + for (p = pattern + 1, h = (char *) patbuf; *p && *p != SLASH; + *h++ = *p++) + continue; + + *h = EOS; + + if (((char *) patbuf)[0] == EOS) { + /* + * handle a plain ~ or ~/ by expanding $HOME + * first and then trying the password file + */ + if ((h = getenv("HOME")) == NULL) { + if ((pwd = getpwuid(getuid())) == NULL) + return pattern; + else + h = pwd->pw_dir; + } + } + else { + /* + * Expand a ~user + */ + if ((pwd = getpwnam((char*) patbuf)) == NULL) + return pattern; + else + h = pwd->pw_dir; + } + + /* Copy the home directory */ + for (b = patbuf; *h; *b++ = *h++) + continue; + + /* Append the rest of the pattern */ + while ((*b++ = *p++) != EOS) + continue; + + return patbuf; +} + + +/* + * The main glob() routine: compiles the pattern (optionally processing + * quotes), calls glob1() to do the real pattern matching, and finally + * sorts the list (unless unsorted operation is requested). Returns 0 + * if things went well, nonzero if errors occurred. It is not an error + * to find no matches. + */ +static int +glob0(pattern, pglob) + const Char *pattern; + glob_t *pglob; +{ + const Char *qpatnext; + int c, err, oldpathc; + Char *bufnext, patbuf[MAXPATHLEN+1]; + + qpatnext = globtilde(pattern, patbuf, pglob); + oldpathc = pglob->gl_pathc; + bufnext = patbuf; + + /* We don't need to check for buffer overflow any more. */ + while ((c = *qpatnext++) != EOS) { + switch (c) { + case LBRACKET: + c = *qpatnext; + if (c == NOT) + ++qpatnext; + if (*qpatnext == EOS || + g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) { + *bufnext++ = LBRACKET; + if (c == NOT) + --qpatnext; + break; + } + *bufnext++ = M_SET; + if (c == NOT) + *bufnext++ = M_NOT; + c = *qpatnext++; + do { + *bufnext++ = CHAR(c); + if (*qpatnext == RANGE && + (c = qpatnext[1]) != RBRACKET) { + *bufnext++ = M_RNG; + *bufnext++ = CHAR(c); + qpatnext += 2; + } + } while ((c = *qpatnext++) != RBRACKET); + pglob->gl_flags |= GLOB_MAGCHAR; + *bufnext++ = M_END; + break; + case QUESTION: + pglob->gl_flags |= GLOB_MAGCHAR; + *bufnext++ = M_ONE; + break; + case STAR: + pglob->gl_flags |= GLOB_MAGCHAR; + /* collapse adjacent stars to one, + * to avoid exponential behavior + */ + if (bufnext == patbuf || bufnext[-1] != M_ALL) + *bufnext++ = M_ALL; + break; + default: + *bufnext++ = CHAR(c); + break; + } + } + *bufnext = EOS; +#ifdef DEBUG + qprintf("glob0:", patbuf); +#endif + + if ((err = glob1(patbuf, pglob)) != 0) + return(err); + + /* + * If there was no match we are going to append the pattern + * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified + * and the pattern did not contain any magic characters + * GLOB_NOMAGIC is there just for compatibility with csh. + */ + if (pglob->gl_pathc == oldpathc && + ((pglob->gl_flags & GLOB_NOCHECK) || + ((pglob->gl_flags & GLOB_NOMAGIC) && + !(pglob->gl_flags & GLOB_MAGCHAR)))) + return(globextend(pattern, pglob)); + else if (!(pglob->gl_flags & GLOB_NOSORT)) + qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, + pglob->gl_pathc - oldpathc, sizeof(char *), compare); + return(0); +} + +static int +compare(p, q) + const void *p, *q; +{ + return(strcmp(*(char **)p, *(char **)q)); +} + +static int +glob1(pattern, pglob) + Char *pattern; + glob_t *pglob; +{ + Char pathbuf[MAXPATHLEN+1]; + + /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ + if (*pattern == EOS) + return(0); + return(glob2(pathbuf, pathbuf, pattern, pglob)); +} + +/* + * The functions glob2 and glob3 are mutually recursive; there is one level + * of recursion for each segment in the pattern that contains one or more + * meta characters. + */ +static int +glob2(pathbuf, pathend, pattern, pglob) + Char *pathbuf, *pathend, *pattern; + glob_t *pglob; +{ + struct stat sb; + Char *p, *q; + int anymeta; + + /* + * Loop over pattern segments until end of pattern or until + * segment with meta character found. + */ + for (anymeta = 0;;) { + if (*pattern == EOS) { /* End of pattern? */ + *pathend = EOS; + if (g_lstat(pathbuf, &sb, pglob)) + return(0); + + if (((pglob->gl_flags & GLOB_MARK) && + pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) + || (S_ISLNK(sb.st_mode) && + (g_stat(pathbuf, &sb, pglob) == 0) && + S_ISDIR(sb.st_mode)))) { + *pathend++ = SEP; + *pathend = EOS; + } + ++pglob->gl_matchc; + return(globextend(pathbuf, pglob)); + } + + /* Find end of next segment, copy tentatively to pathend. */ + q = pathend; + p = pattern; + while (*p != EOS && *p != SEP) { + if (ismeta(*p)) + anymeta = 1; + *q++ = *p++; + } + + if (!anymeta) { /* No expansion, do next segment. */ + pathend = q; + pattern = p; + while (*pattern == SEP) + *pathend++ = *pattern++; + } else /* Need expansion, recurse. */ + return(glob3(pathbuf, pathend, pattern, p, pglob)); + } + /* NOTREACHED */ +} + +static int +glob3(pathbuf, pathend, pattern, restpattern, pglob) + Char *pathbuf, *pathend, *pattern, *restpattern; + glob_t *pglob; +{ + register struct dirent *dp; + DIR *dirp; + int err; + char buf[MAXPATHLEN]; + + /* + * The readdirfunc declaration can't be prototyped, because it is + * assigned, below, to two functions which are prototyped in glob.h + * and dirent.h as taking pointers to differently typed opaque + * structures. + */ + struct dirent *(*readdirfunc)(); + + *pathend = EOS; + errno = 0; + + if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { + /* TODO: don't call for ENOENT or ENOTDIR? */ + if (pglob->gl_errfunc) { + g_Ctoc(pathbuf, buf); + if (pglob->gl_errfunc(buf, errno) || + pglob->gl_flags & GLOB_ERR) + return (GLOB_ABEND); + } + return(0); + } + + err = 0; + + /* Search directory for matching names. */ + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + readdirfunc = pglob->gl_readdir; + else + readdirfunc = readdir; + while ((dp = (*readdirfunc)(dirp))) { + register u_char *sc; + register Char *dc; + + /* Initial DOT must be matched literally. */ + if (dp->d_name[0] == DOT && *pattern != DOT) + continue; + for (sc = (u_char *) dp->d_name, dc = pathend; + (*dc++ = *sc++) != EOS;) + continue; + if (!match(pathend, pattern, restpattern)) { + *pathend = EOS; + continue; + } + err = glob2(pathbuf, --dc, restpattern, pglob); + if (err) + break; + } + + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + (*pglob->gl_closedir)(dirp); + else + closedir(dirp); + return(err); +} + + +/* + * Extend the gl_pathv member of a glob_t structure to accomodate a new item, + * add the new item, and update gl_pathc. + * + * This assumes the BSD realloc, which only copies the block when its size + * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic + * behavior. + * + * Return 0 if new item added, error code if memory couldn't be allocated. + * + * Invariant of the glob_t structure: + * Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and + * gl_pathv points to (gl_offs + gl_pathc + 1) items. + */ +static int +globextend(path, pglob) + const Char *path; + glob_t *pglob; +{ + register char **pathv; + register int i; + u_int newsize; + char *copy; + const Char *p; + + newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs); + pathv = pglob->gl_pathv ? + realloc((char *)pglob->gl_pathv, newsize) : + malloc(newsize); + if (pathv == NULL) + return(GLOB_NOSPACE); + + if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { + /* first time around -- clear initial gl_offs items */ + pathv += pglob->gl_offs; + for (i = pglob->gl_offs; --i >= 0; ) + *--pathv = NULL; + } + pglob->gl_pathv = pathv; + + for (p = path; *p++;) + continue; + if ((copy = malloc(p - path)) != NULL) { + g_Ctoc(path, copy); + pathv[pglob->gl_offs + pglob->gl_pathc++] = copy; + } + pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; + return(copy == NULL ? GLOB_NOSPACE : 0); +} + + +/* + * pattern matching function for filenames. Each occurrence of the * + * pattern causes a recursion level. + */ +static int +match(name, pat, patend) + register Char *name, *pat, *patend; +{ + int ok, negate_range; + Char c, k; + + while (pat < patend) { + c = *pat++; + switch (c & M_MASK) { + case M_ALL: + if (pat == patend) + return(1); + do + if (match(name, pat, patend)) + return(1); + while (*name++ != EOS); + return(0); + case M_ONE: + if (*name++ == EOS) + return(0); + break; + case M_SET: + ok = 0; + if ((k = *name++) == EOS) + return(0); + if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS) + ++pat; + while (((c = *pat++) & M_MASK) != M_END) + if ((*pat & M_MASK) == M_RNG) { + if (c <= k && k <= pat[1]) + ok = 1; + pat += 2; + } else if (c == k) + ok = 1; + if (ok == negate_range) + return(0); + break; + default: + if (*name++ != c) + return(0); + break; + } + } + return(*name == EOS); +} + +/* Free allocated data belonging to a glob_t structure. */ +void +globfree(pglob) + glob_t *pglob; +{ + register int i; + register char **pp; + + if (pglob->gl_pathv != NULL) { + pp = pglob->gl_pathv + pglob->gl_offs; + for (i = pglob->gl_pathc; i--; ++pp) + if (*pp) + free(*pp); + free(pglob->gl_pathv); + } +} + +static DIR * +g_opendir(str, pglob) + register Char *str; + glob_t *pglob; +{ + char buf[MAXPATHLEN]; + + if (!*str) + strcpy(buf, "."); + else + g_Ctoc(str, buf); + + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + return((*pglob->gl_opendir)(buf)); + + return(opendir(buf)); +} + +static int +g_lstat(fn, sb, pglob) + register Char *fn; + struct stat *sb; + glob_t *pglob; +{ + char buf[MAXPATHLEN]; + + g_Ctoc(fn, buf); + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + return((*pglob->gl_lstat)(buf, sb)); + return(lstat(buf, sb)); +} + +static int +g_stat(fn, sb, pglob) + register Char *fn; + struct stat *sb; + glob_t *pglob; +{ + char buf[MAXPATHLEN]; + + g_Ctoc(fn, buf); + if (pglob->gl_flags & GLOB_ALTDIRFUNC) + return((*pglob->gl_stat)(buf, sb)); + return(stat(buf, sb)); +} + +static Char * +g_strchr(str, ch) + Char *str; + int ch; +{ + do { + if (*str == ch) + return (str); + } while (*str++); + return (NULL); +} + +#ifdef notdef +static Char * +g_strcat(dst, src) + Char *dst; + const Char* src; +{ + Char *sdst = dst; + + while (*dst++) + continue; + --dst; + while((*dst++ = *src++) != EOS) + continue; + + return (sdst); +} +#endif + +static void +g_Ctoc(str, buf) + register const Char *str; + char *buf; +{ + register char *dc; + + for (dc = buf; (*dc++ = *str++) != EOS;) + continue; +} + +#ifdef DEBUG +static void +qprintf(str, s) + const char *str; + register Char *s; +{ + register Char *p; + + (void)printf("%s:\n", str); + for (p = s; *p; p++) + (void)printf("%c", CHAR(*p)); + (void)printf("\n"); + for (p = s; *p; p++) + (void)printf("%c", *p & M_PROTECT ? '"' : ' '); + (void)printf("\n"); + for (p = s; *p; p++) + (void)printf("%c", ismeta(*p) ? '_' : ' '); + (void)printf("\n"); +} +#endif diff --git a/util.subproj/hton.c b/util.subproj/hton.c new file mode 100644 index 0000000..312d514 --- /dev/null +++ b/util.subproj/hton.c @@ -0,0 +1,52 @@ +/* + * 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) 1994 NeXT Computer, Inc. All rights reserved. + * + * File: hton.c + * Author: Matt Watson, NeXT Computer, Inc. + * + * Use the machine independent byte-swapping code for htonl-type functions. + * + * HISTORY + * 15-Dec-94 Matt Watson (Matt_Watson@NeXT.COM) + * Created. + */ + +#import + +long ntohl(long x) { + return NXSwapBigLongToHost(x); +} + +short ntohs(short x) { + return NXSwapBigShortToHost(x); +} + +long htonl(long x) { + return NXSwapHostLongToBig(x); +} + +short htons(short x) { + return NXSwapHostShortToBig(x); +} diff --git a/util.subproj/putpwpasswd.c b/util.subproj/putpwpasswd.c new file mode 100644 index 0000000..976ef2f --- /dev/null +++ b/util.subproj/putpwpasswd.c @@ -0,0 +1,137 @@ +/* + * 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@ + */ +/* + * putpwpasswd() + * Copyright (C) 1989 by NeXT, Inc. + * + * Changes a user's password entry. Works only for NetInfo. + * + * NOTE: This is not done in lookupd because we need to know + * the identity of the user and there is currently no way to + * get that information through a Mach message. Privileged users + * get privileged sockets and do not need to supply a old password + * if they are changing their password on the master server for their + * account entry. Unprivileged users get unprivileged sockets and must + * supply the old password. + */ +#include +#include +#include +#include +#include +#include + +static const ni_name NAME_USERS = "users"; +static const ni_name NAME_PASSWD = "passwd"; + +static int +changeit( + void *ni, + ni_id *id, + char *login, + char *old_passwd, + char *new_passwd + ) +{ + ni_proplist pl; + ni_index i; + ni_index prop_index; + ni_property prop; + ni_status stat; + + ni_setabort(ni, TRUE); + ni_needwrite(ni, TRUE); + ni_setuser(ni, login); + ni_setpassword(ni, old_passwd); + + if (ni_read(ni, id, &pl) != NI_OK) { + return (0); + } + prop_index = NI_INDEX_NULL; + for (i = 0; i < pl.nipl_len; i++) { + if (ni_name_match(pl.nipl_val[i].nip_name, NAME_PASSWD)) { + prop_index = i; + break; + } + } + if (prop_index == NI_INDEX_NULL) { + prop.nip_name = NAME_PASSWD; + prop.nip_val.ninl_len = 1; + prop.nip_val.ninl_val = &new_passwd; + stat = ni_createprop(ni, id, prop, NI_INDEX_NULL); + } else { + if (pl.nipl_val[i].nip_val.ninl_len == 0) { + stat = ni_createname(ni, id, prop_index, + new_passwd, 0); + } else { + stat = ni_writename(ni, id, prop_index, 0, + new_passwd); + } + } + ni_proplist_free(&pl); + return (stat == NI_OK); +} + +int +putpwpasswd( + char *login, + char *old_passwd, /* cleartext */ + char *new_passwd /* encrypted */ + ) +{ + char *dir; + void *ni; + void *newni; + ni_id id; + ni_status stat; + int changed; + + stat = ni_open(NULL, ".", &ni); + if (stat != NI_OK) { + return (0); + } + + dir = malloc(1 + strlen(NAME_USERS) + 1 + strlen(login) + 1); + sprintf(dir, "/%s/%s", NAME_USERS, login); + + changed = 0; + for (;;) { + stat = ni_pathsearch(ni, &id, dir); + if (stat == NI_OK) { + changed = changeit(ni, &id, login, old_passwd, + new_passwd); + break; + } + stat = ni_open(ni, "..", &newni); + if (stat != NI_OK) { + break; + } + ni_free(ni); + ni = newni; + } + free(dir); + ni_free(ni); + return (changed); +} + diff --git a/util.subproj/pwcache.c b/util.subproj/pwcache.c new file mode 100644 index 0000000..f0a4eec --- /dev/null +++ b/util.subproj/pwcache.c @@ -0,0 +1,111 @@ +/* + * 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) 1995 NeXT Computer, Inc. All Rights Reserved + * + * Copyright (c) 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * The NEXTSTEP Software License Agreement specifies the terms + * and conditions for redistribution. + * + * @(#)pwcache.c 8.1 (Berkeley) 6/4/93 + */ + + +#include + +#include +#include +#include +#include + +#define NCACHE 64 /* power of 2 */ +#define MASK NCACHE - 1 /* bits to store with */ + +char * +user_from_uid(uid, nouser) + uid_t uid; + int nouser; +{ + static struct ncache { + uid_t uid; + char name[UT_NAMESIZE + 1]; + } c_uid[NCACHE]; + static int pwopen; + static char nbuf[15]; /* 32 bits == 10 digits */ + register struct passwd *pw; + register struct ncache *cp; + + cp = c_uid + (uid & MASK); + if (cp->uid != uid || !*cp->name) { + if (pwopen == 0) { + setpassent(1); + pwopen = 1; + } + if ((pw = getpwuid(uid)) == NULL) { + if (nouser) + return (NULL); + (void)snprintf(nbuf, sizeof(nbuf), "%u", uid); + return (nbuf); + } + cp->uid = uid; + (void)strncpy(cp->name, pw->pw_name, UT_NAMESIZE); + cp->name[UT_NAMESIZE] = '\0'; + } + return (cp->name); +} + +char * +group_from_gid(gid, nogroup) + gid_t gid; + int nogroup; +{ + static struct ncache { + gid_t gid; + char name[UT_NAMESIZE + 1]; + } c_gid[NCACHE]; + static int gropen; + static char nbuf[15]; /* 32 bits == 10 digits */ + struct group *gr; + struct ncache *cp; + + cp = c_gid + (gid & MASK); + if (cp->gid != gid || !*cp->name) { + if (gropen == 0) { + setgroupent(1); + gropen = 1; + } + if ((gr = getgrgid(gid)) == NULL) { + if (nogroup) + return (NULL); + (void)snprintf(nbuf, sizeof(nbuf), "%u", gid); + return (nbuf); + } + cp->gid = gid; + (void)strncpy(cp->name, gr->gr_name, UT_NAMESIZE); + cp->name[UT_NAMESIZE] = '\0'; + } + return (cp->name); +} diff --git a/util.subproj/rcmd.c b/util.subproj/rcmd.c new file mode 100644 index 0000000..611b94d --- /dev/null +++ b/util.subproj/rcmd.c @@ -0,0 +1,637 @@ +/* + * 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) 1995, 1996, 1998 Theo de Raadt. All rights reserved. + * Copyright (c) 1983, 1993, 1994 + * 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. + * This product includes software developed by Theo de Raadt. + * 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. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: rcmd.c,v 1.30 1998/02/12 02:21:19 deraadt Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef u_int32_t in_addr_t; /* base type for internet address */ +typedef u_int16_t in_port_t; /* IP port type */ + +extern int bindresvport(int sd, struct sockaddr_in *sin); +extern int getdomainname(char *val, size_t len); +extern int rcmdsh(char **ahost, int rport, const char *locuser, const char *remuser, const char *cmd, char *rshprog); + +int __ivaliduser __P((FILE *, in_addr_t, const char *, const char *)); +static int __icheckhost __P((u_int32_t, const char *)); +static char *__gethostloop __P((u_int32_t)); + +int +rcmd(ahost, rport, locuser, remuser, cmd, fd2p) + char **ahost; + in_port_t rport; + const char *locuser, *remuser, *cmd; + int *fd2p; +{ + struct hostent *hp; + struct sockaddr_in sin, from; + fd_set *readsp = NULL; + int oldmask; + pid_t pid; + int s, lport, timo; + char c, *p; + + /* call rcmdsh() with specified remote shell if appropriate. */ + if ((getuid() == geteuid()) && (p = getenv("RSH"))) { + struct servent *sp = getservbyname("shell", "tcp"); + + if (sp && sp->s_port == rport) + return (rcmdsh(ahost, rport, locuser, remuser, + cmd, p)); + } + + /* use rsh(1) if non-root and remote port is shell. */ + if (geteuid()) { + struct servent *sp = getservbyname("shell", "tcp"); + + if (sp && sp->s_port == rport) + return (rcmdsh(ahost, rport, locuser, remuser, + cmd, NULL)); + } + + pid = getpid(); + hp = gethostbyname(*ahost); + if (hp == NULL) { + herror(*ahost); + return (-1); + } + *ahost = hp->h_name; + + oldmask = sigblock(sigmask(SIGURG)); + for (timo = 1, lport = IPPORT_RESERVED - 1;;) { + s = rresvport(&lport); + if (s < 0) { + if (errno == EAGAIN) + (void)fprintf(stderr, + "rcmd: socket: All ports in use\n"); + else + (void)fprintf(stderr, "rcmd: socket: %s\n", + strerror(errno)); + sigsetmask(oldmask); + return (-1); + } + fcntl(s, F_SETOWN, pid); + bzero(&sin, sizeof sin); + sin.sin_len = sizeof(struct sockaddr_in); + sin.sin_family = hp->h_addrtype; + sin.sin_port = rport; + bcopy(hp->h_addr_list[0], &sin.sin_addr, hp->h_length); + if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0) + break; + (void)close(s); + if (errno == EADDRINUSE) { + lport--; + continue; + } + if (errno == ECONNREFUSED && timo <= 16) { + (void)sleep(timo); + timo *= 2; + continue; + } + if (hp->h_addr_list[1] != NULL) { + int oerrno = errno; + + (void)fprintf(stderr, "connect to address %s: ", + inet_ntoa(sin.sin_addr)); + errno = oerrno; + perror(0); + hp->h_addr_list++; + bcopy(hp->h_addr_list[0], &sin.sin_addr, hp->h_length); + (void)fprintf(stderr, "Trying %s...\n", + inet_ntoa(sin.sin_addr)); + continue; + } + (void)fprintf(stderr, "%s: %s\n", hp->h_name, strerror(errno)); + sigsetmask(oldmask); + return (-1); + } +#if 0 + /* + * try to rresvport() to the same port. This will make rresvport() + * fail it's first bind, resulting in it choosing a random port. + */ + lport--; +#endif + if (fd2p == 0) { + write(s, "", 1); + lport = 0; + } else { + char num[8]; + int s2 = rresvport(&lport), s3; + int len = sizeof(from); + int fdssize = howmany(MAX(s, s2)+1, NFDBITS) * sizeof(fd_mask); + + if (s2 < 0) + goto bad; + readsp = (fd_set *)malloc(fdssize); + if (readsp == NULL) + goto bad; + listen(s2, 1); + (void)snprintf(num, sizeof(num), "%d", lport); + if (write(s, num, strlen(num)+1) != strlen(num)+1) { + (void)fprintf(stderr, + "rcmd: write (setting up stderr): %s\n", + strerror(errno)); + (void)close(s2); + goto bad; + } +again: + bzero(readsp, fdssize); + FD_SET(s, readsp); + FD_SET(s2, readsp); + errno = 0; + if (select(MAX(s, s2) + 1, readsp, 0, 0, 0) < 1 || + !FD_ISSET(s2, readsp)) { + if (errno != 0) + (void)fprintf(stderr, + "rcmd: select (setting up stderr): %s\n", + strerror(errno)); + else + (void)fprintf(stderr, + "select: protocol failure in circuit setup\n"); + (void)close(s2); + goto bad; + } + s3 = accept(s2, (struct sockaddr *)&from, &len); + /* + * XXX careful for ftp bounce attacks. If discovered, shut them + * down and check for the real auxiliary channel to connect. + */ + if (from.sin_family == AF_INET && from.sin_port == htons(20)) { + close(s3); + goto again; + } + (void)close(s2); + if (s3 < 0) { + (void)fprintf(stderr, + "rcmd: accept: %s\n", strerror(errno)); + lport = 0; + goto bad; + } + *fd2p = s3; + from.sin_port = ntohs(from.sin_port); + if (from.sin_family != AF_INET || + from.sin_port >= IPPORT_RESERVED || + from.sin_port < IPPORT_RESERVED / 2) { + (void)fprintf(stderr, + "socket: protocol failure in circuit setup.\n"); + goto bad2; + } + } + (void)write(s, locuser, strlen(locuser)+1); + (void)write(s, remuser, strlen(remuser)+1); + (void)write(s, cmd, strlen(cmd)+1); + if (read(s, &c, 1) != 1) { + (void)fprintf(stderr, + "rcmd: %s: %s\n", *ahost, strerror(errno)); + goto bad2; + } + if (c != 0) { + while (read(s, &c, 1) == 1) { + (void)write(STDERR_FILENO, &c, 1); + if (c == '\n') + break; + } + goto bad2; + } + sigsetmask(oldmask); + free(readsp); + return (s); +bad2: + if (lport) + (void)close(*fd2p); +bad: + if (readsp) + free(readsp); + (void)close(s); + sigsetmask(oldmask); + return (-1); +} + +int +rresvport(alport) + int *alport; +{ + struct sockaddr_in sin; + int s; + + bzero(&sin, sizeof sin); + sin.sin_len = sizeof(struct sockaddr_in); + sin.sin_family = AF_INET; + sin.sin_addr.s_addr = INADDR_ANY; + s = socket(AF_INET, SOCK_STREAM, 0); + if (s < 0) + return (-1); + sin.sin_port = htons((in_port_t)*alport); + if (*alport < IPPORT_RESERVED - 1) { + if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0) + return (s); + if (errno != EADDRINUSE) { + (void)close(s); + return (-1); + } + } + sin.sin_port = 0; + if (bindresvport(s, &sin) == -1) { + (void)close(s); + return (-1); + } + *alport = (int)ntohs(sin.sin_port); + return (s); +} + +int __check_rhosts_file = 1; +char *__rcmd_errstr; + +int +ruserok(rhost, superuser, ruser, luser) + const char *rhost, *ruser, *luser; + int superuser; +{ + struct hostent *hp; + char **ap; + int i; +#define MAXADDRS 35 + u_int32_t addrs[MAXADDRS + 1]; + + if ((hp = gethostbyname(rhost)) == NULL) + return (-1); + for (i = 0, ap = hp->h_addr_list; *ap && i < MAXADDRS; ++ap, ++i) + bcopy(*ap, &addrs[i], sizeof(addrs[i])); + addrs[i] = 0; + + for (i = 0; i < MAXADDRS && addrs[i]; i++) + if (iruserok((in_addr_t)addrs[i], superuser, ruser, luser) == 0) + return (0); + return (-1); +} + +/* + * New .rhosts strategy: We are passed an ip address. We spin through + * hosts.equiv and .rhosts looking for a match. When the .rhosts only + * has ip addresses, we don't have to trust a nameserver. When it + * contains hostnames, we spin through the list of addresses the nameserver + * gives us and look for a match. + * + * Returns 0 if ok, -1 if not ok. + */ +int +iruserok(raddr, superuser, ruser, luser) + unsigned long raddr; + int superuser; + const char *ruser, *luser; +{ + register char *cp; + struct stat sbuf; + struct passwd *pwd; + FILE *hostf; + uid_t uid; + int first; + char pbuf[MAXPATHLEN]; + + first = 1; + hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "r"); +again: + if (hostf) { + if (__ivaliduser(hostf, raddr, luser, ruser) == 0) { + (void)fclose(hostf); + return (0); + } + (void)fclose(hostf); + } + if (first == 1 && (__check_rhosts_file || superuser)) { + first = 0; + if ((pwd = getpwnam(luser)) == NULL) + return (-1); + (void)strcpy(pbuf, pwd->pw_dir); + (void)strcat(pbuf, "/.rhosts"); + + /* + * Change effective uid while opening .rhosts. If root and + * reading an NFS mounted file system, can't read files that + * are protected read/write owner only. + */ + uid = geteuid(); + (void)seteuid(pwd->pw_uid); + hostf = fopen(pbuf, "r"); + (void)seteuid(uid); + + if (hostf == NULL) + return (-1); + /* + * If not a regular file, or is owned by someone other than + * user or root or if writeable by anyone but the owner, quit. + */ + cp = NULL; + if (lstat(pbuf, &sbuf) < 0) + cp = ".rhosts lstat failed"; + else if (!S_ISREG(sbuf.st_mode)) + cp = ".rhosts not regular file"; + else if (fstat(fileno(hostf), &sbuf) < 0) + cp = ".rhosts fstat failed"; + else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid) + cp = "bad .rhosts owner"; + else if (sbuf.st_mode & (S_IWGRP|S_IWOTH)) + cp = ".rhosts writeable by other than owner"; + /* If there were any problems, quit. */ + if (cp) { + __rcmd_errstr = cp; + (void)fclose(hostf); + return (-1); + } + goto again; + } + return (-1); +} + +/* + * XXX + * Don't make static, used by lpd(8). + * + * Returns 0 if ok, -1 if not ok. + */ +int +__ivaliduser(hostf, raddrl, luser, ruser) + FILE *hostf; + in_addr_t raddrl; + const char *luser, *ruser; +{ + register char *user, *p; + char *buf; + const char *auser, *ahost; + int hostok, userok; + char *rhost = (char *)-1; + char domain[MAXHOSTNAMELEN]; + u_int32_t raddr = (u_int32_t)raddrl; + size_t buflen; + + getdomainname(domain, sizeof(domain)); + + while ((buf = fgetln(hostf, &buflen))) { + p = buf; + if (*p == '#') + continue; + while (*p != '\n' && *p != ' ' && *p != '\t' && p < buf + buflen) { + if (!isprint(*p)) + goto bail; + *p = isupper(*p) ? tolower(*p) : *p; + p++; + } + if (p >= buf + buflen) + continue; + if (*p == ' ' || *p == '\t') { + *p++ = '\0'; + while (*p == ' ' || *p == '\t' && p < buf + buflen) + p++; + if (p >= buf + buflen) + continue; + user = p; + while (*p != '\n' && *p != ' ' && + *p != '\t' && p < buf + buflen) { + if (!isprint(*p)) + goto bail; + p++; + } + } else + user = p; + *p = '\0'; + + if (p == buf) + continue; + + auser = *user ? user : luser; + ahost = buf; + + if (strlen(ahost) >= MAXHOSTNAMELEN) + continue; + + /* + * innetgr() must lookup a hostname (we do not attempt + * to change the semantics so that netgroups may have + * #.#.#.# addresses in the list.) + */ + if (ahost[0] == '+') + switch (ahost[1]) { + case '\0': + hostok = 1; + break; + case '@': + if (rhost == (char *)-1) + rhost = __gethostloop(raddr); + hostok = 0; + if (rhost) + hostok = innetgr(&ahost[2], rhost, + NULL, domain); + break; + default: + hostok = __icheckhost(raddr, &ahost[1]); + break; + } + else if (ahost[0] == '-') + switch (ahost[1]) { + case '\0': + hostok = -1; + break; + case '@': + if (rhost == (char *)-1) + rhost = __gethostloop(raddr); + hostok = 0; + if (rhost) + hostok = -innetgr(&ahost[2], rhost, + NULL, domain); + break; + default: + hostok = -__icheckhost(raddr, &ahost[1]); + break; + } + else + hostok = __icheckhost(raddr, ahost); + + + if (auser[0] == '+') + switch (auser[1]) { + case '\0': + userok = 1; + break; + case '@': + userok = innetgr(&auser[2], NULL, ruser, + domain); + break; + default: + userok = strcmp(ruser, &auser[1]) ? 0 : 1; + break; + } + else if (auser[0] == '-') + switch (auser[1]) { + case '\0': + userok = -1; + break; + case '@': + userok = -innetgr(&auser[2], NULL, ruser, + domain); + break; + default: + userok = strcmp(ruser, &auser[1]) ? 0 : -1; + break; + } + else + userok = strcmp(ruser, auser) ? 0 : 1; + + /* Check if one component did not match */ + if (hostok == 0 || userok == 0) + continue; + + /* Check if we got a forbidden pair */ + if (userok <= -1 || hostok <= -1) + return (-1); + + /* Check if we got a valid pair */ + if (hostok >= 1 && userok >= 1) + return (0); + } +bail: + return (-1); +} + +/* + * Returns "true" if match, 0 if no match. If we do not find any + * semblance of an A->PTR->A loop, allow a simple #.#.#.# match to work. + */ +static int +__icheckhost(raddr, lhost) + u_int32_t raddr; + const char *lhost; +{ + register struct hostent *hp; + register char **pp; + struct in_addr in; + + hp = gethostbyname(lhost); + if (hp != NULL) { + /* Spin through ip addresses. */ + for (pp = hp->h_addr_list; *pp; ++pp) + if (!bcmp(&raddr, *pp, sizeof(raddr))) + return (1); + } + + in.s_addr = raddr; + if (strcmp(lhost, inet_ntoa(in)) == 0) + return (1); + return (0); +} + +/* + * Return the hostname associated with the supplied address. + * Do a reverse lookup as well for security. If a loop cannot + * be found, pack the result of inet_ntoa() into the string. + */ +static char * +__gethostloop(raddr) + u_int32_t raddr; +{ + static char remotehost[MAXHOSTNAMELEN]; + struct hostent *hp; + struct in_addr in; + + hp = gethostbyaddr((char *) &raddr, sizeof(raddr), AF_INET); + if (hp == NULL) + return (NULL); + + /* + * Look up the name and check that the supplied + * address is in the list + */ + strncpy(remotehost, hp->h_name, sizeof(remotehost) - 1); + remotehost[sizeof(remotehost) - 1] = '\0'; + hp = gethostbyname(remotehost); + if (hp == NULL) + return (NULL); + + for (; hp->h_addr_list[0] != NULL; hp->h_addr_list++) + if (!bcmp(hp->h_addr_list[0], (caddr_t)&raddr, sizeof(raddr))) + return (remotehost); + + /* + * either the DNS adminstrator has made a configuration + * mistake, or someone has attempted to spoof us + */ + in.s_addr = raddr; + syslog(LOG_NOTICE, "rcmd: address %s not listed for host %s", + inet_ntoa(in), hp->h_name); + return (NULL); +} diff --git a/util.subproj/rcmdsh.c b/util.subproj/rcmdsh.c new file mode 100644 index 0000000..49f9eee --- /dev/null +++ b/util.subproj/rcmdsh.c @@ -0,0 +1,146 @@ +/* + * 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@ + */ +/* $OpenBSD: rcmdsh.c,v 1.4 1997/07/23 16:59:37 millert Exp $ */ + +/* + * This is an rcmd() replacement originally by + * Chris Siebenmann . + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: rcmdsh.c,v 1.4 1997/07/23 16:59:37 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/* + * This is a replacement rcmd() function that uses the rsh(1) + * program in place of a direct rcmd(3) function call so as to + * avoid having to be root. Note that rport is ignored. + */ +/* ARGSUSED */ +int +rcmdsh(ahost, rport, locuser, remuser, cmd, rshprog) + char **ahost; + int rport; + const char *locuser, *remuser, *cmd; + char *rshprog; +{ + struct hostent *hp; + int cpid, sp[2]; + char *p; + struct passwd *pw; + + /* What rsh/shell to use. */ + if (rshprog == NULL) + rshprog = _PATH_RSH; + + /* locuser must exist on this host. */ + if ((pw = getpwnam(locuser)) == NULL) { + (void) fprintf(stderr, "rcmdsh: unknown user: %s\n", locuser); + return(-1); + } + + /* Validate remote hostname. */ + if (strcmp(*ahost, "localhost") != 0) { + if ((hp = gethostbyname(*ahost)) == NULL) { + herror(*ahost); + return(-1); + } + *ahost = hp->h_name; + } + + /* Get a socketpair we'll use for stdin and stdout. */ + if (socketpair(AF_UNIX, SOCK_STREAM, 0, sp) < 0) { + perror("rcmdsh: socketpair"); + return(-1); + } + + cpid = fork(); + if (cpid < 0) { + perror("rcmdsh: fork failed"); + return(-1); + } else if (cpid == 0) { + /* + * Child. We use sp[1] to be stdin/stdout, and close sp[0]. + */ + (void) close(sp[0]); + if (dup2(sp[1], 0) < 0 || dup2(0, 1) < 0) { + perror("rcmdsh: dup2 failed"); + _exit(255); + } + /* Fork again to lose parent. */ + cpid = fork(); + if (cpid < 0) { + perror("rcmdsh: fork to lose parent failed"); + _exit(255); + } + if (cpid > 0) + _exit(0); + + /* In grandchild here. Become local user for rshprog. */ + if (setuid(pw->pw_uid)) { + (void) fprintf(stderr, "rcmdsh: setuid(%u): %s\n", + pw->pw_uid, strerror(errno)); + _exit(255); + } + + /* + * If remote host is "localhost" and local and remote user + * are the same, avoid running remote shell for efficiency. + */ + if (!strcmp(*ahost, "localhost") && !strcmp(locuser, remuser)) { + if (pw->pw_shell[0] == '\0') + rshprog = _PATH_BSHELL; + else + rshprog = pw->pw_shell; + p = strrchr(rshprog, '/'); + execlp(rshprog, p ? p+1 : rshprog, "-c", cmd, + (char *) NULL); + } else { + p = strrchr(rshprog, '/'); + execlp(rshprog, p ? p+1 : rshprog, *ahost, "-l", + remuser, cmd, (char *) NULL); + } + (void) fprintf(stderr, "rcmdsh: execlp %s failed: %s\n", + rshprog, strerror(errno)); + _exit(255); + } else { + /* Parent. close sp[1], return sp[0]. */ + (void) close(sp[1]); + /* Reap child. */ + (void) wait(NULL); + return(sp[0]); + } + /* NOTREACHED */ +} -- 2.7.4