From 03fb6eb005e0e1ca66f0422cb7821f0a2ad2d381 Mon Sep 17 00:00:00 2001
From: Apple <opensource@apple.com>
Date: Wed, 11 Apr 2001 00:34:00 +0000
Subject: [PATCH] Libinfo-78.tar.gz

---
 Makefile                            |   56 +
 Makefile.postamble                  |    4 +
 Makefile.preamble                   |    4 +
 PB.project                          |   39 +
 dns.subproj/Makefile                |   55 +
 dns.subproj/Makefile.postamble      |    7 +
 dns.subproj/Makefile.preamble       |   24 +
 dns.subproj/PB.project              |   41 +
 dns.subproj/gethnamaddr.c           |  810 ++++++++++
 dns.subproj/getnetbyaddr.c          |   80 +
 dns.subproj/getnetbyname.c          |   87 ++
 dns.subproj/getnetent.c             |  187 +++
 dns.subproj/getnetnamadr.c          |  328 ++++
 dns.subproj/herror.c                |  145 ++
 dns.subproj/inet.h                  |  111 ++
 dns.subproj/nameser.h               |  368 +++++
 dns.subproj/options.h               |  189 +++
 dns.subproj/portability.h           |  570 +++++++
 dns.subproj/res_comp.c              |  452 ++++++
 dns.subproj/res_data.c              |   46 +
 dns.subproj/res_debug.c             |  857 ++++++++++
 dns.subproj/res_init.c              |  675 ++++++++
 dns.subproj/res_mkquery.c           |  272 ++++
 dns.subproj/res_query.c             |  417 +++++
 dns.subproj/res_send.c              |  784 ++++++++++
 dns.subproj/resolv.h                |  263 ++++
 dns.subproj/sethostent.c            |   85 +
 gen.subproj/Makefile                |   47 +
 gen.subproj/Makefile.preamble       |   31 +
 gen.subproj/PB.project              |   37 +
 gen.subproj/aliasdb.c               |   54 +
 gen.subproj/ether_addr.c            |  188 +++
 gen.subproj/fstab.c                 |  330 ++++
 gen.subproj/getaddrinfo.c           | 1608 +++++++++++++++++++
 gen.subproj/getgrent.c              |  204 +++
 gen.subproj/getproto.c              |   78 +
 gen.subproj/getprotoent.c           |  142 ++
 gen.subproj/getprotoname.c          |   85 +
 gen.subproj/getpwent.c              |  370 +++++
 gen.subproj/getservbyname.c         |   88 ++
 gen.subproj/getservbyport.c         |   83 +
 gen.subproj/getservent.c            |  144 ++
 gen.subproj/initgroups.c            |   81 +
 gen.subproj/printerdb.c             |  286 ++++
 lookup.subproj/Makefile             |   54 +
 lookup.subproj/Makefile.postamble   |    8 +
 lookup.subproj/Makefile.preamble    |    8 +
 lookup.subproj/PB.project           |   48 +
 lookup.subproj/_lu_types.x          |  247 +++
 lookup.subproj/aliasdb.h            |   48 +
 lookup.subproj/bootparams.h         |   52 +
 lookup.subproj/lookup.defs          |   71 +
 lookup.subproj/lookup_types.h       |   47 +
 lookup.subproj/lu_alias.c           |  249 +++
 lookup.subproj/lu_bootp.c           |  145 ++
 lookup.subproj/lu_bootparam.c       |  246 +++
 lookup.subproj/lu_fstab.c           |  296 ++++
 lookup.subproj/lu_group.c           |  396 +++++
 lookup.subproj/lu_host.c            |  378 +++++
 lookup.subproj/lu_netgroup.c        |  257 +++
 lookup.subproj/lu_network.c         |  334 ++++
 lookup.subproj/lu_overrides.h       |  106 ++
 lookup.subproj/lu_printer.c         |  268 ++++
 lookup.subproj/lu_protocol.c        |  299 ++++
 lookup.subproj/lu_rpc.c             |  301 ++++
 lookup.subproj/lu_service.c         |  323 ++++
 lookup.subproj/lu_user.c            |  380 +++++
 lookup.subproj/lu_utils.c           |  332 ++++
 lookup.subproj/lu_utils.h           |  130 ++
 lookup.subproj/netgr.h              |   47 +
 lookup.subproj/printerdb.h          |   54 +
 netinfo.subproj/Makefile            |   51 +
 netinfo.subproj/Makefile.postamble  |    5 +
 netinfo.subproj/Makefile.preamble   |    6 +
 netinfo.subproj/PB.project          |   23 +
 netinfo.subproj/clib.h              |   34 +
 netinfo.subproj/mm.h                |   57 +
 netinfo.subproj/multi_call.c        |  352 +++++
 netinfo.subproj/ni.h                |  124 ++
 netinfo.subproj/ni_error.c          |   77 +
 netinfo.subproj/ni_glue.c           | 2251 +++++++++++++++++++++++++++
 netinfo.subproj/ni_prot.x           |  502 ++++++
 netinfo.subproj/ni_pwdomain.c       |  345 ++++
 netinfo.subproj/ni_useful.c         |  745 +++++++++
 netinfo.subproj/ni_util.c           |  527 +++++++
 netinfo.subproj/ni_util.h           |   98 ++
 netinfo.subproj/nibind_prot.x       |  116 ++
 nis.subproj/Makefile                |   58 +
 nis.subproj/Makefile.preamble       |    1 +
 nis.subproj/PB.project              |   58 +
 nis.subproj/getdomainname.c         |   39 +
 nis.subproj/getnetgrent.c           |  236 +++
 nis.subproj/innetgr.c               |  337 ++++
 nis.subproj/setdomainname.c         |   39 +
 nis.subproj/xdr_domainname.c        |   77 +
 nis.subproj/xdr_keydat.c            |   78 +
 nis.subproj/xdr_mapname.c           |   77 +
 nis.subproj/xdr_peername.c          |   77 +
 nis.subproj/xdr_valdat.c            |   78 +
 nis.subproj/xdr_ypbind_binding.c    |   80 +
 nis.subproj/xdr_ypbind_resp.c       |   91 ++
 nis.subproj/xdr_ypbind_resptype.c   |   77 +
 nis.subproj/xdr_ypbind_setdom.c     |   83 +
 nis.subproj/xdr_ypmaplist.c         |   81 +
 nis.subproj/xdr_ypreq_key.c         |   83 +
 nis.subproj/xdr_ypreq_nokey.c       |   80 +
 nis.subproj/xdr_ypresp_all.c        |   88 ++
 nis.subproj/xdr_ypresp_key_val.c    |   83 +
 nis.subproj/xdr_ypresp_maplist.c    |   81 +
 nis.subproj/xdr_ypresp_master.c     |   80 +
 nis.subproj/xdr_ypresp_order.c      |   80 +
 nis.subproj/xdr_ypresp_val.c        |   80 +
 nis.subproj/xdr_ypstat.c            |   77 +
 nis.subproj/yp_all.c                |  193 +++
 nis.subproj/yp_bind.c               |  315 ++++
 nis.subproj/yp_first.c              |  136 ++
 nis.subproj/yp_get_default_domain.c |   87 ++
 nis.subproj/yp_maplist.c            |  106 ++
 nis.subproj/yp_master.c             |  119 ++
 nis.subproj/yp_order.c              |  125 ++
 nis.subproj/yp_prot.h               |  365 +++++
 nis.subproj/ypclnt.h                |  111 ++
 nis.subproj/yperr_string.c          |  118 ++
 nis.subproj/ypinternal.h            |  100 ++
 nis.subproj/ypmatch_cache.c         |  324 ++++
 nis.subproj/yppasswdd_xdr.c         |  105 ++
 nis.subproj/ypprot_err.c            |  103 ++
 rpc.subproj/Makefile                |   60 +
 rpc.subproj/Makefile.preamble       |    8 +
 rpc.subproj/PB.project              |   88 ++
 rpc.subproj/auth.h                  |  201 +++
 rpc.subproj/auth_none.c             |  158 ++
 rpc.subproj/auth_unix.c             |  364 +++++
 rpc.subproj/auth_unix.h             |  102 ++
 rpc.subproj/authunix_prot.c         |   92 ++
 rpc.subproj/bindresvport.c          |  107 ++
 rpc.subproj/clnt.h                  |  387 +++++
 rpc.subproj/clnt_generic.c          |  131 ++
 rpc.subproj/clnt_perror.c           |  326 ++++
 rpc.subproj/clnt_raw.c              |  263 ++++
 rpc.subproj/clnt_simple.c           |  139 ++
 rpc.subproj/clnt_tcp.c              |  482 ++++++
 rpc.subproj/clnt_udp.c              |  458 ++++++
 rpc.subproj/get_myaddress.c         |  139 ++
 rpc.subproj/getrpcent.c             |  231 +++
 rpc.subproj/getrpcport.c            |   81 +
 rpc.subproj/pmap_clnt.c             |  152 ++
 rpc.subproj/pmap_clnt.h             |  107 ++
 rpc.subproj/pmap_getmaps.c          |  109 ++
 rpc.subproj/pmap_getport.c          |  112 ++
 rpc.subproj/pmap_prot.c             |   82 +
 rpc.subproj/pmap_prot.h             |  127 ++
 rpc.subproj/pmap_prot2.c            |  141 ++
 rpc.subproj/pmap_rmt.c              |  411 +++++
 rpc.subproj/pmap_rmt.h              |   86 +
 rpc.subproj/rpc.h                   |   93 ++
 rpc.subproj/rpc_callmsg.c           |  215 +++
 rpc.subproj/rpc_commondata.c        |   73 +
 rpc.subproj/rpc_dtablesize.c        |   78 +
 rpc.subproj/rpc_msg.h               |  218 +++
 rpc.subproj/rpc_prot.c              |  316 ++++
 rpc.subproj/svc.c                   |  475 ++++++
 rpc.subproj/svc.h                   |  325 ++++
 rpc.subproj/svc_auth.c              |  140 ++
 rpc.subproj/svc_auth.h              |   73 +
 rpc.subproj/svc_auth_unix.c         |  160 ++
 rpc.subproj/svc_raw.c               |  191 +++
 rpc.subproj/svc_run.c               |   90 ++
 rpc.subproj/svc_simple.c            |  168 ++
 rpc.subproj/svc_tcp.c               |  435 ++++++
 rpc.subproj/svc_udp.c               |  503 ++++++
 rpc.subproj/types.h                 |   85 +
 rpc.subproj/xdr.c                   |  605 +++++++
 rpc.subproj/xdr.h                   |  318 ++++
 rpc.subproj/xdr_array.c             |  178 +++
 rpc.subproj/xdr_float.c             |  306 ++++
 rpc.subproj/xdr_mem.c               |  213 +++
 rpc.subproj/xdr_rec.c               |  607 ++++++++
 rpc.subproj/xdr_reference.c         |  157 ++
 rpc.subproj/xdr_stdio.c             |  214 +++
 util.subproj/Makefile               |   46 +
 util.subproj/PB.project             |   21 +
 util.subproj/getgrouplist.c         |  112 ++
 util.subproj/glob.c                 |  845 ++++++++++
 util.subproj/hton.c                 |   52 +
 util.subproj/putpwpasswd.c          |  137 ++
 util.subproj/pwcache.c              |  111 ++
 util.subproj/rcmd.c                 |  637 ++++++++
 util.subproj/rcmdsh.c               |  146 ++
 189 files changed, 39342 insertions(+)
 create mode 100644 Makefile
 create mode 100644 Makefile.postamble
 create mode 100644 Makefile.preamble
 create mode 100644 PB.project
 create mode 100644 dns.subproj/Makefile
 create mode 100644 dns.subproj/Makefile.postamble
 create mode 100644 dns.subproj/Makefile.preamble
 create mode 100644 dns.subproj/PB.project
 create mode 100644 dns.subproj/gethnamaddr.c
 create mode 100644 dns.subproj/getnetbyaddr.c
 create mode 100644 dns.subproj/getnetbyname.c
 create mode 100644 dns.subproj/getnetent.c
 create mode 100644 dns.subproj/getnetnamadr.c
 create mode 100644 dns.subproj/herror.c
 create mode 100644 dns.subproj/inet.h
 create mode 100644 dns.subproj/nameser.h
 create mode 100644 dns.subproj/options.h
 create mode 100644 dns.subproj/portability.h
 create mode 100644 dns.subproj/res_comp.c
 create mode 100644 dns.subproj/res_data.c
 create mode 100644 dns.subproj/res_debug.c
 create mode 100644 dns.subproj/res_init.c
 create mode 100644 dns.subproj/res_mkquery.c
 create mode 100644 dns.subproj/res_query.c
 create mode 100644 dns.subproj/res_send.c
 create mode 100644 dns.subproj/resolv.h
 create mode 100644 dns.subproj/sethostent.c
 create mode 100644 gen.subproj/Makefile
 create mode 100644 gen.subproj/Makefile.preamble
 create mode 100644 gen.subproj/PB.project
 create mode 100644 gen.subproj/aliasdb.c
 create mode 100644 gen.subproj/ether_addr.c
 create mode 100644 gen.subproj/fstab.c
 create mode 100644 gen.subproj/getaddrinfo.c
 create mode 100644 gen.subproj/getgrent.c
 create mode 100644 gen.subproj/getproto.c
 create mode 100644 gen.subproj/getprotoent.c
 create mode 100644 gen.subproj/getprotoname.c
 create mode 100644 gen.subproj/getpwent.c
 create mode 100644 gen.subproj/getservbyname.c
 create mode 100644 gen.subproj/getservbyport.c
 create mode 100644 gen.subproj/getservent.c
 create mode 100644 gen.subproj/initgroups.c
 create mode 100644 gen.subproj/printerdb.c
 create mode 100644 lookup.subproj/Makefile
 create mode 100644 lookup.subproj/Makefile.postamble
 create mode 100644 lookup.subproj/Makefile.preamble
 create mode 100644 lookup.subproj/PB.project
 create mode 100644 lookup.subproj/_lu_types.x
 create mode 100644 lookup.subproj/aliasdb.h
 create mode 100644 lookup.subproj/bootparams.h
 create mode 100644 lookup.subproj/lookup.defs
 create mode 100644 lookup.subproj/lookup_types.h
 create mode 100644 lookup.subproj/lu_alias.c
 create mode 100644 lookup.subproj/lu_bootp.c
 create mode 100644 lookup.subproj/lu_bootparam.c
 create mode 100644 lookup.subproj/lu_fstab.c
 create mode 100644 lookup.subproj/lu_group.c
 create mode 100644 lookup.subproj/lu_host.c
 create mode 100644 lookup.subproj/lu_netgroup.c
 create mode 100644 lookup.subproj/lu_network.c
 create mode 100644 lookup.subproj/lu_overrides.h
 create mode 100644 lookup.subproj/lu_printer.c
 create mode 100644 lookup.subproj/lu_protocol.c
 create mode 100644 lookup.subproj/lu_rpc.c
 create mode 100644 lookup.subproj/lu_service.c
 create mode 100644 lookup.subproj/lu_user.c
 create mode 100644 lookup.subproj/lu_utils.c
 create mode 100644 lookup.subproj/lu_utils.h
 create mode 100644 lookup.subproj/netgr.h
 create mode 100644 lookup.subproj/printerdb.h
 create mode 100644 netinfo.subproj/Makefile
 create mode 100644 netinfo.subproj/Makefile.postamble
 create mode 100644 netinfo.subproj/Makefile.preamble
 create mode 100644 netinfo.subproj/PB.project
 create mode 100644 netinfo.subproj/clib.h
 create mode 100644 netinfo.subproj/mm.h
 create mode 100644 netinfo.subproj/multi_call.c
 create mode 100644 netinfo.subproj/ni.h
 create mode 100644 netinfo.subproj/ni_error.c
 create mode 100644 netinfo.subproj/ni_glue.c
 create mode 100644 netinfo.subproj/ni_prot.x
 create mode 100644 netinfo.subproj/ni_pwdomain.c
 create mode 100644 netinfo.subproj/ni_useful.c
 create mode 100644 netinfo.subproj/ni_util.c
 create mode 100644 netinfo.subproj/ni_util.h
 create mode 100644 netinfo.subproj/nibind_prot.x
 create mode 100644 nis.subproj/Makefile
 create mode 100644 nis.subproj/Makefile.preamble
 create mode 100644 nis.subproj/PB.project
 create mode 100644 nis.subproj/getdomainname.c
 create mode 100644 nis.subproj/getnetgrent.c
 create mode 100644 nis.subproj/innetgr.c
 create mode 100644 nis.subproj/setdomainname.c
 create mode 100644 nis.subproj/xdr_domainname.c
 create mode 100644 nis.subproj/xdr_keydat.c
 create mode 100644 nis.subproj/xdr_mapname.c
 create mode 100644 nis.subproj/xdr_peername.c
 create mode 100644 nis.subproj/xdr_valdat.c
 create mode 100644 nis.subproj/xdr_ypbind_binding.c
 create mode 100644 nis.subproj/xdr_ypbind_resp.c
 create mode 100644 nis.subproj/xdr_ypbind_resptype.c
 create mode 100644 nis.subproj/xdr_ypbind_setdom.c
 create mode 100644 nis.subproj/xdr_ypmaplist.c
 create mode 100644 nis.subproj/xdr_ypreq_key.c
 create mode 100644 nis.subproj/xdr_ypreq_nokey.c
 create mode 100644 nis.subproj/xdr_ypresp_all.c
 create mode 100644 nis.subproj/xdr_ypresp_key_val.c
 create mode 100644 nis.subproj/xdr_ypresp_maplist.c
 create mode 100644 nis.subproj/xdr_ypresp_master.c
 create mode 100644 nis.subproj/xdr_ypresp_order.c
 create mode 100644 nis.subproj/xdr_ypresp_val.c
 create mode 100644 nis.subproj/xdr_ypstat.c
 create mode 100644 nis.subproj/yp_all.c
 create mode 100644 nis.subproj/yp_bind.c
 create mode 100644 nis.subproj/yp_first.c
 create mode 100644 nis.subproj/yp_get_default_domain.c
 create mode 100644 nis.subproj/yp_maplist.c
 create mode 100644 nis.subproj/yp_master.c
 create mode 100644 nis.subproj/yp_order.c
 create mode 100644 nis.subproj/yp_prot.h
 create mode 100644 nis.subproj/ypclnt.h
 create mode 100644 nis.subproj/yperr_string.c
 create mode 100644 nis.subproj/ypinternal.h
 create mode 100644 nis.subproj/ypmatch_cache.c
 create mode 100644 nis.subproj/yppasswdd_xdr.c
 create mode 100644 nis.subproj/ypprot_err.c
 create mode 100644 rpc.subproj/Makefile
 create mode 100644 rpc.subproj/Makefile.preamble
 create mode 100644 rpc.subproj/PB.project
 create mode 100644 rpc.subproj/auth.h
 create mode 100644 rpc.subproj/auth_none.c
 create mode 100644 rpc.subproj/auth_unix.c
 create mode 100644 rpc.subproj/auth_unix.h
 create mode 100644 rpc.subproj/authunix_prot.c
 create mode 100644 rpc.subproj/bindresvport.c
 create mode 100644 rpc.subproj/clnt.h
 create mode 100644 rpc.subproj/clnt_generic.c
 create mode 100644 rpc.subproj/clnt_perror.c
 create mode 100644 rpc.subproj/clnt_raw.c
 create mode 100644 rpc.subproj/clnt_simple.c
 create mode 100644 rpc.subproj/clnt_tcp.c
 create mode 100644 rpc.subproj/clnt_udp.c
 create mode 100644 rpc.subproj/get_myaddress.c
 create mode 100644 rpc.subproj/getrpcent.c
 create mode 100644 rpc.subproj/getrpcport.c
 create mode 100644 rpc.subproj/pmap_clnt.c
 create mode 100644 rpc.subproj/pmap_clnt.h
 create mode 100644 rpc.subproj/pmap_getmaps.c
 create mode 100644 rpc.subproj/pmap_getport.c
 create mode 100644 rpc.subproj/pmap_prot.c
 create mode 100644 rpc.subproj/pmap_prot.h
 create mode 100644 rpc.subproj/pmap_prot2.c
 create mode 100644 rpc.subproj/pmap_rmt.c
 create mode 100644 rpc.subproj/pmap_rmt.h
 create mode 100644 rpc.subproj/rpc.h
 create mode 100644 rpc.subproj/rpc_callmsg.c
 create mode 100644 rpc.subproj/rpc_commondata.c
 create mode 100644 rpc.subproj/rpc_dtablesize.c
 create mode 100644 rpc.subproj/rpc_msg.h
 create mode 100644 rpc.subproj/rpc_prot.c
 create mode 100644 rpc.subproj/svc.c
 create mode 100644 rpc.subproj/svc.h
 create mode 100644 rpc.subproj/svc_auth.c
 create mode 100644 rpc.subproj/svc_auth.h
 create mode 100644 rpc.subproj/svc_auth_unix.c
 create mode 100644 rpc.subproj/svc_raw.c
 create mode 100644 rpc.subproj/svc_run.c
 create mode 100644 rpc.subproj/svc_simple.c
 create mode 100644 rpc.subproj/svc_tcp.c
 create mode 100644 rpc.subproj/svc_udp.c
 create mode 100644 rpc.subproj/types.h
 create mode 100644 rpc.subproj/xdr.c
 create mode 100644 rpc.subproj/xdr.h
 create mode 100644 rpc.subproj/xdr_array.c
 create mode 100644 rpc.subproj/xdr_float.c
 create mode 100644 rpc.subproj/xdr_mem.c
 create mode 100644 rpc.subproj/xdr_rec.c
 create mode 100644 rpc.subproj/xdr_reference.c
 create mode 100644 rpc.subproj/xdr_stdio.c
 create mode 100644 util.subproj/Makefile
 create mode 100644 util.subproj/PB.project
 create mode 100644 util.subproj/getgrouplist.c
 create mode 100644 util.subproj/glob.c
 create mode 100644 util.subproj/hton.c
 create mode 100644 util.subproj/putpwpasswd.c
 create mode 100644 util.subproj/pwcache.c
 create mode 100644 util.subproj/rcmd.c
 create mode 100644 util.subproj/rcmdsh.c

diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..5784600
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,56 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = info
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Library
+
+SUBPROJECTS = dns.subproj gen.subproj lookup.subproj netinfo.subproj\
+              nis.subproj rpc.subproj util.subproj
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CURRENTLY_ACTIVE_VERSION = YES
+DEPLOY_WITH_VERSION_NAME = A
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = library.make
+NEXTSTEP_INSTALLDIR = /usr/local/lib/system
+WINDOWS_INSTALLDIR = /Developer/Libraries
+PDO_UNIX_INSTALLDIR = /lib
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_PUBLIC_HEADERS_DIR = /usr/include
+
+WINDOWS_PUBLIC_HEADERS_DIR = /Developer/Headers/$(NAME)
+
+PDO_UNIX_PUBLIC_HEADERS_DIR = /Developer/Headers/$(NAME)
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/Makefile.postamble b/Makefile.postamble
new file mode 100644
index 0000000..0e9365d
--- /dev/null
+++ b/Makefile.postamble
@@ -0,0 +1,4 @@
+override DEBUG_SUFFIX = _debug
+PRODUCTS += $(LIBRARY_PREFIX)$(NAME)$(DEBUG_SUFFIX)$(LIBRARY_EXT)
+PRODUCTS += $(LIBRARY_PREFIX)$(NAME)$(PROFILE_SUFFIX)$(LIBRARY_EXT)
+RECURSIVE_FLAGS += "LINK_SUBPROJECTS = NO"
diff --git a/Makefile.preamble b/Makefile.preamble
new file mode 100644
index 0000000..4e19fe6
--- /dev/null
+++ b/Makefile.preamble
@@ -0,0 +1,4 @@
+LIBRARY_STYLE = STATIC
+STRIP_ON_INSTALL = NO
+BEFORE_INSTALL += debug profile
+override LINK_SUBPROJECTS = NO
diff --git a/PB.project b/PB.project
new file mode 100644
index 0000000..5ebc657
--- /dev/null
+++ b/PB.project
@@ -0,0 +1,39 @@
+{
+    CURRENTLY_ACTIVE_VERSION = YES; 
+    DEPLOY_WITH_VERSION_NAME = A; 
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        FRAMEWORKS = (); 
+        H_FILES = (); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble); 
+        SUBPROJECTS = (
+            dns.subproj, 
+            gen.subproj, 
+            lookup.subproj, 
+            netinfo.subproj, 
+            nis.subproj, 
+            rpc.subproj, 
+            util.subproj
+        ); 
+    }; 
+    LANGUAGE = English; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /usr/local/lib/system; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    NEXTSTEP_PUBLICHEADERSDIR = /usr/include;
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_INSTALLDIR = /lib; 
+    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PDO_UNIX_PUBLICHEADERSDIR = "/Developer/Headers/$(NAME)"; 
+    PROJECTNAME = info; 
+    PROJECTTYPE = Library; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_INSTALLDIR = /Developer/Libraries; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+    WINDOWS_PUBLICHEADERSDIR = "/Developer/Headers/$(NAME)"; 
+}
diff --git a/dns.subproj/Makefile b/dns.subproj/Makefile
new file mode 100644
index 0000000..7097677
--- /dev/null
+++ b/dns.subproj/Makefile
@@ -0,0 +1,55 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = dns
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Component
+
+HFILES = inet.h nameser.h options.h portability.h resolv.h
+
+CFILES = gethnamaddr.c getnetbyaddr.c getnetbyname.c getnetent.c\
+         getnetnamadr.c herror.c res_comp.c res_data.c res_debug.c\
+	 res_init.c res_mkquery.c res_query.c res_send.c sethostent.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = subproj.make
+NEXTSTEP_INSTALLDIR = /Local/Developer/System
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+NEXTSTEP_PB_CFLAGS = -DUSE_OPTIONS_H
+PUBLIC_HEADERS = resolv.h nameser.h
+
+
+
+NEXTSTEP_PUBLIC_HEADERS_DIR = /usr/include
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/dns.subproj/Makefile.postamble b/dns.subproj/Makefile.postamble
new file mode 100644
index 0000000..e0bdfec
--- /dev/null
+++ b/dns.subproj/Makefile.postamble
@@ -0,0 +1,7 @@
+arpa_headers: $(DSTROOT)$(PUBLIC_HDR_INSTALLDIR)$(ARPA_HEADER_DIR_SUFFIX)
+	$(RM) -f $(foreach header, $(ARPA_SYMLINKED_HEADERS), $(DSTROOT)$(PUBLIC_HDR_INSTALLDIR)$(ARPA_HEADER_DIR_SUFFIX)/$(header))
+	$(LN) -s $(foreach header, $(ARPA_SYMLINKED_HEADERS), ../$(header)) $(DSTROOT)$(PUBLIC_HDR_INSTALLDIR)$(ARPA_HEADER_DIR_SUFFIX)
+	$(SILENT) $(FASTCP) $(ARPA_HEADERS) $(DSTROOT)$(PUBLIC_HDR_INSTALLDIR)$(ARPA_HEADER_DIR_SUFFIX)
+
+$(DSTROOT)$(PUBLIC_HDR_INSTALLDIR)$(ARPA_HEADER_DIR_SUFFIX):
+	$(MKDIRS) $@
diff --git a/dns.subproj/Makefile.preamble b/dns.subproj/Makefile.preamble
new file mode 100644
index 0000000..89f0837
--- /dev/null
+++ b/dns.subproj/Makefile.preamble
@@ -0,0 +1,24 @@
+OTHER_CFLAGS = \
+	-Dsethostent=_res_sethostent \
+	-Dgethostent=_res_gethostent \
+	-Dendhostent=_res_endhostent \
+	-Dgethostbyname=_res_gethostbyname \
+	-Dgethostbyaddr=_res_gethostbyaddr \
+	-Dsetnetent=_old_setnetent \
+	-Dgetnetent=_old_getnetent \
+	-Dendnetent=_old_endnetent \
+	-Dgetnetbyname=_res_getnetbyname \
+	-Dgetnetbyaddr=_res_getnetbyaddr \
+	-D_sethtent=_old_sethostent \
+	-D_gethtent=_old_gethostent \
+	-D_endhtent=_old_endhostent \
+	-D_gethtbyname=_old_gethostbyname \
+	-D_gethtbyaddr=_old_gethostbyaddr \
+	-D_getnetbyname=_old_getnetbyname \
+	-D_getnetbyaddr=_old_getnetbyaddr
+
+PUBLIC_HEADER_DIR_SUFFIX = 
+ARPA_HEADER_DIR_SUFFIX = /arpa
+ARPA_HEADERS = inet.h
+ARPA_SYMLINKED_HEADERS = nameser.h
+AFTER_INSTALLHDRS += arpa_headers
diff --git a/dns.subproj/PB.project b/dns.subproj/PB.project
new file mode 100644
index 0000000..32107f8
--- /dev/null
+++ b/dns.subproj/PB.project
@@ -0,0 +1,41 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        H_FILES = (inet.h, nameser.h, options.h, portability.h, resolv.h); 
+        OTHER_LINKED = (
+            gethnamaddr.c, 
+            getnetbyaddr.c, 
+            getnetbyname.c, 
+            getnetent.c, 
+            getnetnamadr.c, 
+            herror.c, 
+            res_comp.c, 
+            res_data.c, 
+            res_debug.c, 
+            res_init.c, 
+            res_mkquery.c, 
+            res_query.c, 
+            res_send.c, 
+            sethostent.c
+        ); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble); 
+        PUBLIC_HEADERS = (resolv.h, nameser.h); 
+    }; 
+    LANGUAGE = English; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_COMPILEROPTIONS = "-DUSE_OPTIONS_H"; 
+    NEXTSTEP_INSTALLDIR = /Local/Developer/System; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    NEXTSTEP_PUBLICHEADERSDIR = /usr/include;
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = dns; 
+    PROJECTTYPE = Component; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/dns.subproj/gethnamaddr.c b/dns.subproj/gethnamaddr.c
new file mode 100644
index 0000000..1d6aba5
--- /dev/null
+++ b/dns.subproj/gethnamaddr.c
@@ -0,0 +1,810 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * ++Copyright++ 1985, 1988, 1993
+ * -
+ * Copyright (c) 1985, 1988, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ * 
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)gethostnamadr.c	8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id: gethnamaddr.c,v 1.2 1999/10/14 21:56:44 wsanchez Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <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
index 0000000..415aa1b
--- /dev/null
+++ b/dns.subproj/getnetbyaddr.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getnetbyaddr.c	1.1 (Coimbra) 93/06/02";
+static char rcsid[] = "$Id: getnetbyaddr.c,v 1.2 1999/10/14 21:56:44 wsanchez Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <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
index 0000000..fe5ac4d
--- /dev/null
+++ b/dns.subproj/getnetbyname.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getnetbyname.c	8.1 (Berkeley) 6/4/93";
+static char sccsid_[] = "from getnetbyname.c	1.1 (Coimbra) 93/06/02";
+static char rcsid[] = "$Id: getnetbyname.c,v 1.2 1999/10/14 21:56:44 wsanchez Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <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
index 0000000..00f9d6e
--- /dev/null
+++ b/dns.subproj/getnetent.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* Portions Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
+ *	Dep. Matematica Universidade de Coimbra, Portugal, Europe
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * from getnetent.c	1.1 (Coimbra) 93/06/02
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getnetent.c	8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id: getnetent.c,v 1.2 1999/10/14 21:56:44 wsanchez Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <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
index 0000000..f3d3265
--- /dev/null
+++ b/dns.subproj/getnetnamadr.c
@@ -0,0 +1,328 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
+ *	Dep. Matematica Universidade de Coimbra, Portugal, Europe
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getnetbyaddr.c	8.1 (Berkeley) 6/4/93";
+static char sccsid_[] = "from getnetnamadr.c	1.4 (Coimbra) 93/06/03";
+static char rcsid[] = "$Id: getnetnamadr.c,v 1.2 1999/10/14 21:56:44 wsanchez Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <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
index 0000000..dcfe656
--- /dev/null
+++ b/dns.subproj/herror.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * ++Copyright++ 1987, 1993
+ * -
+ * Copyright (c) 1987, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ * 
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)herror.c	8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id: herror.c,v 1.2 1999/10/14 21:56:44 wsanchez Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <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
index 0000000..ae203b2
--- /dev/null
+++ b/dns.subproj/inet.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * ++Copyright++ 1983, 1993
+ * -
+ * Copyright (c) 1983, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ * 
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+/*
+ *	@(#)inet.h	8.1 (Berkeley) 6/2/93
+ *	$Id: inet.h,v 1.2 1999/10/14 21:56:45 wsanchez Exp $
+ */
+
+#ifndef _INET_H_
+#define	_INET_H_
+
+/* External definitions for functions in inet(3) */
+
+#include <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
index 0000000..b3874e4
--- /dev/null
+++ b/dns.subproj/nameser.h
@@ -0,0 +1,368 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * ++Copyright++ 1983, 1989, 1993
+ * -
+ * Copyright (c) 1983, 1989, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ * 
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+/*
+ *      @(#)nameser.h	8.1 (Berkeley) 6/2/93
+ *	$Id: nameser.h,v 1.2 1999/10/14 21:56:45 wsanchez Exp $
+ */
+
+#ifndef _NAMESER_H_
+#define	_NAMESER_H_
+
+#include <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
index 0000000..6a79326
--- /dev/null
+++ b/dns.subproj/options.h
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* options.h - specify the conditionally-compiled features
+ * vix 28mar92 [moved out of the Makefile because they were getting too big]
+ *
+ * $Id: options.h,v 1.2 1999/10/14 21:56:45 wsanchez Exp $
+ */
+
+/*
+ * ++Copyright++
+ * -
+ * Copyright (c) 
+ *    The Regents of the University of California.  All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ * 
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+/* Key:
+ *	ucb = U C Berkeley 4.8.3 release
+ *	vix = Paul Vixie of Digital
+ *	del = Don Lewis of Harris
+ *	mcsun = Piet Beertema of EUNet
+ *	asp = Andrew Partan of UUNet
+ *	pma = Paul Albitz of Hewlett Packard
+ *	bb = Bryan Beecher of UMich
+ *	mpa = Mark Andrews of CSIRO - DMS
+ *	rossc = Ross Cartlidge of The Univeritsy of Sydney
+ *	mtr = Marshall Rose of TPC.INT
+ *      bg = Benoit Grange of INRIA
+ *      ckd = Christopher Davis of Kapor Enterprises
+ *      gns = Greg Shapiro of WPI
+ */
+
+#define DEBUG		/* enable -d flag and SIGUSR[12] support (ucb) */
+/*#define ALLOW_T_UNSPEC  enable the "unspec" RR type for old athena (ucb) */
+/*#define INVQ		 enable inverse queries (nslookup) (ucb/vix) */
+/*#define DSTORAGE	 debug malloc overruns using storage.o (ucb/vix) */
+/*#define DMALLOC	 trace malloc orphans using dmalloc.o (vix) */
+#define XFRNETS  	/* enable "xfrnets" command in named.boot (vix) */
+#define PID_FIX   	/* be careful about overwriting named.pid file (del) */
+#define FWD_LOOP	/* try to break out of forwarding loops (del) */
+#define NO_GLUE  	/* don't accept or send out-of-zone glue (del) */
+#define	BOGUSNS  	/* detect bogus nameservers (mcsun) */
+#define QRYLOG  	/* enable SIGWINCH for query logging (bb) */
+/*#define YPKLUDGE  	 deal effectively with broken "ypserv -i" (mcsun) */
+#define TRACEROOT  	/* trace bogus root servers and ignore them (pma,bb) */
+/*#define LOCALDOM	 permit "domain" directive in named.boot (ucb) */
+#define FORCED_RELOAD	/* refresh secondary zones on SIGHUP (pma) */
+#define SLAVE_FORWARD	/* use sensible timeouts on slave forwarders (pma) */
+#define WANT_PIDFILE	/* if you want the named.pid file (ucb/arc) */
+#define DOTTED_SERIAL	/* if you want to be able to specify dotted serial#s */
+/*#define SENSIBLE_DOTS	 if you want dotted serial#s to make numeric sense */
+#define NCACHE		/* negative caching (anant@isi.edu) */
+/*#define VALIDATE	 validation procedure (anant@isi.edu) (DO NOT USE!)*/
+/*#define SHORT_FNAMES	 file names used in named-xfer need to be short */
+#define RESOLVSORT	/* allow sorting of addresses in gethostbyname (mpa) */
+#define STUBS		/* allow transfers of NS only for a zone (mpa) */
+#ifndef LOGFAC
+#define	LOGFAC LOG_DAEMON /* what syslog facility should named use? */
+#endif
+#define SECURE_ZONES	/* if you want to inhibit world access to zones (gns)*/
+#define ROUND_ROBIN	/* rotate databuf list after each access (mtr) */
+#define ADDAUTH 	/* return NS and glue w/ authorative answers (mpa) */
+#define RFC1535		/* use RFC 1535 default for "search" list (vix) */
+#define GEN_AXFR	/* distinct zones within each class */
+#define DATUMREFCNT	/* use reference counts on datums (mpa) */
+#define LAME_DELEGATION	/* lame delegations (original-del,reworked-bb&del)*/
+#define LAME_LOGGING LOG_WARNING /* log lame delegations, set log level */
+#define GETSER_LOGGING LOG_INFO /* log errors/timeouts getting serial number */
+/*#define RETURNSOA	 good code that the world isn't ready for yet */
+#define CLEANCACHE	/* useful and necessary in the face of NCACHE */
+#define PURGE_ZONE	/* remove all traces of a zone when reloading (mpa) */
+#define STATS		/* keep nameserver statistics; uses more memory */
+#define RENICE  	/* named-xfer should run at normal priority */
+#define XSTATS		/* extended statistics, syslogged periodically (bg) */
+/*#define BIND_NOTIFY	 experimental - do not enable in customer products */
+/*#define LOC_RR	 support for (draft) LOC record parsing (ckd) */
+
+/*--------------------------------------------*
+ * no user-servicable parts beyond this point *
+ *--------------------------------------------*/
+
+/* if DSTORAGE is defined, we need to disable DMALLOC and remap
+ * malloc and free to storage.o's exported names.  storage.o also
+ * includes a calloc and a realloc, but once we drag in its malloc
+ * and free we'll get the others automatically and so will never
+ * pull in those routines from libc.a.
+ */
+#ifdef DSTORAGE
+# ifdef DMALLOC
+#  undef DMALLOC
+# endif /*DMALLOC*/
+# define malloc	rt_malloc
+# define free rt_free
+#endif /*DSTORAGE*/
+
+/* if DMALLOC is defined, grab the header file which will remap
+ * all the malloc-style names to those exported by dmalloc.o.  note
+ * that DMALLOC also changes the function signatures of several
+ * functions in private named source modules, and that this file
+ * (options.h) must be included before any other private *.h files
+ * since those *.h files have some conditional remapping to do.
+ */
+#ifdef DMALLOC
+# include "dmalloc.h"
+#endif
+
+/* systems with killall(1M) don't need this
+ */
+#ifdef __sgi
+# ifdef WANT_PIDFILE
+#  undef WANT_PIDFILE
+# endif
+#endif
+
+#ifdef LAME_LOGGING
+# define LAME_DELEGATION
+#endif
+
+#if defined(XSTATS) && !defined(STATS)
+# define STATS
+#endif
diff --git a/dns.subproj/portability.h b/dns.subproj/portability.h
new file mode 100644
index 0000000..55ed578
--- /dev/null
+++ b/dns.subproj/portability.h
@@ -0,0 +1,570 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* portability.h - include or define things that aren't present on all systems
+ * vixie@decwrl 26dec92 [new]
+ *
+ * $Id: portability.h,v 1.2 1999/10/14 21:56:45 wsanchez Exp $
+ */
+
+/*
+ * ++Copyright++
+ * -
+ * Copyright (c) 
+ *    The Regents of the University of California.  All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ * 
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+/* XXX:	this file has become a hopeless morass, and will be redone someday. */
+
+#include <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
index 0000000..7c07818
--- /dev/null
+++ b/dns.subproj/res_comp.c
@@ -0,0 +1,452 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * ++Copyright++ 1985, 1993
+ * -
+ * Copyright (c) 1985, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ * 
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_comp.c	8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id: res_comp.c,v 1.2 1999/10/14 21:56:45 wsanchez Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <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
index 0000000..93d648d
--- /dev/null
+++ b/dns.subproj/res_data.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * This file contains global data but it is a `private_extern' in the
+ * shared library so that its address and size can change.
+ */
+
+#if defined(__APPLE__)
+
+#include <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
index 0000000..519104a
--- /dev/null
+++ b/dns.subproj/res_debug.c
@@ -0,0 +1,857 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * ++Copyright++ 1985, 1990, 1993
+ * -
+ * Copyright (c) 1985, 1990, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ * 
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_debug.c	8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id: res_debug.c,v 1.2 1999/10/14 21:56:45 wsanchez Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <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
index 0000000..5eb64dd
--- /dev/null
+++ b/dns.subproj/res_init.c
@@ -0,0 +1,675 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * ++Copyright++ 1985, 1989, 1993
+ * -
+ * Copyright (c) 1985, 1989, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ * 
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_init.c	8.1 (Berkeley) 6/7/93";
+static char rcsid[] = "$Id: res_init.c,v 1.3 2000/08/01 23:12:13 lindak Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <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
index 0000000..deda02f
--- /dev/null
+++ b/dns.subproj/res_mkquery.c
@@ -0,0 +1,272 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * ++Copyright++ 1985, 1993
+ * -
+ * Copyright (c) 1985, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ * 
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_mkquery.c	8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id: res_mkquery.c,v 1.2 1999/10/14 21:56:45 wsanchez Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <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
index 0000000..85b705a
--- /dev/null
+++ b/dns.subproj/res_query.c
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * ++Copyright++ 1988, 1993
+ * -
+ * Copyright (c) 1988, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ * 
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_query.c	8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id: res_query.c,v 1.2 1999/10/14 21:56:45 wsanchez Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <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
index 0000000..b1c3a08
--- /dev/null
+++ b/dns.subproj/res_send.c
@@ -0,0 +1,784 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * ++Copyright++ 1985, 1989, 1993
+ * -
+ * Copyright (c) 1985, 1989, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ * 
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)res_send.c	8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id: res_send.c,v 1.2 1999/10/14 21:56:45 wsanchez Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+	/* change this to "0"
+	 * if you talk to a lot
+	 * of multi-homed SunOS
+	 * ("broken") name servers.
+	 */
+#define	CHECK_SRVR_ADDR	1	/* XXX - should be in options.h */
+
+/*
+ * Send query to name server and wait for reply.
+ */
+
+#include <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
index 0000000..12302ac
--- /dev/null
+++ b/dns.subproj/resolv.h
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * ++Copyright++ 1983, 1987, 1989, 1993
+ * -
+ * Copyright (c) 1983, 1987, 1989, 1993
+ *    The Regents of the University of California.  All rights reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ * 	This product includes software developed by the University of
+ * 	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * -
+ * Portions Copyright (c) 1993 by Digital Equipment Corporation.
+ * 
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies, and that
+ * the name of Digital Equipment Corporation not be used in advertising or
+ * publicity pertaining to distribution of the document or software without
+ * specific, written prior permission.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
+ * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
+ * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
+ * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
+ * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
+ * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
+ * SOFTWARE.
+ * -
+ * --Copyright--
+ */
+
+/*
+ *	@(#)resolv.h	8.1 (Berkeley) 6/2/93
+ *	$Id: resolv.h,v 1.2 1999/10/14 21:56:45 wsanchez Exp $
+ */
+
+#ifndef _RESOLV_H_
+#define	_RESOLV_H_
+
+#include <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
index 0000000..3070283
--- /dev/null
+++ b/dns.subproj/sethostent.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1985, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)sethostent.c	8.1 (Berkeley) 6/4/93";
+static char rcsid[] = "$Id: sethostent.c,v 1.2 1999/10/14 21:56:45 wsanchez Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <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
index 0000000..3e59457
--- /dev/null
+++ b/gen.subproj/Makefile
@@ -0,0 +1,47 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = gen
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Component
+
+CFILES = aliasdb.c ether_addr.c fstab.c getaddrinfo.c getgrent.c getproto.c\
+         getprotoent.c getprotoname.c getpwent.c getservbyname.c\
+         getservbyport.c getservent.c initgroups.c printerdb.c
+
+OTHERSRCS = Makefile.preamble Makefile
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = subproj.make
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/gen.subproj/Makefile.preamble b/gen.subproj/Makefile.preamble
new file mode 100644
index 0000000..8bcebdc
--- /dev/null
+++ b/gen.subproj/Makefile.preamble
@@ -0,0 +1,31 @@
+OTHER_CFLAGS = \
+	-Dsetservent=_old_setservent \
+	-Dgetservent=_old_getservent \
+	-Dendservent=_old_endservent \
+	-Dgetservbyname=_old_getservbyname \
+	-Dgetservbyport=_old_getservbyport \
+	-Dsetprotoent=_old_setprotoent \
+	-Dgetprotoent=_old_getprotoent \
+	-Dendprotoent=_old_endprotoent \
+	-Dgetprotobyname=_old_getprotobyname \
+	-Dgetprotobynumber=_old_getprotobynumber \
+	-Dsetnetgrent=_old_setnetgrent \
+	-Dgetnetgrent=_old_getnetgrent \
+	-Dendnetgrent=_old_endnetgrent \
+	-Dsetpwent=_old_setpwent \
+	-Dgetpwent=_old_getpwent \
+	-Dendpwent=_old_endpwent \
+	-Dgetpwnam=_old_getpwnam \
+	-Dgetpwuid=_old_getpwuid \
+	-Dsetgrent=_old_setgrent \
+	-Dgetgrent=_old_getgrent \
+	-Dendgrent=_old_endgrent \
+	-Dgetgrnam=_old_getgrnam \
+	-Dgetgrgid=_old_getgrgid \
+	-Dsetfsent=_old_setfsent \
+	-Dendfsent=_old_endfsent \
+	-Dgetfsent=_old_getfsent \
+	-Dgetfsfile=_old_getfsfile \
+	-Dgetfsspec=_old_getfsspec \
+	-Dinitgroups=_old_initgroups \
+	-I../lookup.subproj
diff --git a/gen.subproj/PB.project b/gen.subproj/PB.project
new file mode 100644
index 0000000..5e70c18
--- /dev/null
+++ b/gen.subproj/PB.project
@@ -0,0 +1,37 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        H_FILES = (); 
+        OTHER_LINKED = (
+            aliasdb.c, 
+            ether_addr.c, 
+            fstab.c, 
+            getaddrinfo.c, 
+            getgrent.c, 
+            getproto.c, 
+            getprotoent.c, 
+            getprotoname.c, 
+            getpwent.c, 
+            getservbyname.c, 
+            getservbyport.c, 
+            getservent.c, 
+            initgroups.c, 
+            printerdb.c
+        ); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile); 
+    }; 
+    LANGUAGE = English; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = gen; 
+    PROJECTTYPE = Component; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/gen.subproj/aliasdb.c b/gen.subproj/aliasdb.c
new file mode 100644
index 0000000..ad0bd4f
--- /dev/null
+++ b/gen.subproj/aliasdb.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Unimplemented backward-compatible alias lookup routines.
+ * These are only called if NetInfo is not running or if YP
+ * has been turned on, in which case NetInfo will be tried first.
+ * This is the standard NeXT policy for all lookup routines.
+ */
+
+#include <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
index 0000000..d3d1aea
--- /dev/null
+++ b/gen.subproj/ether_addr.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static  char sccsid[] = "@(#)ether_addr.c	1.2 88/05/10 4.0NFSSRC; from 1.9 88/02/08 Copyr 1985 Sun Micro";
+#endif
+
+/*
+ * Copyright (c) 1985 by Sun Microsystems, Inc.
+ *
+ * All routines necessary to deal with the file /etc/ethers.  The file
+ * contains mappings from 48 bit ethernet addresses to their corresponding
+ * hosts name.  The addresses have an ascii representation of the form
+ * "x:x:x:x:x:x" where x is a hex number between 0x00 and 0xff;  the
+ * bytes are always in network order.
+ */
+
+#include <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
index 0000000..09a2f7b
--- /dev/null
+++ b/gen.subproj/fstab.c
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved
+ *
+ * Copyright (c) 1980, 1988, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * The NEXTSTEP Software License Agreement specifies the terms
+ * and conditions for redistribution.
+ *
+ *	@(#)fstab.c	8.1 (Berkeley) 6/4/93
+ */
+
+
+#include <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
index 0000000..bce133f
--- /dev/null
+++ b/gen.subproj/getaddrinfo.c
@@ -0,0 +1,1608 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <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
index 0000000..e9552d4
--- /dev/null
+++ b/gen.subproj/getgrent.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getgrent.c	8.2 (Berkeley) 3/21/94";
+#endif /* LIBC_SCCS and not lint */
+
+#include <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
index 0000000..0c3634e
--- /dev/null
+++ b/gen.subproj/getproto.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getproto.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <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
index 0000000..0320109
--- /dev/null
+++ b/gen.subproj/getprotoent.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getprotoent.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <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
index 0000000..49551e1
--- /dev/null
+++ b/gen.subproj/getprotoname.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getprotoname.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <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
index 0000000..a9f4798
--- /dev/null
+++ b/gen.subproj/getpwent.c
@@ -0,0 +1,370 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright 1997 Apple Computer, Inc. (unpublished)
+ * 
+ * /etc/passwd file access routines.
+ * Just read from the /etc/passwd file and skip the dbm database, since
+ * lookupd does all flat file lookups when the system is multi-user.
+ * These routines are only used in single-user mode.
+ *
+ * 17 Apr 1997 file created - Marc Majka
+ */
+
+#include <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
index 0000000..45766e3
--- /dev/null
+++ b/gen.subproj/getservbyname.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getservbyname.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <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
index 0000000..af3eeb0
--- /dev/null
+++ b/gen.subproj/getservbyport.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getservbyport.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <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
index 0000000..16d5cd9
--- /dev/null
+++ b/gen.subproj/getservent.c
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getservent.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <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
index 0000000..455c363
--- /dev/null
+++ b/gen.subproj/initgroups.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1983, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)initgroups.c	8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <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
index 0000000..2d77bdf
--- /dev/null
+++ b/gen.subproj/printerdb.c
@@ -0,0 +1,286 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * /etc/printcap reader (in case NetInfo is not running)
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+#include <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
index 0000000..2122bc1
--- /dev/null
+++ b/lookup.subproj/Makefile
@@ -0,0 +1,54 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = lookup
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Component
+
+HFILES = aliasdb.h bootparams.h lookup_types.h lu_overrides.h\
+         lu_utils.h netgr.h printerdb.h
+
+CFILES = lu_alias.c lu_bootp.c lu_bootparam.c lu_fstab.c lu_group.c\
+         lu_host.c lu_netgroup.c lu_network.c lu_printer.c\
+         lu_protocol.c lu_rpc.c lu_service.c lu_user.c lu_utils.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble lookup.defs\
+            _lu_types.x
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = subproj.make
+NEXTSTEP_INSTALLDIR = /Local/Developer/System
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+PUBLIC_HEADERS = aliasdb.h bootparams.h printerdb.h
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/lookup.subproj/Makefile.postamble b/lookup.subproj/Makefile.postamble
new file mode 100644
index 0000000..cf76087
--- /dev/null
+++ b/lookup.subproj/Makefile.postamble
@@ -0,0 +1,8 @@
+%_xdr.c: %.x
+	$(RPCGEN) $(ALL_RPCFLAGS) -c -o $(SYM_DIR)/$*_xdr.c $*.x
+
+netinfo_hdrs: $(DSTROOT)$(PUBLIC_HDR_INSTALLDIR)$(NETINFO_HEADER_DIR_SUFFIX)
+	$(SILENT) $(FASTCP) $(NETINFO_HDRS) $(DSTROOT)$(PUBLIC_HDR_INSTALLDIR)$(NETINFO_HEADER_DIR_SUFFIX)
+
+$(DSTROOT)$(PUBLIC_HDR_INSTALLDIR)$(NETINFO_HEADER_DIR_SUFFIX):
+	$(MKDIRS) $@
diff --git a/lookup.subproj/Makefile.preamble b/lookup.subproj/Makefile.preamble
new file mode 100644
index 0000000..9a094c2
--- /dev/null
+++ b/lookup.subproj/Makefile.preamble
@@ -0,0 +1,8 @@
+RPCFILES = _lu_types.x
+OTHER_OFILES = lookupUser.o _lu_types_xdr.o
+AFTER_PREBUILD = _lu_types.h lookupUser.c 
+NETINFO_HDRS = lookup.h _lu_types.h lookup_types.h lookup.defs _lu_types.x
+BEFORE_INSTALLHDRS += $(SFILE_DIR) $(NETINFO_HDRS)
+AFTER_INSTALLHDRS += netinfo_hdrs
+PUBLIC_HEADER_DIR_SUFFIX = 
+NETINFO_HEADER_DIR_SUFFIX = /netinfo
diff --git a/lookup.subproj/PB.project b/lookup.subproj/PB.project
new file mode 100644
index 0000000..8270f85
--- /dev/null
+++ b/lookup.subproj/PB.project
@@ -0,0 +1,48 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        H_FILES = (
+            aliasdb.h, 
+            bootparams.h, 
+            lookup_types.h, 
+            lu_overrides.h, 
+            lu_utils.h, 
+            netgr.h, 
+            printerdb.h
+        ); 
+        OTHER_LINKED = (
+            lu_alias.c, 
+            lu_bootp.c, 
+            lu_bootparam.c, 
+            lu_fstab.c, 
+            lu_group.c, 
+            lu_host.c, 
+            lu_netgroup.c, 
+            lu_network.c, 
+            lu_printer.c, 
+            lu_protocol.c, 
+            lu_rpc.c, 
+            lu_service.c, 
+            lu_user.c
+        ); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, lookup.defs, _lu_types.x); 
+        PRECOMPILED_HEADERS = (); 
+        PROJECT_HEADERS = (); 
+        PUBLIC_HEADERS = (aliasdb.h, bootparams.h, printerdb.h); 
+    }; 
+    LANGUAGE = English; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_INSTALLDIR = /Local/Developer/System; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = lookup; 
+    PROJECTTYPE = Component; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/lookup.subproj/_lu_types.x b/lookup.subproj/_lu_types.x
new file mode 100644
index 0000000..0fa320e
--- /dev/null
+++ b/lookup.subproj/_lu_types.x
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Lookup server protocol - Internal to NeXT
+ * Copyright (C) 1989 by NeXT, Inc.
+ * 
+ * This server uses a protocol based upon XDR layered on top of 
+ * a mach rpc call. There are three procedures defined in the "lookup.defs"
+ * file. A "lookup_link" operation takes a procedure string name and returns a
+ * number to be used in the other two calls. "lookup_all" takes a procedure
+ * number and XDR'd arguments and returns XDR'd results. It returns the
+ * entire list of entries. "lookup_one" has a similar calling convention,
+ * but returns only a single entry.
+ *
+ * The syntax of calls described here in comments looks like this:
+ *
+ *		result_type procedure_name(arg_type1 arg1, arg_type2 arg2, ...)
+ *
+ *	The arguments are assumed to be XDR'd in sequence and a single XDR'd
+ * 	result is returned.
+ */
+const _LU_MAXLUSTRLEN = 256;
+
+const _LU_MAXGRP = 1024;
+const _LU_MAXHNAMES = 32;
+const _LU_MAXADDRS = 32;
+const _LU_MAXNNAMES = 32;
+const _LU_MAXPNAMES = 32;
+const _LU_MAXSNAMES = 32;
+const _LU_MAXRNAMES = 32;
+const _LU_MAXPRNAMES = 32;
+const _LU_MAXPRPROPS = 1024;
+const _LU_MAX_BOOTPARAMS_KV = 32;
+const _LU_MAXALIASMEMBERS = 4096;
+
+
+typedef string _lu_string<_LU_MAXLUSTRLEN>;
+
+
+/*
+ * Calls available:
+ *	int putpwpasswd(_lu_string long, _lu_string old, _lu_string new)
+ * 	_lu_passwd * getpwuid(int uid)
+ * 	_lu_passwd * getpwnam(_lu_string name)
+ * 	_lu_passwd<> getpwent(void)
+ */
+struct _lu_passwd {
+	_lu_string pw_name;
+	_lu_string pw_passwd;
+	int pw_uid;
+	int pw_gid;
+	int pw_change;
+	_lu_string pw_class;
+	_lu_string pw_gecos;
+	_lu_string pw_dir;
+	_lu_string pw_shell;
+	int pw_expire;
+};
+typedef _lu_passwd *_lu_passwd_ptr;
+
+
+/*
+ * Calls available:
+ * 	_lu_group * getgrgid(int gid)
+ * 	_lu_group * getgrnam(_lu_string name)
+ * 	_lu_group<> getgrent(void)
+ */
+struct _lu_group {
+	_lu_string gr_name;
+	_lu_string gr_passwd;
+	int gr_gid;
+	_lu_string gr_mem<_LU_MAXGRP>;
+};
+typedef _lu_group *_lu_group_ptr;
+
+/*
+ * Calls available:
+ * 	_lu_hostent * gethostbyaddr(unsigned long addr) -- IP only
+ * 	_lu_hostent * gethostbyname(_lu_string name)
+ * 	_lu_hostent<> gethostent(void)
+ */
+struct _lu_hostent {
+	_lu_string h_names<_LU_MAXHNAMES>;
+	unsigned long h_addrs<_LU_MAXADDRS>; /* IP only */
+};
+typedef _lu_hostent *_lu_hostent_ptr;
+
+/*
+ * Calls available:
+ * 	_lu_netent * getnetbyaddr(unsigned long addr) --IP only
+ * 	_lu_netent * getnetbyname(_lu_string name)
+ * 	_lu_netent<> getnetent(void)
+ */
+struct _lu_netent {
+	_lu_string n_names<_LU_MAXNNAMES>;
+	unsigned long n_net;	/* IP only */
+};
+typedef _lu_netent *_lu_netent_ptr;
+
+
+/*
+ * Calls available:
+ * 	_lu_servent * getservbyport(int port, _lu_string proto)
+ * 	_lu_servent * getservbyname(_lu_string name, _lu_string proto)
+ * 	_lu_servent<> getservent(void)
+ */
+struct _lu_servent {
+	_lu_string s_names<_LU_MAXSNAMES>;
+	int s_port;
+	_lu_string s_proto;
+};
+typedef _lu_servent *_lu_servent_ptr;
+
+/*
+ * Calls available:
+ * 	_lu_protoent * getprotobynumber(int number)
+ * 	_lu_protoent * getprotobyname(_lu_string name)
+ * 	_lu_protoent<> getprotoent(void)
+ */
+struct _lu_protoent {
+	_lu_string p_names<_LU_MAXPNAMES>;
+	int p_proto;
+};
+typedef _lu_protoent *_lu_protoent_ptr;
+
+
+/*
+ * Calls available:
+ * 	_lu_rpcent * getrpcbynumber(int number)
+ * 	_lu_rpcent * getrpcbyname(_lu_string name)
+ * 	_lu_rpcent<> getrpcent(void)
+ */
+struct _lu_rpcent {
+	_lu_string r_names<_LU_MAXRNAMES>;
+	int r_number;
+};
+typedef _lu_rpcent *_lu_rpcent_ptr;
+
+/* 
+ * Calls available:
+ * 	_lu_fsent<> getfsent(void)
+ * 	_lu_fsent * getfsbyname(_lu_string name)
+ */
+struct _lu_fsent {
+	_lu_string fs_spec;
+	_lu_string fs_file;
+	_lu_string fs_vfstype;
+	_lu_string fs_mntops;
+	_lu_string fs_type;
+	int fs_freq;
+	int fs_passno;
+};
+typedef _lu_fsent *_lu_fsent_ptr;
+
+/* 
+ * Calls available:
+ *	_lu_prdb_ent * prdb_getbyname
+ * 	_lu_prdb_ent<> prdb_get(void)
+ */
+struct _lu_prdb_property {
+	_lu_string pp_key;
+	_lu_string pp_value;
+};
+
+struct _lu_prdb_ent {
+	_lu_string pe_names<_LU_MAXPRNAMES>;
+	_lu_prdb_property pe_props<_LU_MAXPRPROPS>;
+};
+typedef _lu_prdb_ent *_lu_prdb_ent_ptr;
+
+
+/* 
+ * Calls available:
+ *	_lu_bootp_ent * bootp_getbyip(unsigned long addr)
+ *	_lu_bootp_ent * bootp_getbyether(opaque bootp_enaddr[6])
+ */
+struct _lu_bootp_ent {
+	_lu_string bootp_name;
+	_lu_string bootp_bootfile;
+	unsigned long bootp_ipaddr;
+	opaque bootp_enaddr[6];
+};
+typedef _lu_bootp_ent *_lu_bootp_ent_ptr;
+
+/*
+ * Calls available:
+ *	_lu_bootparams_ent * bootparams_getbyname(_lu_string name)
+ *	_lu_bootparams_ent<> bootparams_getent(void)
+ */
+struct _lu_bootparams_ent {
+	_lu_string bootparams_name;
+	_lu_string bootparams_keyvalues<_LU_MAX_BOOTPARAMS_KV>;
+};
+typedef _lu_bootparams_ent *_lu_bootparams_ent_ptr;
+
+
+/*
+ * Calls available:
+ *	_lu_aliasent * alias_getbyname(_lu_string name)
+ *	_lu_aliasent<> alias_getent(void)
+ */
+struct _lu_aliasent {
+	_lu_string alias_name;
+	_lu_string alias_members<_LU_MAXALIASMEMBERS>;
+	int alias_local;
+};
+typedef _lu_aliasent *_lu_aliasent_ptr;
+
+/*
+ * Calls available:
+ *	int innetgr(_lu_innetgr_args args)
+ *	_lu_netgrent<> getnetgrent(_lu_string group)
+ */
+struct _lu_innetgr_args {
+	_lu_string group;
+	_lu_string *host;
+	_lu_string *user;
+	_lu_string *domain;
+};
+
+struct _lu_netgrent{
+	_lu_string ng_host;
+	_lu_string ng_user;
+	_lu_string ng_domain;
+};
+
diff --git a/lookup.subproj/aliasdb.h b/lookup.subproj/aliasdb.h
new file mode 100644
index 0000000..7961135
--- /dev/null
+++ b/lookup.subproj/aliasdb.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Mail alias lookup routines
+ * Copyright (c) 1989 by NeXT, Inc.
+ */
+
+#ifndef _ALIAS_H_
+#define _ALIAS_H_
+
+struct aliasent {
+	char		*alias_name;
+	unsigned	alias_members_len;
+	char		**alias_members;
+	int			alias_local;
+};
+
+#include <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
index 0000000..377298d
--- /dev/null
+++ b/lookup.subproj/bootparams.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Bootparams lookup routines
+ *
+ * Copyright 1997
+ * Apple Computer Inc.
+ */
+
+#ifndef _BOOTPARAMS_H_
+#define _BOOTPARAMS_H_
+
+#include <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
index 0000000..167d609
--- /dev/null
+++ b/lookup.subproj/lookup.defs
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* 
+ * Lookup protocol specification - internal to NeXT
+ * Copyright (C) 1989 by NeXT, Inc.
+ *
+ * History:
+ * 25-Jun-1998	Umesh Vaishampayan (umeshv@apple.com)
+ *	Ported to MacOSX.
+ */
+
+subsystem lookup 4241775;
+serverprefix _;
+
+import <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
index 0000000..7d8fcd2
--- /dev/null
+++ b/lookup.subproj/lookup_types.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Lookup protocol definitions - internal to NeXT
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+
+/*
+ * the port to lookupd is obtained through the (internal)
+ * _lookupd_port() syscall instead of through the nameserver
+ * with LOOKUP_SERVER_NAME as "C Library Lookup"
+ */
+
+#define UNIT_SIZE 4
+
+typedef struct unit {
+	char data[UNIT_SIZE];
+} unit;
+
+#define MAX_INLINE_UNITS 4095
+#define MAX_LOOKUP_NAMELEN 256
+#define MAX_INLINE_DATA (MAX_INLINE_UNITS * sizeof(unit))
+
+typedef char lookup_name[MAX_LOOKUP_NAMELEN];
+typedef unit inline_data[MAX_INLINE_UNITS];
+typedef char *ooline_data;
diff --git a/lookup.subproj/lu_alias.c b/lookup.subproj/lu_alias.c
new file mode 100644
index 0000000..f215067
--- /dev/null
+++ b/lookup.subproj/lu_alias.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Alias lookup
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+
+#include <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
index 0000000..ca85dbe
--- /dev/null
+++ b/lookup.subproj/lu_bootp.c
@@ -0,0 +1,145 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Bootp lookup - netinfo only
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+#include <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
index 0000000..9386e98
--- /dev/null
+++ b/lookup.subproj/lu_bootparam.c
@@ -0,0 +1,246 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Bootparams lookup - netinfo only
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+#include <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
index 0000000..b206a8a
--- /dev/null
+++ b/lookup.subproj/lu_fstab.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * fstab entry lookup
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+
+#include <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
index 0000000..5022f9c
--- /dev/null
+++ b/lookup.subproj/lu_group.c
@@ -0,0 +1,396 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Unix group lookup
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+
+#include <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
index 0000000..ca56659
--- /dev/null
+++ b/lookup.subproj/lu_host.c
@@ -0,0 +1,378 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * host lookup
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+#include <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
index 0000000..8e52272
--- /dev/null
+++ b/lookup.subproj/lu_netgroup.c
@@ -0,0 +1,257 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Netgroup lookup
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+#include <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
index 0000000..78533f9
--- /dev/null
+++ b/lookup.subproj/lu_network.c
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * network lookup
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+#include <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
index 0000000..c7134b2
--- /dev/null
+++ b/lookup.subproj/lu_overrides.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * These are routines typically defined in libc
+ * that are replaced by NetInfo.
+ *
+ * Copyright (c) 1995,  NeXT Computer Inc.
+ */
+
+#ifndef _LU_OVERRIDES_H_
+#define	_LU_OVERRIDES_H_
+
+#include <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
index 0000000..0290e10
--- /dev/null
+++ b/lookup.subproj/lu_printer.c
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Printer lookup
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+#include <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
index 0000000..f3c0e4b
--- /dev/null
+++ b/lookup.subproj/lu_protocol.c
@@ -0,0 +1,299 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Protocol lookup
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+#include <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
index 0000000..3bd9460
--- /dev/null
+++ b/lookup.subproj/lu_rpc.c
@@ -0,0 +1,301 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * RPC lookup
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+
+#include <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
index 0000000..2fd3e2a
--- /dev/null
+++ b/lookup.subproj/lu_service.c
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Services file lookup
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+#include <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
index 0000000..ecf36f6
--- /dev/null
+++ b/lookup.subproj/lu_user.c
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * user information (passwd) lookup
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+#include <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
index 0000000..b458b74
--- /dev/null
+++ b/lookup.subproj/lu_utils.c
@@ -0,0 +1,332 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+#include <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
index 0000000..d1a268c
--- /dev/null
+++ b/lookup.subproj/lu_utils.h
@@ -0,0 +1,130 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Useful macros and other stuff for generic lookups
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+
+#import <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
index 0000000..f2b1917
--- /dev/null
+++ b/lookup.subproj/netgr.h
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Netgroup lookup routines
+ * Copyright (c) 1989 by NeXT, Inc.
+ */
+
+#ifndef _NETGR_H_
+#define _NETGR_H_
+
+struct netgrent {
+	char	*ng_host;
+	char	*ng_user;
+	char	*ng_domain;
+};
+
+#include <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
index 0000000..8058f4d
--- /dev/null
+++ b/lookup.subproj/printerdb.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* 
+ * Printer database lookup routines
+ * Copyright (c) 1989 by NeXT, Inc. 
+ */
+
+#ifndef _PRDB_H_
+#define _PRDB_H_
+
+typedef struct prdb_property {
+	char *pp_key;
+	char *pp_value;
+} prdb_property;
+
+typedef struct prdb_ent {
+	char **pe_name;
+	unsigned pe_nprops;
+	prdb_property *pe_prop;
+} prdb_ent;
+
+#include <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
index 0000000..baf2315
--- /dev/null
+++ b/netinfo.subproj/Makefile
@@ -0,0 +1,51 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = netinfo
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Component
+
+HFILES = clib.h mm.h ni.h ni_util.h
+
+CFILES = multi_call.c ni_error.c ni_glue.c ni_pwdomain.c ni_useful.c\
+         ni_util.c
+
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble nibind_prot.x\
+            ni_prot.x
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = subproj.make
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+PUBLIC_HEADERS = ni.h ni_util.h nibind_prot.x ni_prot.x
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/netinfo.subproj/Makefile.postamble b/netinfo.subproj/Makefile.postamble
new file mode 100644
index 0000000..8361d56
--- /dev/null
+++ b/netinfo.subproj/Makefile.postamble
@@ -0,0 +1,5 @@
+%_clnt.c: %.x
+	$(RPCGEN) $(ALL_RPCFLAGS) -l -o $(SYM_DIR)/$*_clnt.c $*.x
+
+%_xdr.c: %.x
+	$(RPCGEN) $(ALL_RPCFLAGS) -c -o $(SYM_DIR)/$*_xdr.c $*.x
diff --git a/netinfo.subproj/Makefile.preamble b/netinfo.subproj/Makefile.preamble
new file mode 100644
index 0000000..77e442b
--- /dev/null
+++ b/netinfo.subproj/Makefile.preamble
@@ -0,0 +1,6 @@
+OTHER_OFILES = nibind_prot_clnt.o ni_prot_clnt.o nibind_prot_xdr.o ni_prot_xdr.o
+NETINFO_HEADERS = nibind_prot.h ni_prot.h
+AFTER_PREBUILD = $(NETINFO_HEADERS)
+OTHER_PUBLIC_HEADERS = $(NETINFO_HEADERS)
+BEFORE_INSTALLHEADERS += $(NETINFO_HEADERS)
+PUBLIC_HEADER_DIR_SUFFIX = /netinfo
diff --git a/netinfo.subproj/PB.project b/netinfo.subproj/PB.project
new file mode 100644
index 0000000..ecd1da8
--- /dev/null
+++ b/netinfo.subproj/PB.project
@@ -0,0 +1,23 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        H_FILES = (clib.h, mm.h, ni.h, ni_util.h); 
+        OTHER_LINKED = (multi_call.c, ni_error.c, ni_glue.c, ni_pwdomain.c, ni_useful.c, ni_util.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile, Makefile.postamble, nibind_prot.x, ni_prot.x); 
+        PUBLIC_HEADERS = (ni.h, ni_util.h); 
+    }; 
+    LANGUAGE = English; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = netinfo; 
+    PROJECTTYPE = Component; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/netinfo.subproj/clib.h b/netinfo.subproj/clib.h
new file mode 100644
index 0000000..d284ec5
--- /dev/null
+++ b/netinfo.subproj/clib.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Standard libc stuff used by source files in this directory
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+
+enum clnt_stat multi_call(unsigned,
+			  struct in_addr *, u_long, u_long, u_long,
+			  xdrproc_t, void *, unsigned, xdrproc_t, 
+			  void *,
+			  int (*)(), int);
+//bool_t xdr_free(xdrproc_t, void *);
diff --git a/netinfo.subproj/mm.h b/netinfo.subproj/mm.h
new file mode 100644
index 0000000..7c32dee
--- /dev/null
+++ b/netinfo.subproj/mm.h
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Useful memory managment macros
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+#define  mm_used() mstats()
+
+#define MM_ALLOC(obj) obj = ((void *)malloc(sizeof(*(obj))))
+
+#define MM_FREE(obj)  free((void *)(obj))
+
+#define MM_ZERO(obj)  bzero((void *)(obj), sizeof(*(obj)))
+
+#define MM_BCOPY(b1, b2, size) bcopy((void *)(b1), (void *)(b2), \
+				     (unsigned)(size))
+
+#define MM_BEQ(b1, b2, size) (bcmp((void *)(b1), (void *)(b2), \
+				   (unsigned)(size)) == 0)
+
+#define MM_ALLOC_ARRAY(obj, len)  \
+	obj = ((void *)malloc(sizeof(*(obj)) * (len)))
+
+#define MM_ZERO_ARRAY(obj, len) bzero((void *)(obj), sizeof(*obj) * len)
+
+#define MM_FREE_ARRAY(obj, len) free((void *)(obj))
+
+#define MM_GROW_ARRAY(obj, len) \
+	((obj == NULL) ? (MM_ALLOC_ARRAY((obj), (len) + 1)) : \
+	 (obj = (void *)realloc((void *)(obj), \
+				sizeof(*(obj)) * ((len) + 1))))
+
+#define MM_SHRINK_ARRAY(obj, len) \
+	obj = (void *)realloc((void *)(obj), \
+			      sizeof(*(obj)) * ((len) - 1))
+
diff --git a/netinfo.subproj/multi_call.c b/netinfo.subproj/multi_call.c
new file mode 100644
index 0000000..47b031f
--- /dev/null
+++ b/netinfo.subproj/multi_call.c
@@ -0,0 +1,352 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * multi_call: send out multiple call messages, wait for first reply
+ * Copyright (C) 1991 by NeXT, Inc.
+ */
+#include <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
index 0000000..6de58bc
--- /dev/null
+++ b/netinfo.subproj/ni.h
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * NetInfo library entry points
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+
+#ifndef __NI_HEADER__
+#define __NI_HEADER__
+
+#ifndef SUN_RPC
+#define SUN_RPC 1
+#endif
+
+#include <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
index 0000000..63aaff8
--- /dev/null
+++ b/netinfo.subproj/ni_error.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * NetInfo error status -> string conversion.
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+#include <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
index 0000000..0a22e74
--- /dev/null
+++ b/netinfo.subproj/ni_glue.c
@@ -0,0 +1,2251 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Glues the library routines to the stub routines
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+#include <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
index 0000000..a83e0fe
--- /dev/null
+++ b/netinfo.subproj/ni_prot.x
@@ -0,0 +1,502 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* 
+ * NetInfo protocol specification
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+
+/* Preamble appearing on all generated output */
+#ifndef NOPREAMBLE
+%/*
+% * Output of the RPC protocol compiler: DO NOT EDIT
+% * Copyright (C) 1989 by NeXT, Inc.
+% */
+#endif
+
+#ifndef RPC_HDR
+%#include <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
index 0000000..c872cc8
--- /dev/null
+++ b/netinfo.subproj/ni_pwdomain.c
@@ -0,0 +1,345 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (C) 1990 by NeXT, Inc. All rights reserved.
+ */
+
+/*
+ * ni_pwdomain function: present working domain for a netinfo handle
+ *
+ * usage:
+ * 	ni_status ni_pwdomain(void *ni, ni_name *buf)
+ *
+ * pwd is returned in buf, which can be freed with ni_name_free
+ */
+#include <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
index 0000000..a3d3df6
--- /dev/null
+++ b/netinfo.subproj/ni_useful.c
@@ -0,0 +1,745 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Useful stuff for programming netinfo
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+#include <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
index 0000000..c279510
--- /dev/null
+++ b/netinfo.subproj/ni_util.c
@@ -0,0 +1,527 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Utility routines for netinfo data structures
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+#include <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
index 0000000..6cb2c56
--- /dev/null
+++ b/netinfo.subproj/ni_util.h
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Utility routines for NetInfo
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+
+#ifndef _NI_UTIL_H_
+#define _NI_UTIL_H_
+
+#include <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
index 0000000..19ef737
--- /dev/null
+++ b/netinfo.subproj/nibind_prot.x
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* 
+ * NetInfo binder protocol specification
+ * Copyright (C) 1989 by NeXT, Inc.
+ */
+
+/* Preamble appearing on all generated output */
+#ifndef NOPREAMBLE
+%/*
+% * Output of the RPC protocol compiler: DO NOT EDIT
+% * Copyright (C) 1989 by NeXT, Inc.
+% */
+#endif
+
+#ifdef RPC_HDR
+%#ifndef NI_PROG
+%#include <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
index 0000000..fd7babb
--- /dev/null
+++ b/nis.subproj/Makefile
@@ -0,0 +1,58 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = nis
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Component
+
+HFILES = ypclnt.h ypinternal.h yp_prot.h
+
+CFILES = getdomainname.c getnetgrent.c innetgr.c setdomainname.c\
+         xdr_domainname.c xdr_keydat.c xdr_mapname.c xdr_peername.c\
+         xdr_valdat.c xdr_ypbind_binding.c xdr_ypbind_resp.c\
+         xdr_ypbind_resptype.c xdr_ypbind_setdom.c xdr_ypmaplist.c\
+         xdr_ypreq_key.c xdr_ypreq_nokey.c xdr_ypresp_all.c\
+         xdr_ypresp_key_val.c xdr_ypresp_maplist.c xdr_ypresp_master.c\
+         xdr_ypresp_order.c xdr_ypresp_val.c xdr_ypstat.c\
+         yperr_string.c ypmatch_cache.c yppasswdd_xdr.c ypprot_err.c\
+         yp_all.c yp_bind.c yp_first.c yp_get_default_domain.c\
+         yp_maplist.c yp_master.c yp_order.c
+
+OTHERSRCS = Makefile.preamble Makefile
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = subproj.make
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+PUBLIC_HEADERS = ypclnt.h yp_prot.h
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/nis.subproj/Makefile.preamble b/nis.subproj/Makefile.preamble
new file mode 100644
index 0000000..eb86120
--- /dev/null
+++ b/nis.subproj/Makefile.preamble
@@ -0,0 +1 @@
+PUBLIC_HEADER_DIR_SUFFIX = /rpcsvc
diff --git a/nis.subproj/PB.project b/nis.subproj/PB.project
new file mode 100644
index 0000000..6d2b72e
--- /dev/null
+++ b/nis.subproj/PB.project
@@ -0,0 +1,58 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        H_FILES = (ypclnt.h, ypinternal.h, yp_prot.h); 
+        OTHER_LINKED = (
+            getdomainname.c, 
+            getnetgrent.c, 
+            innetgr.c, 
+            setdomainname.c, 
+            xdr_domainname.c, 
+            xdr_keydat.c, 
+            xdr_mapname.c, 
+            xdr_peername.c, 
+            xdr_valdat.c, 
+            xdr_ypbind_binding.c, 
+            xdr_ypbind_resp.c, 
+            xdr_ypbind_resptype.c, 
+            xdr_ypbind_setdom.c, 
+            xdr_ypmaplist.c, 
+            xdr_ypreq_key.c, 
+            xdr_ypreq_nokey.c, 
+            xdr_ypresp_all.c, 
+            xdr_ypresp_key_val.c, 
+            xdr_ypresp_maplist.c, 
+            xdr_ypresp_master.c, 
+            xdr_ypresp_order.c, 
+            xdr_ypresp_val.c, 
+            xdr_ypstat.c, 
+            yperr_string.c, 
+            ypmatch_cache.c, 
+            yppasswdd_xdr.c, 
+            ypprot_err.c, 
+            yp_all.c, 
+            yp_bind.c, 
+            yp_first.c, 
+            yp_get_default_domain.c, 
+            yp_maplist.c, 
+            yp_master.c, 
+            yp_order.c
+        ); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile); 
+        PUBLIC_HEADERS = (ypclnt.h, yp_prot.h); 
+    }; 
+    LANGUAGE = English; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = nis; 
+    PROJECTTYPE = Component; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/nis.subproj/getdomainname.c b/nis.subproj/getdomainname.c
new file mode 100644
index 0000000..e0e4dc8
--- /dev/null
+++ b/nis.subproj/getdomainname.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * cover for getdomainname()
+ * Copyright (C) 1995 by NeXT Computer, Inc.
+ */
+#include <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
index 0000000..3894676
--- /dev/null
+++ b/nis.subproj/getnetgrent.c
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static	char sccsid[] = "@(#)getnetgrent.c	1.2 90/07/20 4.1NFSSRC; from 1.22 88/02/08 Copyr 1985 Sun Micro";
+#endif
+
+/* 
+ * Copyright (c) 1985 by Sun Microsystems, Inc.
+ */
+
+#include <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
index 0000000..d146233
--- /dev/null
+++ b/nis.subproj/innetgr.c
@@ -0,0 +1,337 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+#if !defined(lint) && defined(SCCSIDS)
+static	char sccsid[] = "@(#)innetgr.c	1.2 90/07/20 4.1NFSSRC; from 1.17 88/02/08 SMI Copyr 1985 Sun Micro";
+#endif
+
+/* 
+ * Copyright (c) 1990 by Sun Microsystems, Inc.
+ */
+
+#include <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
index 0000000..1541c01
--- /dev/null
+++ b/nis.subproj/setdomainname.c
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * cover for getdomainname()
+ * Copyright (C) 1995 by NeXT Computer, Inc.
+ */
+#include <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
index 0000000..5308c1e
--- /dev/null
+++ b/nis.subproj/xdr_domainname.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..9e0c6f0
--- /dev/null
+++ b/nis.subproj/xdr_keydat.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..6c4323a
--- /dev/null
+++ b/nis.subproj/xdr_mapname.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..7c4726d
--- /dev/null
+++ b/nis.subproj/xdr_peername.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..1ab9024
--- /dev/null
+++ b/nis.subproj/xdr_valdat.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..53b82fa
--- /dev/null
+++ b/nis.subproj/xdr_ypbind_binding.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..832973f
--- /dev/null
+++ b/nis.subproj/xdr_ypbind_resp.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..12096e2
--- /dev/null
+++ b/nis.subproj/xdr_ypbind_resptype.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..be681a2
--- /dev/null
+++ b/nis.subproj/xdr_ypbind_setdom.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..137ea49
--- /dev/null
+++ b/nis.subproj/xdr_ypmaplist.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..eababd8
--- /dev/null
+++ b/nis.subproj/xdr_ypreq_key.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..b3e1552
--- /dev/null
+++ b/nis.subproj/xdr_ypreq_nokey.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..cee7c8a
--- /dev/null
+++ b/nis.subproj/xdr_ypresp_all.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..dfb11b8
--- /dev/null
+++ b/nis.subproj/xdr_ypresp_key_val.c
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..cce1529
--- /dev/null
+++ b/nis.subproj/xdr_ypresp_maplist.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..b844a40
--- /dev/null
+++ b/nis.subproj/xdr_ypresp_master.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..4660014
--- /dev/null
+++ b/nis.subproj/xdr_ypresp_order.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..26226e0
--- /dev/null
+++ b/nis.subproj/xdr_ypresp_val.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..15a4842
--- /dev/null
+++ b/nis.subproj/xdr_ypstat.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..55778c8
--- /dev/null
+++ b/nis.subproj/yp_all.c
@@ -0,0 +1,193 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..a8b9c9d
--- /dev/null
+++ b/nis.subproj/yp_bind.c
@@ -0,0 +1,315 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1996 Theo de Raadt <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
index 0000000..5bdcf11
--- /dev/null
+++ b/nis.subproj/yp_first.c
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..373d1a4
--- /dev/null
+++ b/nis.subproj/yp_get_default_domain.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..e795ad2
--- /dev/null
+++ b/nis.subproj/yp_maplist.c
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..b3a0795
--- /dev/null
+++ b/nis.subproj/yp_master.c
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..44b7a7c
--- /dev/null
+++ b/nis.subproj/yp_order.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..1be2a2e
--- /dev/null
+++ b/nis.subproj/yp_prot.h
@@ -0,0 +1,365 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..c09e8b1
--- /dev/null
+++ b/nis.subproj/ypclnt.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..4b98ee6
--- /dev/null
+++ b/nis.subproj/yperr_string.c
@@ -0,0 +1,118 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..03e40fc
--- /dev/null
+++ b/nis.subproj/ypinternal.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: ypinternal.h,v 1.2 1996/09/15 09:32:00 tholo Exp $	 */
+
+/*
+ * Copyright (c) 1992, 1993, 1996 Theo de Raadt <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
index 0000000..e689913
--- /dev/null
+++ b/nis.subproj/ypmatch_cache.c
@@ -0,0 +1,324 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..d285182
--- /dev/null
+++ b/nis.subproj/yppasswdd_xdr.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: yppasswdd_xdr.c,v 1.4 1997/08/19 07:00:52 niklas Exp $	*/
+
+/*
+ * Copyright (c) 1994 Mats O Jansson <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
index 0000000..7c955fb
--- /dev/null
+++ b/nis.subproj/ypprot_err.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1992, 1993 Theo de Raadt <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
index 0000000..4bf2c53
--- /dev/null
+++ b/rpc.subproj/Makefile
@@ -0,0 +1,60 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = rpc
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Component
+
+HFILES = auth.h auth_unix.h clnt.h pmap_clnt.h pmap_prot.h pmap_rmt.h\
+         rpc.h rpc_msg.h svc.h svc_auth.h types.h xdr.h
+
+CFILES = auth_none.c auth_unix.c authunix_prot.c bindresvport.c\
+         clnt_generic.c clnt_perror.c clnt_raw.c clnt_simple.c\
+         clnt_tcp.c clnt_udp.c get_myaddress.c pmap_clnt.c\
+         pmap_getmaps.c pmap_getport.c pmap_prot.c pmap_prot2.c\
+         pmap_rmt.c rpc_callmsg.c rpc_commondata.c rpc_dtablesize.c\
+         rpc_prot.c svc.c svc_auth.c svc_auth_unix.c svc_raw.c\
+         svc_run.c svc_simple.c svc_tcp.c getrpcent.c svc_udp.c xdr.c\
+         xdr_array.c xdr_float.c xdr_mem.c xdr_rec.c xdr_reference.c\
+         xdr_stdio.c getrpcport.c
+
+OTHERSRCS = Makefile.preamble Makefile
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = subproj.make
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+PUBLIC_HEADERS = auth.h auth_unix.h clnt.h pmap_clnt.h pmap_prot.h\
+                 pmap_rmt.h rpc.h rpc_msg.h svc.h svc_auth.h types.h\
+                 xdr.h
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/rpc.subproj/Makefile.preamble b/rpc.subproj/Makefile.preamble
new file mode 100644
index 0000000..1d84ceb
--- /dev/null
+++ b/rpc.subproj/Makefile.preamble
@@ -0,0 +1,8 @@
+OTHER_CFLAGS = \
+	-Dsetrpcent=_old_setrpcent \
+	-Dgetrpcent=_old_getrpcent \
+	-Dendrpcent=_old_endrpcent \
+	-Dgetrpcbyname=_old_getrpcbyname \
+	-Dgetrpcbynumber=_old_getrpcbynumber
+
+PUBLIC_HEADER_DIR_SUFFIX = /rpc
diff --git a/rpc.subproj/PB.project b/rpc.subproj/PB.project
new file mode 100644
index 0000000..859704b
--- /dev/null
+++ b/rpc.subproj/PB.project
@@ -0,0 +1,88 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        H_FILES = (
+            auth.h, 
+            auth_unix.h, 
+            clnt.h, 
+            pmap_clnt.h, 
+            pmap_prot.h, 
+            pmap_rmt.h, 
+            rpc.h, 
+            rpc_msg.h, 
+            svc.h, 
+            svc_auth.h, 
+            types.h, 
+            xdr.h
+        ); 
+        OTHER_LINKED = (
+            auth_none.c, 
+            auth_unix.c, 
+            authunix_prot.c, 
+            bindresvport.c, 
+            clnt_generic.c, 
+            clnt_perror.c, 
+            clnt_raw.c, 
+            clnt_simple.c, 
+            clnt_tcp.c, 
+            clnt_udp.c, 
+            get_myaddress.c, 
+            pmap_clnt.c, 
+            pmap_getmaps.c, 
+            pmap_getport.c, 
+            pmap_prot.c, 
+            pmap_prot2.c, 
+            pmap_rmt.c, 
+            rpc_callmsg.c, 
+            rpc_commondata.c, 
+            rpc_dtablesize.c, 
+            rpc_prot.c, 
+            svc.c, 
+            svc_auth.c, 
+            svc_auth_unix.c, 
+            svc_raw.c, 
+            svc_run.c, 
+            svc_simple.c, 
+            svc_tcp.c, 
+            getrpcent.c, 
+            svc_udp.c, 
+            xdr.c, 
+            xdr_array.c, 
+            xdr_float.c, 
+            xdr_mem.c, 
+            xdr_rec.c, 
+            xdr_reference.c, 
+            xdr_stdio.c, 
+            getrpcport.c
+        ); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile); 
+        PUBLIC_HEADERS = (
+            auth.h, 
+            auth_unix.h, 
+            clnt.h, 
+            pmap_clnt.h, 
+            pmap_prot.h, 
+            pmap_rmt.h, 
+            rpc.h, 
+            rpc_msg.h, 
+            svc.h, 
+            svc_auth.h, 
+            types.h, 
+            xdr.h
+        ); 
+    }; 
+    LANGUAGE = English; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = rpc; 
+    PROJECTTYPE = Component; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/rpc.subproj/auth.h b/rpc.subproj/auth.h
new file mode 100644
index 0000000..bc5f843
--- /dev/null
+++ b/rpc.subproj/auth.h
@@ -0,0 +1,201 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ *
+ *	from: @(#)auth.h 1.17 88/02/08 SMI
+ *	from: @(#)auth.h	2.3 88/08/07 4.0 RPCSRC
+ *	$Id: auth.h,v 1.2 1999/10/14 21:56:52 wsanchez Exp $
+ */
+
+/*
+ * auth.h, Authentication interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The data structures are completely opaque to the client.  The client
+ * is required to pass a AUTH * to routines that create rpc
+ * "sessions".
+ */
+
+#ifndef _RPC_AUTH_H
+#define _RPC_AUTH_H
+#include <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
index 0000000..220a8ca
--- /dev/null
+++ b/rpc.subproj/auth_none.c
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)auth_none.c	2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: auth_none.c,v 1.2 1999/10/14 21:56:52 wsanchez Exp $";
+#endif
+
+/*
+ * auth_none.c
+ * Creates a client authentication handle for passing "null" 
+ * credentials and verifiers to remote systems. 
+ * 
+ * Copyright (C) 1984, Sun Microsystems, Inc. 
+ */
+
+#include <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
index 0000000..448654d
--- /dev/null
+++ b/rpc.subproj/auth_unix.c
@@ -0,0 +1,364 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)auth_unix.c	2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$Id: auth_unix.c,v 1.3 2001/01/17 19:05:42 majka Exp $";
+#endif
+
+/*
+ * auth_unix.c, Implements UNIX style authentication parameters. 
+ *  
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The system is very weak.  The client uses no encryption for it's
+ * credentials and only sends null verifiers.  The server sends backs
+ * null verifiers or optionally a verifier that suggests a new short hand
+ * for the credentials.
+ *
+ */
+
+#include <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
index 0000000..a26f59a
--- /dev/null
+++ b/rpc.subproj/auth_unix.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ *
+ *	from: @(#)auth_unix.h 1.8 88/02/08 SMI
+ *	from: @(#)auth_unix.h	2.2 88/07/29 4.0 RPCSRC
+ *	$Id: auth_unix.h,v 1.3 2001/01/17 19:05:42 majka Exp $
+ */
+
+/*
+ * auth_unix.h, Protocol for UNIX style authentication parameters for RPC
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+/*
+ * The system is very weak.  The client uses no encryption for  it
+ * credentials and only sends null verifiers.  The server sends backs
+ * null verifiers or optionally a verifier that suggests a new short hand
+ * for the credentials.
+ */
+
+#ifndef _RPC_AUTH_UNIX_H
+#define _RPC_AUTH_UNIX_H
+#include <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
index 0000000..dce59b3
--- /dev/null
+++ b/rpc.subproj/authunix_prot.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)authunix_prot.c 1.15 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)authunix_prot.c	2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: authunix_prot.c,v 1.3 2001/01/17 19:05:42 majka Exp $";
+#endif
+
+/*
+ * authunix_prot.c
+ * XDR for UNIX style authentication parameters for RPC
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+
+#include <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
index 0000000..14261d1
--- /dev/null
+++ b/rpc.subproj/bindresvport.c
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)bindresvport.c 1.8 88/02/08 SMI";*/
+/*static char *sccsid = "from: @(#)bindresvport.c	2.2 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: bindresvport.c,v 1.2 1999/10/14 21:56:52 wsanchez Exp $";
+#endif
+
+/*
+ * Copyright (c) 1987 by Sun Microsystems, Inc.
+ */
+
+#include <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
index 0000000..1efee44
--- /dev/null
+++ b/rpc.subproj/clnt.h
@@ -0,0 +1,387 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ *
+ *	from: @(#)clnt.h 1.31 88/02/08 SMI
+ *	from: @(#)clnt.h	2.1 88/07/29 4.0 RPCSRC
+ *	$Id: clnt.h,v 1.2 1999/10/14 21:56:52 wsanchez Exp $
+ */
+
+/*
+ * clnt.h - Client side remote procedure call interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_CLNT_H_
+#define _RPC_CLNT_H_
+#include <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
index 0000000..cd966ef
--- /dev/null
+++ b/rpc.subproj/clnt_generic.c
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_generic.c 1.4 87/08/11 (C) 1987 SMI";*/
+/*static char *sccsid = "from: @(#)clnt_generic.c	2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$Id: clnt_generic.c,v 1.2 1999/10/14 21:56:52 wsanchez Exp $";
+#endif
+
+/*
+ * Copyright (C) 1987, Sun Microsystems, Inc.
+ */
+#include <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
index 0000000..7ad8e75
--- /dev/null
+++ b/rpc.subproj/clnt_perror.c
@@ -0,0 +1,326 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)clnt_perror.c	2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: clnt_perror.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $";
+#endif
+
+/*
+ * clnt_perror.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ */
+#include <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
index 0000000..100b870
--- /dev/null
+++ b/rpc.subproj/clnt_raw.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)clnt_raw.c	2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$Id: clnt_raw.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $";
+#endif
+
+/*
+ * clnt_raw.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * Memory based rpc for simple testing and timing.
+ * Interface to create an rpc client and server in the same process.
+ * This lets us similate rpc and get round trip overhead, without
+ * any interference from the kernal.
+ */
+
+#include <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
index 0000000..ec99490
--- /dev/null
+++ b/rpc.subproj/clnt_simple.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)clnt_simple.c	2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$Id: clnt_simple.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $";
+#endif
+
+/* 
+ * clnt_simple.c
+ * Simplified front end to rpc.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <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
index 0000000..22f6616
--- /dev/null
+++ b/rpc.subproj/clnt_tcp.c
@@ -0,0 +1,482 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)clnt_tcp.c	2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$Id: clnt_tcp.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $";
+#endif
+ 
+/*
+ * clnt_tcp.c, Implements a TCP/IP based, client side RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * TCP based RPC supports 'batched calls'.
+ * A sequence of calls may be batched-up in a send buffer.  The rpc call
+ * return immediately to the client even though the call was not necessarily
+ * sent.  The batching occurs if the results' xdr routine is NULL (0) AND
+ * the rpc timeout value is zero (see clnt.h, rpc).
+ *
+ * Clients should NOT casually batch calls that in fact return results; that is,
+ * the server side should be aware that a call is batched and not produce any
+ * return message.  Batched calls that produce many result messages can
+ * deadlock (netlock) the client and the server....
+ *
+ * Now go hang yourself.
+ */
+
+#include <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
index 0000000..38a03fe
--- /dev/null
+++ b/rpc.subproj/clnt_udp.c
@@ -0,0 +1,458 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)clnt_udp.c	2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$Id: clnt_udp.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $";
+#endif
+
+/*
+ * clnt_udp.c, Implements a UDP/IP based, client side RPC.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <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
index 0000000..944a0e8
--- /dev/null
+++ b/rpc.subproj/get_myaddress.c
@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)get_myaddress.c 1.4 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)get_myaddress.c	2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: get_myaddress.c,v 1.3 2000/08/03 20:25:14 ajn Exp $";
+#endif
+
+/*
+ * get_myaddress.c
+ *
+ * Get client's IP address via ioctl.  This avoids using the yellowpages.
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * Re-worked for 4.4BSD by Marc Majka at Apple.
+ */
+
+#include <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
index 0000000..1b57d99
--- /dev/null
+++ b/rpc.subproj/getrpcent.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user or with the express written consent of
+ * Sun Microsystems, Inc.
+ *
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ *
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)getrpcent.c 1.14 91/03/11 Copyr 1984 Sun Micro";*/
+static char *rcsid = "$Id: getrpcent.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $";
+#endif
+
+/*
+ * Copyright (c) 1984 by Sun Microsystems, Inc.
+ */
+
+#include <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
index 0000000..af368dd
--- /dev/null
+++ b/rpc.subproj/getrpcport.c
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)getrpcport.c 1.3 87/08/11 SMI";*/
+/*static char *sccsid = "from: @(#)getrpcport.c	2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: getrpcport.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $";
+#endif
+
+/*
+ * Copyright (c) 1985 by Sun Microsystems, Inc.
+ */
+
+#include <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
index 0000000..cdd3261
--- /dev/null
+++ b/rpc.subproj/pmap_clnt.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_clnt.c	2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$Id: pmap_clnt.c,v 1.3 2000/08/03 20:25:14 ajn Exp $";
+#endif
+
+/*
+ * pmap_clnt.c
+ * Client interface to pmap rpc service.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <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
index 0000000..16e7fed
--- /dev/null
+++ b/rpc.subproj/pmap_clnt.h
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ *
+ *	from: @(#)pmap_clnt.h 1.11 88/02/08 SMI 
+ *	from: @(#)pmap_clnt.h	2.1 88/07/29 4.0 RPCSRC
+ *	$Id: pmap_clnt.h,v 1.2 1999/10/14 21:56:53 wsanchez Exp $
+ */
+
+/*
+ * pmap_clnt.h
+ * Supplies C routines to get to portmap services.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+/*
+ * Usage:
+ *	success = pmap_set(program, version, protocol, port);
+ *	success = pmap_unset(program, version);
+ *	port = pmap_getport(address, program, version, protocol);
+ *	head = pmap_getmaps(address);
+ *	clnt_stat = pmap_rmtcall(address, program, version, procedure,
+ *		xdrargs, argsp, xdrres, resp, tout, port_ptr)
+ *		(works for udp only.) 
+ * 	clnt_stat = clnt_broadcast(program, version, procedure,
+ *		xdrargs, argsp,	xdrres, resp, eachresult)
+ *		(like pmap_rmtcall, except the call is broadcasted to all
+ *		locally connected nets.  For each valid response received,
+ *		the procedure eachresult is called.  Its form is:
+ *	done = eachresult(resp, raddr)
+ *		bool_t done;
+ *		caddr_t resp;
+ *		struct sockaddr_in raddr;
+ *		where resp points to the results of the call and raddr is the
+ *		address if the responder to the broadcast.
+ */
+
+#ifndef _RPC_PMAPCLNT_H
+#define _RPC_PMAPCLNT_H
+#include <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
index 0000000..7946572
--- /dev/null
+++ b/rpc.subproj/pmap_getmaps.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_getmaps.c	2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$Id: pmap_getmaps.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $";
+#endif
+
+/*
+ * pmap_getmap.c
+ * Client interface to pmap rpc service.
+ * contains pmap_getmaps, which is only tcp service involved
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <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
index 0000000..b4b6eb5
--- /dev/null
+++ b/rpc.subproj/pmap_getport.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_getport.c	2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$Id: pmap_getport.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $";
+#endif
+
+/*
+ * pmap_getport.c
+ * Client interface to pmap rpc service.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <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
index 0000000..b3d4a02
--- /dev/null
+++ b/rpc.subproj/pmap_prot.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_prot.c	2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: pmap_prot.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $";
+#endif
+
+/*
+ * pmap_prot.c
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <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
index 0000000..1565f5e
--- /dev/null
+++ b/rpc.subproj/pmap_prot.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ *
+ *	from: @(#)pmap_prot.h 1.14 88/02/08 SMI 
+ *	from: @(#)pmap_prot.h	2.1 88/07/29 4.0 RPCSRC
+ *	$Id: pmap_prot.h,v 1.2 1999/10/14 21:56:53 wsanchez Exp $
+ */
+
+/*
+ * pmap_prot.h
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * The following procedures are supported by the protocol:
+ *
+ * PMAPPROC_NULL() returns ()
+ * 	takes nothing, returns nothing
+ *
+ * PMAPPROC_SET(struct pmap) returns (bool_t)
+ * 	TRUE is success, FALSE is failure.  Registers the tuple
+ *	[prog, vers, prot, port].
+ *
+ * PMAPPROC_UNSET(struct pmap) returns (bool_t)
+ *	TRUE is success, FALSE is failure.  Un-registers pair
+ *	[prog, vers].  prot and port are ignored.
+ *
+ * PMAPPROC_GETPORT(struct pmap) returns (long unsigned).
+ *	0 is failure.  Otherwise returns the port number where the pair
+ *	[prog, vers] is registered.  It may lie!
+ *
+ * PMAPPROC_DUMP() RETURNS (struct pmaplist *)
+ *
+ * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>)
+ * 	RETURNS (port, string<>);
+ * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs);
+ * 	Calls the procedure on the local machine.  If it is not registered,
+ *	this procedure is quite; ie it does not return error information!!!
+ *	This procedure only is supported on rpc/udp and calls via
+ *	rpc/udp.  This routine only passes null authentication parameters.
+ *	This file has no interface to xdr routines for PMAPPROC_CALLIT.
+ *
+ * The service supports remote procedure calls on udp/ip or tcp/ip socket 111.
+ */
+
+#ifndef _RPC_PMAPPROT_H
+#define _RPC_PMAPPROT_H
+#include <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
index 0000000..986c2c8
--- /dev/null
+++ b/rpc.subproj/pmap_prot2.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_prot2.c	2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: pmap_prot2.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $";
+#endif
+
+/*
+ * pmap_prot2.c
+ * Protocol for the local binder service, or pmap.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <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
index 0000000..cbfffa6
--- /dev/null
+++ b/rpc.subproj/pmap_rmt.c
@@ -0,0 +1,411 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)pmap_rmt.c	2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$Id: pmap_rmt.c,v 1.2 1999/10/14 21:56:53 wsanchez Exp $";
+#endif
+
+/*
+ * pmap_rmt.c
+ * Client interface to pmap rpc service.
+ * remote call and broadcast service
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <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
index 0000000..a6782a5
--- /dev/null
+++ b/rpc.subproj/pmap_rmt.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ *
+ *	from: @(#)pmap_rmt.h 1.2 88/02/08 SMI 
+ *	from: @(#)pmap_rmt.h	2.1 88/07/29 4.0 RPCSRC
+ *	$Id: pmap_rmt.h,v 1.2 1999/10/14 21:56:53 wsanchez Exp $
+ */
+
+/*
+ * Structures and XDR routines for parameters to and replies from
+ * the portmapper remote-call-service.
+ *
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_PMAPRMT_H
+#define _RPC_PMAPRMT_H
+#include <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
index 0000000..da89dff
--- /dev/null
+++ b/rpc.subproj/rpc.h
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ *
+ *	from: @(#)rpc.h 1.9 88/02/08 SMI 
+ *	from: @(#)rpc.h	2.4 89/07/11 4.0 RPCSRC
+ *	$Id: rpc.h,v 1.2 1999/10/14 21:56:53 wsanchez Exp $
+ */
+
+/*
+ * rpc.h, Just includes the billions of rpc header files necessary to
+ * do remote procedure calling.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+#ifndef _RPC_RPC_H
+#define _RPC_RPC_H
+
+#include <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
index 0000000..45014db
--- /dev/null
+++ b/rpc.subproj/rpc_callmsg.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)rpc_callmsg.c	2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: rpc_callmsg.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $";
+#endif
+
+/*
+ * rpc_callmsg.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ */
+
+#include <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
index 0000000..c12c265
--- /dev/null
+++ b/rpc.subproj/rpc_commondata.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)rpc_commondata.c	2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: rpc_commondata.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $";
+#endif
+
+#include <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
index 0000000..bfdd00b
--- /dev/null
+++ b/rpc.subproj/rpc_dtablesize.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)rpc_dtablesize.c 1.2 87/08/11 Copyr 1987 Sun Micro";*/
+/*static char *sccsid = "from: @(#)rpc_dtablesize.c	2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: rpc_dtablesize.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $";
+#endif
+
+#include <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
index 0000000..53373d0
--- /dev/null
+++ b/rpc.subproj/rpc_msg.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ *
+ *	from: @(#)rpc_msg.h 1.7 86/07/16 SMI
+ *	from: @(#)rpc_msg.h	2.1 88/07/29 4.0 RPCSRC
+ *	$Id: rpc_msg.h,v 1.2 1999/10/14 21:56:54 wsanchez Exp $
+ */
+
+/*
+ * rpc_msg.h
+ * rpc message definition
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_RPCMSG_H
+#define _RPC_RPCMSG_H
+
+#define RPC_MSG_VERSION		((u_long) 2)
+#define RPC_SERVICE_PORT	((u_short) 2048)
+
+/*
+ * Bottom up definition of an rpc message.
+ * NOTE: call and reply use the same overall stuct but
+ * different parts of unions within it.
+ */
+
+enum msg_type {
+	CALL=0,
+	REPLY=1
+};
+
+enum reply_stat {
+	MSG_ACCEPTED=0,
+	MSG_DENIED=1
+};
+
+enum accept_stat {
+	SUCCESS=0,
+	PROG_UNAVAIL=1,
+	PROG_MISMATCH=2,
+	PROC_UNAVAIL=3,
+	GARBAGE_ARGS=4,
+	SYSTEM_ERR=5
+};
+
+enum reject_stat {
+	RPC_MISMATCH=0,
+	AUTH_ERROR=1
+};
+
+/*
+ * Reply part of an rpc exchange
+ */
+
+/*
+ * Reply to an rpc request that was accepted by the server.
+ * Note: there could be an error even though the request was
+ * accepted.
+ */
+struct accepted_reply {
+	struct opaque_auth	ar_verf;
+	enum accept_stat	ar_stat;
+	union {
+		struct {
+			u_long	low;
+			u_long	high;
+		} AR_versions;
+		struct {
+			caddr_t	where;
+			xdrproc_t proc;
+		} AR_results;
+		/* and many other null cases */
+	} ru;
+#define	ar_results	ru.AR_results
+#define	ar_vers		ru.AR_versions
+};
+
+/*
+ * Reply to an rpc request that was rejected by the server.
+ */
+struct rejected_reply {
+	enum reject_stat rj_stat;
+	union {
+		struct {
+			u_long low;
+			u_long high;
+		} RJ_versions;
+		enum auth_stat RJ_why;  /* why authentication did not work */
+	} ru;
+#define	rj_vers	ru.RJ_versions
+#define	rj_why	ru.RJ_why
+};
+
+/*
+ * Body of a reply to an rpc request.
+ */
+struct reply_body {
+	enum reply_stat rp_stat;
+	union {
+		struct accepted_reply RP_ar;
+		struct rejected_reply RP_dr;
+	} ru;
+#define	rp_acpt	ru.RP_ar
+#define	rp_rjct	ru.RP_dr
+};
+
+/*
+ * Body of an rpc request call.
+ */
+struct call_body {
+	u_long cb_rpcvers;	/* must be equal to two */
+	u_long cb_prog;
+	u_long cb_vers;
+	u_long cb_proc;
+	struct opaque_auth cb_cred;
+	struct opaque_auth cb_verf; /* protocol specific - provided by client */
+};
+
+/*
+ * The rpc message
+ */
+struct rpc_msg {
+	u_long			rm_xid;
+	enum msg_type		rm_direction;
+	union {
+		struct call_body RM_cmb;
+		struct reply_body RM_rmb;
+	} ru;
+#define	rm_call		ru.RM_cmb
+#define	rm_reply	ru.RM_rmb
+};
+#define	acpted_rply	ru.RM_rmb.ru.RP_ar
+#define	rjcted_rply	ru.RM_rmb.ru.RP_dr
+
+__BEGIN_DECLS
+/*
+ * XDR routine to handle a rpc message.
+ * xdr_callmsg(xdrs, cmsg)
+ * 	XDR *xdrs;
+ * 	struct rpc_msg *cmsg;
+ */
+extern bool_t	xdr_callmsg	__P((XDR *, struct rpc_msg *));
+
+/*
+ * XDR routine to pre-serialize the static part of a rpc message.
+ * xdr_callhdr(xdrs, cmsg)
+ * 	XDR *xdrs;
+ * 	struct rpc_msg *cmsg;
+ */
+extern bool_t	xdr_callhdr	__P((XDR *, struct rpc_msg *));
+
+/*
+ * XDR routine to handle a rpc reply.
+ * xdr_replymsg(xdrs, rmsg)
+ * 	XDR *xdrs;
+ * 	struct rpc_msg *rmsg;
+ */
+extern bool_t	xdr_replymsg	__P((XDR *, struct rpc_msg *));
+
+/*
+ * Fills in the error part of a reply message.
+ * _seterr_reply(msg, error)
+ * 	struct rpc_msg *msg;
+ * 	struct rpc_err *error;
+ */
+extern void	_seterr_reply	__P((struct rpc_msg *, struct rpc_err *));
+__END_DECLS
+
+#endif /* !_RPC_RPCMSG_H */
diff --git a/rpc.subproj/rpc_prot.c b/rpc.subproj/rpc_prot.c
new file mode 100644
index 0000000..ab74c4b
--- /dev/null
+++ b/rpc.subproj/rpc_prot.c
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro";*/
+static char *rcsid = "$Id: rpc_prot.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $";
+#endif
+
+/*
+ * rpc_prot.c
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * This set of routines implements the rpc message definition,
+ * its serializer and some common rpc utility routines.
+ * The routines are meant for various implementations of rpc -
+ * they are NOT for the rpc client or rpc service implementations!
+ * Because authentication stuff is easy and is part of rpc, the opaque
+ * routines are also in this program.
+ */
+
+#include <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
index 0000000..fffefc0
--- /dev/null
+++ b/rpc.subproj/svc.c
@@ -0,0 +1,475 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint) 
+/*static char *sccsid = "from: @(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc.c	2.4 88/08/11 4.0 RPCSRC";*/
+static char *rcsid = "$Id: svc.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $";
+#endif
+
+/*
+ * svc.c, Server-side remote procedure call interface.
+ *
+ * There are two sets of procedures here.  The xprt routines are
+ * for handling transport handles.  The svc routines handle the
+ * list of service routines.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <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
index 0000000..8a3004e
--- /dev/null
+++ b/rpc.subproj/svc.h
@@ -0,0 +1,325 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ *
+ *	from: @(#)svc.h 1.20 88/02/08 SMI 
+ *	from: @(#)svc.h	2.2 88/07/29 4.0 RPCSRC
+ *	$Id: svc.h,v 1.2 1999/10/14 21:56:54 wsanchez Exp $
+ */
+
+/*
+ * svc.h, Server-side remote procedure call interface.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_SVC_H
+#define _RPC_SVC_H
+#include <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
index 0000000..6586c98
--- /dev/null
+++ b/rpc.subproj/svc_auth.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ *
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ *
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ *
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_auth.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_auth.c	2.1 88/08/07 4.0 RPCSRC";*/
+static char *rcsid = "$Id: svc_auth.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $";
+#endif
+
+/*
+ * svc_auth_nodes.c, Server-side rpc authenticator interface,
+ * *WITHOUT* DES authentication.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <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
index 0000000..3dc0959
--- /dev/null
+++ b/rpc.subproj/svc_auth.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ *
+ *	from: @(#)svc_auth.h 1.6 86/07/16 SMI
+ *	from: @(#)svc_auth.h	2.1 88/07/29 4.0 RPCSRC
+ *	$Id: svc_auth.h,v 1.2 1999/10/14 21:56:54 wsanchez Exp $
+ */
+
+/*
+ * svc_auth.h, Service side of rpc authentication.
+ * 
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_SVCAUTH_H
+#define _RPC_SVCAUTH_H
+
+/*
+ * Server side authenticator
+ */
+__BEGIN_DECLS
+extern enum auth_stat _authenticate __P((struct svc_req *, struct rpc_msg *));
+__END_DECLS
+
+#endif /* !_RPC_SVCAUTH_H */
diff --git a/rpc.subproj/svc_auth_unix.c b/rpc.subproj/svc_auth_unix.c
new file mode 100644
index 0000000..2f30dd7
--- /dev/null
+++ b/rpc.subproj/svc_auth_unix.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_auth_unix.c 1.28 88/02/08 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_auth_unix.c	2.3 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$Id: svc_auth_unix.c,v 1.3 2001/01/17 19:05:42 majka Exp $";
+#endif
+
+/*
+ * svc_auth_unix.c
+ * Handles UNIX flavor authentication parameters on the service side of rpc.
+ * There are two svc auth implementations here: AUTH_UNIX and AUTH_SHORT.
+ * _svcauth_unix does full blown unix style uid,gid+gids auth,
+ * _svcauth_short uses a shorthand auth to index into a cache of longhand auths.
+ * Note: the shorthand has been gutted for efficiency.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <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
index 0000000..6729e4d
--- /dev/null
+++ b/rpc.subproj/svc_raw.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_raw.c 1.15 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_raw.c	2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: svc_raw.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $";
+#endif
+
+/*
+ * svc_raw.c,   This a toy for simple testing and timing.
+ * Interface to create an rpc client and server in the same UNIX process.
+ * This lets us similate rpc and get rpc (round trip) overhead, without
+ * any interference from the kernal.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <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
index 0000000..47b467a
--- /dev/null
+++ b/rpc.subproj/svc_run.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_run.c	2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: svc_run.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $";
+#endif
+
+/*
+ * This is the rpc server side idle loop
+ * Wait for input, call server program.
+ */
+#include <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
index 0000000..6174d04
--- /dev/null
+++ b/rpc.subproj/svc_simple.c
@@ -0,0 +1,168 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_simple.c 1.18 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_simple.c	2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$Id: svc_simple.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $";
+#endif
+
+/* 
+ * svc_simple.c
+ * Simplified front end to rpc.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <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
index 0000000..8828b63
--- /dev/null
+++ b/rpc.subproj/svc_tcp.c
@@ -0,0 +1,435 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_tcp.c	2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$Id: svc_tcp.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $";
+#endif
+
+/*
+ * svc_tcp.c, Server side for TCP/IP based RPC. 
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * Actually implements two flavors of transporter -
+ * a tcp rendezvouser (a listner and connection establisher)
+ * and a record/tcp stream.
+ */
+
+#include <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
index 0000000..5af3045
--- /dev/null
+++ b/rpc.subproj/svc_udp.c
@@ -0,0 +1,503 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)svc_udp.c 1.24 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)svc_udp.c	2.2 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: svc_udp.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $";
+#endif
+
+/*
+ * svc_udp.c,
+ * Server side for UDP/IP based RPC.  (Does some caching in the hopes of
+ * achieving execute-at-most-once semantics.)
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#include <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
index 0000000..b9cd3cf
--- /dev/null
+++ b/rpc.subproj/types.h
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ *
+ *	from: @(#)types.h 1.18 87/07/24 SMI
+ *	from: @(#)types.h	2.3 88/08/15 4.0 RPCSRC
+ *	$Id: types.h,v 1.2 1999/10/14 21:56:54 wsanchez Exp $
+ */
+
+/*
+ * Rpc additions to <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
index 0000000..b523fee
--- /dev/null
+++ b/rpc.subproj/xdr.c
@@ -0,0 +1,605 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr.c 1.35 87/08/12";*/
+/*static char *sccsid = "from: @(#)xdr.c	2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: xdr.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $";
+#endif
+
+/*
+ * xdr.c, Generic XDR routines implementation.
+ *
+ * Copyright (C) 1986, Sun Microsystems, Inc.
+ *
+ * These are the "generic" xdr routines used to serialize and de-serialize
+ * most common data items.  See xdr.h for more info on the interface to
+ * xdr.
+ */
+
+#include <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
index 0000000..6289bc8
--- /dev/null
+++ b/rpc.subproj/xdr.h
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ *
+ *	from: @(#)xdr.h 1.19 87/04/22 SMI
+ *	from: @(#)xdr.h	2.2 88/07/29 4.0 RPCSRC
+ *	$Id: xdr.h,v 1.2 1999/10/14 21:56:54 wsanchez Exp $
+ */
+
+/*
+ * xdr.h, External Data Representation Serialization Routines.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
+
+#ifndef _RPC_XDR_H
+#define _RPC_XDR_H
+#include <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
index 0000000..356b795
--- /dev/null
+++ b/rpc.subproj/xdr_array.c
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_array.c 1.10 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)xdr_array.c	2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: xdr_array.c,v 1.2 1999/10/14 21:56:55 wsanchez Exp $";
+#endif
+
+/*
+ * xdr_array.c, Generic XDR routines impelmentation.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * These are the "non-trivial" xdr primitives used to serialize and de-serialize
+ * arrays.  See xdr.h for more info on the interface to xdr.
+ */
+
+#include <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
index 0000000..775022a
--- /dev/null
+++ b/rpc.subproj/xdr_float.c
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)xdr_float.c	2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: xdr_float.c,v 1.2 1999/10/14 21:56:55 wsanchez Exp $";
+#endif
+
+/*
+ * xdr_float.c, Generic XDR routines impelmentation.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * These are the "floating point" xdr routines used to (de)serialize
+ * most common data items.  See xdr.h for more info on the interface to
+ * xdr.
+ */
+
+#include <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
index 0000000..3bec281
--- /dev/null
+++ b/rpc.subproj/xdr_mem.c
@@ -0,0 +1,213 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)xdr_mem.c	2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: xdr_mem.c,v 1.2 1999/10/14 21:56:55 wsanchez Exp $";
+#endif
+
+/*
+ * xdr_mem.h, XDR implementation using memory buffers.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * If you have some data to be interpreted as external data representation
+ * or to be converted to external data representation in a memory buffer,
+ * then this is the package for you.
+ *
+ */
+
+
+#include <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
index 0000000..912dbfb
--- /dev/null
+++ b/rpc.subproj/xdr_rec.c
@@ -0,0 +1,607 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+#if defined(LIBC_SCCS) && !defined(lint) 
+/*static char *sccsid = "from: @(#)xdr_rec.c 1.21 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)xdr_rec.c	2.2 88/08/01 4.0 RPCSRC";*/
+static char *rcsid = "$Id: xdr_rec.c,v 1.2 1999/10/14 21:56:55 wsanchez Exp $";
+#endif
+
+/*
+ * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking"
+ * layer above tcp (for rpc's use).
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * These routines interface XDRSTREAMS to a tcp/ip connection.
+ * There is a record marking layer between the xdr stream
+ * and the tcp transport level.  A record is composed on one or more
+ * record fragments.  A record fragment is a thirty-two bit header followed
+ * by n bytes of data, where n is contained in the header.  The header
+ * is represented as a htonl(u_long).  Thegh order bit encodes
+ * whether or not the fragment is the last fragment of the record
+ * (1 => fragment is last, 0 => more fragments to follow. 
+ * The other 31 bits encode the byte length of the fragment.
+ */
+
+#include <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
index 0000000..bfc82e1
--- /dev/null
+++ b/rpc.subproj/xdr_reference.c
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint) 
+/*static char *sccsid = "from: @(#)xdr_reference.c 1.11 87/08/11 SMI";*/
+/*static char *sccsid = "from: @(#)xdr_reference.c	2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: xdr_reference.c,v 1.2 1999/10/14 21:56:55 wsanchez Exp $";
+#endif
+
+/*
+ * xdr_reference.c, Generic XDR routines impelmentation.
+ *
+ * Copyright (C) 1987, Sun Microsystems, Inc.
+ *
+ * These are the "non-trivial" xdr primitives used to serialize and de-serialize
+ * "pointers".  See xdr.h for more info on the interface to xdr.
+ */
+
+#include <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
index 0000000..d4c6b49
--- /dev/null
+++ b/rpc.subproj/xdr_stdio.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+ * unrestricted use provided that this legend is included on all tape
+ * media and as a part of the software program in whole or part.  Users
+ * may copy or modify Sun RPC without charge, but are not authorized
+ * to license or distribute it to anyone else except as part of a product or
+ * program developed by the user.
+ * 
+ * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+ * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+ * 
+ * Sun RPC is provided with no support and without any obligation on the
+ * part of Sun Microsystems, Inc. to assist in its use, correction,
+ * modification or enhancement.
+ * 
+ * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+ * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+ * OR ANY PART THEREOF.
+ * 
+ * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+ * or profits or other special, indirect and consequential damages, even if
+ * Sun has been advised of the possibility of such damages.
+ * 
+ * Sun Microsystems, Inc.
+ * 2550 Garcia Avenue
+ * Mountain View, California  94043
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+/*static char *sccsid = "from: @(#)xdr_stdio.c 1.16 87/08/11 Copyr 1984 Sun Micro";*/
+/*static char *sccsid = "from: @(#)xdr_stdio.c	2.1 88/07/29 4.0 RPCSRC";*/
+static char *rcsid = "$Id: xdr_stdio.c,v 1.2 1999/10/14 21:56:55 wsanchez Exp $";
+#endif
+
+/*
+ * xdr_stdio.c, XDR implementation on standard i/o file.
+ *
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ *
+ * This set of routines implements a XDR on a stdio stream.
+ * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes
+ * from the stream.
+ */
+
+#include <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
index 0000000..aede900
--- /dev/null
+++ b/util.subproj/Makefile
@@ -0,0 +1,46 @@
+#
+# Generated by the NeXT Project Builder.
+#
+# NOTE: Do NOT change this file -- Project Builder maintains it.
+#
+# Put all of your customizations in files called Makefile.preamble
+# and Makefile.postamble (both optional), and Makefile will include them.
+#
+
+NAME = util
+
+PROJECTVERSION = 2.8
+PROJECT_TYPE = Component
+
+CFILES = getgrouplist.c glob.c hton.c putpwpasswd.c pwcache.c rcmd.c\
+         rcmdsh.c
+
+OTHERSRCS = Makefile
+
+
+MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
+CODE_GEN_STYLE = DYNAMIC
+MAKEFILE = subproj.make
+LIBS = 
+DEBUG_LIBS = $(LIBS)
+PROF_LIBS = $(LIBS)
+
+
+
+
+NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
+PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
+NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
+WINDOWS_JAVA_COMPILER = $(JDKBINDIR)/javac.exe
+PDO_UNIX_JAVA_COMPILER = $(JDKBINDIR)/javac
+
+include $(MAKEFILEDIR)/platform.make
+
+-include Makefile.preamble
+
+include $(MAKEFILEDIR)/$(MAKEFILE)
+
+-include Makefile.postamble
+
+-include Makefile.dependencies
diff --git a/util.subproj/PB.project b/util.subproj/PB.project
new file mode 100644
index 0000000..eab47ff
--- /dev/null
+++ b/util.subproj/PB.project
@@ -0,0 +1,21 @@
+{
+    DYNAMIC_CODE_GEN = YES; 
+    FILESTABLE = {
+        OTHER_LINKED = (getgrouplist.c, glob.c, hton.c, putpwpasswd.c, pwcache.c, rcmd.c, rcmdsh.c); 
+        OTHER_SOURCES = (Makefile); 
+    }; 
+    LANGUAGE = English; 
+    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
+    NEXTSTEP_BUILDTOOL = /bin/gnumake; 
+    NEXTSTEP_JAVA_COMPILER = /usr/bin/javac; 
+    NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc; 
+    PDO_UNIX_BUILDTOOL = $NEXT_ROOT/Developer/bin/make; 
+    PDO_UNIX_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
+    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
+    PROJECTNAME = util; 
+    PROJECTTYPE = Component; 
+    PROJECTVERSION = 2.8; 
+    WINDOWS_BUILDTOOL = $NEXT_ROOT/Developer/Executables/make; 
+    WINDOWS_JAVA_COMPILER = "$(JDKBINDIR)/javac.exe"; 
+    WINDOWS_OBJCPLUS_COMPILER = "$(DEVDIR)/gcc"; 
+}
diff --git a/util.subproj/getgrouplist.c b/util.subproj/getgrouplist.c
new file mode 100644
index 0000000..305f1b8
--- /dev/null
+++ b/util.subproj/getgrouplist.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1991, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getgrouplist.c	8.2 (Berkeley) 12/8/94";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * get credential
+ */
+#include <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
index 0000000..f19459e
--- /dev/null
+++ b/util.subproj/glob.c
@@ -0,0 +1,845 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved
+ *
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * The NEXTSTEP Software License Agreement specifies the terms
+ * and conditions for redistribution.
+ *
+ *	@(#)glob.c	8.3 (Berkeley) 10/13/93
+ */
+
+
+/*
+ * glob(3) -- a superset of the one defined in POSIX 1003.2.
+ *
+ * The [!...] convention to negate a range is supported (SysV, Posix, ksh).
+ *
+ * Optional extra services, controlled by flags not defined by POSIX:
+ *
+ * GLOB_QUOTE:
+ *	Escaping convention: \ inhibits any special meaning the following
+ *	character might have (except \ at end of string is retained).
+ * GLOB_MAGCHAR:
+ *	Set in gl_flags if pattern contained a globbing character.
+ * GLOB_NOMAGIC:
+ *	Same as GLOB_NOCHECK, but it will only append pattern if it did
+ *	not contain any magic characters.  [Used in csh style globbing]
+ * GLOB_ALTDIRFUNC:
+ *	Use alternately specified directory access functions.
+ * GLOB_TILDE:
+ *	expand ~user/foo to the /home/dir/of/user/foo
+ * GLOB_BRACE:
+ *	expand {1,2}{a,b} to 1a 1b 2a 2b 
+ * gl_matchc:
+ *	Number of matches in the current invocation of glob.
+ */
+
+#include <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
index 0000000..312d514
--- /dev/null
+++ b/util.subproj/hton.c
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/* Copyright (c) 1994 NeXT Computer, Inc.  All rights reserved.
+ *
+ *      File:   hton.c
+ *      Author: Matt Watson, NeXT Computer, Inc.
+ *
+ *      Use the machine independent byte-swapping code for htonl-type functions.
+ *
+ * HISTORY
+ * 15-Dec-94  Matt Watson (Matt_Watson@NeXT.COM)
+ *      Created.
+ */
+
+#import <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
index 0000000..976ef2f
--- /dev/null
+++ b/util.subproj/putpwpasswd.c
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * putpwpasswd()
+ * Copyright (C) 1989 by NeXT, Inc.
+ *
+ * Changes a user's password entry. Works only for NetInfo. 
+ *
+ * NOTE: This is not done in lookupd because we need to know
+ * the identity of the user and there is currently no way to
+ * get that information through a Mach message. Privileged users
+ * get privileged sockets and do not need to supply a old password
+ * if they are changing their password on the master server for their
+ * account entry. Unprivileged users get unprivileged sockets and must
+ * supply the old password.
+ */
+#include <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
index 0000000..f0a4eec
--- /dev/null
+++ b/util.subproj/pwcache.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved
+ *
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * The NEXTSTEP Software License Agreement specifies the terms
+ * and conditions for redistribution.
+ *
+ *	@(#)pwcache.c	8.1 (Berkeley) 6/4/93
+ */
+
+
+#include <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
index 0000000..611b94d
--- /dev/null
+++ b/util.subproj/rcmd.c
@@ -0,0 +1,637 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*
+ * Copyright (c) 1995, 1996, 1998 Theo de Raadt.  All rights reserved.
+ * Copyright (c) 1983, 1993, 1994
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ *	This product includes software developed by Theo de Raadt.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char *rcsid = "$OpenBSD: rcmd.c,v 1.30 1998/02/12 02:21:19 deraadt Exp $";
+#endif /* LIBC_SCCS and not lint */
+
+#include <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
index 0000000..49f9eee
--- /dev/null
+++ b/util.subproj/rcmdsh.c
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
+ * License for the specific language governing rights and limitations
+ * under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+/*	$OpenBSD: rcmdsh.c,v 1.4 1997/07/23 16:59:37 millert Exp $	*/ 
+
+/*
+ * This is an rcmd() replacement originally by 
+ * Chris Siebenmann <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 */
+}
-- 
2.45.2