]> git.saurik.com Git - apple/libinfo.git/commitdiff
Libinfo-78.tar.gz mac-os-x-100 v78
authorApple <opensource@apple.com>
Wed, 11 Apr 2001 00:34:00 +0000 (00:34 +0000)
committerApple <opensource@apple.com>
Wed, 11 Apr 2001 00:34:00 +0000 (00:34 +0000)
189 files changed:
Makefile [new file with mode: 0644]
Makefile.postamble [new file with mode: 0644]
Makefile.preamble [new file with mode: 0644]
PB.project [new file with mode: 0644]
dns.subproj/Makefile [new file with mode: 0644]
dns.subproj/Makefile.postamble [new file with mode: 0644]
dns.subproj/Makefile.preamble [new file with mode: 0644]
dns.subproj/PB.project [new file with mode: 0644]
dns.subproj/gethnamaddr.c [new file with mode: 0644]
dns.subproj/getnetbyaddr.c [new file with mode: 0644]
dns.subproj/getnetbyname.c [new file with mode: 0644]
dns.subproj/getnetent.c [new file with mode: 0644]
dns.subproj/getnetnamadr.c [new file with mode: 0644]
dns.subproj/herror.c [new file with mode: 0644]
dns.subproj/inet.h [new file with mode: 0644]
dns.subproj/nameser.h [new file with mode: 0644]
dns.subproj/options.h [new file with mode: 0644]
dns.subproj/portability.h [new file with mode: 0644]
dns.subproj/res_comp.c [new file with mode: 0644]
dns.subproj/res_data.c [new file with mode: 0644]
dns.subproj/res_debug.c [new file with mode: 0644]
dns.subproj/res_init.c [new file with mode: 0644]
dns.subproj/res_mkquery.c [new file with mode: 0644]
dns.subproj/res_query.c [new file with mode: 0644]
dns.subproj/res_send.c [new file with mode: 0644]
dns.subproj/resolv.h [new file with mode: 0644]
dns.subproj/sethostent.c [new file with mode: 0644]
gen.subproj/Makefile [new file with mode: 0644]
gen.subproj/Makefile.preamble [new file with mode: 0644]
gen.subproj/PB.project [new file with mode: 0644]
gen.subproj/aliasdb.c [new file with mode: 0644]
gen.subproj/ether_addr.c [new file with mode: 0644]
gen.subproj/fstab.c [new file with mode: 0644]
gen.subproj/getaddrinfo.c [new file with mode: 0644]
gen.subproj/getgrent.c [new file with mode: 0644]
gen.subproj/getproto.c [new file with mode: 0644]
gen.subproj/getprotoent.c [new file with mode: 0644]
gen.subproj/getprotoname.c [new file with mode: 0644]
gen.subproj/getpwent.c [new file with mode: 0644]
gen.subproj/getservbyname.c [new file with mode: 0644]
gen.subproj/getservbyport.c [new file with mode: 0644]
gen.subproj/getservent.c [new file with mode: 0644]
gen.subproj/initgroups.c [new file with mode: 0644]
gen.subproj/printerdb.c [new file with mode: 0644]
lookup.subproj/Makefile [new file with mode: 0644]
lookup.subproj/Makefile.postamble [new file with mode: 0644]
lookup.subproj/Makefile.preamble [new file with mode: 0644]
lookup.subproj/PB.project [new file with mode: 0644]
lookup.subproj/_lu_types.x [new file with mode: 0644]
lookup.subproj/aliasdb.h [new file with mode: 0644]
lookup.subproj/bootparams.h [new file with mode: 0644]
lookup.subproj/lookup.defs [new file with mode: 0644]
lookup.subproj/lookup_types.h [new file with mode: 0644]
lookup.subproj/lu_alias.c [new file with mode: 0644]
lookup.subproj/lu_bootp.c [new file with mode: 0644]
lookup.subproj/lu_bootparam.c [new file with mode: 0644]
lookup.subproj/lu_fstab.c [new file with mode: 0644]
lookup.subproj/lu_group.c [new file with mode: 0644]
lookup.subproj/lu_host.c [new file with mode: 0644]
lookup.subproj/lu_netgroup.c [new file with mode: 0644]
lookup.subproj/lu_network.c [new file with mode: 0644]
lookup.subproj/lu_overrides.h [new file with mode: 0644]
lookup.subproj/lu_printer.c [new file with mode: 0644]
lookup.subproj/lu_protocol.c [new file with mode: 0644]
lookup.subproj/lu_rpc.c [new file with mode: 0644]
lookup.subproj/lu_service.c [new file with mode: 0644]
lookup.subproj/lu_user.c [new file with mode: 0644]
lookup.subproj/lu_utils.c [new file with mode: 0644]
lookup.subproj/lu_utils.h [new file with mode: 0644]
lookup.subproj/netgr.h [new file with mode: 0644]
lookup.subproj/printerdb.h [new file with mode: 0644]
netinfo.subproj/Makefile [new file with mode: 0644]
netinfo.subproj/Makefile.postamble [new file with mode: 0644]
netinfo.subproj/Makefile.preamble [new file with mode: 0644]
netinfo.subproj/PB.project [new file with mode: 0644]
netinfo.subproj/clib.h [new file with mode: 0644]
netinfo.subproj/mm.h [new file with mode: 0644]
netinfo.subproj/multi_call.c [new file with mode: 0644]
netinfo.subproj/ni.h [new file with mode: 0644]
netinfo.subproj/ni_error.c [new file with mode: 0644]
netinfo.subproj/ni_glue.c [new file with mode: 0644]
netinfo.subproj/ni_prot.x [new file with mode: 0644]
netinfo.subproj/ni_pwdomain.c [new file with mode: 0644]
netinfo.subproj/ni_useful.c [new file with mode: 0644]
netinfo.subproj/ni_util.c [new file with mode: 0644]
netinfo.subproj/ni_util.h [new file with mode: 0644]
netinfo.subproj/nibind_prot.x [new file with mode: 0644]
nis.subproj/Makefile [new file with mode: 0644]
nis.subproj/Makefile.preamble [new file with mode: 0644]
nis.subproj/PB.project [new file with mode: 0644]
nis.subproj/getdomainname.c [new file with mode: 0644]
nis.subproj/getnetgrent.c [new file with mode: 0644]
nis.subproj/innetgr.c [new file with mode: 0644]
nis.subproj/setdomainname.c [new file with mode: 0644]
nis.subproj/xdr_domainname.c [new file with mode: 0644]
nis.subproj/xdr_keydat.c [new file with mode: 0644]
nis.subproj/xdr_mapname.c [new file with mode: 0644]
nis.subproj/xdr_peername.c [new file with mode: 0644]
nis.subproj/xdr_valdat.c [new file with mode: 0644]
nis.subproj/xdr_ypbind_binding.c [new file with mode: 0644]
nis.subproj/xdr_ypbind_resp.c [new file with mode: 0644]
nis.subproj/xdr_ypbind_resptype.c [new file with mode: 0644]
nis.subproj/xdr_ypbind_setdom.c [new file with mode: 0644]
nis.subproj/xdr_ypmaplist.c [new file with mode: 0644]
nis.subproj/xdr_ypreq_key.c [new file with mode: 0644]
nis.subproj/xdr_ypreq_nokey.c [new file with mode: 0644]
nis.subproj/xdr_ypresp_all.c [new file with mode: 0644]
nis.subproj/xdr_ypresp_key_val.c [new file with mode: 0644]
nis.subproj/xdr_ypresp_maplist.c [new file with mode: 0644]
nis.subproj/xdr_ypresp_master.c [new file with mode: 0644]
nis.subproj/xdr_ypresp_order.c [new file with mode: 0644]
nis.subproj/xdr_ypresp_val.c [new file with mode: 0644]
nis.subproj/xdr_ypstat.c [new file with mode: 0644]
nis.subproj/yp_all.c [new file with mode: 0644]
nis.subproj/yp_bind.c [new file with mode: 0644]
nis.subproj/yp_first.c [new file with mode: 0644]
nis.subproj/yp_get_default_domain.c [new file with mode: 0644]
nis.subproj/yp_maplist.c [new file with mode: 0644]
nis.subproj/yp_master.c [new file with mode: 0644]
nis.subproj/yp_order.c [new file with mode: 0644]
nis.subproj/yp_prot.h [new file with mode: 0644]
nis.subproj/ypclnt.h [new file with mode: 0644]
nis.subproj/yperr_string.c [new file with mode: 0644]
nis.subproj/ypinternal.h [new file with mode: 0644]
nis.subproj/ypmatch_cache.c [new file with mode: 0644]
nis.subproj/yppasswdd_xdr.c [new file with mode: 0644]
nis.subproj/ypprot_err.c [new file with mode: 0644]
rpc.subproj/Makefile [new file with mode: 0644]
rpc.subproj/Makefile.preamble [new file with mode: 0644]
rpc.subproj/PB.project [new file with mode: 0644]
rpc.subproj/auth.h [new file with mode: 0644]
rpc.subproj/auth_none.c [new file with mode: 0644]
rpc.subproj/auth_unix.c [new file with mode: 0644]
rpc.subproj/auth_unix.h [new file with mode: 0644]
rpc.subproj/authunix_prot.c [new file with mode: 0644]
rpc.subproj/bindresvport.c [new file with mode: 0644]
rpc.subproj/clnt.h [new file with mode: 0644]
rpc.subproj/clnt_generic.c [new file with mode: 0644]
rpc.subproj/clnt_perror.c [new file with mode: 0644]
rpc.subproj/clnt_raw.c [new file with mode: 0644]
rpc.subproj/clnt_simple.c [new file with mode: 0644]
rpc.subproj/clnt_tcp.c [new file with mode: 0644]
rpc.subproj/clnt_udp.c [new file with mode: 0644]
rpc.subproj/get_myaddress.c [new file with mode: 0644]
rpc.subproj/getrpcent.c [new file with mode: 0644]
rpc.subproj/getrpcport.c [new file with mode: 0644]
rpc.subproj/pmap_clnt.c [new file with mode: 0644]
rpc.subproj/pmap_clnt.h [new file with mode: 0644]
rpc.subproj/pmap_getmaps.c [new file with mode: 0644]
rpc.subproj/pmap_getport.c [new file with mode: 0644]
rpc.subproj/pmap_prot.c [new file with mode: 0644]
rpc.subproj/pmap_prot.h [new file with mode: 0644]
rpc.subproj/pmap_prot2.c [new file with mode: 0644]
rpc.subproj/pmap_rmt.c [new file with mode: 0644]
rpc.subproj/pmap_rmt.h [new file with mode: 0644]
rpc.subproj/rpc.h [new file with mode: 0644]
rpc.subproj/rpc_callmsg.c [new file with mode: 0644]
rpc.subproj/rpc_commondata.c [new file with mode: 0644]
rpc.subproj/rpc_dtablesize.c [new file with mode: 0644]
rpc.subproj/rpc_msg.h [new file with mode: 0644]
rpc.subproj/rpc_prot.c [new file with mode: 0644]
rpc.subproj/svc.c [new file with mode: 0644]
rpc.subproj/svc.h [new file with mode: 0644]
rpc.subproj/svc_auth.c [new file with mode: 0644]
rpc.subproj/svc_auth.h [new file with mode: 0644]
rpc.subproj/svc_auth_unix.c [new file with mode: 0644]
rpc.subproj/svc_raw.c [new file with mode: 0644]
rpc.subproj/svc_run.c [new file with mode: 0644]
rpc.subproj/svc_simple.c [new file with mode: 0644]
rpc.subproj/svc_tcp.c [new file with mode: 0644]
rpc.subproj/svc_udp.c [new file with mode: 0644]
rpc.subproj/types.h [new file with mode: 0644]
rpc.subproj/xdr.c [new file with mode: 0644]
rpc.subproj/xdr.h [new file with mode: 0644]
rpc.subproj/xdr_array.c [new file with mode: 0644]
rpc.subproj/xdr_float.c [new file with mode: 0644]
rpc.subproj/xdr_mem.c [new file with mode: 0644]
rpc.subproj/xdr_rec.c [new file with mode: 0644]
rpc.subproj/xdr_reference.c [new file with mode: 0644]
rpc.subproj/xdr_stdio.c [new file with mode: 0644]
util.subproj/Makefile [new file with mode: 0644]
util.subproj/PB.project [new file with mode: 0644]
util.subproj/getgrouplist.c [new file with mode: 0644]
util.subproj/glob.c [new file with mode: 0644]
util.subproj/hton.c [new file with mode: 0644]
util.subproj/putpwpasswd.c [new file with mode: 0644]
util.subproj/pwcache.c [new file with mode: 0644]
util.subproj/rcmd.c [new file with mode: 0644]
util.subproj/rcmdsh.c [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
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 (file)
index 0000000..0e9365d
--- /dev/null
@@ -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 (file)
index 0000000..4e19fe6
--- /dev/null
@@ -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 (file)
index 0000000..5ebc657
--- /dev/null
@@ -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 (file)
index 0000000..7097677
--- /dev/null
@@ -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 (file)
index 0000000..e0bdfec
--- /dev/null
@@ -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 (file)
index 0000000..89f0837
--- /dev/null
@@ -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 (file)
index 0000000..32107f8
--- /dev/null
@@ -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 (file)
index 0000000..1d6aba5
--- /dev/null
@@ -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 <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <ctype.h>
+#include <errno.h>
+#include <syslog.h>
+
+#ifndef LOG_AUTH
+# define LOG_AUTH 0
+#endif
+
+#define MULTI_PTRS_ARE_ALIASES 1       /* XXX - experimental */
+
+#if defined(BSD) && (BSD >= 199103)
+# include <string.h>
+#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 (file)
index 0000000..415aa1b
--- /dev/null
@@ -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 <netdb.h>
+
+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 (file)
index 0000000..fe5ac4d
--- /dev/null
@@ -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 <netdb.h>
+#include <string.h>
+
+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 (file)
index 0000000..00f9d6e
--- /dev/null
@@ -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 <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <resolv.h>
+#include <netdb.h>
+#include <string.h>
+
+#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 (file)
index 0000000..f3d3265
--- /dev/null
@@ -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 <sys/param.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <ctype.h>
+#include <errno.h>
+#include <string.h>
+
+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 (file)
index 0000000..dcfe656
--- /dev/null
@@ -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 <sys/param.h>
+#include <sys/uio.h>
+#include <netdb.h>
+#if defined(BSD) && (BSD >= 199103)
+# include <unistd.h>
+# include <string.h>
+#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 (file)
index 0000000..ae203b2
--- /dev/null
@@ -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 <sys/param.h>
+#if (!defined(BSD)) || (BSD < 199306)
+# include <sys/bitypes.h>
+#else
+# include <sys/types.h>
+#endif
+#include <sys/cdefs.h>
+
+__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 (file)
index 0000000..b3874e4
--- /dev/null
@@ -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 <sys/param.h>
+#if (!defined(BSD)) || (BSD < 199306)
+# include <sys/bitypes.h>
+#else
+# include <sys/types.h>
+#endif
+#include <sys/cdefs.h>
+
+#ifdef _AUX_SOURCE
+#include <sys/types.h>                 /* 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 <machine/endian.h>
+#else
+#ifdef linux
+# include <endian.h>
+#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 (file)
index 0000000..6a79326
--- /dev/null
@@ -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 (file)
index 0000000..55ed578
--- /dev/null
@@ -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 <string.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#ifndef TIME_H_INCLUDED
+# include <sys/time.h>
+# 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 <sys/bsdtypes.h>
+# include <sys/sioctl.h>
+# include <sys/stream.h>
+# include <net/errno.h>
+#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 <netinet/in_systm.h>
+# 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 <stdlib.h>
+# include <unistd.h>
+# include <limits.h>
+
+#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 <sys/resource.h>
+#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 (file)
index 0000000..7c07818
--- /dev/null
@@ -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 <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <resolv.h>
+#include <ctype.h>
+
+#if defined(BSD) && (BSD >= 199103)
+# include <unistd.h>
+# include <string.h>
+#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 (file)
index 0000000..93d648d
--- /dev/null
@@ -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 <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+
+/* 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 (file)
index 0000000..519104a
--- /dev/null
@@ -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 <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <netdb.h>
+#include <resolv.h>
+#if defined(BSD) && (BSD >= 199103)
+# include <string.h>
+#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 (file)
index 0000000..5eb64dd
--- /dev/null
@@ -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 <sys/param.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <ctype.h>
+#include <resolv.h>
+#if defined(BSD) && (BSD >= 199103)
+# include <unistd.h>
+# include <stdlib.h>
+# include <string.h>
+#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 <netinfo/ni.h>
+#  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 (file)
index 0000000..deda02f
--- /dev/null
@@ -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 <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <netdb.h>
+#include <resolv.h>
+#if defined(BSD) && (BSD >= 199103)
+# include <string.h>
+#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 (file)
index 0000000..85b705a
--- /dev/null
@@ -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 <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+#include <stdio.h>
+#include <netdb.h>
+#include <resolv.h>
+#include <ctype.h>
+#include <errno.h>
+#if defined(BSD) && (BSD >= 199306)
+# include <stdlib.h>
+# include <string.h>
+#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:"<Nil>", 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 (file)
index 0000000..b1c3a08
--- /dev/null
@@ -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 <sys/param.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+
+#include <stdio.h>
+#include <netdb.h>
+#include <errno.h>
+#include <resolv.h>
+#if defined(BSD) && (BSD >= 199306)
+# include <stdlib.h>
+# include <string.h>
+# include <unistd.h>
+#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 (file)
index 0000000..12302ac
--- /dev/null
@@ -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 <sys/param.h>
+#if (!defined(BSD)) || (BSD < 199306)
+# include <sys/bitypes.h>
+#else
+# include <sys/types.h>
+#endif
+#include <sys/cdefs.h>
+#include <stdio.h>
+
+/*
+ * 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 (file)
index 0000000..3070283
--- /dev/null
@@ -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 <sys/param.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <netdb.h>
+#include <resolv.h>
+
+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 (file)
index 0000000..3e59457
--- /dev/null
@@ -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 (file)
index 0000000..8bcebdc
--- /dev/null
@@ -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 (file)
index 0000000..5e70c18
--- /dev/null
@@ -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 (file)
index 0000000..ad0bd4f
--- /dev/null
@@ -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 <aliasdb.h>
+#include <string.h>
+
+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 (file)
index 0000000..d3d1aea
--- /dev/null
@@ -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 <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/if_ether.h>
+
+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, &currente, host) == 0) &&
+                       (bcmp(e, &currente, 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 (file)
index 0000000..09a2f7b
--- /dev/null
@@ -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 <errno.h>
+#include <fstab.h>
+#include <paths.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/param.h>
+#include <sys/stat.h>
+#include <sys/mount.h>
+
+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 (file)
index 0000000..bce133f
--- /dev/null
@@ -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 <netdb.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <mach/mach.h>
+#include <servers/bootstrap.h>
+#include <nameser.h>
+#include <resolv.h>
+
+#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 (file)
index 0000000..e9552d4
--- /dev/null
@@ -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 <sys/types.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <grp.h>
+
+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 (file)
index 0000000..0c3634e
--- /dev/null
@@ -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 <netdb.h>
+
+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 (file)
index 0000000..0320109
--- /dev/null
@@ -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 <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#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 (file)
index 0000000..49551e1
--- /dev/null
@@ -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 <netdb.h>
+#include <string.h>
+
+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 (file)
index 0000000..a9f4798
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pwd.h>
+
+#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 (file)
index 0000000..45766e3
--- /dev/null
@@ -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 <netdb.h>
+#include <string.h>
+
+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 (file)
index 0000000..af3eeb0
--- /dev/null
@@ -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 <netdb.h>
+#include <string.h>
+
+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 (file)
index 0000000..16d5cd9
--- /dev/null
@@ -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 <sys/types.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#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 (file)
index 0000000..455c363
--- /dev/null
@@ -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 <sys/param.h>
+
+#include <stdio.h>
+
+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 (file)
index 0000000..2d77bdf
--- /dev/null
@@ -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 <stdlib.h>
+#include <stdio.h>
+#include <printerdb.h>
+
+#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 (file)
index 0000000..2122bc1
--- /dev/null
@@ -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 (file)
index 0000000..cf76087
--- /dev/null
@@ -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 (file)
index 0000000..9a094c2
--- /dev/null
@@ -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 (file)
index 0000000..8270f85
--- /dev/null
@@ -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 (file)
index 0000000..0fa320e
--- /dev/null
@@ -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 (file)
index 0000000..7961135
--- /dev/null
@@ -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 <sys/cdefs.h>
+
+__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 (file)
index 0000000..377298d
--- /dev/null
@@ -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 <sys/param.h>
+#include <sys/cdefs.h>
+
+/*
+ * 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 (file)
index 0000000..167d609
--- /dev/null
@@ -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 <netinfo/lookup_types.h>;
+
+
+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 (file)
index 0000000..7d8fcd2
--- /dev/null
@@ -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 (file)
index 0000000..f215067
--- /dev/null
@@ -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 <stdlib.h>
+#include <mach/mach.h>
+#include <stdio.h>
+#include <string.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <aliasdb.h>
+
+#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 (file)
index 0000000..ca85dbe
--- /dev/null
@@ -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 <mach/mach.h>
+#include <stdio.h>
+#include <string.h>
+#include "lookup.h"
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include "_lu_types.h"
+#include "lu_utils.h"
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <net/if.h>
+#include <netinet/if_ether.h>
+
+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 (file)
index 0000000..9386e98
--- /dev/null
@@ -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 <stdlib.h>
+#include <mach/mach.h>
+#include <stdio.h>
+#include <string.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <bootparams.h>
+
+#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 (file)
index 0000000..b206a8a
--- /dev/null
@@ -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 <stdlib.h>
+#include <mach/mach.h>
+#include <stdio.h>
+#include <string.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <fstab.h>
+
+#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 (file)
index 0000000..5022f9c
--- /dev/null
@@ -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 <stdlib.h>
+#include <mach/mach.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <grp.h>
+#include <netinet/in.h>
+#include <sys/param.h>
+#include <unistd.h>
+
+#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 (file)
index 0000000..ca56659
--- /dev/null
@@ -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 <stdlib.h>
+#include <mach/mach.h>
+#include <stdio.h>
+#include <string.h>
+#include "lookup.h"
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include "_lu_types.h"
+#include <netdb.h>
+#include "lu_utils.h"
+#include <sys/socket.h>
+#import <netinet/in.h>
+
+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 (file)
index 0000000..8e52272
--- /dev/null
@@ -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 <netgr.h>
+#include <mach/mach.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#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 (file)
index 0000000..78533f9
--- /dev/null
@@ -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 <stdlib.h>
+#include <mach/mach.h>
+#include <stdio.h>
+#include <string.h>
+#include "lookup.h"
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include "_lu_types.h"
+#include <netdb.h>
+#include "lu_utils.h"
+#include <sys/socket.h>
+#import <netinet/in.h>
+
+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 (file)
index 0000000..c7134b2
--- /dev/null
@@ -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 <sys/cdefs.h>
+#include <sys/types.h>
+
+__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 (file)
index 0000000..0290e10
--- /dev/null
@@ -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 <stdlib.h>
+#include <mach/mach.h>
+#include <stdio.h>
+#include <string.h>
+#include "lookup.h"
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#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 (file)
index 0000000..f3c0e4b
--- /dev/null
@@ -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 <stdlib.h>
+#include <mach/mach.h>
+#include <stdio.h>
+#include <string.h>
+#include "lookup.h"
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include "_lu_types.h"
+#include <netdb.h>
+#include "lu_utils.h"
+#import <netinet/in.h>
+
+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 (file)
index 0000000..3bd9460
--- /dev/null
@@ -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 <rpc/rpc.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <mach/mach.h>
+#include <stdio.h>
+#include <string.h>
+#include <netinet/in.h>
+
+#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 (file)
index 0000000..2fd3e2a
--- /dev/null
@@ -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 <stdlib.h>
+#include <mach/mach.h>
+#include <stdio.h>
+#include <string.h>
+#include "lookup.h"
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include "_lu_types.h"
+#include <netdb.h>
+#include "lu_utils.h"
+#import <netinet/in.h>
+
+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 (file)
index 0000000..ecf36f6
--- /dev/null
@@ -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 <stdlib.h>
+#include <mach/mach.h>
+#include <stdio.h>
+#include <string.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <pwd.h>
+#include <netinet/in.h>
+
+#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 (file)
index 0000000..b458b74
--- /dev/null
@@ -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 <stdlib.h>
+#include <string.h>
+#include <mach/mach.h>
+
+#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 (file)
index 0000000..d1a268c
--- /dev/null
@@ -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 <netinfo/lookup_types.h>
+#include <netinfo/ni.h>
+#include <stdarg.h>
+
+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 (file)
index 0000000..f2b1917
--- /dev/null
@@ -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 <sys/cdefs.h>
+
+__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 (file)
index 0000000..8058f4d
--- /dev/null
@@ -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 <sys/cdefs.h>
+
+__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 (file)
index 0000000..baf2315
--- /dev/null
@@ -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 (file)
index 0000000..8361d56
--- /dev/null
@@ -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 (file)
index 0000000..77e442b
--- /dev/null
@@ -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 (file)
index 0000000..ecd1da8
--- /dev/null
@@ -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 (file)
index 0000000..d284ec5
--- /dev/null
@@ -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 (file)
index 0000000..7c32dee
--- /dev/null
@@ -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 (file)
index 0000000..47b031f
--- /dev/null
@@ -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 <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <sys/socket.h>
+#include <syslog.h>
+#include <sys/param.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <unistd.h>
+
+#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 (file)
index 0000000..6de58bc
--- /dev/null
@@ -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 <rpc/rpc.h>
+#include <netinfo/ni_prot.h>
+#include <netinfo/nibind_prot.h>
+typedef const char *ni_name_const;
+#include <netinfo/ni_util.h>
+
+/*
+ * 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 (file)
index 0000000..63aaff8
--- /dev/null
@@ -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 <netinfo/ni.h>
+
+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 (file)
index 0000000..0a22e74
--- /dev/null
@@ -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 <libc.h>
+#include <syslog.h>
+#include <netinfo/ni.h>
+#include <rpc/pmap_clnt.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/xdr.h>
+#include <net/if.h>
+#include <ctype.h>
+#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; i<nl.ninl_len; i++) {
+               addr.s_addr = inet_addr(nl.ninl_val[i]);
+               target_ni->addrs[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 (file)
index 0000000..a83e0fe
--- /dev/null
@@ -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 <string.h>
+#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<NI_NAME_MAXLEN>;
+
+
+typedef ni_name ni_namelist<NI_NAMELIST_MAXLEN>;
+
+/*
+ * A property
+ */
+struct ni_property {
+       ni_name nip_name;
+       ni_namelist nip_val;
+};
+
+/*
+ * A list of properties
+ */
+typedef ni_property ni_proplist<NI_PROPLIST_MAXLEN>;
+
+/*
+ * A list of IDs (yet another variable-length array)
+ */
+typedef ni_index ni_idlist<NI_IDLIST_MAXLEN>;
+
+
+/*
+ * 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<NI_IDLIST_MAXLEN>;
+
+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<NI_IDLIST_MAXLEN>;
+
+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 (file)
index 0000000..c872cc8
--- /dev/null
@@ -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 <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <stdio.h>
+#include <string.h>
+#include <netinfo/ni.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+
+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 (file)
index 0000000..a3d3df6
--- /dev/null
@@ -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 <stdlib.h>
+#include <netinfo/ni.h>
+#include <string.h>
+#include <ctype.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <arpa/inet.h>
+
+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 <tag>@<address> 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 <tag>@<address> 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> [/[<domainspec>][:[<dirspec>]]]
+        * hostspec ::= [[[user][:[password]]]@]hostref
+        * hostref ::= <inet_addr> | <hostname>
+        * domainspec ::= <abs_domain> | <rel_domain>
+        * dirspec ::= <path> | <unsigned_integer>
+        */
+
+       x = strlen("netinfo://");
+
+       if (strncmp(url, "netinfo://", x)) return;
+
+       /*
+        * Look for <hostspec> 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 <domainspec> 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 <dirspec> part
+        * NULL <dirspec> 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 (file)
index 0000000..c279510
--- /dev/null
@@ -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 <netinfo/ni.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+#include <regex.h>
+#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 (file)
index 0000000..6cb2c56
--- /dev/null
@@ -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 <netinfo/ni.h>
+
+#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> [/[<domainspec>][:[<dirspec>]]]
+ * hostspec ::= [[[user][:[password]]]@]hostref
+ * hostref ::= <inet_addr> | <hostname>
+ * domainspec ::= <abs_domain> | <rel_domain>
+ * dirspec ::= <path> | <unsigned_integer>
+ */
+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 (file)
index 0000000..19ef737
--- /dev/null
@@ -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 <netinfo/ni_prot.h>
+%#endif
+#else
+%#include <string.h>
+#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<NIBIND_MAXREGS>;
+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 (file)
index 0000000..fd7babb
--- /dev/null
@@ -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 (file)
index 0000000..eb86120
--- /dev/null
@@ -0,0 +1 @@
+PUBLIC_HEADER_DIR_SUFFIX = /rpcsvc
diff --git a/nis.subproj/PB.project b/nis.subproj/PB.project
new file mode 100644 (file)
index 0000000..6d2b72e
--- /dev/null
@@ -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 (file)
index 0000000..e0e4dc8
--- /dev/null
@@ -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 <mach/mach_types.h>
+#include <sys/sysctl.h>
+
+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 (file)
index 0000000..3894676
--- /dev/null
@@ -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 <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rpcsvc/ypclnt.h>
+
+#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 (file)
index 0000000..d146233
--- /dev/null
@@ -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 <stdio.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rpcsvc/ypclnt.h>
+
+/* 
+ * 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 (file)
index 0000000..1541c01
--- /dev/null
@@ -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 <mach/mach_types.h>
+#include <sys/sysctl.h>
+
+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 (file)
index 0000000..5308c1e
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+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 (file)
index 0000000..9e0c6f0
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+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 (file)
index 0000000..6c4323a
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+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 (file)
index 0000000..7c4726d
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+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 (file)
index 0000000..1ab9024
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+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 (file)
index 0000000..53b82fa
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+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 (file)
index 0000000..832973f
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+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 (file)
index 0000000..12096e2
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+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 (file)
index 0000000..be681a2
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+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 (file)
index 0000000..137ea49
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+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 (file)
index 0000000..eababd8
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+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 (file)
index 0000000..b3e1552
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+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 (file)
index 0000000..cee7c8a
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+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 (file)
index 0000000..dfb11b8
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+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 (file)
index 0000000..cce1529
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+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 (file)
index 0000000..b844a40
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+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 (file)
index 0000000..4660014
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+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 (file)
index 0000000..26226e0
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+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 (file)
index 0000000..15a4842
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+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 (file)
index 0000000..55778c8
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+#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 (file)
index 0000000..a8b9c9d
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * Copyright (c) 1992, 1993 Theo de Raadt <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+#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 (file)
index 0000000..5bdcf11
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+#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 (file)
index 0000000..373d1a4
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+#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 (file)
index 0000000..e795ad2
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+#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 (file)
index 0000000..b3a0795
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+#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 (file)
index 0000000..44b7a7c
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+#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 (file)
index 0000000..1be2a2e
--- /dev/null
@@ -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 <deraadt@fsa.ca>
+ * 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 (file)
index 0000000..c09e8b1
--- /dev/null
@@ -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 <deraadt@fsa.ca>
+ * 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 (file)
index 0000000..4b98ee6
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+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 (file)
index 0000000..03e40fc
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 (file)
index 0000000..e689913
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+/* #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 (file)
index 0000000..d285182
--- /dev/null
@@ -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 <moj@stacken.kth.se>
+ * 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 <rpc/rpc.h>
+#include <rpcsvc/yppasswd.h>
+
+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 (file)
index 0000000..7c955fb
--- /dev/null
@@ -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 <deraadt@theos.com>
+ * 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 <sys/param.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/file.h>
+#include <sys/uio.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <rpc/rpc.h>
+#include <rpc/xdr.h>
+#include <rpcsvc/yp.h>
+#include <rpcsvc/ypclnt.h>
+
+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 (file)
index 0000000..4bf2c53
--- /dev/null
@@ -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 (file)
index 0000000..1d84ceb
--- /dev/null
@@ -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 (file)
index 0000000..859704b
--- /dev/null
@@ -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 (file)
index 0000000..bc5f843
--- /dev/null
@@ -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 <sys/cdefs.h>
+
+#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 (file)
index 0000000..220a8ca
--- /dev/null
@@ -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 <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#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 (file)
index 0000000..448654d
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <sys/param.h>
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_unix.h>
+
+/*
+ * 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 (file)
index 0000000..a26f59a
--- /dev/null
@@ -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 <sys/cdefs.h>
+
+/* 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 (file)
index 0000000..dce59b3
--- /dev/null
@@ -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 <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/auth.h>
+#include <rpc/auth_unix.h>
+#include <sys/param.h>
+
+/*
+ * 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 (file)
index 0000000..14261d1
--- /dev/null
@@ -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 <sys/types.h>
+#include <sys/errno.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+/*
+ * 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 (file)
index 0000000..1efee44
--- /dev/null
@@ -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 <sys/cdefs.h>
+
+/*
+ * 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 (file)
index 0000000..cd966ef
--- /dev/null
@@ -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 <rpc/rpc.h>
+#include <sys/socket.h>
+#include <sys/errno.h>
+#include <netdb.h>
+
+/*
+ * 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 (file)
index 0000000..7ad8e75
--- /dev/null
@@ -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 <stdio.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <rpc/types.h>
+#include <rpc/auth.h>
+#include <rpc/clnt.h>
+
+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 (file)
index 0000000..100b870
--- /dev/null
@@ -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 <rpc/rpc.h>
+
+#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 (file)
index 0000000..ec99490
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+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 (file)
index 0000000..22f6616
--- /dev/null
@@ -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 <stdio.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <errno.h>
+#include <rpc/pmap_clnt.h>
+
+#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 (file)
index 0000000..38a03fe
--- /dev/null
@@ -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 <stdio.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <netdb.h>
+#include <errno.h>
+#include <rpc/pmap_clnt.h>
+
+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 (file)
index 0000000..944a0e8
--- /dev/null
@@ -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 <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/pmap_prot.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+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 (file)
index 0000000..1b57d99
--- /dev/null
@@ -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 <stdio.h>
+#include <sys/types.h>
+#include <string.h>
+#include <rpc/rpc.h>
+
+/*
+ * 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 (file)
index 0000000..af368dd
--- /dev/null
@@ -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 <stdio.h>
+#include <rpc/rpc.h>
+#include <netdb.h>
+#include <sys/socket.h>
+
+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 (file)
index 0000000..cdd3261
--- /dev/null
@@ -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 <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+
+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 (file)
index 0000000..16e7fed
--- /dev/null
@@ -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 <sys/cdefs.h>
+
+__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 (file)
index 0000000..7946572
--- /dev/null
@@ -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 <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <errno.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#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 (file)
index 0000000..b4b6eb5
--- /dev/null
@@ -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 <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <sys/socket.h>
+#include <net/if.h>
+
+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 (file)
index 0000000..b3d4a02
--- /dev/null
@@ -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 <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/pmap_prot.h>
+
+
+bool_t
+xdr_pmap(xdrs, regs)
+       XDR *xdrs;
+       struct pmap *regs;
+{
+
+       if (xdr_u_long(xdrs, &regs->pm_prog) && 
+               xdr_u_long(xdrs, &regs->pm_vers) && 
+               xdr_u_long(xdrs, &regs->pm_prot))
+               return (xdr_u_long(xdrs, &regs->pm_port));
+       return (FALSE);
+}
diff --git a/rpc.subproj/pmap_prot.h b/rpc.subproj/pmap_prot.h
new file mode 100644 (file)
index 0000000..1565f5e
--- /dev/null
@@ -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 <sys/cdefs.h>
+
+#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 (file)
index 0000000..986c2c8
--- /dev/null
@@ -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 <rpc/types.h>
+#include <rpc/xdr.h>
+#include <rpc/pmap_prot.h>
+
+
+/* 
+ * 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 (file)
index 0000000..cbfffa6
--- /dev/null
@@ -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 <rpc/rpc.h>
+#include <rpc/pmap_prot.h>
+#include <rpc/pmap_clnt.h>
+#include <rpc/pmap_rmt.h>
+#include <sys/socket.h>
+#include <stdio.h>
+#include <errno.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <arpa/inet.h>
+#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 (file)
index 0000000..a6782a5
--- /dev/null
@@ -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 <sys/cdefs.h>
+
+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 (file)
index 0000000..da89dff
--- /dev/null
@@ -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 <rpc/types.h>         /* some typedefs */
+#include <netinet/in.h>
+
+/* external data representation interfaces */
+#include <rpc/xdr.h>           /* generic (de)serializer */
+
+/* Client side only authentication */
+#include <rpc/auth.h>          /* generic authenticator (client side) */
+
+/* Client side (mostly) remote procedure call */
+#include <rpc/clnt.h>          /* generic rpc stuff */
+
+/* semi-private protocol headers */
+#include <rpc/rpc_msg.h>       /* protocol for rpc messages */
+#include <rpc/auth_unix.h>     /* 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 <rpc/auth_des.h>     protocol for des style cred */
+
+/* Server side only remote procedure callee */
+#include <rpc/svc.h>           /* service manager and multiplexer */
+#include <rpc/svc_auth.h>      /* service side authenticator */
+
+#include <netdb.h>
+
+#endif /* !_RPC_RPC_H */
diff --git a/rpc.subproj/rpc_callmsg.c b/rpc.subproj/rpc_callmsg.c
new file mode 100644 (file)
index 0000000..45014db
--- /dev/null
@@ -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 <sys/param.h>
+
+#include <rpc/rpc.h>
+
+/*
+ * 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 (file)
index 0000000..c12c265
--- /dev/null
@@ -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 <rpc/rpc.h>
+/*
+ * 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 (file)
index 0000000..bfdd00b
--- /dev/null
@@ -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 <sys/types.h>
+
+/*
+ * 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 (file)
index 0000000..53373d0
--- /dev/null
@@ -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 (file)
index 0000000..ab74c4b
--- /dev/null
@@ -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 <sys/param.h>
+
+#include <rpc/rpc.h>
+
+/* * * * * * * * * * * * * * 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 (file)
index 0000000..fffefc0
--- /dev/null
@@ -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 <sys/errno.h>
+#include <rpc/rpc.h>
+#include <rpc/pmap_clnt.h>
+
+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 (file)
index 0000000..8a3004e
--- /dev/null
@@ -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 <sys/cdefs.h>
+
+/*
+ * 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 (file)
index 0000000..6586c98
--- /dev/null
@@ -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 <rpc/rpc.h>
+
+/*
+ * 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 (file)
index 0000000..3dc0959
--- /dev/null
@@ -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 (file)
index 0000000..2f30dd7
--- /dev/null
@@ -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 <stdio.h>
+#include <sys/param.h>
+#include <rpc/rpc.h>
+
+/*
+ * 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 (file)
index 0000000..6729e4d
--- /dev/null
@@ -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 <rpc/rpc.h>
+
+
+/*
+ * 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 (file)
index 0000000..47b467a
--- /dev/null
@@ -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 <rpc/rpc.h>
+#include <sys/errno.h>
+
+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 (file)
index 0000000..6174d04
--- /dev/null
@@ -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 <stdio.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <netdb.h>
+
+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 (file)
index 0000000..8828b63
--- /dev/null
@@ -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 <stdio.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <errno.h>
+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 (file)
index 0000000..5af3045
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <rpc/rpc.h>
+#include <sys/socket.h>
+#include <errno.h>
+
+
+#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 (file)
index 0000000..b9cd3cf
--- /dev/null
@@ -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 <sys/types.h>
+ */
+#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 <sys/types.h>
+#endif
+#include <sys/time.h>
+
+#endif /* !_RPC_TYPES_H */
diff --git a/rpc.subproj/xdr.c b/rpc.subproj/xdr.c
new file mode 100644 (file)
index 0000000..b523fee
--- /dev/null
@@ -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 <stdio.h>
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+/*
+ * 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 (file)
index 0000000..6289bc8
--- /dev/null
@@ -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 <sys/cdefs.h>
+
+/*
+ * 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;
+ *             <type> *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 (file)
index 0000000..356b795
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#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 (file)
index 0000000..775022a
--- /dev/null
@@ -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 <stdio.h>
+#include <sys/types.h>
+#include <sys/param.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+/*
+ * 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 (file)
index 0000000..3bec281
--- /dev/null
@@ -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 <rpc/types.h>
+#include <rpc/xdr.h>
+#include <netinet/in.h>
+
+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 (file)
index 0000000..912dbfb
--- /dev/null
@@ -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 <stdio.h>
+#include <stdlib.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+#include <netinet/in.h>
+
+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 (file)
index 0000000..bfc82e1
--- /dev/null
@@ -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 <stdio.h>
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#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 (file)
index 0000000..d4c6b49
--- /dev/null
@@ -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 <rpc/types.h>
+#include <stdio.h>
+#include <rpc/xdr.h>
+
+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 (file)
index 0000000..aede900
--- /dev/null
@@ -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 (file)
index 0000000..eab47ff
--- /dev/null
@@ -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 (file)
index 0000000..305f1b8
--- /dev/null
@@ -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 <sys/types.h>
+#include <string.h>
+#include <grp.h>
+
+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 (file)
index 0000000..f19459e
--- /dev/null
@@ -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 <sys/param.h>
+#include <sys/stat.h>
+
+#include <ctype.h>
+#include <dirent.h>
+#include <errno.h>
+#include <glob.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#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 (file)
index 0000000..312d514
--- /dev/null
@@ -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 <architecture/byte_order.h>
+
+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 (file)
index 0000000..976ef2f
--- /dev/null
@@ -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 <stdlib.h>
+#include <stdio.h>
+#include <pwd.h>
+#include <ctype.h>
+#include <netinfo/ni.h>
+#include <libc.h>
+
+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 (file)
index 0000000..f0a4eec
--- /dev/null
@@ -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 <sys/types.h>
+
+#include <grp.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <utmp.h>
+
+#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 (file)
index 0000000..611b94d
--- /dev/null
@@ -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 <sys/param.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netinfo/ni_util.h>
+
+#include <signal.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <errno.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <syslog.h>
+#include <stdlib.h>
+
+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 (file)
index 0000000..49f9eee
--- /dev/null
@@ -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 <cks@utcc.utoronto.ca>.
+ */
+
+#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      <sys/types.h>
+#include      <sys/socket.h>
+#include      <sys/wait.h>
+#include      <signal.h>
+#include      <errno.h>
+#include      <netdb.h>
+#include      <stdio.h>
+#include      <string.h>
+#include      <pwd.h>
+#include      <paths.h>
+#include      <unistd.h>
+/*
+ * 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 */
+}