]> git.saurik.com Git - apple/libinfo.git/commitdiff
Libinfo-278.tar.gz mac-os-x-105 mac-os-x-1051 mac-os-x-1052 v278
authorApple <opensource@apple.com>
Thu, 27 Sep 2007 21:46:25 +0000 (21:46 +0000)
committerApple <opensource@apple.com>
Thu, 27 Sep 2007 21:46:25 +0000 (21:46 +0000)
182 files changed:
Makefile
PB.project
dns.subproj/Makefile.preamble
dns.subproj/gethnamaddr.c
dns.subproj/inet.h
dns.subproj/nameser8_compat.h
dns.subproj/options.h
dns.subproj/res_debug.c
dns.subproj/res_init.c
dns.subproj/res_send.c
gen.subproj/Makefile
gen.subproj/Makefile.postamble
gen.subproj/Makefile.preamble
gen.subproj/PB.project
gen.subproj/ether_addr.3 [deleted file]
gen.subproj/fstab.c
gen.subproj/getgrent.c
gen.subproj/gethostbyname.3
gen.subproj/getifaddrs.c
gen.subproj/getnetent.3
gen.subproj/getprotoent.3
gen.subproj/getpwent.c
gen.subproj/getservent.3
gen.subproj/if_indextoname.3
gen.subproj/inet_ntop.c
gen.subproj/inet_pton.c
gen.subproj/initgroups.c
gen.subproj/printerdb.c
lookup.subproj/DSlibinfoMIG.defs [new file with mode: 0644]
lookup.subproj/DSlibinfoMIGAsyncReply.defs [new file with mode: 0644]
lookup.subproj/DSlibinfoMIG_types.h [new file with mode: 0644]
lookup.subproj/Makefile
lookup.subproj/Makefile.postamble
lookup.subproj/Makefile.preamble
lookup.subproj/PB.project
lookup.subproj/bootparams.5 [new file with mode: 0644]
lookup.subproj/gai_strerror.3 [new file with mode: 0644]
lookup.subproj/getaddrinfo.3
lookup.subproj/getaddrinfo.c
lookup.subproj/getfsent.3 [new file with mode: 0644]
lookup.subproj/getgrent.3 [new file with mode: 0644]
lookup.subproj/getgrouplist.3 [new file with mode: 0644]
lookup.subproj/getnameinfo.3
lookup.subproj/getnetgrent.3 [new file with mode: 0644]
lookup.subproj/getpwent.3 [new file with mode: 0644]
lookup.subproj/initgroups.3 [new file with mode: 0644]
lookup.subproj/kvbuf.h [new file with mode: 0644]
lookup.subproj/lu_alias.c
lookup.subproj/lu_bootp.c
lookup.subproj/lu_bootparam.c
lookup.subproj/lu_fstab.c
lookup.subproj/lu_group.c
lookup.subproj/lu_host.c
lookup.subproj/lu_host.h
lookup.subproj/lu_host_async.c
lookup.subproj/lu_netgroup.c
lookup.subproj/lu_network.c
lookup.subproj/lu_overrides.h
lookup.subproj/lu_printer.c
lookup.subproj/lu_protocol.c
lookup.subproj/lu_rpc.c
lookup.subproj/lu_service.c
lookup.subproj/lu_user.c
lookup.subproj/lu_utils.c
lookup.subproj/lu_utils.h
lookup.subproj/netdb.h
lookup.subproj/netdb_async.h
lookup.subproj/netgr.h [deleted file]
mdns.subproj/DNSServiceDiscovery.c [deleted file]
mdns.subproj/DNSServiceDiscovery.h [deleted file]
mdns.subproj/DNSServiceDiscoveryDefines.h [deleted file]
mdns.subproj/DNSServiceDiscoveryReply.defs [deleted file]
mdns.subproj/DNSServiceDiscoveryRequest.defs [deleted file]
mdns.subproj/Makefile [deleted file]
mdns.subproj/Makefile.postamble [deleted file]
mdns.subproj/Makefile.preamble [deleted file]
mdns.subproj/PB.project [deleted file]
mdns.subproj/dns_sd.h [deleted file]
mdns.subproj/dnssd_clientlib.c [deleted file]
mdns.subproj/dnssd_clientstub.c [deleted file]
mdns.subproj/dnssd_ipc.c [deleted file]
mdns.subproj/dnssd_ipc.h [deleted file]
membership.subproj/DSmemberdMIG.defs [new file with mode: 0644]
membership.subproj/Makefile
membership.subproj/Makefile.postamble
membership.subproj/Makefile.preamble
membership.subproj/PB.project
membership.subproj/mbr_check_membership.3 [new file with mode: 0644]
membership.subproj/mbr_uid_to_uuid.3 [new file with mode: 0644]
membership.subproj/mbr_uid_to_uuid_so.3 [new file with mode: 0644]
membership.subproj/memberd.defs [deleted file]
membership.subproj/memberd_defines.h [deleted file]
membership.subproj/membership.c
membership.subproj/membershipPriv.h
netinfo.subproj/Makefile
netinfo.subproj/Makefile.postamble [deleted file]
netinfo.subproj/Makefile.preamble
netinfo.subproj/PB.project
netinfo.subproj/clib.h [deleted file]
netinfo.subproj/mm.h [deleted file]
netinfo.subproj/multi_call.c [deleted file]
netinfo.subproj/netinfo.3 [deleted file]
netinfo.subproj/netinfo.5 [deleted file]
netinfo.subproj/ni.h [deleted file]
netinfo.subproj/ni_error.c [deleted file]
netinfo.subproj/ni_glue.c [deleted file]
netinfo.subproj/ni_prot.x [deleted file]
netinfo.subproj/ni_pwdomain.c [deleted file]
netinfo.subproj/ni_stub.c [new file with mode: 0644]
netinfo.subproj/ni_useful.c [deleted file]
netinfo.subproj/ni_util.c [deleted file]
netinfo.subproj/ni_util.h [deleted file]
netinfo.subproj/nibind_prot.x [deleted file]
netinfo.subproj/sys_interfaces.c [deleted file]
netinfo.subproj/sys_interfaces.h [deleted file]
nis.subproj/Makefile
nis.subproj/Makefile.postamble
nis.subproj/Makefile.preamble
nis.subproj/xdr_ypmaplist.c
nis.subproj/xdr_ypresp_maplist.c
nis.subproj/yp.8 [new file with mode: 0644]
nis.subproj/yp_all.c
nis.subproj/yp_bind.c
nis.subproj/yp_first.c
nis.subproj/yp_maplist.c
nis.subproj/yp_master.c
nis.subproj/yp_order.c
nis.subproj/ypclnt.3
nis.subproj/ypinternal.h
nis.subproj/ypmatch_cache.c
rpc.subproj/Makefile
rpc.subproj/Makefile.postamble [new file with mode: 0644]
rpc.subproj/Makefile.preamble
rpc.subproj/auth.h
rpc.subproj/auth_unix.c
rpc.subproj/auth_unix.h
rpc.subproj/authunix_prot.c
rpc.subproj/bindresvport.3 [new file with mode: 0644]
rpc.subproj/bindresvport.c
rpc.subproj/clnt.h
rpc.subproj/clnt_generic.c
rpc.subproj/clnt_perror.c
rpc.subproj/clnt_raw.c
rpc.subproj/clnt_tcp.c
rpc.subproj/clnt_udp.c
rpc.subproj/getrpcent.3 [new file with mode: 0644]
rpc.subproj/getrpcent.c
rpc.subproj/getrpcport.3 [new file with mode: 0644]
rpc.subproj/pmap_clnt.c
rpc.subproj/pmap_clnt.h
rpc.subproj/pmap_getmaps.c
rpc.subproj/pmap_getport.c
rpc.subproj/pmap_prot.h
rpc.subproj/pmap_prot2.c
rpc.subproj/pmap_rmt.c
rpc.subproj/pmap_rmt.h
rpc.subproj/pmap_wakeup.c
rpc.subproj/pmap_wakeup.h
rpc.subproj/rpc.3 [new file with mode: 0644]
rpc.subproj/rpc_callmsg.c
rpc.subproj/rpc_msg.h
rpc.subproj/rpc_prot.c
rpc.subproj/svc.c
rpc.subproj/svc.h
rpc.subproj/svc_auth_unix.c
rpc.subproj/svc_simple.c
rpc.subproj/svc_tcp.c
rpc.subproj/svc_udp.c
rpc.subproj/types.h
rpc.subproj/xdr.3 [new file with mode: 0644]
rpc.subproj/xdr.c
rpc.subproj/xdr.h
rpc.subproj/xdr_mem.c
rpc.subproj/xdr_rec.c
rpc.subproj/xdr_sizeof.c
rpc.subproj/xdr_stdio.c
util.subproj/Makefile.postamble
util.subproj/Makefile.preamble
util.subproj/hosts.equiv.5
util.subproj/putpwpasswd.c
util.subproj/pwcache.c
util.subproj/rcmd.c

index 6739fadb97b3bb02ed27f2e90936c361aed905cc..35007d3bfb5b2cb266b1f7c857c3c73b002ae19a 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -13,8 +13,7 @@ PROJECTVERSION = 2.8
 PROJECT_TYPE = Library
 
 SUBPROJECTS = dns.subproj gen.subproj lookup.subproj membership.subproj\
-              netinfo.subproj nis.subproj rpc.subproj util.subproj\
-              mdns.subproj
+              netinfo.subproj nis.subproj rpc.subproj util.subproj
 
 OTHERSRCS = Makefile.preamble Makefile Makefile.postamble
 
index 34ca56b41febeb94d7caa7dda86cd8cc461f76f8..314f8be9c1b12eb9c5cb43a3a8cb2c66d31a769b 100644 (file)
@@ -14,8 +14,7 @@
             netinfo.subproj, 
             nis.subproj, 
             rpc.subproj, 
-            util.subproj, 
-            mdns.subproj
+            util.subproj
         ); 
     }; 
     LANGUAGE = English; 
index c775255faf955d27cb6c045cab134823920479bd..f88e7ffc0190d5b58666a6e456ef23da76c74fef 100644 (file)
@@ -1,4 +1,5 @@
 OTHER_CFLAGS = \
+       -D__DARWIN_NON_CANCELABLE=1 \
        -Dsethostent=_res_sethostent \
        -Dgethostent=_res_gethostent \
        -Dendhostent=_res_endhostent \
index b95f26fcc1f2cb037b2d65080e0267dde058d7a2..f00f3ddef908b9d614c778f1e90d1578f5909d89 100644 (file)
@@ -118,8 +118,9 @@ static const char AskedForGot[] =
                          "gethostby*.getanswer: asked for \"%s\", got \"%s\"";
 
 static char *h_addr_ptrs[MAXADDRS + 1];
+#ifdef NOTDEF
 static struct hostent *gethostbyname_ipv4 __P((const char *));
-
+#endif
 static struct hostent host;
 static char *host_aliases[MAXALIASES];
 static char *hostbuf = NULL;
@@ -149,8 +150,6 @@ typedef union {
 
 extern int h_errno;
 
-extern int _lu_running(void);
-
 #ifdef DEBUG
 static void
 dprintf(msg, num)
@@ -442,6 +441,7 @@ gethostbyname(name)
        return (gethostbyname2(name, AF_INET));
 }
 
+#ifdef NOTDEF
 static struct hostent *
 gethostbyname_ipv4(name)
        const char *name;
@@ -524,6 +524,7 @@ gethostbyname_ipv4(name)
        }
        return (getanswer(&buf, n, name, C_IN, T_A));
 }
+#endif
 
 struct hostent *
 gethostbyaddr(vaddr, len, type)
index 6091ed930036b466c9c12739b9b93ff3644e780c..2d75a40c1f338aca574bf42f92fe78c917bbb0b9 100644 (file)
@@ -78,7 +78,7 @@
 
 /*
  *     @(#)inet.h      8.1 (Berkeley) 6/2/93
- *     $Id: inet.h,v 1.7 2004/10/28 21:58:13 emoy Exp $
+ *     $Id: inet.h,v 1.10 2006/02/01 18:09:47 majka Exp $
  */
 
 #ifndef _INET_H_
 
 /* External definitions for functions in inet(3) */
 
+#include <_types.h>
 #include <stdint.h>            /* uint32_t uint16_t */
-#include <machine/endian.h>    /* htonl() and family if !_POSIX_C_SOURCE */
-#include <sys/_endian.h>       /* htonl() and family if _POSIX_C_SOURCE */
+#include <machine/endian.h>    /* htonl() and family if (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
+#include <sys/_endian.h>       /* htonl() and family if (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */
 #include <netinet/in.h>                /* in_addr */
-#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
 
 in_addr_t       inet_addr(const char *);
 char           *inet_ntoa(struct in_addr);
-const char     *inet_ntop(int, const void *, char *, size_t);
+const char     *inet_ntop(int, const void *, char *, socklen_t);
 int             inet_pton(int, const char *, void *);
-#ifndef _POSIX_C_SOURCE
+#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
 int             ascii2addr(int, const char *, void *);
 char           *addr2ascii(int, const void *, int, char *);
 int             inet_aton(const char *, struct in_addr *);
@@ -112,12 +106,12 @@ in_addr_t  inet_lnaof(struct in_addr);
 struct in_addr  inet_makeaddr(in_addr_t, in_addr_t);
 in_addr_t       inet_netof(struct in_addr);
 in_addr_t       inet_network(const char *);
-char           *inet_net_ntop(int, const void *, int, char *, size_t);
-int             inet_net_pton(int, const char *, void *, size_t);
-char           *inet_neta(in_addr_t, char *, size_t);
+char           *inet_net_ntop(int, const void *, int, char *, __darwin_size_t);
+int             inet_net_pton(int, const char *, void *, __darwin_size_t);
+char           *inet_neta(in_addr_t, char *, __darwin_size_t);
 unsigned int    inet_nsap_addr(const char *, unsigned char *, int maxlen);
 char   *inet_nsap_ntoa(int, const unsigned char *, char *ascii);
-#endif /* _POSIX_C_SOURCE */
+#endif /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */
 
 __END_DECLS
 
index 809ec6b87e1f49f8d160f584e2db692fb3245dee..d48d59a4376182682800542c87d94e722f3b17a1 100644 (file)
 #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) || \
+#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
index 6a793266e8ebaaaec7d0adf976e06ac68a179332..a632bb30638d0000250cf210d5142ffd9207c79a 100644 (file)
  *      gns = Greg Shapiro of WPI
  */
 
+#ifndef DEBUG
 #define DEBUG          /* enable -d flag and SIGUSR[12] support (ucb) */
+#endif
+
 /*#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) */
index ba2cfb4740a46d45c4b89543909f3115f21c36a6..bf837306f50387494017048cff5a88b495415815 100644 (file)
@@ -477,7 +477,7 @@ __p_rr(cp, msg, file)
        FILE *file;
 {
        int type, class, n, c;
-       long dlen;
+       int dlen;
        struct in_addr inaddr;
        const u_char *cp1, *cp2;
        u_int32_t tmpttl, t;
@@ -704,8 +704,11 @@ __p_rr(cp, msg, file)
        putc('\n', file);
 #endif
        if (cp - cp1 != dlen) {
-               fprintf(file, ";; packet size error (found %ld, dlen was %ld)\n",
-                       cp - cp1, dlen);
+#ifdef __LP64__
+               fprintf(file, ";; packet size error (found %ld, dlen was %d)\n", cp - cp1, dlen);
+#else
+               fprintf(file, ";; packet size error (found %d, dlen was %d)\n", cp - cp1, dlen);
+#endif
                cp = NULL;
        }
        return (cp);
index d45795ff55264380f2f2cf800a132f3e6d9af91b..7336289144f15eeb37ce397f0ebcf1a3dad2757b 100644 (file)
@@ -99,35 +99,6 @@ static char rcsid[] = "$Id: res_init.c,v 1.8 2003/02/18 17:29:24 majka Exp $";
 # 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__) && defined(CONFIGURE_RESOLVER_FROM_NETINFO)
-#  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
@@ -403,9 +374,6 @@ res_init()
 #endif
            (void) fclose(fp);
        }
-#if defined(__APPLE__) && defined(CONFIGURE_RESOLVER_FROM_NETINFO)
-       else netinfo_res_init(&haveenv, &havesearch);
-#endif
 
        if (_res.defdname[0] == 0 &&
            gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&
@@ -510,161 +478,6 @@ net_mask(in)              /* XXX - should really use system's version of this */
 }
 #endif
 
-#if defined(__APPLE__) && defined(CONFIGURE_RESOLVER_FROM_NETINFO)
-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 = '\0';
-                       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()
 {
index 5e2a2fbf25e6115d410534544a86b5b5bebe709e..d6cf0f573cdcd47f0a3d46ac6743c3015230696c 100644 (file)
@@ -584,7 +584,7 @@ res_send(buf, buflen, ans, anssiz)
                        struct timeval timeout;
                        fd_set dsmask;
                        struct sockaddr_in from;
-                       int fromlen;
+                       unsigned int fromlen;
 
                        if ((s < 0) || vc) {
                                if (vc)
index 0c859d62473c3756c2afe1909dcf04a494989e94..ae7b3ee38d721b8b20c29bc3ebd48ccb766e0439 100644 (file)
@@ -22,11 +22,13 @@ CFILES = aliasdb.c ether_addr.c fstab.c getgrent.c\
          map_v4v6.c ip6opt.c rthdr.c vars.c
 
 OTHERSRCS = Makefile.preamble Makefile Makefile.postamble\
-            ether_addr.3 getifaddrs.3 if_indextoname.3 inet6_rthdr_space.3\
+            getifaddrs.3 if_indextoname.3 inet6_rthdr_space.3\
             gethostbyname.3 inet6_option_space.3\
             getprotoent.3 gethostbyname.3 getipnodebyname.3\
             getnetent.3 getservent.3 inet6_option_space.3
 
+OTHERLINKEDOFILES = _version.o
+
 
 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
 CODE_GEN_STYLE = DYNAMIC
index 0db669870deaca91c841fd9f05b0ef65dee97822..3cc4f8eded9fce2ca5b4e38a27b05310c4c1de9b 100644 (file)
@@ -118,7 +118,6 @@ install-man-page:
        $(LN) -f "$(DSTROOT)/usr/share/man/man3/gethostbyname.3" "$(DSTROOT)/usr/share/man/man3/herror.3"
        $(LN) -f "$(DSTROOT)/usr/share/man/man3/gethostbyname.3" "$(DSTROOT)/usr/share/man/man3/hstrerror.3"
        $(LN) -f "$(DSTROOT)/usr/share/man/man3/gethostbyname.3" "$(DSTROOT)/usr/share/man/man3/sethostent.3"
-       install -c -m 644 ether_addr.3 "$(DSTROOT)/usr/share/man/man3"
        install -c -m 644 getifaddrs.3 "$(DSTROOT)/usr/share/man/man3"
        $(LN) -f "$(DSTROOT)/usr/share/man/man3/getifaddrs.3" "$(DSTROOT)/usr/share/man/man3/freeifaddrs.3"
        install -c -m 644 getipnodebyname.3 "$(DSTROOT)/usr/share/man/man3"
index baa75c4ce819b26d650990e7067e8e94c62063ff..7f9c621bddcf24ea4cc16f2765a72e03916955ed 100644 (file)
@@ -1,5 +1,6 @@
 AFTER_POSTINSTALL += install-man-page
 OTHER_CFLAGS = \
+       -D__DARWIN_NON_CANCELABLE=1 \
        -DINET6=1 \
        -Dsetservent=_old_setservent \
        -Dgetservent=_old_getservent \
@@ -35,3 +36,6 @@ OTHER_CFLAGS = \
 # for building 64-bit
 # <rdar://problem/3819761> Libinfo need to build with gcc-3.5 and 3-way fat
 NEXTSTEP_OBJCPLUS_COMPILER = $(CCOMPILER)
+
+$(OFILE_DIR)/_version.c:
+       /Developer/Makefiles/bin/version.pl Libinfo > $@
index 387e3a54f36a311b5ac8e9404a3f036efc76ebc7..7dbd7443803bce46bf0347ea7d50a17afb7c5177 100644 (file)
@@ -31,7 +31,6 @@
             Makefile.preamble, 
             Makefile, 
             Makefile.postamble, 
-            ether_addr.3, 
             getifaddrs.3, 
             if_indextoname.3, 
             inet6_rthdr_space.3, 
diff --git a/gen.subproj/ether_addr.3 b/gen.subproj/ether_addr.3
deleted file mode 100644 (file)
index 4c50e4d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-.so man3/ethers.3
index 5ccc4b1afb09e7e7251366ca5ada49677299957b..8ed58244678dea8e5ad13defdc96272b84d5f389 100644 (file)
  * 
  * @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.
+ *
+ *     @(#)fstab.c     8.1 (Berkeley) 6/4/93
+ */
 
 #include <errno.h>
 #include <fstab.h>
index 36a01d2906be1c8bbde96e6cc8eb276f05c2d0b0..b867892a6beef965fbdb1d5a53b3ce79740563b2 100644 (file)
@@ -124,10 +124,10 @@ start_gr()
        return((_gr_fp = fopen(_PATH_GROUP, "r")) ? 1 : 0);
 }
 
-int
+void
 setgrent()
 {
-       return(setgroupent(0));
+       setgroupent(0);
 }
 
 int
index 779383ec50971122d76a9b5248175c0c700936aa..1789cb51e006e535a1b4ec104763a481a8b44507 100644 (file)
 .Dt GETHOSTBYNAME 3
 .Os
 .Sh NAME
+.Nm endhostent ,
+.Nm gethostbyaddr ,
 .Nm gethostbyname ,
 .Nm gethostbyname2 ,
-.Nm gethostbyaddr ,
 .Nm gethostent ,
-.Nm sethostent ,
-.Nm endhostent ,
 .Nm herror ,
-.Nm hstrerror
+.Nm hstrerror ,
+.Nm sethostent
 .Nd get network host entry
 .Sh LIBRARY
 .Lb libc
 .Sh SYNOPSIS
 .Fd #include <netdb.h>
 .Vt extern int h_errno ;
+.Ft void
+.Fo endhostent
+.Fa void
+.Fc
 .Ft struct hostent *
-.Fn gethostbyname "const char *name"
+.Fo gethostbyaddr
+.Fa "const void *addr"
+.Fa "socklen_t len"
+.Fa "int type"
+.Fc
 .Ft struct hostent *
-.Fn gethostbyname2 "const char *name" "int af"
+.Fo gethostbyname
+.Fa "const char *name"
+.Fc
 .Ft struct hostent *
-.Fn gethostbyaddr "const char *addr" "socklen_t len" "int type"
+.Fo gethostbyname2
+.Fa "const char *name"
+.Fa "int af"
+.Fc
 .Ft struct hostent *
-.Fn gethostent void
-.Ft void
-.Fn sethostent "int stayopen"
-.Ft void
-.Fn endhostent void
+.Fo gethostent
+.Fa void
+.Fc
 .Ft void
-.Fn herror "const char *string"
+.Fo herror
+.Fa "const char *string"
+.Fc
 .Ft const char *
-.Fn hstrerror "int err"
+.Fo hstrerror
+.Fa "int err"
+.Fc
+.Ft void
+.Fo sethostent
+.Fa "int stayopen"
+.Fc
 .Sh DESCRIPTION
 The
 .Fn gethostbyname ,
@@ -236,6 +255,22 @@ Another type of request to the name server using this domain name
 will result in an answer;
 for example, a mail-forwarder may be registered for this domain.
 .El
+.Sh LEGACY SYNOPSIS
+.Fd #include <netdb.h>
+.Pp
+.Vt extern int h_errno ;
+.Pp
+.Ft struct hostent *
+.br
+.Fo gethostbyaddr
+.Fa "const void *addr"
+.Fa "socklen_t len"
+.Fa "int type"
+.Fc ;
+.Pp
+The type of
+.Fa addr
+has changed slightly.
 .Sh SEE ALSO
 .Xr getaddrinfo 3 ,
 .Xr resolver 3 ,
index b2e286e7c292ec989177eee646cb6cb2b1a1a5be..63c4bfcb6ce8d17c964d422222d6a53000a15bfc 100644 (file)
 
 #include <errno.h>
 #include <ifaddrs.h>
+#include <netinet/in.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdint.h>
 
 #if !defined(AF_LINK)
 #define        SA_LEN(sa)      sizeof(struct sockaddr)
@@ -50,7 +52,7 @@
 #define        SA_LEN(sa)      (sa)->sa_len
 #endif
 
-#define        SALIGN  (sizeof(long) - 1)
+#define        SALIGN  (sizeof(int32_t) - 1)
 #define        SA_RLEN(sa)     ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : (SALIGN + 1))
 
 #ifndef        ALIGNBYTES
 #define HAVE_IFM_DATA
 #endif
 
+#define MEMORY_MIN 2048
+#define MEMORY_MAX 4194304
+
 int
 getifaddrs(struct ifaddrs **pif)
 {
        int icnt = 1;
        int dcnt = 0;
        int ncnt = 0;
+       struct ifaddrs *ifa, *ift;
+       struct sockaddr_in6 *sin6;
+       uint16_t esid;
 #ifdef NET_RT_IFLIST
        int mib[6];
        size_t needed;
@@ -99,7 +107,6 @@ getifaddrs(struct ifaddrs **pif)
        struct ifa_msghdr *ifam;
        struct sockaddr_dl *dl;
        struct sockaddr *sa;
-       struct ifaddrs *ifa, *ift;
        u_short index = 0;
 #else  /* NET_RT_IFLIST */
        char buf[1024];
@@ -108,7 +115,7 @@ getifaddrs(struct ifaddrs **pif)
        struct ifreq *ifr;
        struct ifreq *lifr;
 #endif /* NET_RT_IFLIST */
-       int i;
+       int i, status;
        size_t len, alen;
        char *data;
        char *names;
@@ -120,13 +127,22 @@ getifaddrs(struct ifaddrs **pif)
        mib[3] = 0;             /* wildcard address family */
        mib[4] = NET_RT_IFLIST;
        mib[5] = 0;             /* no flags */
-       if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0)
-               return (-1);
-       if ((buf = malloc(needed)) == NULL)
-               return (-1);
-       if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0) {
+       if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) return (-1);
+
+       if (needed < MEMORY_MIN) needed = MEMORY_MIN;
+       needed *= 2;
+
+       while (needed <= MEMORY_MAX)
+       {
+               buf = malloc(needed);
+               if (buf == NULL) return (-1);
+
+               status = sysctl(mib, 6, buf, &needed, NULL, 0);
+               if (status >= 0) break;
+
                free(buf);
-               return (-1);
+               buf = NULL;
+               needed *= 2;
        }
 
        for (next = buf; next < buf + needed; next += rtm->rtm_msglen) {
@@ -196,12 +212,17 @@ getifaddrs(struct ifaddrs **pif)
        ifc.ifc_buf = buf;
        ifc.ifc_len = sizeof(buf);
 
-       if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0)
+       if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+               free(buf);
                return (-1);
+       }
+
        i =  ioctl(sock, SIOCGIFCONF, (char *)&ifc);
        close(sock);
-       if (i < 0)
+       if (i < 0) {
+               free(buf);
                return (-1);
+       }
 
        ifr = ifc.ifc_req;
        lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len];
@@ -213,7 +234,7 @@ getifaddrs(struct ifaddrs **pif)
                ++icnt;
                dcnt += SA_RLEN(sa);
                ncnt += sizeof(ifr->ifr_name) + 1;
-               
+
                ifr = (struct ifreq *)(((char *)sa) + SA_LEN(sa));
        }
 #endif /* NET_RT_IFLIST */
@@ -364,7 +385,7 @@ getifaddrs(struct ifaddrs **pif)
                sa = &ifr->ifr_addr;
                memcpy(data, sa, SA_LEN(sa));
                data += SA_RLEN(sa);
-               
+
                ifr = (struct ifreq *)(((char *)sa) + SA_LEN(sa));
                ift = (ift->ifa_next = ift + 1);
        }
@@ -376,6 +397,21 @@ getifaddrs(struct ifaddrs **pif)
                *pif = NULL;
                free(ifa);
        }
+
+       for (ift = ifa; ift != NULL; ift = ift->ifa_next)
+       {
+               if (ift->ifa_addr->sa_family == AF_INET6)
+               {
+                       sin6 = (struct sockaddr_in6 *)ift->ifa_addr;
+                       if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) || IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr))
+                       {
+                               esid = ntohs(sin6->sin6_addr.__u6_addr.__u6_addr16[1]);
+                               sin6->sin6_addr.__u6_addr.__u6_addr16[1] = 0;
+                               if (sin6->sin6_scope_id == 0) sin6->sin6_scope_id = esid;
+                       }
+               }
+       }
+
        return (0);
 }
 
index 18bbd70b6d313c057ab8cbaf44f072ef6a3e7430..7786ce0a0de706156a02d2d45d4ad2e0b9491c2c 100644 (file)
 .Dt GETNETENT 3
 .Os
 .Sh NAME
-.Nm getnetent ,
+.Nm endnetent ,
 .Nm getnetbyaddr ,
 .Nm getnetbyname ,
-.Nm setnetent ,
-.Nm endnetent
+.Nm getnetent ,
+.Nm setnetent
 .Nd get network entry
 .Sh LIBRARY
 .Lb libc
 .Sh SYNOPSIS
 .Fd #include <netdb.h>
+.Ft void
+.Fo endnetent
+.Fa void
+.Fc
 .Ft struct netent *
-.Fn getnetent void
+.Fo getnetbyaddr
+.Fa "uint32_t net"
+.Fa "int type"
+.Fc
 .Ft struct netent *
-.Fn getnetbyname "const char *name"
+.Fo getnetbyname
+.Fa "const char *name"
+.Fc
 .Ft struct netent *
-.Fn getnetbyaddr "uint32_t net" "int type"
-.Ft void
-.Fn setnetent "int stayopen"
+.Fo getnetent
+.Fa void
+.Fc
 .Ft void
-.Fn endnetent void
+.Fo setnetent
+.Fa "int stayopen"
+.Fc
 .Sh DESCRIPTION
 The
 .Fn getnetent ,
index e0fd91c9e90a593d52ff4e4a64cd7c7a63877a2f..5a22328c127dbd7f9002c71e4511686034971069 100644 (file)
 .Dt GETPROTOENT 3
 .Os
 .Sh NAME
-.Nm getprotoent ,
-.Nm getprotobynumber ,
+.Nm endprotoent ,
 .Nm getprotobyname ,
-.Nm setprotoent ,
-.Nm endprotoent
+.Nm getprotobynumber ,
+.Nm getprotoent ,
+.Nm setprotoent
 .Nd get protocol entry
 .Sh LIBRARY
 .Lb libc
 .Sh SYNOPSIS
 .Fd #include <netdb.h>
+.Ft void
+.Fo endprotoent
+.Fa void
+.Fc
 .Ft struct protoent *
-.Fn getprotoent void
+.Fo getprotobyname
+.Fa "const char *name"
+.Fc
 .Ft struct protoent *
-.Fn getprotobyname "const char *name"
+.Fo getprotobynumber
+.Fa "int proto"
+.Fc
 .Ft struct protoent *
-.Fn getprotobynumber "int proto"
-.Ft void
-.Fn setprotoent "int stayopen"
+.Fo getprotoent
+.Fa void
+.Fc
 .Ft void
-.Fn endprotoent void
+.Fo setprotoent
+.Fa "int stayopen"
+.Fc
 .Sh DESCRIPTION
 The
 .Fn getprotoent ,
index 8081b715638a5d572abc0f1128110cabcfec3279..01a9eee0a73d67f85bd2b6ca6569582a64e9b37b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2007 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -26,7 +26,7 @@
  * 
  * /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.
+ * Directory Service 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
@@ -36,6 +36,9 @@
 #include <stdlib.h>
 #include <string.h>
 #include <pwd.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
 #include <unistd.h>
 
 #define forever for (;;)
 #define _PWUID_ 2
 
 static struct passwd _pw = { 0 };
-static FILE *_pfp;
-static int _pwStayOpen;
+static FILE *_pfp = NULL;
 static int _pwFileFormat = 1;
 
-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);
+#define _HENT_  0
+#define _HNAM_  1
+#define _HADDR_ 2
 
-       _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 struct hostent _h = { 0 };
+static FILE *_hfp = NULL;
+
+/* Forward */
+__private_extern__ void LI_files_setpwent();
+__private_extern__ void LI_files_endhostent();
 
 static void
 freeList(char **l)
@@ -143,7 +138,6 @@ appendString(char *s, char **l)
        return insertString(s, l, (unsigned int)-1);
 }
 
-
 static char **
 tokenize(const char *data, const char *sep)
 {
@@ -189,14 +183,14 @@ tokenize(const char *data, const char *sep)
                                if (p[0] == sep[j] || (p[0] == '\0')) scanning = 0;
                        }
                }
-       
+
                /* back over trailing whitespace */
                i--;
                if (i > -1) { /* did we actually copy anything? */
                        while ((buf[i] == ' ') || (buf[i] == '\t') || (buf[i] == '\n')) i--;
                }
                buf[++i] = '\0';
-       
+
                tokens = appendString(buf, tokens);
 
                /* check for end of line */
@@ -220,11 +214,49 @@ tokenize(const char *data, const char *sep)
                        return tokens;
                }
        }
+
        return tokens;
 }
 
-struct passwd *
-parseUser(char *data)
+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;
+}
+
+/* USERS */
+
+static void
+LI_files_free_user()
+{
+       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 struct passwd *
+LI_files_parse_user(char *data)
 {
        char **tokens;
        int ntokens;
@@ -234,13 +266,13 @@ parseUser(char *data)
        tokens = tokenize(data, ":");
        ntokens = listLength(tokens);
        if (( _pwFileFormat && (ntokens != 10)) ||
-           (!_pwFileFormat && (ntokens !=  7)))
+               (!_pwFileFormat && (ntokens !=  7)))
        {
                freeList(tokens);
                return NULL;
        }
 
-       free_pw();
+       LI_files_free_user();
 
        _pw.pw_name = tokens[0];
        _pw.pw_passwd = tokens[1];
@@ -275,32 +307,79 @@ parseUser(char *data)
        return &_pw;
 }
 
-static char *
-getLine(FILE *fp)
+static struct passwd *
+LI_files_getpw(const char *name, uid_t uid, int which)
 {
-       char s[1024];
-       char *out;
+       char *line;
+       struct passwd *pw;
 
-    s[0] = '\0';
+       if (_pfp == NULL) LI_files_setpwent();
+       if (_pfp == NULL) return NULL;
 
-    fgets(s, 1024, fp);
-    if (s == NULL || s[0] == '\0') return NULL;
+       if (which != _PWENT_) rewind(_pfp);
 
-       if (s[0] != '#') s[strlen(s) - 1] = '\0';
+       forever
+       {
+               line = getLine(_pfp);
+               if (line == NULL) break;
 
-       out = copyString(s);
-       return out;
+               if (line[0] == '#') 
+               {
+                       free(line);
+                       line = NULL;
+                       continue;
+               }
+
+               pw = LI_files_parse_user(line);
+               free(line);
+               line = NULL;
+
+               if (pw == NULL) continue;
+
+               if (which == _PWENT_) return pw;
+
+               if (((which == _PWNAM_) && (!strcmp(name, pw->pw_name))) || ((which == _PWUID_) && (uid == pw->pw_uid)))
+               {
+                       fclose(_pfp);
+                       _pfp = NULL;
+                       return pw;
+               }
+       }
+
+       fclose(_pfp);
+       _pfp = NULL;
+
+       return NULL;
+}
+
+/* "Public" */
+
+__private_extern__ struct passwd *
+LI_files_getpwent()
+{
+       return LI_files_getpw(NULL, 0, _PWENT_);
+}
+
+__private_extern__ struct passwd *
+LI_files_getpwnam(const char *name)
+{
+       return LI_files_getpw(name, 0, _PWNAM_);
+}
+
+__private_extern__ struct passwd *
+LI_files_getpwuid(uid_t uid)
+{
+       return LI_files_getpw(NULL, uid, _PWUID_);
 }
 
 int
 setpassent(int stayopen)
 {
-       _pwStayOpen = stayopen;
-       return(1);
+       return 1;
 }
 
-int
-setpwent()
+__private_extern__ void
+LI_files_setpwent()
 {
        if (_pfp == NULL)
        {
@@ -314,20 +393,14 @@ setpwent()
                        pwFile = _PATH_PASSWD;
                        _pwFileFormat = 0;
                }
+
                _pfp = fopen(pwFile, "r");
-               if (_pfp == NULL)
-               {
-                       perror(pwFile);
-                       return(0);
-               }
        }
        else rewind(_pfp);
-       _pwStayOpen = 0;
-       return(1);
 }
 
-void
-endpwent()
+__private_extern__ void
+LI_files_endpwent()
 {
        if (_pfp != NULL)
        {
@@ -336,20 +409,110 @@ endpwent()
        }
 }
 
-static struct passwd *
-getpw(const char *nam, uid_t uid, int which)
+/* HOSTS */
+
+static void
+LI_files_free_host()
 {
-       char *line;
-       struct passwd *pw;
+       int i;
+
+       if (_h.h_name != NULL) free(_h.h_name);
 
-       if (which != 0)
+       if (_h.h_aliases != NULL)
        {
-               if (setpwent() == 0) return NULL;
+               for (i = 0; _h.h_aliases[i] != NULL; i++) free(_h.h_aliases[i]);
+               free(_h.h_aliases);
        }
 
+       if (_h.h_addr_list != NULL)
+       {
+               for (i = 0; _h.h_addr_list[i] != NULL; i++) free(_h.h_addr_list[i]);
+               free(_h.h_addr_list);
+       }
+
+       _h.h_name = NULL;
+       _h.h_aliases = NULL;
+       _h.h_addrtype = 0;
+       _h.h_length = 0;
+       _h.h_addr_list = NULL;
+}
+
+static struct hostent *
+LI_files_parse_host(char *data)
+{
+       char **tokens, *addrstr;
+       int i, ntokens, af;
+       struct in_addr a4;
+       struct in6_addr a6;
+
+       if (data == NULL) return NULL;
+
+       tokens = tokenize(data, "       ");
+       ntokens = listLength(tokens);
+       if (ntokens < 2)
+       {
+               freeList(tokens);
+               return NULL;
+       }
+
+       LI_files_free_host();
+
+       af = AF_UNSPEC;
+       if (inet_pton(AF_INET, tokens[0], &a4) == 1) af = AF_INET;
+       else if (inet_pton(AF_INET6, tokens[0], &a6) == 1) af = AF_INET6;
+
+       if (af == AF_UNSPEC)
+       {
+               freeList(tokens);
+               return NULL;
+       }
+
+       addrstr = tokens[0];
+
+       _h.h_addrtype = af;
+       if (af == AF_INET)
+       {
+               _h.h_length = sizeof(struct in_addr);
+               _h.h_addr_list = (char **)calloc(2, sizeof(char *));
+               _h.h_addr_list[0] = (char *)calloc(1, _h.h_length);
+               memcpy(_h.h_addr_list[0], &a4, _h.h_length);
+       }
+       else
+       {
+               _h.h_length = sizeof(struct in6_addr);
+               _h.h_addr_list = (char **)calloc(2, sizeof(char *));
+               _h.h_addr_list[0] = (char *)calloc(1, _h.h_length);
+               memcpy(_h.h_addr_list[0], &a6, _h.h_length);
+       }
+
+       _h.h_name = tokens[1];
+
+       _h.h_aliases = (char **)calloc(ntokens - 1, sizeof(char *));
+       for (i = 2; i < ntokens; i++) _h.h_aliases[i-2] = tokens[i];
+
+       free(addrstr);
+       free(tokens);
+
+       return &_h;
+}
+
+static struct hostent *
+LI_files_get_host(const char *name, const void *addr, int af, int which)
+{
+       char *line;
+       struct hostent *h;
+       int i, got_host;
+
+       if ((which == _HADDR_) && (addr == NULL)) return NULL;
+
+       if (_hfp == NULL) _hfp = fopen(_PATH_HOSTS, "r");
+       if (_hfp == NULL) return NULL;
+
+       if (which != _HENT_) rewind(_hfp);
+
        forever
        {
-               line = getLine(_pfp);
+               line = getLine(_hfp);
                if (line == NULL) break;
 
                if (line[0] == '#') 
@@ -359,42 +522,84 @@ getpw(const char *nam, uid_t uid, int which)
                        continue;
                }
 
-               pw = parseUser(line);
+               h = LI_files_parse_host(line);
                free(line);
                line = NULL;
 
-               if ((pw == NULL) || (which == _PWENT_))
+               if (h == NULL) continue;
+
+               if (which == _HENT_) return h;
+
+               got_host = 0;
+
+               if ((which == _HNAM_) && (af == h->h_addrtype))
                {
-                       if (_pwStayOpen == 0) endpwent();
-                       return pw;
+                       if (!strcmp(name, h->h_name)) got_host = 1;
+                       else if (h->h_aliases != NULL)
+                       {
+                               for (i = 0; (h->h_aliases[i] != NULL) && (got_host == 0); i++)
+                                       if (!strcmp(name, h->h_aliases[i])) got_host = 1;
+                       }
                }
 
-               if (((which == _PWNAM_) && (!strcmp(nam, pw->pw_name))) ||
-                       ((which == _PWUID_) && (uid == pw->pw_uid)))
+               if ((which == _HADDR_) && (h->h_addrtype == af))
                {
-                       if (_pwStayOpen == 0) endpwent();
-                       return pw;
+                       for (i = 0; (h->h_addr_list[i] != NULL) && (got_host == 0); i++)
+                               if (memcmp(addr, h->h_addr_list[i], h->h_length) == 0) got_host = 1;
+               }
+
+               if (got_host == 1)
+               {
+                       fclose(_hfp);
+                       _hfp = NULL;
+                       return h;
                }
        }
 
-       if (_pwStayOpen == 0) endpwent();
+       fclose(_hfp);
+       _hfp = NULL;
+
+       return NULL;
+}
+
+/* "Public" */
+
+__private_extern__ struct hostent *
+LI_files_gethostbyname(const char *name)
+{
+       return LI_files_get_host(name, NULL, AF_INET, _HNAM_);
+}
+
+__private_extern__ struct hostent *
+LI_files_gethostbyname2(const char *name, int af)
+{
+       return LI_files_get_host(name, NULL, af, _HNAM_);
+}
+
+__private_extern__ struct hostent *
+LI_files_gethostbyaddr(const void *addr, socklen_t len, int type)
+{
+       if ((type == AF_INET) || (type == AF_INET6)) return LI_files_get_host(NULL, addr, type, _HADDR_);
        return NULL;
 }
 
-struct passwd *
-getpwent()
+__private_extern__ struct hostent *
+LI_files_gethostent()
 {
-       return getpw(NULL, 0, _PWENT_);
+       return LI_files_get_host(NULL, NULL, AF_UNSPEC, _HENT_);
 }
 
-struct passwd *
-getpwnam(const char *nam)
+__private_extern__ void
+LI_files_sethostent(int stayopen)
 {
-       return getpw(nam, 0, _PWNAM_);
 }
 
-struct passwd *
-getpwuid(uid_t uid)
+__private_extern__ void
+LI_files_endhostent()
 {
-       return getpw(NULL, uid, _PWUID_);
+       if (_hfp != NULL)
+       {
+               fclose(_hfp);
+               _hfp = NULL;
+       }
 }
index bcf5c23018e018b787217d1b840f462f66791a36..79953ff541d2542046b309e99a280aefe3af7266 100644 (file)
 .Dt GETSERVENT 3
 .Os
 .Sh NAME
-.Nm getservent ,
-.Nm getservbyport ,
+.Nm endservent ,
 .Nm getservbyname ,
-.Nm setservent ,
-.Nm endservent
+.Nm getservbyport ,
+.Nm getservent ,
+.Nm setservent
 .Nd get service entry
 .Sh LIBRARY
 .Lb libc
 .Sh SYNOPSIS
 .Fd #include <netdb.h>
+.Ft void
+.Fo endservent
+.Fa void
+.Fc
 .Ft struct servent *
-.Fn getservent
+.Fo getservbyname
+.Fa "const char *name"
+.Fa "const char *proto"
+.Fc
 .Ft struct servent *
-.Fn getservbyname "const char *name" "const char *proto"
+.Fo getservbyport
+.Fa "int port"
+.Fa "const char *proto"
+.Fc
 .Ft struct servent *
-.Fn getservbyport "int port" "const char *proto"
-.Ft void
-.Fn setservent "int stayopen"
+.Fo getservent
+.Fa void
+.Fc
 .Ft void
-.Fn endservent void
+.Fo setservent
+.Fa "int stayopen"
+.Fc
 .Sh DESCRIPTION
 The
 .Fn getservent ,
index 9327c1252d558c40584d8e2294bc66ea8fa3a956..5d550f3d3e5af0b38bcdeb07e76fc4b26fbf53b0 100644 (file)
 .Dt IF_NAMETOINDEX 3
 .Os
 .Sh NAME
-.Nm if_nametoindex ,
+.Nm if_freenameindex ,
 .Nm if_indextoname ,
 .Nm if_nameindex ,
-.Nm if_freenameindex
+.Nm if_nametoindex
 .Nd convert interface index to name, and vice versa
 .Sh LIBRARY
 .Lb libc
 .Fd #include <sys/types.h>
 .Fd #include <sys/socket.h>
 .Fd #include <net/if.h>
-.Ft "unsigned int"
-.Fn if_nametoindex "const char *ifname"
+.Ft void
+.Fo if_freenameindex
+.Fa "struct if_nameindex *ptr"
+.Fc
 .Ft "char *"
-.Fn if_indextoname "unsigned int ifindex" "char *ifname"
+.Fo if_indextoname
+.Fa "unsigned ifindex"
+.Fa "char *ifname"
+.Fc
 .Ft "struct if_nameindex *"
-.Fn if_nameindex "void"
-.Ft "void"
-.Fn if_freenameindex "struct if_nameindex *ptr"
+.Fo if_nameindex
+.Fa void
+.Fc
+.Ft "unsigned int"
+.Fo if_nametoindex
+.Fa "const char *ifname"
+.Fc
 .Sh DESCRIPTION
 The functions map interface index to readable interface name
 (such as
index d4f08aebc2c3d9da4edd1d072a3995fd95f9a46a..51f70501ef7ff74fb9ba24d5cd2829e29df530d5 100644 (file)
@@ -5,31 +5,43 @@
 #include <stdio.h>
 #include <stdint.h>
 #include <string.h>
+#include <errno.h>
 #include <sys/socket.h>
 
 void __res_close()
 {
 }
 
+#define MAX_V4_ADDR_LEN 16
 #define MAX_V6_ADDR_LEN 64
 
 static const char *hexchars = "0123456789abcdef";
 
 const char *
-inet_ntop6(const struct in6_addr *addr, char *dst, size_t size)
+inet_ntop6(const struct in6_addr *addr, char *dst, socklen_t size)
 {
        char hexa[8][5], tmp[MAX_V6_ADDR_LEN];
        int zr[8];
-       size_t len;
+       socklen_t len;
        int32_t i, j, k, skip;
        uint8_t x8, hx8;
        uint16_t x16;
        struct in_addr a4;
-       
-       if (addr == NULL) return NULL;
-       
+
+       if (addr == NULL)
+       {
+               errno = EAFNOSUPPORT;
+               return NULL;
+       }
+
+       if (dst == NULL)
+       {
+               errno = ENOSPC;
+               return NULL;
+       }
+
        memset(tmp, 0, MAX_V6_ADDR_LEN);
-       
+
        /*  check for mapped or compat addresses */
        i = IN6_IS_ADDR_V4MAPPED(addr);
        j = IN6_IS_ADDR_V4COMPAT(addr);
@@ -38,49 +50,54 @@ inet_ntop6(const struct in6_addr *addr, char *dst, size_t size)
                a4.s_addr = addr->__u6_addr.__u6_addr32[3];
                sprintf(tmp, "::%s%s", (i != 0) ? "ffff:" : "", inet_ntoa(a4));
                len = strlen(tmp) + 1;
-               if (len > size) return NULL;
+               if (len > size)
+               {
+                       errno = ENOSPC;
+                       return NULL;
+               }
+
                memcpy(dst, tmp, len);
                return dst;
        }
-       
+
        k = 0;
        for (i = 0; i < 16; i += 2)
        {
                j = 0;
                skip = 1;
-               
+
                memset(hexa[k], 0, 5);
-               
+
                x8 = addr->__u6_addr.__u6_addr8[i];
-               
+
                hx8 = x8 >> 4;
                if (hx8 != 0)
                {
                        skip = 0;
                        hexa[k][j++] = hexchars[hx8];
                }
-               
+
                hx8 = x8 & 0x0f;
                if ((skip == 0) || ((skip == 1) && (hx8 != 0)))
                {
                        skip = 0;
                        hexa[k][j++] = hexchars[hx8];
                }
-               
+
                x8 = addr->__u6_addr.__u6_addr8[i + 1];
-               
+
                hx8 = x8 >> 4;
                if ((skip == 0) || ((skip == 1) && (hx8 != 0)))
                {
                        hexa[k][j++] = hexchars[hx8];
                }
-               
+
                hx8 = x8 & 0x0f;
                hexa[k][j++] = hexchars[hx8];
-               
+
                k++;
        }
-       
+
        /* find runs of zeros for :: convention */
        j = 0;
        for (i = 7; i >= 0; i--)
@@ -91,7 +108,7 @@ inet_ntop6(const struct in6_addr *addr, char *dst, size_t size)
                else j = 0;
                zr[i] = j;
        }
-       
+
        /* find longest run of zeros */
        k = -1;
        j = 0;
@@ -103,12 +120,12 @@ inet_ntop6(const struct in6_addr *addr, char *dst, size_t size)
                        j = zr[i];
                }
        }
-       
+
        for(i = 0; i < 8; i++)
        {
                if (i != k) zr[i] = 0;
        }
-       
+
        len = 0;
        for (i = 0; i < 8; i++)
        {
@@ -127,41 +144,67 @@ inet_ntop6(const struct in6_addr *addr, char *dst, size_t size)
        /* trailing NULL */
        len++;
 
-       if (len > size) return NULL;
+       if (len > size)
+       {
+               errno = ENOSPC;
+               return NULL;
+       }
+
        memcpy(dst, tmp, len);
        return dst;
 }
 
 const char *
-inet_ntop4(const struct in_addr *addr, char *buf, size_t len)
+inet_ntop4(const struct in_addr *addr, char *dst, socklen_t size)
 {
+       char tmp[MAX_V4_ADDR_LEN], *p;
        const u_int8_t *ap = (u_int8_t *)&addr->s_addr;
-       int i;
-       char *bp=buf;
-       
+       int i, ql, len;
+
+       if (addr == NULL)
+       {
+               errno = EAFNOSUPPORT;
+               return NULL;
+       }
+
+       if (dst == NULL)
+       {
+               errno = ENOSPC;
+               return NULL;
+       }
+
+       memset(tmp, 0, MAX_V4_ADDR_LEN);
+
+       /* 3 dots, trailing nul */
+       len = 4;
+
+       p = tmp;
+
        for (i = 0; i < 4; i++, ap++)
        {
-               if (bp >= buf + len - 1)
-               {
-                       buf[len-1] = 0;
-                       return buf;
-               }
+               snprintf(p, 4, "%d", *ap);
+               ql = strlen(p);
+               len += ql;
+               p += ql;
+               if (i < 3) *p++ = '.';
+       }
 
-               sprintf(bp, "%d", *ap);
-               bp += strlen(bp);
-               if (i != 3) *bp++='.';
+       if (len > size)
+       {
+               errno = ENOSPC;
+               return NULL;
        }
 
-       *bp = 0;
-       return buf;
+       memcpy(dst, tmp, len);
+       return dst;
 }
 
 const char *
-inet_ntop(int af, const void *addr, char *buf, size_t len)
+inet_ntop(int af, const void *addr, char *buf, socklen_t len)
 {
-       if(af==AF_INET6)
-               return inet_ntop6(addr, buf, len);
-       if(af==AF_INET)
-               return inet_ntop4(addr, buf, len);
+       if (af == AF_INET6) return inet_ntop6(addr, buf, len);
+       if (af == AF_INET) return inet_ntop4(addr, buf, len);
+
+       errno = EAFNOSUPPORT;
        return NULL;
 }
index e49eae497551910b57aecda7370ac5b8a35db83e..e46a7a1f235fb7cc526276ba076bc193d3b21948 100644 (file)
@@ -28,6 +28,7 @@ static char rcsid[] = "$Id: inet_pton.c,v 1.3 2003/04/10 18:53:29 majka Exp $";
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <net/if.h>
 #include <arpa/nameser.h>
 #include <string.h>
 #include <stdlib.h>
@@ -82,16 +83,20 @@ int
 inet_pton(int af, const char *src, void *dst)
 {
        int status;
+       unsigned short ifnum;
        char *p, *s;
 
        switch (af)
        {
-               case AF_INET: return (inet_pton4(src, dst));
+               case AF_INET:
+               {
+                       return (inet_pton4(src, dst));
+               }
 
 #ifdef INET6
                case AF_INET6:
-                       /* Ignore trailing %xxx (interface specification) */
-
+               {
+                       ifnum = 0;
                        p = NULL;
                        s = (char *)src;
 
@@ -99,19 +104,39 @@ inet_pton(int af, const char *src, void *dst)
                        if (p != NULL)
                        {
                                s = strdup(src);
+                               if (s == NULL)
+                               {
+                                       errno = ENOMEM;
+                                       return -1;
+                               }
+                               
                                s[p - src] = '\0';
                        }
 
                        status = inet_pton6(s, dst);
                        if (p != NULL) free(s);
-                       return status;
+                       if (status != 1) return status;
+                       
+                       if ((p != NULL) && IN6_IS_ADDR_LINKLOCAL((struct in6_addr *)dst))
+                       {
+                               ifnum = if_nametoindex(++p);
+                               ifnum = htons(ifnum);
+                               ((struct in6_addr *)dst)->__u6_addr.__u6_addr16[1] = ifnum;
+                       }
+
+                       return 1;
+               }
 #endif
 
                default:
+               {
                        errno = EAFNOSUPPORT;
                        return -1;
+               }
        }
+
        /* NOTREACHED */
+       return -1;
 }
 
 /* int
@@ -125,23 +150,21 @@ inet_pton(int af, const char *src, void *dst)
  *     Paul Vixie, 1996.
  */
 static int
-inet_pton4(src, dst)
-       const char *src;
-       u_char *dst;
+inet_pton4(const char *src, u_char *dst)
 {
        static const char digits[] = "0123456789";
        int saw_digit, octets, ch;
        u_char tmp[NS_INADDRSZ], *tp;
-
+       
        saw_digit = 0;
        octets = 0;
        *(tp = tmp) = 0;
        while ((ch = *src++) != '\0') {
                const char *pch;
-
+               
                if ((pch = strchr(digits, ch)) != NULL) {
                        u_int new = *tp * 10 + (pch - digits);
-
+                       
                        if (new > 255)
                                return (0);
                        *tp = new;
@@ -179,17 +202,15 @@ inet_pton4(src, dst)
  *     Paul Vixie, 1996.
  */
 static int
-inet_pton6(src, dst)
-       const char *src;
-       u_char *dst;
+inet_pton6(const char *src, u_char *dst)
 {
        static const char xdigits_l[] = "0123456789abcdef",
-                         xdigits_u[] = "0123456789ABCDEF";
+       xdigits_u[] = "0123456789ABCDEF";
        u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
        const char *xdigits, *curtok;
        int ch, saw_xdigit;
        u_int val;
-
+       
        memset((tp = tmp), '\0', NS_IN6ADDRSZ);
        endp = tp + NS_IN6ADDRSZ;
        colonp = NULL;
@@ -202,7 +223,7 @@ inet_pton6(src, dst)
        val = 0;
        while ((ch = *src++) != '\0') {
                const char *pch;
-
+               
                if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
                        pch = strchr((xdigits = xdigits_u), ch);
                if (pch != NULL) {
@@ -252,7 +273,7 @@ inet_pton6(src, dst)
                 */
                const int n = tp - colonp;
                int i;
-
+               
                if (tp == endp)
                        return (0);
                for (i = 1; i <= n; i++) {
index 0ca077a509575b4814e1572b3e220896772c05c1..2cce6892b87a1437e5ed1f3b05e87d4e75448479 100644 (file)
@@ -66,6 +66,9 @@ static char sccsid[] = "@(#)initgroups.c      8.1 (Berkeley) 6/4/93";
 #include <err.h>
 #include <pwd.h>
 
+__private_extern__ struct passwd *LI_files_getpwnam(const char *name);
+
+/* this is _old_initgroups */
 int
 initgroups(uname, agroup)
        const char *uname;
@@ -75,7 +78,7 @@ initgroups(uname, agroup)
        struct passwd *pw;
 
        /* get the UID for this user */
-       if ((pw = getpwnam(uname)) == NULL)
+       if ((pw = LI_files_getpwnam(uname)) == NULL)
                return(-1);
 
        /* fetch the initial (advisory) group list */
index c1ec9fea1f5a4d4b7f86743be0cc9f9e2866c89d..26bde6218c3306f20b3ef89c46e7a4305e822f9a 100644 (file)
  */
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 #include <printerdb.h>
 
-#define strdup(x)  strcpy(malloc(strlen(x) + 1), x)
-
-extern size_t strlen(const char *);
-extern char *index(const char *, int);
-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 *);
diff --git a/lookup.subproj/DSlibinfoMIG.defs b/lookup.subproj/DSlibinfoMIG.defs
new file mode 100644 (file)
index 0000000..14ebc7e
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*!
+ * @header DSLookupMIG.defs
+ */
+
+/*
+ * Warning!
+ * Do not re-order this file as it will cause MIG API number
+ * changes.  Always add to the end of the file for new defs.
+ */
+
+subsystem DSlibinfoMIG 50000;
+
+userprefix libinfoDSmig_;
+serverprefix libinfoDSmig_do_;
+
+import <sys/types.h>;
+
+#include <mach/std_types.defs>
+#include <mach/mach_types.defs>
+
+import <DSlibinfoMIG_types.h>;
+
+type proc_name_t = c_string [* : 256];
+type inline_data_t = array [* : 16384] of char;
+
+routine GetProcedureNumber
+(
+       server : mach_port_t;
+       name : proc_name_t;
+       out procno : int32_t;
+       ServerAuditToken bsmtoken : audit_token_t;
+       UserSecToken usertoken : security_token_t
+);
+
+routine Query
+(
+       server : mach_port_t;
+       proc : int32_t;
+       request : inline_data_t;
+       out reply : inline_data_t;
+       out ooreply : pointer_t, Dealloc;
+       ServerAuditToken bsmtoken : audit_token_t;
+       UserSecToken usertoken : security_token_t
+);
+
+simpleroutine Query_async
+(
+       server : mach_port_t;
+       replyToPort : mach_port_make_send_once_t;
+       proc : int32_t;
+       request : inline_data_t;
+       callbackAddr : mach_vm_address_t;
+       ServerAuditToken bsmtoken : audit_token_t
+);
diff --git a/lookup.subproj/DSlibinfoMIGAsyncReply.defs b/lookup.subproj/DSlibinfoMIGAsyncReply.defs
new file mode 100644 (file)
index 0000000..4524a8e
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2005 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*!
+ * @header DSLookupMIGAsyncReply.defs
+ */
+
+/*
+ * Warning!
+ * Do not re-order this file as it will cause MIG API number
+ * changes.  Always add to the end of the file for new defs.
+ */
+
+subsystem DSlibinfoMIGAsyncReply 50050;
+
+userprefix libinfoDSmig_;
+serverprefix libinfoDSmig_do_;
+
+import <sys/types.h>;
+
+#include <mach/std_types.defs>
+#include <mach/mach_types.defs>
+
+import <DSlibinfoMIG_types.h>;
+
+type inline_data_t = array [* : 16384] of char;
+
+simpleroutine Response_async
+(
+       server : mach_port_move_send_once_t;
+       reply : inline_data_t;
+       ooreply : pointer_t, Dealloc;
+       callbackAddr : mach_vm_address_t;
+       ServerSecToken servertoken : security_token_t
+);
diff --git a/lookup.subproj/DSlibinfoMIG_types.h b/lookup.subproj/DSlibinfoMIG_types.h
new file mode 100644 (file)
index 0000000..f6e0350
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_LICENSE_HEADER_END@
+ */
+
+/*!
+ * @header DSlibinfoMIG_types.h
+ */
+
+#ifndef __DSLIBINFOMIG_TYPES_H__
+#define __DSLIBINFOMIG_TYPES_H__
+
+#ifndef kDSStdMachDSLookupPortName
+#define kDSStdMachDSLookupPortName "com.apple.system.DirectoryService.libinfo_v1"
+#endif
+
+#define MAX_MIG_INLINE_DATA 16384
+
+typedef char *inline_data_t;
+typedef char *proc_name_t;
+
+struct sLibinfoRequest
+{
+    mach_port_t fReplyPort;
+    int32_t fProcedure;
+    char *fBuffer;
+    int32_t fBufferLen;
+    mach_vm_address_t fCallbackAddr;
+    audit_token_t fToken;
+};
+
+extern boolean_t DSlibinfoMIGAsyncReply_server(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP);
+
+#endif /* __DSLIBINFOMIG_TYPES_H__ */
index 32f6ba84a21eac60cd094e554f9310d3bf036e48..4085a6a57c50350b1b9ae01ebf70c7872c9ca30b 100644 (file)
@@ -12,15 +12,17 @@ NAME = lookup
 PROJECTVERSION = 2.8
 PROJECT_TYPE = Component
 
-HFILES = aliasdb.h bootparams.h lookup_types.h lu_overrides.h\
-         lu_host.h lu_utils.h netdb.h netdb_async.h netgr.h printerdb.h
+HFILES = aliasdb.h bootparams.h kvbuf.h lookup_types.h lu_overrides.h\
+         lu_host.h lu_utils.h netdb.h netdb_async.h printerdb.h
 
 CFILES = getaddrinfo.c lu_alias.c lu_bootp.c lu_bootparam.c lu_fstab.c\
          lu_group.c lu_host.c lu_host_async.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
+         lu_printer.c lu_protocol.c lu_rpc.c lu_service.c lu_user.c lu_utils.c
 
-OTHERSRCS = Makefile.preamble Makefile Makefile.postamble getaddrinfo.3\
-            getnameinfo.3 lookup.defs _lu_types.x
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble\
+         bootparams.5 gai_strerror.3 getaddrinfo.3 getfsent.3 getgrent.3 getgrouplist.3\
+         getnameinfo.3 getnetgrent.3 getpwent.3 initgroups.3\
+         DSlibinfoMIG_types.h DSlibinfoMIG.defs DSlibinfoMIGAsyncReply.defs lookup.defs _lu_types.x
 
 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
 CODE_GEN_STYLE = DYNAMIC
index f4013b104ef8d1bb2ea69b49a08d9a89cd339106..a5404b30356eed449ec24b3f9641849de7c62cfa 100644 (file)
@@ -1,10 +1,10 @@
 %_xdr.c: %.x
        $(RPCGEN) $(ALL_RPCFLAGS) -c -o $(SYM_DIR)/$*_xdr.c $*.x
 
-async_hdrs: $(DSTROOT)$(PRIVATE_HDR_INSTALLDIR)$(ASYNC_HEADER_DIR_SUFFIX)
-       $(SILENT) $(FASTCP) $(ASYNC_HDRS) $(DSTROOT)$(PRIVATE_HDR_INSTALLDIR)$(ASYNC_HEADER_DIR_SUFFIX)
+private_hdrs: $(DSTROOT)$(PRIVATE_HDR_INSTALLDIR)$(PRIVATE_HEADER_DIR_SUFFIX)
+       $(SILENT) $(FASTCP) $(PRIVATE_HDRS) $(DSTROOT)$(PRIVATE_HDR_INSTALLDIR)$(PRIVATE_HEADER_DIR_SUFFIX)
 
-$(DSTROOT)$(PRIVATE_HDR_INSTALLDIR)$(ASYNC_HEADER_DIR_SUFFIX):
+$(DSTROOT)$(PRIVATE_HDR_INSTALLDIR)$(PRIVATE_HEADER_DIR_SUFFIX):
        $(MKDIRS) $@
 
 netinfo_hdrs: $(DSTROOT)$(PRIVATE_HDR_INSTALLDIR)$(NETINFO_HEADER_DIR_SUFFIX)
@@ -15,7 +15,38 @@ $(DSTROOT)$(PRIVATE_HDR_INSTALLDIR)$(NETINFO_HEADER_DIR_SUFFIX):
 
 install-man-page:
        mkdir -p "$(DSTROOT)/usr/share/man/man3"
+       install -c -m 644 gai_strerror.3 "$(DSTROOT)/usr/share/man/man3"
        install -c -m 644 getaddrinfo.3 "$(DSTROOT)/usr/share/man/man3"
-       install -c -m 644 getnameinfo.3 "$(DSTROOT)/usr/share/man/man3"
        $(LN) -f "$(DSTROOT)/usr/share/man/man3/getaddrinfo.3" "$(DSTROOT)/usr/share/man/man3/freeaddrinfo.3"
-       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getaddrinfo.3" "$(DSTROOT)/usr/share/man/man3/gai_strerror.3"
+       install -c -m 644 getfsent.3 "$(DSTROOT)/usr/share/man/man3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getfsent.3" "$(DSTROOT)/usr/share/man/man3/endfsent.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getfsent.3" "$(DSTROOT)/usr/share/man/man3/getfsfile.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getfsent.3" "$(DSTROOT)/usr/share/man/man3/getfsspec.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getfsent.3" "$(DSTROOT)/usr/share/man/man3/getfstype.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getfsent.3" "$(DSTROOT)/usr/share/man/man3/setfsent.3"
+       install -c -m 644 getgrent.3 "$(DSTROOT)/usr/share/man/man3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getgrent.3" "$(DSTROOT)/usr/share/man/man3/endgrent.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getgrent.3" "$(DSTROOT)/usr/share/man/man3/getgrgid.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getgrent.3" "$(DSTROOT)/usr/share/man/man3/getgrgid_r.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getgrent.3" "$(DSTROOT)/usr/share/man/man3/getgrnam.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getgrent.3" "$(DSTROOT)/usr/share/man/man3/getgrnam_r.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getgrent.3" "$(DSTROOT)/usr/share/man/man3/setgrent.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getgrent.3" "$(DSTROOT)/usr/share/man/man3/setgroupent.3"
+       install -c -m 644 getgrouplist.3 "$(DSTROOT)/usr/share/man/man3"
+       install -c -m 644 getnameinfo.3 "$(DSTROOT)/usr/share/man/man3"
+       install -c -m 644 getnetgrent.3 "$(DSTROOT)/usr/share/man/man3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getnetgrent.3" "$(DSTROOT)/usr/share/man/man3/endnetgrent.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getnetgrent.3" "$(DSTROOT)/usr/share/man/man3/innetgr.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getnetgrent.3" "$(DSTROOT)/usr/share/man/man3/setnetgrent.3"
+       install -c -m 644 getpwent.3 "$(DSTROOT)/usr/share/man/man3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getpwent.3" "$(DSTROOT)/usr/share/man/man3/endpwent.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getpwent.3" "$(DSTROOT)/usr/share/man/man3/getpwnam.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getpwent.3" "$(DSTROOT)/usr/share/man/man3/getpwnam_r.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getpwent.3" "$(DSTROOT)/usr/share/man/man3/getpwuid.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getpwent.3" "$(DSTROOT)/usr/share/man/man3/getpwuid_r.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getpwent.3" "$(DSTROOT)/usr/share/man/man3/setpassent.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getpwent.3" "$(DSTROOT)/usr/share/man/man3/setpwent.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getpwent.3" "$(DSTROOT)/usr/share/man/man3/setpwfile.3"
+       install -c -m 644 initgroups.3 "$(DSTROOT)/usr/share/man/man3"
+       mkdir -p "$(DSTROOT)/usr/share/man/man5"
+       install -c -m 644 bootparams.5 "$(DSTROOT)/usr/share/man/man5"
index 0f382d03f17e3736fe91e6c7dfee5d17113f73d5..0300b74bb37e93670508d58fc19659657ef33073 100644 (file)
@@ -1,15 +1,16 @@
 RPCFILES = _lu_types.x
-OTHER_OFILES = lookupUser.o _lu_types_xdr.o
-AFTER_PREBUILD = _lu_types.h lookupUser.c 
-ASYNC_HDRS = netdb_async.h
-NETINFO_HDRS = lookup.h _lu_types.h lookup_types.h lookup.defs _lu_types.x
-BEFORE_INSTALLHDRS += $(SFILE_DIR) $(ASYNC_HDRS) $(NETINFO_HDRS)
-AFTER_INSTALLHDRS += async_hdrs netinfo_hdrs
+OTHER_OFILES = DSlibinfoMIGUser.o DSlibinfoMIGAsyncReplyServer.o
+AFTER_PREBUILD = _lu_types.h DSlibinfoMIGUser.c DSlibinfoMIGAsyncReplyServer.c
+PRIVATE_HDRS = kvbuf.h netdb_async.h
+NETINFO_HDRS = DSlibinfoMIG.h DSlibinfoMIGAsyncReply.h lookup.h _lu_types.h lookup_types.h lookup.defs _lu_types.x
+BEFORE_INSTALLHDRS += $(SFILE_DIR) $(PRIVATE_HDRS) $(NETINFO_HDRS)
+AFTER_INSTALLHDRS += private_hdrs netinfo_hdrs
 PUBLIC_HEADER_DIR_SUFFIX = 
 PRIVATE_HEADER_DIR = /usr/local/include
-ASYNC_HEADER_DIR_SUFFIX = /
+PRIVATE_HEADER_DIR_SUFFIX = /
 NETINFO_HEADER_DIR_SUFFIX = /netinfo
 AFTER_POSTINSTALL += install-man-page
+OTHER_CFLAGS += -D__MigTypeCheck=1 -D__DARWIN_NON_CANCELABLE=1
 
 # for building 64-bit
 # <rdar://problem/3819761> Libinfo need to build with gcc-3.5 and 3-way fat
index 19077d846b92c5d6e7b227c6be3fab885a838101..f54271ce9af7a8cb0e35e6e1d4d6bece89e86112 100644 (file)
@@ -4,13 +4,13 @@
         H_FILES = (
             aliasdb.h, 
             bootparams.h, 
+            kvbuf.h, 
             lookup_types.h, 
             lu_overrides.h, 
             lu_host.h, 
             lu_utils.h, 
             netdb.h, 
             netdb_async.h, 
-            netgr.h, 
             printerdb.h
         ); 
         OTHER_LINKED = (
diff --git a/lookup.subproj/bootparams.5 b/lookup.subproj/bootparams.5
new file mode 100644 (file)
index 0000000..d36d7ee
--- /dev/null
@@ -0,0 +1,39 @@
+.\" Copyright (c) 2006 Apple Computer
+.\" 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.
+.\" 4. Neither the name of Apple Computer 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 APPLE COMPUTER 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.
+.\"
+.\"
+.Dd December 12, 2006
+.Dt BOOTPARAMS 5
+.Os "Mac OS X"
+.Sh NAME
+.Nm bootparams
+.Nd boot parameter database
+.Sh SYNOPSIS
+.Nm /etc/bootparams
+.Sh DESCRIPTION
+Mac OS X no longer supports boot paramters.
+The /etc/bootparams file is unused.
diff --git a/lookup.subproj/gai_strerror.3 b/lookup.subproj/gai_strerror.3
new file mode 100644 (file)
index 0000000..5ed9474
--- /dev/null
@@ -0,0 +1,102 @@
+.\"    $KAME: gai_strerror.3,v 1.1 2005/01/05 03:04:47 itojun Exp $
+.\"    $OpenBSD: gai_strerror.3,v 1.4 2004/12/20 23:04:53 millert Exp $
+.\"
+.\" Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
+.\" Copyright (C) 2000, 2001  Internet Software Consortium.
+.\"
+.\" 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.
+.\"
+.\" THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
+.\" REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+.\" AND FITNESS.  IN NO EVENT SHALL ISC 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.
+.\"
+.\" $FreeBSD: src/lib/libc/net/gai_strerror.3,v 1.3 2005/06/16 19:01:06 ru Exp $
+.\"
+.Dd December 20, 2004
+.Dt GAI_STRERROR 3
+.Os
+.Sh NAME
+.Nm gai_strerror
+.Nd get error message string from EAI_xxx error code
+.Sh SYNOPSIS
+.In sys/types.h
+.In sys/socket.h
+.In netdb.h
+.Ft "const char *"
+.Fo gai_strerror
+.Fa "int ecode"
+.Fc
+.Sh DESCRIPTION
+The
+.Fn gai_strerror
+function returns an error message string corresponding to the error code
+returned by
+.Xr getaddrinfo 3
+or
+.Xr getnameinfo 3 .
+.Pp
+The following error codes and their meaning are defined in
+.In netdb.h :
+.Pp
+.Bl -tag -width ".Dv EAI_BADFLAGS" -offset indent -compact
+.It Dv EAI_AGAIN
+temporary failure in name resolution
+.It Dv EAI_BADFLAGS
+invalid value for
+.Fa ai_flags
+.It Dv EAI_BADHINTS
+invalid value for
+.Fa hints
+.It Dv EAI_FAIL
+non-recoverable failure in name resolution
+.It Dv EAI_FAMILY
+.Fa ai_family
+not supported
+.It Dv EAI_MEMORY
+memory allocation failure
+.It Dv EAI_NONAME
+.Fa hostname
+or
+.Fa servname
+not provided, or not known
+.It Dv EAI_PROTOCOL
+resolved protocol is unknown
+.It Dv EAI_SERVICE
+.Fa servname
+not supported for
+.Fa ai_socktype
+.It Dv EAI_SOCKTYPE
+.Fa ai_socktype
+not supported
+.It Dv EAI_SYSTEM
+system error returned in
+.Va errno
+.El
+.Sh RETURN VALUES
+The
+.Fn gai_strerror
+function
+returns a pointer to the error message string corresponding to
+.Fa ecode .
+If
+.Fa ecode
+is out of range, an implementation-specific error message string is returned.
+.Sh LEGACY SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Fd #include <netdb.h>
+.Pp
+The include files
+.In sys/types.h
+and
+.In sys/socket.h
+are necessary.
+.Sh SEE ALSO
+.Xr getaddrinfo 3 ,
+.Xr getnameinfo 3
index 5ab76fb08ceab6ea8e1306ede9b751392634a906..b03fa0cda00bea5c4845ead67956a8f9253d08dc 100644 (file)
 .Dt GETADDRINFO 3
 .Os
 .Sh NAME
-.Nm getaddrinfo ,
-.Nm freeaddrinfo
+.Nm freeaddrinfo ,
+.Nm getaddrinfo
 .Nd socket address structure to host and service name
 .Sh SYNOPSIS
-.Fd #include <sys/types.h>
 .Fd #include <sys/socket.h>
 .Fd #include <netdb.h>
-.Ft int
-.Fn getaddrinfo "const char *hostname" "const char *servname" \
-    "const struct addrinfo *hints" "struct addrinfo **res"
 .Ft void
-.Fn freeaddrinfo "struct addrinfo *ai"
+.Fo freeaddrinfo
+.Fa "struct addrinfo *ai"
+.Fc
+.Ft int
+.Fo getaddrinfo
+.Fa "const char *restrict nodename"
+.Fa "const char *restrict servname"
+.Fa "const struct addrinfo *restrict hints"
+.Fa "struct addrinfo **restrict res"
+.Fc
 .Sh DESCRIPTION
 The
 .Fn getaddrinfo
 function is used to get a list of
 .Tn IP
 addresses and port numbers for host
-.Fa hostname
+.Fa nodename
 and service
 .Fa servname .
 It is a replacement for and provides more flexibility than the
@@ -49,12 +54,12 @@ and
 functions.
 .Pp
 The
-.Fa hostname
+.Fa nodename
 and
 .Fa servname
 arguments are either pointers to NUL-terminated strings or the null pointer.
 An acceptable value for
-.Fa hostname
+.Fa nodename
 is either a valid host name or a numeric host address string consisting
 of a dotted decimal IPv4 address or an IPv6 address.
 The
@@ -62,7 +67,7 @@ The
 is either a decimal port number or a service name listed in
 .Xr services 5 .
 At least one of
-.Fa hostname
+.Fa nodename
 and
 .Fa servname
 must be non-null.
@@ -136,7 +141,7 @@ structure returned.
 If the
 .Dv AI_NUMERICHOST
 bit is set, it indicates that
-.Fa hostname
+.Fa nodename
 should be treated as a numeric string defining an IPv4 or IPv6 address
 and no name resolution should be attempted.
 .It Dv AI_PASSIVE
@@ -146,7 +151,7 @@ bit is set it indicates that the returned socket address structure
 is intended for use in a call to
 .Xr bind 2 .
 In this case, if the
-.Fa hostname
+.Fa nodename
 argument is the null pointer, then the IP address portion of the
 socket address structure will be set to
 .Dv INADDR_ANY
@@ -169,7 +174,7 @@ The
 .Tn IP
 address portion of the socket address structure will be set to the
 loopback address if
-.Fa hostname
+.Fa nodename
 is the null pointer and
 .Dv AI_PASSIVE
 is not set.
@@ -379,6 +384,14 @@ if (nsock == 0) {
 }
 freeaddrinfo(res0);
 .Ed
+.Sh LEGACY SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Fd #include <netdb.h>
+.Pp
+The include file
+.In sys/types.h
+is necessary.
 .Sh SEE ALSO
 .Xr bind 2 ,
 .Xr connect 2 ,
@@ -429,7 +442,3 @@ function is defined by the
 draft specification and documented in
 .Dv "RFC 3493" ,
 .Dq Basic Socket Interface Extensions for IPv6 .
-.Sh BUGS
-The implementation of
-.Fn getaddrinfo
-is not thread-safe.
index cde6136f719244c3ebebb9539ad131324faeeb20..fc9482ff5fa6bf88fb964bb63905e5e4e3d3c95c 100644 (file)
@@ -32,8 +32,8 @@
 #include <arpa/inet.h>
 #include <string.h>
 #include <stdlib.h>
-#include <errno.h>
 #include <stdio.h>
+#include <errno.h>
 #include <ctype.h>
 #include <rpc/types.h>
 #include <rpc/xdr.h>
 #define SOCK_UNSPEC 0
 #define IPPROTO_UNSPEC 0
 
-#define LONG_STRING_LENGTH 8192
-#define _LU_MAXLUSTRLEN 256
-#define LU_QBUF_SIZE 8192
-
 #define MAX_LOOKUP_ATTEMPTS 10
 
 #define INET_NTOP_AF_INET_OFFSET 4
 #define INET_NTOP_AF_INET6_OFFSET 8
 
-extern mach_port_t _lookupd_port();
-
 static int gai_proc = -1;
 static int gni_proc = -1;
 
@@ -220,18 +214,6 @@ append_addrinfo(struct addrinfo **l, struct addrinfo *a)
        }
 }
 
-static int
-encode_kv(XDR *x, const char *k, const char *v)
-{
-       int32_t n = 1;
-
-       if (!xdr_string(x, (char **)&k, _LU_MAXLUSTRLEN)) return 1;
-       if (!xdr_int(x, &n)) return 1;
-       if (!xdr_string(x, (char **)&v, _LU_MAXLUSTRLEN)) return 1;
-
-       return 0;
-}
-
 void
 freeaddrinfo(struct addrinfo *a)
 {
@@ -248,7 +230,7 @@ freeaddrinfo(struct addrinfo *a)
 }
 
 static struct addrinfo *
-new_addrinfo_v4(int32_t flags, int32_t sock, int32_t proto, uint16_t port, struct in_addr addr, uint32_t iface, char *cname)
+new_addrinfo_v4(int32_t flags, int32_t sock, int32_t proto, uint16_t port, struct in_addr addr, uint32_t iface, const char *cname)
 {
        struct addrinfo *a;
        struct sockaddr_in *sa;
@@ -294,11 +276,12 @@ new_addrinfo_v4(int32_t flags, int32_t sock, int32_t proto, uint16_t port, struc
 }
 
 static struct addrinfo *
-new_addrinfo_v6(int32_t flags, int32_t sock, int32_t proto, uint16_t port, struct in6_addr addr, uint32_t scopeid, char *cname)
+new_addrinfo_v6(int32_t flags, int32_t sock, int32_t proto, uint16_t port, struct in6_addr addr, uint16_t scopeid, const char *cname)
 {
        struct addrinfo *a;
        struct sockaddr_in6 *sa;
        int32_t len;
+       uint16_t esid;
 
        a = (struct addrinfo *)calloc(1, sizeof(struct addrinfo));
        if (a == NULL) return NULL;
@@ -323,9 +306,23 @@ new_addrinfo_v6(int32_t flags, int32_t sock, int32_t proto, uint16_t port, struc
        sa->sin6_family = PF_INET6;
        sa->sin6_port = htons(port);
        sa->sin6_addr = addr;
+
+       /* sin6_scope_id is in host byte order */
        sa->sin6_scope_id = scopeid;
+
        a->ai_addr = (struct sockaddr *)sa;
 
+       if (IN6_IS_ADDR_LINKLOCAL(&sa->sin6_addr))
+       {
+               /* check for embedded scopeid */
+               esid = ntohs(sa->sin6_addr.__u6_addr.__u6_addr16[1]);
+               if (esid != 0)
+               {
+                       sa->sin6_addr.__u6_addr.__u6_addr16[1] = 0;
+                       if (scopeid == 0) sa->sin6_scope_id = esid;
+               }
+       }
+
        if (cname != NULL)
        {
                len = strlen(cname) + 1;
@@ -337,7 +334,8 @@ new_addrinfo_v6(int32_t flags, int32_t sock, int32_t proto, uint16_t port, struc
 }
 
 /*
- * getaddrinfo support in lookupd
+ * getaddrinfo
+ *
  * Input dict may contain the following
  *
  * name: nodename
@@ -364,13 +362,12 @@ new_addrinfo_v6(int32_t flags, int32_t sock, int32_t proto, uint16_t port, struc
  */
 
 static struct addrinfo *
-gai_lookupd_process_dictionary(XDR *inxdr)
+gai_extract(kvarray_t *in)
 {
-       int32_t i, nkeys, nvals;
-       char *key, *val;
-       uint32_t flags, family, socktype, protocol, longport, scopeid;
-       uint16_t port;
-       char *addr, *canonname;
+       uint32_t d, k, kcount;
+       uint32_t flags, family, socktype, protocol, port32;
+       uint16_t port, scopeid;
+       const char *addr, *canonname;
        struct addrinfo *a;
        struct in_addr a4;
        struct in6_addr a6;
@@ -384,69 +381,61 @@ gai_lookupd_process_dictionary(XDR *inxdr)
        addr = NULL;
        canonname = NULL;
 
-       if (!xdr_int(inxdr, &nkeys)) return NULL;
+       if (in == NULL) return NULL;
 
-       for (i = 0; i < nkeys; i++)
-       {
-               key = NULL;
-               val = NULL;
+       d = in->curr;
+       in->curr++;
 
-               if (!xdr_string(inxdr, &key, LONG_STRING_LENGTH)) return NULL;
-               if (!xdr_int(inxdr, &nvals)) 
-               {
-                       free(key);
-                       return NULL;
-               }
+       if (d >= in->count) return NULL;
+
+       kcount = in->dict[d].kcount;
 
-               if (nvals != 1)
+       for (k = 0; k < kcount; k++)
+       {
+               if (!strcmp(in->dict[d].key[k], "gai_flags"))
                {
-                       free(key);
-                       return NULL;
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       flags = atoi(in->dict[d].val[k][0]);
                }
-
-               if (!xdr_string(inxdr, &val, LONG_STRING_LENGTH))
+               else if (!strcmp(in->dict[d].key[k], "gai_family")) 
                {
-                       free(key);
-                       return NULL;
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       family = atoi(in->dict[d].val[k][0]);
                }
-
-               if (!strcmp(key, "flags"))
+               else if (!strcmp(in->dict[d].key[k], "gai_socktype"))
                {
-                       flags = atoi(val);
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       socktype = atoi(in->dict[d].val[k][0]);
                }
-               else if (!strcmp(key, "family")) 
+               else if (!strcmp(in->dict[d].key[k], "gai_protocol"))
                {
-                       family = atoi(val);
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       protocol = atoi(in->dict[d].val[k][0]);
                }
-               else if (!strcmp(key, "socktype"))
+               else if (!strcmp(in->dict[d].key[k], "gai_port"))
                {
-                       socktype = atoi(val);
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       port32 = atoi(in->dict[d].val[k][0]);
+                       port = port32;
                }
-               else if (!strcmp(key, "protocol"))
+               else if (!strcmp(in->dict[d].key[k], "gai_scopeid"))
                {
-                       protocol = atoi(val);
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       scopeid = atoi(in->dict[d].val[k][0]);
                }
-               else if (!strcmp(key, "port"))
+               else if (!strcmp(in->dict[d].key[k], "gai_address"))
                {
-                       longport = atoi(val);
-                       port = longport;
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       addr = in->dict[d].val[k][0];
                }
-               else if (!strcmp(key, "scopeid"))
+               else if (!strcmp(in->dict[d].key[k], "gai_canonname"))
                {
-                       scopeid = atoi(val);
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       canonname = in->dict[d].val[k][0];
                }
-               else if (!strcmp(key, "address")) addr = strdup(val);
-               else if (!strcmp(key, "canonname")) canonname = strdup(val);
-               free(key);
-               free(val);
        }
 
-       if (family == PF_UNSPEC)
-       {
-               if (addr != NULL) free(addr);
-               if (canonname != NULL) free(canonname);
-               return NULL;
-       }
+       if (family == PF_UNSPEC) return NULL;
 
        a = NULL;
        if (family == PF_INET)
@@ -460,43 +449,38 @@ gai_lookupd_process_dictionary(XDR *inxdr)
                a = new_addrinfo_v6(flags, socktype, protocol, port, a6, scopeid, canonname);
        }
 
-       if (addr != NULL) free(addr);
-       if (canonname != NULL) free(canonname);
-
        return a;
 }
 
-static int
-gai_make_query(const char *nodename, const char *servname, const struct addrinfo *hints, char *buf, uint32_t *len)
+static kvbuf_t *
+gai_make_query(const char *nodename, const char *servname, const struct addrinfo *hints)
 {
-       int32_t numerichost, family, proto, socktype, canonname, passive, parallel;
-       uint32_t na;
-       XDR outxdr;
+       int32_t flags, family, proto, socktype;
+       kvbuf_t *request;
        char str[64], *cname;
 
-       numerichost = 0;
+       flags = 0;
        family = PF_UNSPEC;
        proto = IPPROTO_UNSPEC;
        socktype = SOCK_UNSPEC;
-       canonname = 0;
-       passive = 0;
-       parallel = 0;
        cname = NULL;
 
        if (hints != NULL)
        {
                family = hints->ai_family;
-               if (hints->ai_flags & AI_NUMERICHOST) numerichost = 1;
-               if (hints->ai_flags & AI_CANONNAME) canonname = 1;
-               if (hints->ai_flags & AI_PASSIVE) passive = 1;
-               if (hints->ai_flags & AI_PARALLEL) parallel = 1;
+               if (hints->ai_flags & AI_NUMERICHOST) flags |= AI_NUMERICHOST;
+               if (hints->ai_flags & AI_CANONNAME) flags |= AI_CANONNAME;
+               if (hints->ai_flags & AI_PASSIVE) flags |= AI_PASSIVE;
+               if (hints->ai_flags & AI_PARALLEL) flags |= AI_PARALLEL;
 
                proto = hints->ai_protocol;
+
                if (hints->ai_socktype == SOCK_DGRAM)
                {
                        socktype = SOCK_DGRAM;
                        proto = IPPROTO_UDP;
                }
+
                if (hints->ai_socktype == SOCK_STREAM)
                {
                        socktype = SOCK_STREAM;
@@ -504,125 +488,53 @@ gai_make_query(const char *nodename, const char *servname, const struct addrinfo
                }
        }
 
-       xdrmem_create(&outxdr, buf, *len, XDR_ENCODE);
-
-       /* Attribute count */
-       na = 0;
-       if (nodename != NULL) na++;
-       if (servname != NULL) na++;
-       if (proto != IPPROTO_UNSPEC) na++;
-       if (socktype != SOCK_UNSPEC) na++;
-       if (family != PF_UNSPEC) na++;
-       if (canonname != 0) na++;
-       if (passive != 0) na++;
-       if (parallel != 0) na++;
-       if (numerichost != 0) na++;
-
-       if (!xdr_int(&outxdr, (int32_t *)&na))
+       request = kvbuf_new();
+       if (request == NULL)
        {
-               xdr_destroy(&outxdr);
-               errno = EIO;
-               return EAI_SYSTEM;
+               errno = ENOMEM;
+               return NULL;
        }
 
+       kvbuf_add_dict(request);
+
        if (nodename != NULL)
        {
-               if (encode_kv(&outxdr, "name", nodename) != 0)
-               {
-                       xdr_destroy(&outxdr);
-                       errno = EIO;
-                       return EAI_SYSTEM;
-               }
+               kvbuf_add_key(request, "name");
+               kvbuf_add_val(request, nodename);
        }
 
        if (servname != NULL)
        {
-               if (encode_kv(&outxdr, "service", servname) != 0)
-               {
-                       xdr_destroy(&outxdr);
-                       errno = EIO;
-                       return EAI_SYSTEM;
-               }
+               kvbuf_add_key(request, "service");
+               kvbuf_add_val(request, servname);
        }
 
        if (proto != IPPROTO_UNSPEC)
        {
-               snprintf(str, 64, "%u", proto);
-               if (encode_kv(&outxdr, "protocol", str) != 0)
-               {
-                       xdr_destroy(&outxdr);
-                       errno = EIO;
-                       return EAI_SYSTEM;
-               }
+               snprintf(str, sizeof(str), "%u", proto);
+               kvbuf_add_key(request, "protocol");
+               kvbuf_add_val(request, str);
        }
 
        if (socktype != SOCK_UNSPEC)
        {
-               snprintf(str, 64, "%u", socktype);
-               if (encode_kv(&outxdr, "socktype", str) != 0)
-               {
-                       xdr_destroy(&outxdr);
-                       errno = EIO;
-                       return EAI_SYSTEM;
-               }
+               snprintf(str, sizeof(str), "%u", socktype);
+               kvbuf_add_key(request, "socktype");
+               kvbuf_add_val(request, str);
        }
 
        if (family != PF_UNSPEC)
        {
-               snprintf(str, 64, "%u", family);
-               if (encode_kv(&outxdr, "family", str) != 0)
-               {
-                       xdr_destroy(&outxdr);
-                       errno = EIO;
-                       return EAI_SYSTEM;
-               }
+               snprintf(str, sizeof(str), "%u", family);
+               kvbuf_add_key(request, "family");
+               kvbuf_add_val(request, str);
        }
 
-       if (canonname != 0)
-       {
-               if (encode_kv(&outxdr, "canonname", "1") != 0)
-               {
-                       xdr_destroy(&outxdr);
-                       errno = EIO;
-                       return EAI_SYSTEM;
-               }
-       }
+       snprintf(str, sizeof(str), "%u", flags);
+       kvbuf_add_key(request, "ai_flags");
+       kvbuf_add_val(request, str);
 
-       if (passive != 0)
-       {
-               if (encode_kv(&outxdr, "passive", "1") != 0)
-               {
-                       xdr_destroy(&outxdr);
-                       errno = EIO;
-                       return EAI_SYSTEM;
-               }
-       }
-
-       if (parallel != 0)
-       {
-               if (encode_kv(&outxdr, "parallel", "1") != 0)
-               {
-                       xdr_destroy(&outxdr);
-                       errno = EIO;
-                       return EAI_SYSTEM;
-               }
-       }
-
-       if (numerichost != 0)
-       {
-               if (encode_kv(&outxdr, "numerichost", "1") != 0)
-               {
-                       xdr_destroy(&outxdr);
-                       errno = EIO;
-                       return EAI_SYSTEM;
-               }
-       }
-
-       *len = xdr_getpos(&outxdr);
-
-       xdr_destroy(&outxdr);
-
-       return 0;
+       return request;
 }
 
 static int32_t
@@ -699,7 +611,7 @@ gai_trivial(struct in_addr *in4, struct in6_addr *in6, int16_t port, const struc
        }
        else
        {
-               return EAI_NODATA;
+               return EAI_NONAME;
        }
 
        proto = IPPROTO_UNSPEC;
@@ -759,10 +671,11 @@ gai_trivial(struct in_addr *in4, struct in6_addr *in6, int16_t port, const struc
        return 0;
 }
 
-int
+static int
 gai_files(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
 {
-       int32_t i, status, numericserv, numerichost, family, proto, wantv4, wantv6;
+       int32_t i, status, numericserv, numerichost, family, proto, wantv4, wantv6, count;
+       uint16_t scopeid;
        int16_t port;
        struct servent *s;
        struct hostent *h;
@@ -771,6 +684,9 @@ gai_files(const char *nodename, const char *servname, const struct addrinfo *hin
        struct in6_addr a6;
        struct addrinfo *a;
 
+       count = 0;
+       scopeid = 0;
+
        numericserv = 0;
        if (servname != NULL) numericserv = is_a_number(servname);
 
@@ -821,6 +737,11 @@ gai_files(const char *nodename, const char *servname, const struct addrinfo *hin
                        {
                                numerichost = 1;
                                if (family == PF_UNSPEC) family = PF_INET6;
+                               if ((IN6_IS_ADDR_LINKLOCAL(&a6)) && (a6.__u6_addr.__u6_addr16[1] != 0))
+                               {
+                                       scopeid = ntohs(a6.__u6_addr.__u6_addr16[1]);
+                                       a6.__u6_addr.__u6_addr16[1] = 0;
+                               }
                        }
                }
        }
@@ -870,18 +791,21 @@ gai_files(const char *nodename, const char *servname, const struct addrinfo *hin
                        {
                                a = new_addrinfo_v4(0, SOCK_DGRAM, IPPROTO_UDP, port, a4, 0, NULL);
                                append_addrinfo(res, a);
+                               count++;
                        }
 
                        if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_TCP))
                        {
                                a = new_addrinfo_v4(0, SOCK_STREAM, IPPROTO_TCP, port, a4, 0, NULL);
                                append_addrinfo(res, a);
+                               count++;
                        }
 
                        if (proto == IPPROTO_ICMP)
                        {
                                a = new_addrinfo_v4(0, SOCK_RAW, IPPROTO_ICMP, port, a4, 0, NULL);
                                append_addrinfo(res, a);
+                               count++;
                        }
                }
 
@@ -889,30 +813,34 @@ gai_files(const char *nodename, const char *servname, const struct addrinfo *hin
                {
                        if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_UDP))
                        {
-                               a = new_addrinfo_v6(0, SOCK_DGRAM, IPPROTO_UDP, port, a6, 0, NULL);
+                               a = new_addrinfo_v6(0, SOCK_DGRAM, IPPROTO_UDP, port, a6, scopeid, NULL);
                                append_addrinfo(res, a);
+                               count++;
                        }
 
                        if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_TCP))
                        {
-                               a = new_addrinfo_v6(0, SOCK_STREAM, IPPROTO_TCP, port, a6, 0, NULL);
+                               a = new_addrinfo_v6(0, SOCK_STREAM, IPPROTO_TCP, port, a6, scopeid, NULL);
                                append_addrinfo(res, a);
+                               count++;
                        }
 
                        if (proto == IPPROTO_ICMPV6)
                        {
-                               a = new_addrinfo_v6(0, SOCK_RAW, IPPROTO_ICMPV6, port, a6, 0, NULL);
+                               a = new_addrinfo_v6(0, SOCK_RAW, IPPROTO_ICMPV6, port, a6, scopeid, NULL);
                                append_addrinfo(res, a);
+                               count++;
                        }
                }
 
+               if (count == 0) return EAI_AGAIN;
                return 0;
        }
 
        if (wantv4 == 1)
        {
                h = gethostbyname(nodename);
-               if (h == NULL) return 0;
+               if (h == NULL) return EAI_AGAIN;
 
                for (i = 0; h->h_addr_list[i] != 0; i++)
                {
@@ -922,42 +850,65 @@ gai_files(const char *nodename, const char *servname, const struct addrinfo *hin
                        {
                                a = new_addrinfo_v4(0, SOCK_DGRAM, IPPROTO_UDP, port, a4, 0, NULL);
                                append_addrinfo(res, a);
+                               count++;
                        }
 
                        if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_TCP))
                        {
                                a = new_addrinfo_v4(0, SOCK_STREAM, IPPROTO_TCP, port, a4, 0, NULL);
                                append_addrinfo(res, a);
+                               count++;
                        }
                }
        }
 
+       if (wantv6 == 1)
+       {
+               h = gethostbyname2(nodename, AF_INET6);
+               if (h == NULL) return EAI_AGAIN;
+
+               for (i = 0; h->h_addr_list[i] != 0; i++)
+               {
+                       memmove(&(a6.__u6_addr.__u6_addr32[0]), h->h_addr_list[i], h->h_length);
+
+                       if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_UDP))
+                       {
+                               a = new_addrinfo_v6(0, SOCK_DGRAM, IPPROTO_UDP, port, a6, 0, NULL);
+                               append_addrinfo(res, a);
+                               count++;
+                       }
+
+                       if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_TCP))
+                       {
+                               a = new_addrinfo_v6(0, SOCK_STREAM, IPPROTO_TCP, port, a6, 0, NULL);
+                               append_addrinfo(res, a);
+                               count++;
+                       }
+               }
+       }
+
+       if (count == 0) return EAI_AGAIN;
        return 0;
 }
 
 static int
-gai_lookupd(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
+ds_getaddrinfo(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
 {
-       uint32_t n, i, qlen, rlen;
-       XDR inxdr;
-       char qbuf[LU_QBUF_SIZE];
-       char *rbuf;
+       uint32_t i;
+       kvbuf_t *request;
+       kvarray_t *reply;
        char *cname;
-       mach_port_t server_port;
        kern_return_t status;
        struct addrinfo *a;
 
-       server_port = MACH_PORT_NULL;
-       if (_lu_running()) server_port = _lookupd_port(0);
-       if (server_port == MACH_PORT_NULL)
+       if (_ds_running() == 0)
        {
-               /* lookupd isn't available - fall back to the flat files */
                return gai_files(nodename, servname, hints, res);
        }
 
        if (gai_proc < 0)
        {
-               status = _lookup_link(server_port, "getaddrinfo", &gai_proc);
+               status = LI_DSLookupGetProcedureNumber("getaddrinfo", &gai_proc);
                if (status != KERN_SUCCESS)
                {
                        errno = ECONNREFUSED;
@@ -965,40 +916,31 @@ gai_lookupd(const char *nodename, const char *servname, const struct addrinfo *h
                }
        }
 
-       qlen = LU_QBUF_SIZE;
-
-       /* gai_make_query sets errno if it fails */
-       i = gai_make_query(nodename, servname, hints, qbuf, &qlen);
-       if (i != 0) return EAI_SYSTEM;
-
-       qlen /= BYTES_PER_XDR_UNIT;
+       request = gai_make_query(nodename, servname, hints);
+       if (request == NULL) return EAI_SYSTEM;
 
-       rbuf = NULL;
+       reply = NULL;
+       status = LI_DSLookupQuery(gai_proc, request, &reply);
+       kvbuf_free(request);
 
-       status = _lookup_all(server_port, gai_proc, (unit *)qbuf, qlen, &rbuf, &rlen);
-       if (status != KERN_SUCCESS) return EAI_NODATA;
-
-       rlen *= BYTES_PER_XDR_UNIT;
-
-       xdrmem_create(&inxdr, rbuf, rlen, XDR_DECODE);
-
-       if (!xdr_int(&inxdr, (int32_t *)&n))
+       if (status != KERN_SUCCESS)
        {
-               xdr_destroy(&inxdr);
-               errno = EIO;
+               errno = ECONNREFUSED;
                return EAI_SYSTEM;
        }
 
+       if (reply == NULL) return EAI_NONAME;
+
        cname = NULL;
-       for (i = 0; i < n; i++)
+       for (i = 0; i < reply->count; i++)
        {
-               a = gai_lookupd_process_dictionary(&inxdr);
+               a = gai_extract(reply);
+               if (a == NULL) continue;
                if ((cname == NULL) && (a->ai_canonname != NULL)) cname = a->ai_canonname;
                append_addrinfo(res, a);
        }
 
-       xdr_destroy(&inxdr);
-       if (rbuf != NULL) vm_deallocate(mach_task_self(), (vm_address_t)rbuf, rlen);
+       kvarray_free(reply);
 
        if ((cname != NULL) && (res != NULL) && (res[0] != NULL) && (res[0]->ai_canonname == NULL))
        {
@@ -1104,11 +1046,11 @@ getaddrinfo(const char * __restrict nodename, const char * __restrict servname,
        if ((numerichost == 1) && (numericserv == 1)) return gai_trivial(p4, p6, port, hints, res);
        if ((numerichost == 1) && (servnull == 1)) return gai_trivial(p4, p6, 0, hints, res);
 
-       if (nodenull == 1) status = gai_lookupd(NULL, servname, hints, res);
-       else if (servnull == 1) status = gai_lookupd(nodename, NULL, hints, res);
-       else status = gai_lookupd(nodename, servname, hints, res);
+       if (nodenull == 1) status = ds_getaddrinfo(NULL, servname, hints, res);
+       else if (servnull == 1) status = ds_getaddrinfo(nodename, NULL, hints, res);
+       else status = ds_getaddrinfo(nodename, servname, hints, res);
 
-       if ((status == 0) && (*res == NULL)) status = EAI_NODATA;
+       if ((status == 0) && (*res == NULL)) status = EAI_NONAME;
 
        return status;
 }
@@ -1117,9 +1059,7 @@ int32_t
 getaddrinfo_async_start(mach_port_t *p, const char *nodename, const char *servname, const struct addrinfo *hints, getaddrinfo_async_callback callback, void *context)
 {
        int32_t status;
-       uint32_t i, qlen;
-       char qbuf[LU_QBUF_SIZE];
-       mach_port_t server_port;
+       kvbuf_t *request;
 
        *p = MACH_PORT_NULL;
 
@@ -1128,17 +1068,9 @@ getaddrinfo_async_start(mach_port_t *p, const char *nodename, const char *servna
        status = gai_checkhints(hints);
        if (status != 0) return EAI_BADHINTS;
 
-       server_port = MACH_PORT_NULL;
-       if (_lu_running()) server_port = _lookupd_port(0);
-       if (server_port == MACH_PORT_NULL)
-       {
-               errno = ECONNREFUSED;
-               return EAI_SYSTEM;
-       }
-
        if (gai_proc < 0)
        {
-               status = _lookup_link(server_port, "getaddrinfo", &gai_proc);
+               status = LI_DSLookupGetProcedureNumber("getaddrinfo", &gai_proc);
                if (status != KERN_SUCCESS)
                {
                        errno = ECONNREFUSED;
@@ -1146,16 +1078,14 @@ getaddrinfo_async_start(mach_port_t *p, const char *nodename, const char *servna
                }
        }
 
-       qlen = LU_QBUF_SIZE;
+       request = gai_make_query(nodename, servname, hints);
+       if (request == NULL) return EAI_SYSTEM;
 
-       /* gai_make_query sets errno if it fails */
-       i = gai_make_query(nodename, servname, hints, qbuf, &qlen);
-       if (i != 0) return EAI_SYSTEM;
+       status = LI_async_start(p, gai_proc, request, (void *)callback, context);
 
-       qlen /= BYTES_PER_XDR_UNIT;
+       kvbuf_free(request);
 
-       status = lu_async_start(p, gai_proc, qbuf, qlen, (void *)callback, context);
-       if (status != 0)
+       if (status != KERN_SUCCESS)
        {
                errno = ECONNREFUSED;
                return EAI_SYSTEM;
@@ -1164,76 +1094,54 @@ getaddrinfo_async_start(mach_port_t *p, const char *nodename, const char *servna
        return 0;
 }
 
+void
+getaddrinfo_async_cancel(mach_port_t p)
+{
+       LI_async_call_cancel(p, NULL);
+}
+
 int32_t
 getaddrinfo_async_send(mach_port_t *p, const char *nodename, const char *servname, const struct addrinfo *hints)
 {
        return getaddrinfo_async_start(p, nodename, servname, hints, NULL, NULL);
 }
 
-static int
-gai_extract_data(char *buf, uint32_t len, struct addrinfo **res)
+int32_t
+getaddrinfo_async_receive(mach_port_t p, struct addrinfo **res)
 {
-       XDR xdr;
-       uint32_t i, n;
+       kern_return_t status;
        char *cname;
+       kvarray_t *reply;
+       uint32_t i;
        struct addrinfo *a;
 
+       if (res == NULL) return 0;
        *res = NULL;
 
-       if (buf == NULL) return EAI_NODATA;
-       if (len == 0) return EAI_NODATA;
+       reply = NULL;
 
-       xdrmem_create(&xdr, buf, len, XDR_DECODE);
-
-       if (!xdr_int(&xdr, (int32_t *)&n))
-       {
-               xdr_destroy(&xdr);
-               errno = EIO;
-               return EAI_SYSTEM;
-       }
+       status = LI_async_receive(p, &reply);
+       if (status < 0) return EAI_FAIL;
+       if (reply == NULL) return EAI_NONAME;
 
        cname = NULL;
-       for (i = 0; i < n; i++)
+       for (i = 0; i < reply->count; i++)
        {
-               a = gai_lookupd_process_dictionary(&xdr);
-               if (a == NULL) break;
-
+               a = gai_extract(reply);
+               if (a == NULL) continue;
                if ((cname == NULL) && (a->ai_canonname != NULL)) cname = a->ai_canonname;
                append_addrinfo(res, a);
        }
 
-       xdr_destroy(&xdr);
+       kvarray_free(reply);
 
        if ((cname != NULL) && (res != NULL) && (res[0] != NULL) && (res[0]->ai_canonname == NULL))
        {
                res[0]->ai_canonname = strdup(cname);
        }
 
-       if (*res == NULL) return EAI_NODATA;
-       return 0;
-}
 
-int32_t
-getaddrinfo_async_receive(mach_port_t p, struct addrinfo **res)
-{
-       kern_return_t status;
-       char *buf;
-       uint32_t len;
-
-       if (res == NULL) return 0;
-       *res = NULL;
-
-       buf = NULL;
-       len = 0;
-
-       status = lu_async_receive(p, &buf, &len);
-       if (status < 0) return EAI_FAIL;
-
-       status = gai_extract_data(buf, len, res);
-       if (buf != NULL) vm_deallocate(mach_task_self(), (vm_address_t)buf, len);
-       if (status != 0) return status;
-
-       if (*res == NULL) return EAI_NODATA;
+       if (*res == NULL) return EAI_NONAME;
 
        return 0;
 }
@@ -1243,40 +1151,57 @@ getaddrinfo_async_handle_reply(void *msg)
 {
        getaddrinfo_async_callback callback;
        void *context;
-       char *buf;
-       uint32_t len;
+       char *buf, *cname;
+       uint32_t i, len;
        int status;
-       struct addrinfo *res;
+       kvarray_t *reply;
+       struct addrinfo *l, *a, **res;
 
        callback = (getaddrinfo_async_callback)NULL;
        context = NULL;
        buf = NULL;
        len = 0;
-       res = NULL;
+       reply = NULL;
+       l = NULL;
+       res = &l;
 
-       status = lu_async_handle_reply(msg, &buf, &len, (void **)&callback, &context);
+       status = LI_async_handle_reply(msg, &reply, (void **)&callback, &context);
        if (status != KERN_SUCCESS)
        {
                if (status == MIG_REPLY_MISMATCH) return 0;
-               if (callback != NULL) callback(EAI_NODATA, NULL, context);
-               return EAI_NODATA;
+               if (callback != NULL) callback(EAI_FAIL, NULL, context);
+               return EAI_FAIL;
        }
 
-       status = gai_extract_data(buf, len, &res);
-       if (buf != NULL) vm_deallocate(mach_task_self(), (vm_address_t)buf, len);
-       if (status != 0)
+       if (reply == NULL)
        {
-               if (callback != NULL) callback(status, NULL, context);
-               return status;
+               if (callback != NULL) callback(EAI_NONAME, NULL, context);
+               return EAI_NONAME;
+       }
+
+       cname = NULL;
+       for (i = 0; i < reply->count; i++)
+       {
+               a = gai_extract(reply);
+               if (a == NULL) continue;
+               if ((cname == NULL) && (a->ai_canonname != NULL)) cname = a->ai_canonname;
+               append_addrinfo(res, a);
        }
 
-       if (res == NULL)
+       kvarray_free(reply);
+
+       if ((cname != NULL) && (res[0] != NULL) && (res[0]->ai_canonname == NULL))
+       {
+               res[0]->ai_canonname = strdup(cname);
+       }
+
+       if (*res == NULL)
        {
-               callback(EAI_NODATA, NULL, context);
-               return EAI_NODATA;
+               callback(EAI_NONAME, NULL, context);
+               return EAI_NONAME;
        }
 
-       callback(0, res, context);
+       callback(0, *res, context);
        return 0;
 }
 
@@ -1285,7 +1210,7 @@ getaddrinfo_async_handle_reply(void *msg)
  */
  
 /*
- * getnameinfo support in lookupd
+ * getnameinfo support in Directory Service
  * Input dict may contain the following
  *
  * ip_address: node address
@@ -1305,10 +1230,11 @@ getaddrinfo_async_handle_reply(void *msg)
  */
 
 static int
-gni_lookupd_process_dictionary(XDR *inxdr, char **host, char **serv)
+gni_extract(kvarray_t *in, const char **host, const char **serv)
 {
-       int32_t i, j, nkeys, nvals, status;
-       char *key, **vals;
+       uint32_t d, k, kcount;
+
+       if (in == NULL) return -1;
 
        if ((host == NULL) || (serv == NULL))
        {
@@ -1316,75 +1242,63 @@ gni_lookupd_process_dictionary(XDR *inxdr, char **host, char **serv)
                return EAI_SYSTEM;
        }
 
-       if (!xdr_int(inxdr, &nkeys))
-       {
-               errno = EIO;
-               return EAI_SYSTEM;
-       }
-
        *host = NULL;
        *serv = NULL;
 
-       for (i = 0; i < nkeys; i++)
-       {
-               key = NULL;
-               vals = NULL;
-               nvals = 0;
+       d = in->curr;
+       in->curr++;
 
-               status = _lu_xdr_attribute(inxdr, &key, &vals, (uint32_t *)&nvals);
-               if (status < 0)
-               {
-                       errno = EIO;
-                       return EAI_SYSTEM;
-               }
+       if (d >= in->count) return EAI_NONAME;
 
-               if (nvals == 0)
-               {
-                       free(key);
-                       continue;
-               }
+       kcount = in->dict[d].kcount;
+       if (kcount == 0) return EAI_NONAME;
 
-               if ((*host == NULL) && (!strcmp("name", key)))
+       for (k = 0; k < kcount; k++)
+       {
+               if (!strcmp(in->dict[d].key[k], "gni_name"))
                {
-                       *host = vals[0];
-                       for (j = 1; j < nvals; j++) free(vals[j]);
-               }
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       if (*host != NULL) continue;
 
-               else if ((*serv == NULL) && (!strcmp(key, "service")))
-               {
-                       *serv = vals[0];
-                       for (j = 1; j < nvals; j++) free(vals[j]);
+                       *host = in->dict[d].val[k][0];
                }
+               else if (!strcmp(in->dict[d].key[k], "gni_service")) 
+               {
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       if (*serv != NULL) continue;
 
-               if (key != NULL) free(key);
-               free(vals);
+                       *serv = in->dict[d].val[k][0];
+               }
        }
 
+       if ((*host == NULL) && (*serv == NULL)) return EAI_NONAME;
        return 0;
 }
 
-static int
-gni_make_query(const struct sockaddr *sa, size_t salen, int wanthost, int wantserv, int flags, char *buf, uint32_t *len)
+static kvbuf_t *
+gni_make_query(const struct sockaddr *sa, size_t salen, int wanthost, int wantserv, int flags)
 {
-       XDR outxdr;
-       uint16_t port;
-       char str[_LU_MAXLUSTRLEN], *key, ifname[IF_NAMESIZE];
-       uint32_t a4, ifnum, offset, na, proto, fqdn, numerichost, numericserv, name_req, isll, issl;
+       kvbuf_t *request;
+       uint16_t port, ifnum;
+       char str[NI_MAXHOST], ifname[IF_NAMESIZE], tmp[64];
+       uint32_t a4, offset, isll;
        struct sockaddr_in6 *s6;
 
-       if (sa == NULL) return EAI_FAIL;
-       if (sa->sa_len != salen) return EAI_FAMILY;
+       if (sa == NULL)
+       {
+               errno = EINVAL;
+               return NULL;
+       }
+
+       if (sa->sa_len != salen)
+       {
+               errno = EINVAL;
+               return NULL;
+       }
 
-       proto = IPPROTO_TCP;
-       fqdn = 1;
-       numerichost = 0;
-       numericserv = 0;
-       name_req = 0;
        isll = 0;
-       issl = 0;
 
        offset = INET_NTOP_AF_INET_OFFSET;
-       key = "ip_address";
        port = 0;
 
        if (sa->sa_family == PF_INET)
@@ -1394,7 +1308,7 @@ gni_make_query(const struct sockaddr *sa, size_t salen, int wanthost, int wantse
                a4 >>= IN_CLASSA_NSHIFT;
                if (a4 == 0) flags |= NI_NUMERICHOST;
 
-               port = ((struct sockaddr_in *)sa)->sin_port;
+               port = ntohs(((struct sockaddr_in *)sa)->sin_port);
        }
        else if (sa->sa_family == PF_INET6)
        {
@@ -1402,6 +1316,7 @@ gni_make_query(const struct sockaddr *sa, size_t salen, int wanthost, int wantse
                switch (s6->sin6_addr.s6_addr[0])
                {
                        case 0x00:
+                       {
                                if (IN6_IS_ADDR_V4MAPPED(&s6->sin6_addr))
                                {
                                }
@@ -1413,27 +1328,30 @@ gni_make_query(const struct sockaddr *sa, size_t salen, int wanthost, int wantse
                                        flags |= NI_NUMERICHOST;
                                }
                                break;
+                       }
                        default:
+                       {
                                if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr))
                                {
                                        isll = 1;
                                }
-                               else if (IN6_IS_ADDR_SITELOCAL(&s6->sin6_addr))
-                               {
-                                       issl = 1;
-                               }
                                else if (IN6_IS_ADDR_MULTICAST(&s6->sin6_addr))
                                {
                                        flags |= NI_NUMERICHOST;
                                }
                                break;
+                       }
                }
 
-               if ((isll != 0) || (issl != 0))
+               if (isll != 0)
                {
-                       ifnum = s6->sin6_addr.__u6_addr.__u6_addr16[1];
+                       ifnum = ntohs(s6->sin6_addr.__u6_addr.__u6_addr16[1]);
                        if (ifnum == 0) ifnum = s6->sin6_scope_id;
-                       else if ((s6->sin6_scope_id != 0) && (ifnum != s6->sin6_scope_id)) return EAI_FAIL;
+                       else if ((s6->sin6_scope_id != 0) && (ifnum != s6->sin6_scope_id))
+                       {
+                               errno = EINVAL;
+                               return NULL;
+                       }
 
                        s6->sin6_addr.__u6_addr.__u6_addr16[1] = 0;
                        s6->sin6_scope_id = ifnum;
@@ -1441,183 +1359,105 @@ gni_make_query(const struct sockaddr *sa, size_t salen, int wanthost, int wantse
                }
 
                offset = INET_NTOP_AF_INET6_OFFSET;
-               key = "ipv6_address";
-               port = s6->sin6_port;
+               port = ntohs(s6->sin6_port);
        }
        else
        {
-               return EAI_FAMILY;
-       }
-
-       na = 0;
-
-       if (wanthost != 0) na++;
-       if (wantserv != 0) na++;
-
-       if (flags & NI_NOFQDN)
-       {
-               fqdn = 0;
-               na++;
-       }
-
-       if (flags & NI_NUMERICHOST)
-       {
-               numerichost = 1;
-               na++;
-       }
-
-       if (flags & NI_NUMERICSERV)
-       {
-               numericserv = 1;
-               na++;
-       }
-
-       if (flags & NI_NAMEREQD)
-       {
-               name_req = 1;
-               na++;
+               errno = EPFNOSUPPORT;
+               return NULL;
        }
 
-       if (flags & NI_DGRAM)
+       request = kvbuf_new();
+       if (request == NULL)
        {
-               proto = IPPROTO_UDP;
-               na++;
+               errno = ENOMEM;
+               return NULL;
        }
 
-       xdrmem_create(&outxdr, buf, *len, XDR_ENCODE);
-
-       if (!xdr_int(&outxdr, (int32_t *)&na))
-       {
-               xdr_destroy(&outxdr);
-               errno = EIO;
-               return EAI_SYSTEM;
-       }
+       kvbuf_add_dict(request);
 
        if (wanthost != 0)
        {
-               inet_ntop(sa->sa_family, (char *)(sa) + offset, str, _LU_MAXLUSTRLEN);
+               inet_ntop(sa->sa_family, (char *)(sa) + offset, str, NI_MAXHOST);
 
-               if ((flags & NI_WITHSCOPEID) && (sa->sa_family == AF_INET6))
+               if (isll != 0)
                {
                        ifnum = ((struct sockaddr_in6 *)sa)->sin6_scope_id;
-                       if (if_indextoname(ifnum, ifname) != NULL)
+                       if ((ifnum != 0) && (if_indextoname(ifnum, ifname) != NULL))
                        {
                                strcat(str, "%");
                                strcat(str, ifname);
                        }
                }
 
-               if (encode_kv(&outxdr, key, str) != 0)
-               {
-                       xdr_destroy(&outxdr);
-                       errno = EIO;
-                       return EAI_SYSTEM;
-               }
-       }
-
-       if (wantserv != 0)
-       {
-               snprintf(str, _LU_MAXLUSTRLEN, "%hu", port);
-               if (encode_kv(&outxdr, "port", str) != 0)
-               {
-                       xdr_destroy(&outxdr);
-                       errno = EIO;
-                       return EAI_SYSTEM;
-               }
-       }
+               kvbuf_add_key(request, "address");
+               kvbuf_add_val(request, str);
 
-       if (proto == IPPROTO_UDP)
-       {
-               if (encode_kv(&outxdr, "protocol", "udp") != 0)
-               {
-                       xdr_destroy(&outxdr);
-                       errno = EIO;
-                       return EAI_SYSTEM;
-               }
-       }
-
-       if (fqdn == 0)
-       {
-               if (encode_kv(&outxdr, "fqdn", "0") != 0)
-               {
-                       xdr_destroy(&outxdr);
-                       errno = EIO;
-                       return EAI_SYSTEM;
-               }
-       }
-
-       if (numerichost == 1)
-       {
-               if (encode_kv(&outxdr, "numerichost", "1") != 0)
-               {
-                       xdr_destroy(&outxdr);
-                       errno = EIO;
-                       return EAI_SYSTEM;
-               }
-       }
-
-       if (numericserv == 1)
-       {
-               if (encode_kv(&outxdr, "numericserv", "1") != 0)
-               {
-                       xdr_destroy(&outxdr);
-                       errno = EIO;
-                       return EAI_SYSTEM;
-               }
+               kvbuf_add_key(request, "family");
+               snprintf(tmp, sizeof(tmp), "%u", sa->sa_family);
+               kvbuf_add_val(request, tmp);
        }
 
-       if (name_req == 1)
+       if (wantserv != 0)
        {
-               if (encode_kv(&outxdr, "name_required", "1") != 0)
-               {
-                       xdr_destroy(&outxdr);
-                       errno = EIO;
-                       return EAI_SYSTEM;
-               }
+               snprintf(tmp, sizeof(tmp), "%hu", port);
+               kvbuf_add_key(request, "port");
+               kvbuf_add_val(request, tmp);
        }
 
-       *len = xdr_getpos(&outxdr);
-
-       xdr_destroy(&outxdr);
+       snprintf(tmp, sizeof(tmp), "%u", flags);
+       kvbuf_add_key(request, "flags");
+       kvbuf_add_val(request, tmp);
 
-       return 0;
+       return request;
 }
 
 int
 getnameinfo(const struct sockaddr * __restrict sa, socklen_t salen, char * __restrict host, socklen_t hostlen, char * __restrict serv, socklen_t servlen, int flags)
 {
-       uint32_t n, i, qlen, rlen;
-       uint32_t ifnum;
-       int wanth, wants, isll, issl;
-       XDR inxdr;
-       char qbuf[LU_QBUF_SIZE], ifname[IF_NAMESIZE];
-       char *rbuf, *hval, *sval;
-       mach_port_t server_port;
+       uint32_t n, i, ifnum;
+       int wanth, wants, isll;
+       kvbuf_t *request;
+       kvarray_t *reply;
+       char ifname[IF_NAMESIZE];
+       const char *hval, *sval;
        kern_return_t status;
-       struct sockaddr_in *s4;
-       struct sockaddr_in6 *s6;
+       struct sockaddr_in *s4, s4buf;
+       struct sockaddr_in6 *s6, s6buf;
+       struct in_addr *a4;
+       struct in6_addr *a6;
 
        /* Check input */
        if (sa == NULL) return EAI_FAIL;
 
        isll = 0;
-       issl = 0;
        ifnum = 0;
 
-       if (sa->sa_family == AF_INET6)
+       s4 = &s4buf;
+       a4 = NULL;
+
+       s6 = &s6buf;
+       a6 = NULL;
+
+       if (sa->sa_family == AF_INET)
        {
-               s6 = (struct sockaddr_in6 *)sa;
+               memcpy(s4, sa, sizeof(struct sockaddr_in));
+               a4 = &(s4->sin_addr);
+       }
+       else if (sa->sa_family == AF_INET6)
+       {
+               memcpy(s6, sa, sizeof(struct sockaddr_in6));
+               a6 = &(s6->sin6_addr);
 
                if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr)) isll = 1;
-               if (IN6_IS_ADDR_SITELOCAL(&s6->sin6_addr)) issl = 1;
 
                /*
-                * Link-local and site-local IPv6 addresses may have a scope id 
+                * Link-local IPv6 addresses may have a scope id 
                 * in s6->sin6_addr.__u6_addr.__u6_addr16[1] as well as in s6->sin6_scope_id.
                 * If they are both non-zero, they must be equal.
                 * We zero s6->sin6_addr.__u6_addr.__u6_addr16[1] and set s6->sin6_scope_id.
                 */
-               if ((isll != 0) || (issl != 0))
+               if (isll != 0)
                {
                        ifnum = ntohs(s6->sin6_addr.__u6_addr.__u6_addr16[1]);
                        if (ifnum == 0) ifnum = s6->sin6_scope_id;
@@ -1630,17 +1470,17 @@ getnameinfo(const struct sockaddr * __restrict sa, socklen_t salen, char * __res
                /* V4 mapped and compat addresses are converted to plain V4 */
                if ((IN6_IS_ADDR_V4MAPPED(&s6->sin6_addr)) || (IN6_IS_ADDR_V4COMPAT(&s6->sin6_addr)))
                {
-                       s4 = (struct sockaddr_in *)calloc(1, sizeof(struct sockaddr_in));
+                       memset(s4, 0, sizeof(struct sockaddr_in));
+
                        s4->sin_len = sizeof(struct sockaddr_in);
                        s4->sin_family = AF_INET;
                        s4->sin_port = s6->sin6_port;
                        memcpy(&(s4->sin_addr.s_addr), &(s6->sin6_addr.s6_addr[12]), 4);
 
-                       i = getnameinfo((const struct sockaddr *)s4, s4->sin_len, host, hostlen, serv, servlen, flags);
-                       free(s4);
-                       return i;
+                       return getnameinfo((const struct sockaddr *)s4, s4->sin_len, host, hostlen, serv, servlen, flags);
                }
        }
+       else return EAI_FAMILY;
 
        wanth = 0;
        if ((host != NULL) && (hostlen != 0)) wanth = 1;
@@ -1655,11 +1495,16 @@ getnameinfo(const struct sockaddr * __restrict sa, socklen_t salen, char * __res
         */
        if ((wanth == 1) && (flags & NI_NUMERICHOST))
        {
-               i = INET_NTOP_AF_INET_OFFSET;
-               if (sa->sa_family == PF_INET6) i = INET_NTOP_AF_INET6_OFFSET;
-               if (inet_ntop(sa->sa_family, (char *)(sa) + i, host, hostlen) == NULL) return EAI_FAIL;
+               if (sa->sa_family == AF_INET)
+               {
+                       if (inet_ntop(AF_INET, a4, host, hostlen) == NULL) return EAI_FAIL;
+               }
+               else
+               {
+                       if (inet_ntop(AF_INET6, a6, host, hostlen) == NULL) return EAI_FAIL;
+               }
 
-               if (((isll != 0) || (issl != 0)) && (ifnum != 0))
+               if ((isll != 0) && (ifnum != 0))
                {
                        /* append interface name */
                        if (if_indextoname(ifnum, ifname) != NULL)
@@ -1676,29 +1521,21 @@ getnameinfo(const struct sockaddr * __restrict sa, socklen_t salen, char * __res
        {
                if (sa->sa_family == PF_INET)
                {
-                       s4 = (struct sockaddr_in *)sa;
                        n = snprintf(serv, servlen, "%hu", ntohs(s4->sin_port));
                        if (n >= servlen) return EAI_FAIL;
                }
-               else if (sa->sa_family == PF_INET6)
+               else
                {
-                       s6 = (struct sockaddr_in6 *)sa;
                        n = snprintf(serv, servlen, "%hu", ntohs(s6->sin6_port));
                        if (n >= servlen) return EAI_FAIL;
                }
-               else return EAI_FAMILY;
 
                if (wanth == 0) return 0;
        }
 
        if ((wanth == 1) && (flags & NI_NUMERICHOST) && (wants == 1) && (flags & NI_NUMERICSERV)) return 0;
 
-       /*
-        * Ask lookupd
-        */
-       server_port = MACH_PORT_NULL;
-       if (_lu_running()) server_port = _lookupd_port(0);
-       if (server_port == MACH_PORT_NULL)
+       if (_ds_running() == 0)
        {
                errno = ECONNREFUSED;
                return EAI_SYSTEM;
@@ -1706,7 +1543,7 @@ getnameinfo(const struct sockaddr * __restrict sa, socklen_t salen, char * __res
 
        if (gni_proc < 0)
        {
-               status = _lookup_link(server_port, "getnameinfo", &gni_proc);
+               status = LI_DSLookupGetProcedureNumber("getnameinfo", &gni_proc);
                if (status != KERN_SUCCESS)
                {
                        errno = ECONNREFUSED;
@@ -1714,87 +1551,76 @@ getnameinfo(const struct sockaddr * __restrict sa, socklen_t salen, char * __res
                }
        }
 
-       qlen = LU_QBUF_SIZE;
-       i = gni_make_query(sa, salen, wanth, wants, flags, qbuf, &qlen);
-       if (i != 0) return i;
-
-       qlen /= BYTES_PER_XDR_UNIT;
-
-       rbuf = NULL;
-
-       status = _lookup_all(server_port, gni_proc, (unit *)qbuf, qlen, &rbuf, &rlen);
-       if (status != KERN_SUCCESS) return EAI_NONAME;
-
-       rlen *= BYTES_PER_XDR_UNIT;
+       request = gni_make_query(sa, salen, wanth, wants, flags);
+       if (request == NULL) return EAI_SYSTEM;
 
-       xdrmem_create(&inxdr, rbuf, rlen, XDR_DECODE);
+       reply = NULL;
+       status = LI_DSLookupQuery(gni_proc, request, &reply);
+       kvbuf_free(request);
 
-       if (!xdr_int(&inxdr, (int32_t *)&n))
+       if (status != KERN_SUCCESS)
        {
-               xdr_destroy(&inxdr);
-               errno = EIO;
+               errno = ECONNREFUSED;
                return EAI_SYSTEM;
        }
 
-       if (n != 1)
-       {
-               xdr_destroy(&inxdr);
-               return EAI_NONAME;
-       }
+       if (reply == NULL) return EAI_NONAME;
 
        hval = NULL;
        sval = NULL;
 
-       i = gni_lookupd_process_dictionary(&inxdr, &hval, &sval);
-
-       xdr_destroy(&inxdr);
-       if (rbuf != NULL) vm_deallocate(mach_task_self(), (vm_address_t)rbuf, rlen);
+       status = gni_extract(reply, &hval, &sval);
 
-       if (i != 0) return i;
+       if (status != 0)
+       {
+               kvarray_free(reply);
+               return status;
+       }
 
        i = 0;
        if (hval != NULL) i = strlen(hval) + 1;
        if ((host != NULL) && (hostlen != 0) && (i != 0))
        {
-               if (i > hostlen) return EAI_FAIL;
+               if (i > hostlen)
+               {
+                       kvarray_free(reply);
+                       return EAI_FAIL;
+               }
+
                memcpy(host, hval, i);
-               free(hval);
        }
 
        i = 0;
        if (sval != NULL) i = strlen(sval) + 1;
        if ((serv != NULL) && (servlen != 0) && (i != 0))
        {
-               if (i > servlen) return EAI_FAIL;
+               if (i > servlen)
+               {
+                       kvarray_free(reply);
+                       return EAI_FAIL;
+               }
+
                memcpy(serv, sval, i);
-               free(sval);
        }
 
+       kvarray_free(reply);
        return 0;
 }
 
 int32_t
 getnameinfo_async_start(mach_port_t *p, const struct sockaddr *sa, size_t salen, int flags, getnameinfo_async_callback callback, void *context)
 {
-       uint32_t i, qlen;
-       char qbuf[LU_QBUF_SIZE];
-       mach_port_t server_port;
-       kern_return_t status;
+       int32_t status;
+       kvbuf_t *request;
+
+       *p = MACH_PORT_NULL;
 
        /* Check input */
        if (sa == NULL) return EAI_FAIL;
 
-       server_port = MACH_PORT_NULL;
-       if (_lu_running()) server_port = _lookupd_port(0);
-       if (server_port == MACH_PORT_NULL)
-       {
-               errno = ECONNREFUSED;
-               return EAI_SYSTEM;
-       }
-
        if (gni_proc < 0)
        {
-               status = _lookup_link(server_port, "getnameinfo", &gni_proc);
+               status = LI_DSLookupGetProcedureNumber("getnameinfo", &gni_proc);
                if (status != KERN_SUCCESS)
                {
                        errno = ECONNREFUSED;
@@ -1802,14 +1628,14 @@ getnameinfo_async_start(mach_port_t *p, const struct sockaddr *sa, size_t salen,
                }
        }
 
-       qlen = LU_QBUF_SIZE;
-       i = gni_make_query(sa, salen, 1, 1, flags, qbuf, &qlen);
-       if (i != 0) return i;
+       request = gni_make_query(sa, salen, 1, 1, flags);
+       if (request == NULL) return EAI_SYSTEM;
 
-       qlen /= BYTES_PER_XDR_UNIT;
+       status = LI_async_start(p, gni_proc, request, (void *)callback, context);
 
-       status = lu_async_start(p, gni_proc, qbuf, qlen, (void *)callback, context);
-       if (status != 0)
+       kvbuf_free(request);
+
+       if (status != KERN_SUCCESS)
        {
                errno = ECONNREFUSED;
                return EAI_SYSTEM;
@@ -1818,62 +1644,45 @@ getnameinfo_async_start(mach_port_t *p, const struct sockaddr *sa, size_t salen,
        return 0;
 }
 
-int32_t
-getnameinfo_async_send(mach_port_t *p, const struct sockaddr *sa, size_t salen, int flags)
+void
+getnameinfo_async_cancel(mach_port_t p)
 {
-       return getnameinfo_async_start(p, sa, salen, flags, NULL, NULL);
+       LI_async_call_cancel(p, NULL);
 }
 
-static int
-gni_extract_data(char *buf, uint32_t len, char **host, char **serv)
+int32_t
+getnameinfo_async_send(mach_port_t *p, const struct sockaddr *sa, size_t salen, int flags)
 {
-       XDR xdr;
-       uint32_t n;
-       int i;
-
-       *host = NULL;
-       *serv = NULL;
-
-       if (buf == NULL) return EAI_NODATA;
-       if (len == 0) return EAI_NODATA;
-
-       xdrmem_create(&xdr, buf, len, XDR_DECODE);
-
-       if (!xdr_int(&xdr, (int32_t *)&n))
-       {
-               xdr_destroy(&xdr);
-               errno = EIO;
-               return EAI_SYSTEM;
-       }
-
-       if (n != 1)
-       {
-               xdr_destroy(&xdr);
-               return EAI_NONAME;
-       }
-
-       i = gni_lookupd_process_dictionary(&xdr, host, serv);
-       xdr_destroy(&xdr);
-       return i;
+       return getnameinfo_async_start(p, sa, salen, flags, NULL, NULL);
 }
 
 int32_t
 getnameinfo_async_receive(mach_port_t p, char **host, char **serv)
 {
        kern_return_t status;
-       char *buf;
-       uint32_t len;
+       const char *hval, *sval;
+       kvarray_t *reply;
 
-       buf = NULL;
-       len = 0;
+       reply = NULL;
 
-       status = lu_async_receive(p, &buf, &len);
+       status = LI_async_receive(p, &reply);
        if (status < 0) return EAI_FAIL;
+       if (reply == NULL) return EAI_NONAME;
 
-       status = gni_extract_data(buf, len, host, serv);
-       if (buf != NULL) vm_deallocate(mach_task_self(), (vm_address_t)buf, len);
-       if (status != 0) return status;
+       hval = NULL;
+       sval = NULL;
+
+       status = gni_extract(reply, &hval, &sval);
+       if (status != 0)
+       {
+               kvarray_free(reply);
+               return status;
+       }
 
+       if (hval != NULL) *host = strdup(hval);
+       if (sval != NULL) *serv = strdup(sval);
+
+       kvarray_free(reply);
        return 0;
 }
 
@@ -1882,17 +1691,19 @@ getnameinfo_async_handle_reply(void *msg)
 {
        getnameinfo_async_callback callback;
        void *context;
-       char *buf, *hval, *sval;
+       const char *hval, *sval;
+       char *host, *serv;
        uint32_t len;
        int status;
+       kvarray_t *reply;
 
        callback = (getnameinfo_async_callback)NULL;
        context = NULL;
-       buf = NULL;
+       reply = NULL;
        len = 0;
 
-       status = lu_async_handle_reply(msg, &buf, &len, (void **)&callback, &context);
-       if (status != KERN_SUCCESS)
+       status = LI_async_handle_reply(msg, &reply, (void **)&callback, &context);
+       if ((status != KERN_SUCCESS) || (reply == NULL))
        {
                if (status == MIG_REPLY_MISMATCH) return 0;
                if (callback != NULL) callback(EAI_NONAME, NULL, NULL, context);
@@ -1902,14 +1713,21 @@ getnameinfo_async_handle_reply(void *msg)
        hval = NULL;
        sval = NULL;
 
-       status = gni_extract_data(buf, len, &hval, &sval);
-       if (buf != NULL) vm_deallocate(mach_task_self(), (vm_address_t)buf, len);
+       status = gni_extract(reply, &hval, &sval);
        if (status != 0)
        {
                if (callback != NULL) callback(status, NULL, NULL, context);
+               kvarray_free(reply);
                return status;
        }
 
-       callback(0, hval, sval, context);
+       host = NULL;
+       serv = NULL;
+
+       if (hval != NULL) host = strdup(hval);
+       if (sval != NULL) serv = strdup(sval);
+       kvarray_free(reply);
+
+       callback(0, host, serv, context);
        return 0;
 }
diff --git a/lookup.subproj/getfsent.3 b/lookup.subproj/getfsent.3
new file mode 100644 (file)
index 0000000..a898b04
--- /dev/null
@@ -0,0 +1,153 @@
+.\" Copyright (c) 1983, 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.
+.\"
+.\"     @(#)getfsent.3 8.1 (Berkeley) 6/4/93
+.\" $FreeBSD: src/lib/libc/gen/getfsent.3,v 1.9 2001/10/01 16:08:51 ru Exp $
+.\"
+.Dd June 4, 1993
+.Dt GETFSENT 3
+.Os
+.Sh NAME
+.Nm getfsent ,
+.Nm getfsspec ,
+.Nm getfsfile ,
+.Nm setfsent ,
+.Nm endfsent
+.Nd get file system descriptor file entry
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In fstab.h
+.Ft struct fstab *
+.Fn getfsent void
+.Ft struct fstab *
+.Fn getfsspec "const char *spec"
+.Ft struct fstab *
+.Fn getfsfile "const char *file"
+.Ft int
+.Fn setfsent void
+.Ft void
+.Fn endfsent void
+.Sh DESCRIPTION
+The
+.Fn getfsent ,
+.Fn getfsspec ,
+and
+.Fn getfsfile
+functions
+each return a pointer to an object with the following structure
+containing the broken-out fields of a line in the file system
+description file,
+.Aq Pa fstab.h .
+.Bd -literal -offset indent
+struct fstab {
+       char    *fs_spec;       /* block special device name */
+       char    *fs_file;       /* file system path prefix */
+       char    *fs_vfstype;    /* File system type, ufs, nfs */
+       char    *fs_mntops;     /* Mount options ala -o */
+       char    *fs_type;       /* FSTAB_* from fs_mntops */
+       int     fs_freq;        /* dump frequency, in days */
+       int     fs_passno;      /* pass number on parallel fsck */
+};
+.Ed
+.Pp
+The fields have meanings described in
+.Xr fstab 5 .
+.Pp
+The
+.Fn setfsent
+function
+opens the file (closing any previously opened file) or rewinds it
+if it is already open.
+.Pp
+The
+.Fn endfsent
+function
+closes the file.
+.Pp
+The
+.Fn getfsspec
+and
+.Fn getfsfile
+functions
+search the entire file (opening it if necessary) for a matching special
+file name or file system file name.
+.Pp
+For programs wishing to read the entire database,
+.Fn getfsent
+reads the next entry (opening the file if necessary).
+.Pp
+All entries in the file with a type field equivalent to
+.Dv FSTAB_XX
+are ignored.
+.Sh RETURN VALUES
+The
+.Fn getfsent ,
+.Fn getfsspec ,
+and
+.Fn getfsfile
+functions
+return a
+.Dv NULL
+pointer on
+.Dv EOF
+or error.
+The
+.Fn setfsent
+function
+returns 0 on failure, 1 on success.
+The
+.Fn endfsent
+function
+returns nothing.
+.Sh FILES
+.Bl -tag -width /etc/fstab -compact
+.It Pa /etc/fstab
+.El
+.Sh SEE ALSO
+.Xr fstab 5
+.Sh HISTORY
+The
+.Fn getfsent
+function appeared in
+.Bx 4.0 ;
+the
+.Fn endfsent ,
+.Fn getfsfile ,
+.Fn getfsspec ,
+and
+.Fn setfsent
+functions appeared in
+.Bx 4.3 .
+.Sh BUGS
+These functions use static data storage;
+if the data is needed for future use, it should be
+copied before any subsequent calls overwrite it.
diff --git a/lookup.subproj/getgrent.3 b/lookup.subproj/getgrent.3
new file mode 100644 (file)
index 0000000..c4c212c
--- /dev/null
@@ -0,0 +1,260 @@
+.\" Copyright (c) 1989, 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.
+.\"
+.\"     From: @(#)getgrent.3   8.2 (Berkeley) 4/19/94
+.\" $FreeBSD: src/lib/libc/gen/getgrent.3,v 1.16 2001/10/01 16:08:51 ru Exp $
+.\"
+.Dd September 29, 1994
+.Dt GETGRENT 3
+.Os
+.Sh NAME
+.Nm endgrent ,
+.Nm getgrent ,
+.Nm getgrgid ,
+.Nm getgrgid_r ,
+.Nm getgrnam ,
+.Nm getgrnam_r ,
+.Nm setgrent ,
+.\" .Nm setgrfile ,
+.Nm setgroupent
+.Nd group database operations
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In grp.h
+.Ft void
+.Fo endgrent
+.Fa void
+.Fc
+.Ft struct group *
+.Fo getgrent
+.Fa void
+.Fc
+.Ft struct group *
+.Fo getgrgid
+.Fa "gid_t gid"
+.Fc
+.Ft int
+.Fo getgrgid_r
+.Fa "gid_t gid"
+.Fa "struct group *grp"
+.Fa "char *buffer"
+.Fa "size_t bufsize"
+.Fa "struct group **result"
+.Fc
+.Ft struct group *
+.Fo getgrnam
+.Fa "const char *name"
+.Fc
+.Ft int
+.Fo getgrnam_r
+.Fa "const char *name"
+.Fa "struct group *grp"
+.Fa "char *buffer"
+.Fa "size_t bufsize"
+.Fa "struct group **result"
+.Fc
+.Ft void
+.Fo setgrent
+.Fa void
+.Fc
+.\" .Ft void
+.\" .Fn setgrfile "const char *name"
+.Ft int
+.Fo setgroupent
+.Fa "int stayopen"
+.Fc
+.Sh DESCRIPTION
+These functions operate on the group database file
+.Pa /etc/group ,
+which is described
+in
+.Xr group 5 .
+Each line of the database is defined by the structure
+.Ar group ,
+found in the include
+file
+.Aq Pa grp.h :
+.Bd -literal -offset indent
+struct group {
+       char    *gr_name;       /* group name */
+       char    *gr_passwd;     /* group password */
+       int     gr_gid;         /* group id */
+       char    **gr_mem;       /* group members */
+};
+.Ed
+.Pp
+The functions
+.Fn getgrnam
+and
+.Fn getgrgid
+search the group database for the given group name (pointed to by
+.Ar name )
+or the group id (pointed to by
+.Ar gid ) ,
+respectively, returning the first one encountered.  Identical group
+names or group ids may result in undefined behavior.
+.Pp
+All of these routines are thread-safe.
+The
+.Fn getgrent ,
+.Fn getgrgid ,
+and
+.Fn getgrnam
+routines return a pointer to a result managed by the system library in a
+thread-specific data structure.
+Every thread has space for a pointer to a struct group and allocates its own storage for the result.
+Neither previously returned values in memory nor a previously returned pointer value should be used
+by a thread after calling any one of these three routines.
+Memory allocated by a thread is automatically released on subsequent calls by the same thread to any of these
+three routines, and when the thread exits.
+.Pp
+The functions
+.Fn getgrgid_r
+and
+.Fn getgrnam_r
+take additional arguments which supply storage space for the returned result.
+The
+.Fa grp
+parameter is a pointer to a struct group, which must be allocated by the caller.
+The 
+.Fa buffer
+parameter is a pointer to a block of memory with a size specified by
+.Pa bufsize .
+This buffer is used to hold the values which are pointed to by values filled in
+the
+.Fa grp
+structure.
+Zero is returned on success.
+If insufficient memory is supplied, these routines return ERANGE.
+.Pp
+The
+.Fn getgrent
+function
+sequentially reads the group database and is intended for programs
+that wish to step through the complete list of groups.
+.Pp
+All three routines will open the group file for reading, if necessary.
+.Pp
+The
+.Fn setgroupent
+function
+opens the file, or rewinds it if it is already open.  If
+.Fa stayopen
+is non-zero, file descriptors are left open, significantly speeding
+functions' subsequent calls.  This functionality is unnecessary for
+.Fn getgrent ,
+as it doesn't close its file descriptors by default.  It should also
+be noted that it is dangerous for long-running programs to use this
+functionality, as the group file may be updated.
+.Pp
+The
+.Fn setgrent
+function
+is identical to
+.Fn setgroupent
+with an argument of zero.
+.Pp
+The
+.Fn endgrent
+function
+closes any open files.
+.Sh RETURN VALUES
+The functions
+.Fn getgrent ,
+.Fn getgrgid ,
+and
+.Fn getgrnam 
+each return a pointer to the group entry if successful; if end-of-file
+is reached or an error occurs, a null pointer is returned.
+The function
+.Fn setgroupent
+returns the value 1 if successful;
+otherwise, the value 0 is returned.
+The functions
+.Fn endgrent ,
+.Fn setgrent ,
+and
+.Fn setgrfile
+have no return value.
+.Sh FILES
+.Bl -tag -width /etc/group -compact
+.It Pa /etc/group
+group database file
+.El
+.Sh LEGACY SYNOPSIS
+.Fd #include <grp.h>
+.Pp
+.Ft int
+.br
+.Fo setgrent
+.Fa void
+.Fc ;
+.Pp
+The function
+.Fn setgrent
+returns the value 1 if successful;
+otherwise, the value 0 is returned.
+.Sh SEE ALSO
+.Xr getpwent 3 ,
+.Xr yp 8 ,
+.Xr group 5
+.Sh HISTORY
+The functions
+.Fn endgrent ,
+.Fn getgrent ,
+.Fn getgrnam ,
+.Fn getgrgid ,
+and
+.Fn setgrent
+appeared in
+.At v7 .
+The functions
+.Fn setgrfile
+and
+.Fn setgroupent
+appeared in
+.Bx 4.3 Reno .
+.Sh COMPATIBILITY
+The historic function
+.Fn setgrfile ,
+which allowed the specification of alternate password databases, has
+been deprecated and is no longer available.
+.Sh BUGS
+The functions
+.Fn getgrent ,
+.Fn getgrnam ,
+and
+.Fn getgrgid ,
+leave their results in internal thread-specific memory and return
+a pointer to that object.
+Subsequent calls to any of these three routines by the same thread will
+release the object and return a new pointer value.
diff --git a/lookup.subproj/getgrouplist.3 b/lookup.subproj/getgrouplist.3
new file mode 100644 (file)
index 0000000..28364eb
--- /dev/null
@@ -0,0 +1,96 @@
+.\" 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.
+.\"
+.\"     @(#)getgrouplist.3     8.1 (Berkeley) 6/9/93
+.\" $FreeBSD: src/lib/libc/gen/getgrouplist.3,v 1.7 2001/10/01 16:08:51 ru Exp $
+.\"
+.Dd June 9, 1993
+.Dt GETGROUPLIST 3
+.Os
+.Sh NAME
+.Nm getgrouplist
+.Nd calculate group access list
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In unistd.h
+.Ft int
+.Fn getgrouplist "const char *name" "int basegid" "int *groups" "int *ngroups"
+.Sh DESCRIPTION
+The
+.Fn getgrouplist
+function reads through the group file and calculates
+the group access list for the user specified in
+.Fa name .
+The
+.Fa basegid
+is automatically included in the groups list.
+Typically this value is given as
+the group number from the password file.
+.Pp
+The resulting group list is returned in the integer array pointed to by
+.Fa groups .
+The caller specifies the size of the
+.Fa groups
+array in the integer pointed to by
+.Fa ngroups ;
+the actual number of groups found is returned in
+.Fa ngroups .
+.Sh RETURN VALUES
+The
+.Fn getgrouplist
+function
+returns \-1 if the size of the group list is too small to
+hold all the user's groups.
+Here, the group array will be filled with as many groups as will fit.
+.Sh FILES
+.Bl -tag -width /etc/group -compact
+.It Pa /etc/group
+group membership list
+.El
+.Sh SEE ALSO
+.Xr setgroups 2 ,
+.Xr initgroups 3
+.Sh HISTORY
+The
+.Fn getgrouplist
+function first appeared in
+.Bx 4.4 .
+.Sh BUGS
+The
+.Fn getgrouplist
+function
+uses the routines based on
+.Xr getgrent 3 .
+If the invoking program uses any of these routines,
+the group structure will
+be overwritten in the call to
+.Fn getgrouplist .
index 9220959b2d01252ef95e8d45d0f5f2e77973112c..8b0e9397cb63af96db154e05bac5f1ee9893f1d8 100644 (file)
 .Nm getnameinfo
 .Nd socket address structure to hostname and service name
 .Sh SYNOPSIS
-.In sys/types.h
 .In sys/socket.h
 .In netdb.h
 .Ft int
-.Fn getnameinfo "const struct sockaddr *sa" "socklen_t salen" "char *host" \
-    "size_t hostlen" "char *serv" "size_t servlen" "int flags"
+.Fo getnameinfo
+.Fa "const struct sockaddr *restrict sa"
+.Fa "socklen_t salen"
+.Fa "char *restrict node"
+.Fa "socklen_t nodelen"
+.Fa "char *restrict service"
+.Fa "socklen_t servicelen"
+.Fa "int flags"
+.Fc
 .Sh DESCRIPTION
 The
 .Fn getnameinfo
@@ -59,19 +65,19 @@ bytes long.
 The host and service names associated with
 .Fa sa
 are stored in
-.Fa host
+.Fa node
 and
-.Fa serv
+.Fa service
 which have length parameters
-.Fa hostlen
+.Fa nodelen
 and
-.Fa servlen .
+.Fa servicelen .
 The maximum value for
-.Fa hostlen
+.Fa nodelen
 is
 .Dv NI_MAXHOST
 and the maximum value for
-.Fa servlen
+.Fa servicelen
 is
 .Dv NI_MAXSERV ,
 as defined by
@@ -156,6 +162,31 @@ if (getnameinfo(sa, sa-\*[Gt]sa_len, hbuf, sizeof(hbuf), NULL, 0,
 }
 printf("host=%s\en", hbuf);
 .Ed
+.Sh LEGACY SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <sys/socket.h>
+.Fd #include <netdb.h>
+.Pp
+The include file
+.In sys/types.h
+is necessary.
+.Pp
+.Ft int
+.Fo getnameinfo
+.Fa "const struct sockaddr *restrict sa"
+.Fa "socklen_t salen"
+.Fa "char *restrict node"
+.Fa "size_t nodelen"
+.Fa "char *service"
+.Fa "size_t servicelen"
+.Fa "int flags"
+.Fc ;
+.Pp
+The type of
+.Fa nodelen
+and
+.Fa servicelen
+has changed.
 .Sh SEE ALSO
 .Xr gai_strerror 3 ,
 .Xr getaddrinfo 3 ,
@@ -256,10 +287,6 @@ if (error == 0) {
            NULL, 0, NI_NUMERICHOST);
 }
 .Ed
-.Sh BUGS
-The implementation of
-.Fn getnameinfo
-is not thread-safe.
 .\".Pp
 .\".Ox
 .\"intentionally uses a different
diff --git a/lookup.subproj/getnetgrent.3 b/lookup.subproj/getnetgrent.3
new file mode 100644 (file)
index 0000000..7124aef
--- /dev/null
@@ -0,0 +1,133 @@
+.\" Copyright (c) 1992, 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.
+.\"
+.\"     @(#)getnetgrent.3      8.1 (Berkeley) 6/4/93
+.\" $FreeBSD: src/lib/libc/gen/getnetgrent.3,v 1.10 2001/10/01 16:08:51 ru Exp $
+.\"
+.Dd June 4, 1993
+.Dt GETNETGRENT 3
+.Os
+.Sh NAME
+.Nm getnetgrent ,
+.Nm innetgr ,
+.Nm setnetgrent ,
+.Nm endnetgrent
+.Nd netgroup database operations
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In netdb.h
+.Ft int
+.Fn getnetgrent "char **host" "char **user" "char **domain"
+.Ft int
+.Fn innetgr "const char *netgroup" "const char *host" "const char *user" "const char *domain"
+.Ft void
+.Fn setnetgrent "const char *netgroup"
+.Ft void
+.Fn endnetgrent void
+.Sh DESCRIPTION
+These functions operate on the netgroup database file
+.Pa /etc/netgroup
+which is described
+in
+.Xr netgroup 5 .
+The database defines a set of netgroups, each made up of one or more triples:
+.Bd -literal -offset indent
+(host, user, domain)
+.Ed
+that defines a combination of host, user and domain.
+Any of the three fields may be specified as ``wildcards'' that match any
+string.
+.Pp
+The function
+.Fn getnetgrent
+sets the three pointer arguments to the strings of the next member of the
+current netgroup.
+If any of the string pointers are
+.Sy (char *)0
+that field is considered a wildcard.
+.Pp
+The functions
+.Fn setnetgrent
+and
+.Fn endnetgrent
+set the current netgroup and terminate the current netgroup respectively.
+If
+.Fn setnetgrent
+is called with a different netgroup than the previous call, an implicit
+.Fn endnetgrent
+is implied.
+.Fn Setnetgrent
+also sets the offset to the first member of the netgroup.
+.Pp
+The function
+.Fn innetgr
+searches for a match of all fields within the specified group.
+If any of the
+.Sy host ,
+.Sy user ,
+or
+.Sy domain
+arguments are
+.Sy (char *)0
+those fields will match any string value in the netgroup member.
+.Sh RETURN VALUES
+The function
+.Fn getnetgrent
+returns 0 for ``no more netgroup members'' and 1 otherwise.
+The function
+.Fn innetgr
+returns 1 for a successful match and 0 otherwise.
+The functions
+.Fn setnetgrent
+and
+.Fn endnetgrent
+have no return value.
+.Sh FILES
+.Bl -tag -width /etc/netgroup -compact
+.It Pa /etc/netgroup
+netgroup database file
+.El
+.Sh SEE ALSO
+.Xr netgroup 5
+.Sh COMPATIBILITY
+The netgroup members have three string fields to maintain compatibility
+with other vendor implementations, however it is not obvious what use the
+.Sy domain
+string has within
+.Bx .
+.Sh BUGS
+The function
+.Fn getnetgrent
+returns pointers to dynamically allocated data areas that are freed when
+the function
+.Fn endnetgrent
+is called.
diff --git a/lookup.subproj/getpwent.3 b/lookup.subproj/getpwent.3
new file mode 100644 (file)
index 0000000..f60d28a
--- /dev/null
@@ -0,0 +1,315 @@
+.\" Copyright (c) 1988, 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.
+.\"
+.\"     From: @(#)getpwent.3   8.2 (Berkeley) 12/11/93
+.\" $FreeBSD: src/lib/libc/gen/getpwent.3,v 1.18 2001/10/01 16:08:51 ru Exp $
+.\"
+.Dd September 20, 1994
+.Dt GETPWENT 3
+.Os
+.Sh NAME
+.Nm endpwent ,
+.Nm getpwent ,
+.Nm getpwnam ,
+.Nm getpwnam_r ,
+.Nm getpwuid ,
+.Nm getpwuid_r ,
+.Nm setpassent ,
+.Nm setpwent
+.Nd password database operations
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In pwd.h
+.Ft void
+.Fo endpwent
+.Fa void
+.Fc
+.Ft struct passwd *
+.Fo getpwent
+.Fa void
+.Fc
+.Ft struct passwd *
+.Fo getpwnam
+.Fa "const char *login"
+.Fc
+.Ft int
+.Fo getpwnam_r
+.Fa "const char *login"
+.Fa "struct passwd *pwd"
+.Fa "char *buffer"
+.Fa "size_t bufsize"
+.Fa "struct passwd **result"
+.Fc
+.Ft struct passwd *
+.Fo getpwuid
+.Fa "uid_t uid"
+.Fc
+.Ft int
+.Fo getuid_r
+.Fa "uid_t uid"
+.Fa "struct passwd *pwd"
+.Fa "char *buffer"
+.Fa "size_t bufsize"
+.Fa "struct passwd **result"
+.Fc
+.Ft int
+.Fo setpassent
+.Fa "int stayopen"
+.Fc
+.Ft void
+.Fo setpwent
+.Fa void
+.Fc
+.Sh DESCRIPTION
+These functions
+operate on the password database file,
+which is described
+in
+.Xr passwd 5 .
+Each entry in the database is defined by the structure
+.Ar passwd ,
+found in the include file
+.Aq Pa pwd.h :
+.Bd -literal -offset indent
+struct passwd {
+       char    *pw_name;       /* user name */
+       char    *pw_passwd;     /* encrypted password */
+       uid_t   pw_uid;         /* user uid */
+       gid_t   pw_gid;         /* user gid */
+       time_t  pw_change;      /* password change time */
+       char    *pw_class;      /* user access class */
+       char    *pw_gecos;      /* Honeywell login info */
+       char    *pw_dir;        /* home directory */
+       char    *pw_shell;      /* default shell */
+       time_t  pw_expire;      /* account expiration */
+       int     pw_fields;      /* internal: fields filled in */
+};
+.Ed
+.Pp
+The functions
+.Fn getpwnam
+and
+.Fn getpwuid
+search the password database for the given login name or user uid,
+respectively, always returning the first one encountered.
+.Pp
+All of these routines are thread-safe.
+The
+.Fn getpwent ,
+.Fn getpwnam ,
+and
+.Fn getpwuid
+routines return a pointer to a result managed by the system library in a
+thread-specific data structure.
+Every thread has space for a pointer to a struct passwd and allocates its own storage for the result.
+Neither previously returned values in memory nor a previously returned pointer value should be used
+by a thread after calling any one of these three routines.
+Memory allocated by a thread is automatically released on subsequent calls by the same thread to any of these
+three routines, and when the thread exits.
+.Pp
+The functions
+.Fn getpwnam_r
+and
+.Fn getpwuid_r
+take additional arguments which supply storage space for the returned result.
+The
+.Fa pwd
+parameter is a pointer to a struct passwd, which must be allocated by the caller.
+The 
+.Fa buffer
+parameter is a pointer to a block of memory with a size specified by
+.Pa bufsize .
+This buffer is used to hold the values which are pointed to by values filled in
+the
+.Fa pwd
+structure.
+Zero is returned on success.
+If insufficient memory is supplied, these routines return ERANGE.
+.Pp
+The
+.Fn getpwent
+function
+sequentially reads the password database and is intended for programs
+that wish to process the complete list of users.
+.Pp
+The
+.Fn setpassent
+function
+accomplishes two purposes.
+First, it causes
+.Fn getpwent
+to ``rewind'' to the beginning of the database.
+Additionally, if
+.Fa stayopen
+is non-zero, file descriptors are left open, significantly speeding
+up subsequent accesses for all of the routines.
+(This latter functionality is unnecessary for
+.Fn getpwent ,
+as it doesn't close its file descriptors by default.)
+.Pp
+It is dangerous for long-running programs to keep the file descriptors
+open, as the database will become out of date if it is updated while the
+program is running.
+.Pp
+The
+.Fn setpwent
+function
+is identical to
+.Fn setpassent
+with an argument of zero,
+save that it does not return a status value.
+.Pp
+The
+.Fn endpwent
+function
+closes any open files.
+.Pp
+As of Mac OS X 10.3, there are now different per-user behaviours of 
+this function, based on the AuthenticationAuthority value 
+stored for the queried user in DirectoryServices.
+.Pp
+If the queried user is still a legacy crypt password user or now 
+has an AuthenticationAuthority value containing ``;basic;'',
+these routines will behave in their standard BSD fashion.
+These functions will ``shadow'' the password file, e.g.\&
+allow only certain programs to have access to the encrypted password.
+If the process which calls them has an effective uid of 0, the encrypted
+password will be returned, otherwise, the password field of the returned
+structure will point to the string
+.Ql * .
+.Pp
+By default in Mac OS X 10.3 and later all users will have an 
+AuthenticationAuthority with the value ``;ShadowHash;''.
+These users will have a visible password value of ``********''.
+These functions
+will have no access to the encrypted password whatsoever.
+Setting or changing 
+an user password must be done entirely through the DirectoryService APIs 
+for this default user.
+.Pp
+There also exists an ``Apple Password Server'' user whose password 
+value is also ``********'' and with an AuthenticationAuthority that 
+contains the value ";ApplePasswordServer;" among other data.
+There is no getpwnam access to the password for this user either 
+and again set/change password can be done through the DirectoryService API.
+.Pp
+Finally in support of local user caching there is a local cached user 
+whose password is also ``********'' and has an AuthenticationAuthority 
+value containing ``;LocalCachedUser;'' among other data.
+These functions also provide no access to the password for this user 
+and set/change password functionality is through the DirectoryService API.
+.Pp
+.Sh RETURN VALUES
+The functions
+.Fn getpwent ,
+.Fn getpwnam ,
+and
+.Fn getpwuid
+return a valid pointer to a passwd structure on success
+and a null pointer if end-of-file is reached or an error occurs.
+The
+.Fn setpassent
+function returns 0 on failure and 1 on success.
+The
+.Fn endpwent
+and
+.Fn setpwent
+functions have no return value.
+.Sh FILES
+.Bl -tag -width /etc/master.passwd -compact
+.It Pa /etc/pwd.db
+The insecure password database file
+.It Pa /etc/spwd.db
+The secure password database file
+.It Pa /etc/master.passwd
+The current password file
+.It Pa /etc/passwd
+A Version 7 format password file
+.El
+.Sh LEGACY SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd #include <pwd.h>
+.Pp
+The include file
+.In sys/types.h
+is necessary for the
+.Fa getpwent ,
+.Fa getpwnam ,
+and
+.Fa getpwuid
+functions.
+.Pp
+.Ft int
+.br
+.Fo setpwent
+.Fa void
+.Fc ;
+.Pp
+The
+.Fn setpwent
+function returns 0 on failure and 1 on success.
+.Sh SEE ALSO
+.Xr getlogin 2 ,
+.Xr getgrent 3 ,
+.Xr yp 8 ,
+.Xr passwd 5 ,
+.Xr pwd_mkdb 8 ,
+.Xr vipw 8
+.Sh HISTORY
+The
+.Fn getpwent ,
+.Fn getpwnam ,
+.Fn getpwuid ,
+.Fn setpwent ,
+and
+.Fn endpwent
+functions appeared in
+.At v7 .
+The
+.Fn setpassent
+function appeared in
+.Bx 4.3 Reno .
+.Sh COMPATIBILITY
+The historic function
+.Xr setpwfile 3 ,
+which allowed the specification of alternate password databases,
+has been deprecated and is no longer available.
+.Sh BUGS
+The functions
+.Fn getpwent ,
+.Fn getpwnam ,
+and
+.Fn getpwuid
+leave their results in internal thread-specific memory and return
+a pointer to that object.
+Subsequent calls to any of these three routines by the same thread will
+release the object and return a new pointer value.
diff --git a/lookup.subproj/initgroups.3 b/lookup.subproj/initgroups.3
new file mode 100644 (file)
index 0000000..039b87f
--- /dev/null
@@ -0,0 +1,86 @@
+.\" Copyright (c) 1983, 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.
+.\"
+.\"     @(#)initgroups.3       8.1 (Berkeley) 6/4/93
+.\" $FreeBSD: src/lib/libc/gen/initgroups.3,v 1.10 2001/10/01 16:08:51 ru Exp $
+.\"
+.Dd June 4, 1993
+.Dt INITGROUPS 3
+.Os
+.Sh NAME
+.Nm initgroups
+.Nd initialize group access list
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In unistd.h
+.Ft int
+.Fn initgroups "const char *name" "int basegid"
+.Sh DESCRIPTION
+The
+.Fn initgroups
+function
+uses the
+.Xr getgrouplist 3
+function to calculate the group access list for the user
+specified in
+.Fa name .
+This group list is then setup for the current process using
+.Xr setgroups 2 .
+The
+.Fa basegid
+is automatically included in the groups list.
+Typically this value is given as
+the group number from the password file.
+.Sh RETURN VALUES
+The
+.Fn initgroups
+function
+returns \-1 if it was not invoked by the super-user.
+.Sh SEE ALSO
+.Xr setgroups 2 ,
+.Xr getgrouplist 3
+.Sh HISTORY
+The
+.Fn initgroups
+function appeared in
+.Bx 4.2 .
+.Sh BUGS
+The
+.Fn getgrouplist
+function called by
+.Fn initgroups
+uses the routines based on
+.Xr getgrent 3 .
+If the invoking program uses any of these routines,
+the group structure will
+be overwritten in the call to
+.Fn initgroups .
diff --git a/lookup.subproj/kvbuf.h b/lookup.subproj/kvbuf.h
new file mode 100644 (file)
index 0000000..4da841f
--- /dev/null
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2006 Apple Computer, Inc. All rights reserved.
+ *
+ * @APPLE_LICENSE_HEADER_START@
+ * 
+ * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
+ * Reserved.  This file contains Original Code and/or Modifications of
+ * Original Code as defined in and that are subject to the Apple Public
+ * Source License Version 1.1 (the "License").  You may not use this file
+ * except in compliance with the License.  Please obtain a copy of the
+ * License at http://www.apple.com/publicsource and read it before using
+ * this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A 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.
+ */
+
+#ifndef _KVBUF_H_
+#define _KVBUF_H_
+
+#include <stdint.h>
+#include <sys/cdefs.h>
+
+/*
+ * kvbuf_t is used to encode requests and replies.
+ * It encodes a list of dictionaries.
+ * First 4 bytes are number of dictionaries.
+ * All numbers and lengths are uint32_t in network byte order.
+ * Each dictionary is a list of (key, value list) pairs.
+ * First 4 bytes in a dictionary are the number of keys.
+ * Key is 4 bytes (length) followed by nul-terminated string.
+ * Following the key is a value list.
+ * First 4 bytes in a value list are the number of values.
+ * Each value is 4 bytes (length) followed by nul-terminated string.
+ */
+typedef struct
+{
+       uint32_t datalen;
+       char *databuf;
+       uint32_t _size;
+       uint32_t _dict;
+       uint32_t _key;
+       uint32_t _vlist;
+       uint32_t _val;
+} kvbuf_t;
+
+typedef struct
+{
+       uint32_t kcount;
+       const char **key;
+       uint32_t *vcount;
+       const char ***val;
+} kvdict_t;
+
+typedef struct
+{
+       uint32_t count;
+       uint32_t curr;
+       kvdict_t *dict;
+       kvbuf_t *kv;
+} kvarray_t;
+
+__BEGIN_DECLS
+
+/*
+ * Utilities for creating KV buffers
+ */
+kvbuf_t *kvbuf_new(void);
+kvbuf_t *kvbuf_init(char *buffer, uint32_t length);
+
+void kvbuf_add_dict(kvbuf_t *kv);
+void kvbuf_add_key(kvbuf_t *kv, const char *key);
+void kvbuf_add_val(kvbuf_t *kv, const char *val);
+void kvbuf_add_val_len(kvbuf_t *kv, const char *val, uint32_t len);
+uint32_t kvbuf_get_len(const char *p);
+void kvbuf_free(kvbuf_t *kv);
+
+/* 
+ * Utilities for getting data back from KV buffers
+ * These are ugly, but reasonably efficient.
+ * Libinfo routines decode the raw databuf in a single pass
+ * i.e. not with these routines.
+ */
+
+kvarray_t *kvbuf_decode(kvbuf_t *kv);
+void kvarray_free(kvarray_t *a);
+
+/*
+ * Utility to append a kvbuf to an existing kvbuf
+ */
+void kvbuf_append_kvbuf( kvbuf_t *kv, const kvbuf_t *kv2 );
+
+/*
+ * Call this to start walking through the kvbuf.
+ * Returns the number of dictionaries.
+ */
+uint32_t kvbuf_reset(kvbuf_t *kv);
+
+/*
+ * Walk through dictionaries.
+ * Returns the number of keys in the dictionary.
+ */
+uint32_t kvbuf_next_dict(kvbuf_t *kv);
+
+/*
+ * Walk through keys in a dictionary.
+ * Returns the key.  Don't free it!
+ * Sets the number of values for the key in the val_count output parameter.
+ */
+char *kvbuf_next_key(kvbuf_t *kv, uint32_t *val_count);
+
+/*
+ * Walk through values for a key.
+ * Returns the value.  Don't free it!
+ */
+char *kvbuf_next_val(kvbuf_t *kv);
+
+/*
+ * Walk through values for a key, with a length returned
+ * Returns the value.  Don't free it!
+ */
+char *kvbuf_next_val_len(kvbuf_t *kv, uint32_t *vl );
+
+__END_DECLS
+
+#endif /* ! _KVBUF_H_ */
index cb62a7c636886b32f8e2fdeb10f1b0a03ecc2497..5c7d28ac48bb626469c299edeac28ffb2384059b 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include <mach/mach.h>
 #include <stdio.h>
 #include <string.h>
-#include <rpc/types.h>
-#include <rpc/xdr.h>
 #include <aliasdb.h>
 #include <pthread.h>
-
-#include "_lu_types.h"
-#include "lookup.h"
 #include "lu_utils.h"
 #include "lu_overrides.h"
 
+#define ENTRY_SIZE sizeof(struct aliasent)
+#define ENTRY_KEY _li_data_key_alias
+
 static pthread_mutex_t _alias_lock = PTHREAD_MUTEX_INITIALIZER;
 
-static void 
-free_alias_data(struct aliasent *a)
+static struct aliasent *
+copy_alias(struct aliasent *in)
 {
-       int i;
-
-       if (a == NULL) return;
-
-       if (a->alias_name != NULL) free(a->alias_name);
-       for (i = 0; i < a->alias_members_len; i++) free(a->alias_members[i]);
-       if (a->alias_members != NULL) free(a->alias_members);
-}
+       if (in == NULL) return NULL;
 
-static void 
-free_alias(struct aliasent *a)
-{
-       if (a == NULL) return;
-       free_alias_data(a);
-       free(a);
+       return (struct aliasent *)LI_ils_create("s4*4", in->alias_name, in->alias_members_len, in->alias_members, in->alias_local);
 }
 
-static void
-free_lu_thread_info_alias(void *x)
+/*
+ * Extract the next alias entry from a kvarray.
+ */
+static void *
+extract_alias(kvarray_t *in)
 {
-       struct lu_thread_info *tdata;
-
-       if (x == NULL) return;
-
-       tdata = (struct lu_thread_info *)x;
-       
-       if (tdata->lu_entry != NULL)
-       {
-               free_alias((struct aliasent *)tdata->lu_entry);
-               tdata->lu_entry = NULL;
-       }
+       struct aliasent tmp;
+       uint32_t d, k, kcount;
+       char *empty[1];
 
-       _lu_data_free_vm_xdr(tdata);
-
-       free(tdata);
-}
+       if (in == NULL) return NULL;
 
-static struct aliasent *
-extract_alias(XDR *xdr)
-{
-       int i, j, nkeys, nvals, status;
-       char *key, **vals;
-       struct aliasent *a;
+       d = in->curr;
+       in->curr++;
 
-       if (xdr == NULL) return NULL;
+       if (d >= in->count) return NULL;
 
-       if (!xdr_int(xdr, &nkeys)) return NULL;
+       empty[0] = NULL;
+       memset(&tmp, 0, ENTRY_SIZE);
 
-       a = (struct aliasent *)calloc(1, sizeof(struct aliasent));
+       kcount = in->dict[d].kcount;
 
-       for (i = 0; i < nkeys; i++)
+       for (k = 0; k < kcount; k++)
        {
-               key = NULL;
-               vals = NULL;
-               nvals = 0;
-
-               status = _lu_xdr_attribute(xdr, &key, &vals, &nvals);
-               if (status < 0)
+               if (!strcmp(in->dict[d].key[k], "alias_name"))
                {
-                       free_alias(a);
-                       return NULL;
-               }
+                       if (tmp.alias_name != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
 
-               if (nvals == 0)
-               {
-                       free(key);
-                       continue;
+                       tmp.alias_name = (char *)in->dict[d].val[k][0];
                }
-
-               j = 0;
-
-               if ((a->alias_name == NULL) && (!strcmp("name", key)))
-               {
-                       a->alias_name = vals[0];
-                       j = 1;
-               }
-               else if (!strcmp("alias_local", key))
+               else if (!strcmp(in->dict[d].key[k], "alias_members"))
                {
-                       a->alias_local = atoi(vals[0]);
-               }
-               else if ((a->alias_members == NULL) && (!strcmp("members", key)))
-               {
-                       a->alias_members_len = nvals;
-                       a->alias_members = vals;
-                       j = nvals;
-                       vals = NULL;
-               }
+                       if (tmp.alias_members != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
 
-               free(key);
-               if (vals != NULL)
+                       tmp.alias_members_len = in->dict[d].vcount[k];
+                       tmp.alias_members = (char **)in->dict[d].val[k];
+               }
+               else if (!strcmp(in->dict[d].key[k], "alias_local"))
                {
-                       for (; j < nvals; j++) free(vals[j]);
-                       free(vals);
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       tmp.alias_local = atoi(in->dict[d].val[k][0]);
                }
        }
 
-       if (a->alias_name == NULL) a->alias_name = strdup("");
-       if (a->alias_members == NULL) a->alias_members = (char **)calloc(1, sizeof(char *));
+       if (tmp.alias_name == NULL) tmp.alias_name = "";
+       if (tmp.alias_members == NULL) tmp.alias_members = empty;
 
-       return a;
+       return copy_alias(&tmp);
 }
 
+/*
+ * Send a query to the system information daemon.
+ */
 static struct aliasent *
-copy_alias(struct aliasent *in)
-{
-       int i;
-       struct aliasent *a;
-
-       if (in == NULL) return NULL;
-
-       a = (struct aliasent *)calloc(1, sizeof(struct aliasent));
-
-       a->alias_name = LU_COPY_STRING(in->alias_name);
-
-       a->alias_members_len = in->alias_members_len;
-
-       if (a->alias_members_len == 0)
-       {
-               a->alias_members = (char **)calloc(1, sizeof(char *));
-       }
-       else
-       {
-               a->alias_members = (char **)calloc(a->alias_members_len, sizeof(char *));
-       }
-
-       for (i = 0; i < a->alias_members_len; i++)
-       {
-               a->alias_members[i] = strdup(in->alias_members[i]);
-       }
-
-       a->alias_local = in->alias_local;
-
-       return a;
-}
-
-static void
-recycle_alias(struct lu_thread_info *tdata, struct aliasent *in)
-{
-       struct aliasent *a;
-
-       if (tdata == NULL) return;
-       a = (struct aliasent *)tdata->lu_entry;
-
-       if (in == NULL)
-       {
-               free_alias(a);
-               tdata->lu_entry = NULL;
-       }
-
-       if (tdata->lu_entry == NULL)
-       {
-               tdata->lu_entry = in;
-               return;
-       }
-
-       free_alias_data(a);
-
-       a->alias_name = in->alias_name;
-       a->alias_members_len = in->alias_members_len;
-       a->alias_members = in->alias_members;
-       a->alias_local = in->alias_local;
-
-       free(in);
-}
-
-static struct aliasent *
-lu_alias_getbyname(const char *name)
+ds_alias_getbyname(const char *name)
 {
-       struct aliasent *a;
-       unsigned int datalen;
-       char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT];
-       char *lookup_buf;
-       XDR outxdr;
-       XDR inxdr;
        static int proc = -1;
-       int count;
-
-       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, (_lu_string *)&name))
-       {
-               xdr_destroy(&outxdr);
-               return NULL;
-       }
-       
-       datalen = 0;
-       lookup_buf = NULL;
-       
-       if (_lookup_all(_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;
-       if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
-
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
-
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       a = extract_alias(&inxdr);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-
-       return a;
+       return (struct aliasent *)LI_getone("alias_getbyname", &proc, extract_alias, "name", name);
 }
 
+/*
+ * Clean up / initialize / reinitialize the kvarray used to hold a list of all rpc entries.
+ */
 static void
-lu_alias_endent(void)
+ds_alias_endent(void)
 {
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_alias, free_lu_thread_info_alias);
-       _lu_data_free_vm_xdr(tdata);
+       LI_data_free_kvarray(LI_data_find_key(ENTRY_KEY));
 }
 
 static void
-lu_alias_setent(void)
+ds_alias_setent(void)
 {
-       lu_alias_endent();
+       ds_alias_endent();
 }
 
+/*
+ * Get an entry from the getrpcent kvarray.
+ * Calls the system information daemon if the list doesn't exist (first call),
+ * or extracts the next entry if the list has been fetched.
+ */
 static struct aliasent *
-lu_alias_getent(void)
+ds_alias_getent(void)
 {
        static int proc = -1;
-       struct lu_thread_info *tdata;
-       struct aliasent *a;
-
-       tdata = _lu_data_create_key(_lu_data_key_alias, free_lu_thread_info_alias);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_alias, tdata);
-       }
-
-       if (tdata->lu_vm == NULL)
-       {
-               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, &(tdata->lu_vm), &(tdata->lu_vm_length)) != KERN_SUCCESS)
-               {
-                       lu_alias_endent();
-                       return NULL;
-               }
-
-               /* mig stubs measure size in words (4 bytes) */
-               tdata->lu_vm_length *= 4;
-
-               if (tdata->lu_xdr != NULL)
-               {
-                       xdr_destroy(tdata->lu_xdr);
-                       free(tdata->lu_xdr);
-               }
-               tdata->lu_xdr = (XDR *)calloc(1, sizeof(XDR));
 
-               xdrmem_create(tdata->lu_xdr, tdata->lu_vm, tdata->lu_vm_length, XDR_DECODE);
-               if (!xdr_int(tdata->lu_xdr, &tdata->lu_vm_cursor))
-               {
-                       lu_alias_endent();
-                       return NULL;
-               }
-       }
-
-       if (tdata->lu_vm_cursor == 0)
-       {
-               lu_alias_endent();
-               return NULL;
-       }
-
-
-       a = extract_alias(tdata->lu_xdr);
-       if (a == NULL)
-       {
-               lu_alias_endent();
-               return NULL;
-       }
-
-       tdata->lu_vm_cursor--;
-       
-       return a;
+       return (struct aliasent *)LI_getent("alias_getent", &proc, extract_alias, ENTRY_KEY, ENTRY_SIZE);
 }
 
 struct aliasent *
 alias_getbyname(const char *name)
 {
        struct aliasent *res = NULL;
-       struct lu_thread_info *tdata;
+       struct li_thread_info *tdata;
 
-       tdata = _lu_data_create_key(_lu_data_key_alias, free_lu_thread_info_alias);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_alias, tdata);
-       }
+       tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
+       if (tdata == NULL) return NULL;
 
-       if (_lu_running())
+       if (_ds_running())
        {
-               res = lu_alias_getbyname(name);
+               res = ds_alias_getbyname(name);
        }
        else
        {
@@ -384,8 +159,8 @@ alias_getbyname(const char *name)
                pthread_mutex_unlock(&_alias_lock);
        }
 
-       recycle_alias(tdata, res);
-       return (struct aliasent *)tdata->lu_entry;
+       LI_data_recycle(tdata, res, ENTRY_SIZE);
+       return (struct aliasent *)tdata->li_entry;
 
 }
 
@@ -393,18 +168,14 @@ struct aliasent *
 alias_getent(void)
 {
        struct aliasent *res = NULL;
-       struct lu_thread_info *tdata;
+       struct li_thread_info *tdata;
 
-       tdata = _lu_data_create_key(_lu_data_key_alias, free_lu_thread_info_alias);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_alias, tdata);
-       }
+       tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
+       if (tdata == NULL) return NULL;
 
-       if (_lu_running())
+       if (_ds_running())
        {
-               res = lu_alias_getent();
+               res = ds_alias_getent();
        }
        else
        {
@@ -413,21 +184,21 @@ alias_getent(void)
                pthread_mutex_unlock(&_alias_lock);
        }
 
-       recycle_alias(tdata, res);
-       return (struct aliasent *)tdata->lu_entry;
+       LI_data_recycle(tdata, res, ENTRY_SIZE);
+       return (struct aliasent *)tdata->li_entry;
 
 }
 
 void
 alias_setent(void)
 {
-       if (_lu_running()) lu_alias_setent();
+       if (_ds_running()) ds_alias_setent();
        else _old_alias_setent();
 }
 
 void
 alias_endent(void)
 {
-       if (_lu_running()) lu_alias_endent();
+       if (_ds_running()) ds_alias_endent();
        else _old_alias_endent();
 }
index 8f96c94b1a148a5ccec523b9babb5ecd170c49d1..90b0ac3d6981b05480fc1ae3c0bf58dd338f0497 100644 (file)
@@ -29,8 +29,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <rpc/types.h>
-#include <rpc/xdr.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <net/ethernet.h>
 #include <pthread.h>
 
-#include "_lu_types.h"
-#include "lookup.h"
-#include "lu_utils.h"
-
-static pthread_mutex_t _bootp_lock = PTHREAD_MUTEX_INITIALIZER;
-
-struct bootpent
-{
-       char *b_name;
-       struct ether_addr b_enaddr;
-       struct in_addr b_ipaddr;
-       char *b_bootfile;
-};
-
-static void
-free_bootp(struct bootpent *b)
-{
-       if (b == NULL) return;
-
-       if (b->b_name != NULL) free(b->b_name);
-       if (b->b_bootfile != NULL) free(b->b_bootfile);
-
-       free(b);
-}
-
-static struct bootpent *
-extract_bootp(XDR *xdr)
-{
-       struct bootpent *b;
-       struct ether_addr *e;
-       int i, j, nvals, nkeys, status;
-       char *key, **vals;
-
-       if (xdr == NULL) return NULL;
-
-       if (!xdr_int(xdr, &nkeys)) return NULL;
-
-       b = (struct bootpent *)calloc(1, sizeof(struct bootpent));
-
-       for (i = 0; i < nkeys; i++)
-       {
-               key = NULL;
-               vals = NULL;
-               nvals = 0;
-
-               status = _lu_xdr_attribute(xdr, &key, &vals, &nvals);
-               if (status < 0)
-               {
-                       free_bootp(b);
-                       return NULL;
-               }
-
-               if (nvals == 0)
-               {
-                       free(key);
-                       continue;
-               }
-
-               j = 0;
-
-               if ((b->b_name == NULL) && (!strcmp("name", key)))
-               {
-                       b->b_name = vals[0];
-                       j = 1;
-               }
-               if ((b->b_name == NULL) && (!strcmp("bootfile", key)))
-               {
-                       b->b_bootfile = vals[0];
-                       j = 1;
-               }
-               else if (!strcmp("ip_address", key))
-               {
-                       b->b_ipaddr.s_addr = inet_addr(vals[0]);
-               }
-               else if (!strcmp("en_address", key))
-               {
-                       pthread_mutex_lock(&_bootp_lock);
-                       e = ether_aton(vals[0]);
-                       if (e != NULL) memcpy(&(b->b_enaddr), e, sizeof(struct ether_addr));
-                       pthread_mutex_unlock(&_bootp_lock);
-                       j = 1;
-               }
-
-               free(key);
-               if (vals != NULL)
-               {
-                       for (; j < nvals; j++) free(vals[j]);
-                       free(vals);
-               }
-       }
-
-       if (b->b_name == NULL) b->b_name = strdup("");
-       if (b->b_bootfile == NULL) b->b_bootfile = strdup("");
-
-       return b;
-}
-
-static int 
-lu_bootp_getbyether(struct ether_addr *enaddr, char **name,
-       struct in_addr *ipaddr, char **bootfile)
-{
-       unsigned datalen;
-       XDR inxdr;
-       struct bootpent *b;
-       static int proc = -1;
-       char *lookup_buf;
-       int count;
-
-       if (proc < 0)
-       {
-               if (_lookup_link(_lu_port, "bootp_getbyether", &proc) != KERN_SUCCESS)
-               {
-                       return 0;
-               }
-       }
-
-       datalen = 0;
-       lookup_buf = NULL;
-
-       if (_lookup_all(_lu_port, proc, (unit *)enaddr, ((sizeof(*enaddr) + sizeof(unit) - 1) / sizeof(unit)), &lookup_buf, &datalen) != KERN_SUCCESS)
-       {
-               return 0;
-       }
-
-       datalen *= BYTES_PER_XDR_UNIT;
-       if ((lookup_buf == NULL) || (datalen == 0)) return 0;
-
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
-
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return 0;
-       }
-
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return 0;
-       }
-
-       b = extract_bootp(&inxdr);
-       xdr_destroy(&inxdr);
-
-       *name = b->b_name;
-       *bootfile = b->b_bootfile;
-       ipaddr->s_addr = b->b_ipaddr.s_addr;
-
-       free(b);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-
-       return 1;
-}
-
-static int 
-lu_bootp_getbyip(struct ether_addr *enaddr, char **name,
-       struct in_addr *ipaddr, char **bootfile)
-{
-       unsigned datalen;
-       XDR inxdr;
-       struct bootpent *b;
-       static int proc = -1;
-       char *lookup_buf;
-       int count;
-       
-       if (proc < 0)
-       {
-               if (_lookup_link(_lu_port, "bootp_getbyip", &proc) != KERN_SUCCESS)
-               {
-                       return 0;
-               }
-       }
-
-       datalen = 0;
-       lookup_buf = NULL;
-
-       if (_lookup_all(_lu_port, proc, (unit *)ipaddr, ((sizeof(*ipaddr) + sizeof(unit) - 1) / sizeof(unit)), &lookup_buf, &datalen) != KERN_SUCCESS)
-       {
-               return 0;
-       }
-
-       datalen *= BYTES_PER_XDR_UNIT;
-       if ((lookup_buf == NULL) || (datalen == 0)) return 0;
-
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
-
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return 0;
-       }
-
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return 0;
-       }
-
-       b = extract_bootp(&inxdr);
-       xdr_destroy(&inxdr);
-
-       *name = b->b_name;
-       *bootfile = b->b_bootfile;
-       memcpy(enaddr, &(b->b_enaddr), sizeof(struct ether_addr));
-
-       free(b);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-
-       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;
 }
 
index 9fe1b8472ff638df2bd2fb8eebf4203f1abbecc8..ea452e127dc258d761b741fb9fdb36646c1f2c0a 100644 (file)
 #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 void 
-free_bootparams_data(struct bootparamsent *b)
-{
-       char **param;
-
-       if (b == NULL) return;
-
-       if (b->bp_name != NULL) free(b->bp_name);
-
-       param = b->bp_bootparams;
-       if (param != NULL)
-       {
-               while (*param != NULL) free(*param++);
-               free(b->bp_bootparams);
-       }
-}
-
-static void 
-free_bootparams(struct bootparamsent *b)
-{
-       if (b == NULL) return;
-       free_bootparams_data(b);
-       free(b);
-}
-
-static void
-free_lu_thread_info_bootparams(void *x)
-{
-       struct lu_thread_info *tdata;
-
-       if (x == NULL) return;
-
-       tdata = (struct lu_thread_info *)x;
-       
-       if (tdata->lu_entry != NULL)
-       {
-               free_bootparams((struct bootparamsent *)tdata->lu_entry);
-               tdata->lu_entry = NULL;
-       }
-
-       _lu_data_free_vm_xdr(tdata);
-
-       free(tdata);
-}
-
-static struct bootparamsent *
-extract_bootparams(XDR *xdr)
-{
-       int i, j, nkeys, nvals, status;
-       char *key, **vals;
-       struct bootparamsent *b;
-
-       if (xdr == NULL) return NULL;
-
-       if (!xdr_int(xdr, &nkeys)) return NULL;
-
-       b = (struct bootparamsent *)calloc(1, sizeof(struct bootparamsent));
-
-       for (i = 0; i < nkeys; i++)
-       {
-               key = NULL;
-               vals = NULL;
-               nvals = 0;
-
-               status = _lu_xdr_attribute(xdr, &key, &vals, &nvals);
-               if (status < 0)
-               {
-                       free_bootparams(b);
-                       return NULL;
-               }
-
-               if (nvals == 0)
-               {
-                       free(key);
-                       continue;
-               }
-
-               j = 0;
-       
-               if ((b->bp_name == NULL) && (!strcmp("name", key)))
-               {
-                       b->bp_name = vals[0];
-                       j = 1;
-               }
-               else if ((b->bp_bootparams == NULL) && (!strcmp("bootparams", key)))
-               {
-                       b->bp_bootparams = vals;
-                       j = nvals;
-                       vals = NULL;
-               }
-
-               free(key);
-               if (vals != NULL)
-               {
-                       for (; j < nvals; j++) free(vals[j]);
-                       free(vals);
-               }
-       }
-
-       if (b->bp_name == NULL) b->bp_name = strdup("");
-       if (b->bp_bootparams == NULL) b->bp_bootparams = (char **)calloc(1, sizeof(char *));
-
-       return b;
-}
-
-static void 
-recycle_bootparams(struct lu_thread_info *tdata, struct bootparamsent *in)
-{
-       struct bootparamsent *b;
-
-       if (tdata == NULL) return;
-       b = (struct bootparamsent *)tdata->lu_entry;
-
-       if (in == NULL)
-       {
-               free_bootparams(b);
-               tdata->lu_entry = NULL;
-       }
-
-       if (tdata->lu_entry == NULL)
-       {
-               tdata->lu_entry = in;
-               return;
-       }
-
-       free_bootparams_data(b);
-
-       b->bp_name = in->bp_name;
-       b->bp_bootparams = in->bp_bootparams;
-
-       free(in);
-}
-
-static struct bootparamsent *
-lu_bootparams_getbyname(const char *name)
-{
-       struct bootparamsent *b;
-       unsigned datalen;
-       char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT];
-       char *lookup_buf;
-       XDR outxdr;
-       XDR inxdr;
-       int size;
-       static int proc = -1;
-       int count;
-
-       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, (_lu_string *)&name))
-       {
-               xdr_destroy(&outxdr);
-               return (NULL);
-       }
-
-       size = xdr_getpos(&outxdr);
-       xdr_destroy(&outxdr);
-
-       datalen = 0;
-       lookup_buf = NULL;
-
-       if (_lookup_all(_lu_port, proc, (unit *)namebuf, size, &lookup_buf, 
-               &datalen) != KERN_SUCCESS)
-       {
-               return (NULL);
-       }
-
-       datalen *= BYTES_PER_XDR_UNIT;
-       if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
-
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
-
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       b = extract_bootparams(&inxdr);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-
-       return b;
-}
-
-static void
-lu_bootparams_endent(void)
-{
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_bootparams, free_lu_thread_info_bootparams);
-       _lu_data_free_vm_xdr(tdata);
-}
-
-static void
-lu_bootparams_setent(void)
-{
-       lu_bootparams_endent();
-}
-
-static struct bootparamsent *
-lu_bootparams_getent(void)
-{
-       struct bootparamsent *b;
-       static int proc = -1;
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_bootparams, free_lu_thread_info_bootparams);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_bootparams, tdata);
-       }
-
-       if (tdata->lu_vm == NULL)
-       {
-               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, &(tdata->lu_vm), &(tdata->lu_vm_length)) != KERN_SUCCESS)
-               {
-                       lu_bootparams_endent();
-                       return NULL;
-               }
-
-               /* mig stubs measure size in words (4 bytes) */
-               tdata->lu_vm_length *= 4;
-
-               if (tdata->lu_xdr != NULL)
-               {
-                       xdr_destroy(tdata->lu_xdr);
-                       free(tdata->lu_xdr);
-               }
-               tdata->lu_xdr = (XDR *)calloc(1, sizeof(XDR));
-
-               xdrmem_create(tdata->lu_xdr, tdata->lu_vm, tdata->lu_vm_length, XDR_DECODE);
-               if (!xdr_int(tdata->lu_xdr, &tdata->lu_vm_cursor))
-               {
-                       lu_bootparams_endent();
-                       return NULL;
-               }
-       }
-
-       if (tdata->lu_vm_cursor == 0)
-       {
-               lu_bootparams_endent();
-               return NULL;
-       }
-
-       b = extract_bootparams(tdata->lu_xdr);
-       if (b == NULL)
-       {
-               lu_bootparams_endent();
-               return NULL;
-       }
-
-       tdata->lu_vm_cursor--;
-
-       return b;       
-}
-
 struct bootparamsent *
 bootparams_getbyname(const char *name)
 {
-       struct bootparamsent *res;
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_bootparams, free_lu_thread_info_bootparams);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_bootparams, tdata);
-       }
-
-       if (_lu_running())
-       {
-               res = lu_bootparams_getbyname(name);
-               recycle_bootparams(tdata, res);
-               return (struct bootparamsent *)tdata->lu_entry;
-       }
-
        return NULL;
 }
 
 struct bootparamsent *
 bootparams_getent(void)
 {
-       struct bootparamsent *res;
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_bootparams, free_lu_thread_info_bootparams);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_bootparams, tdata);
-       }
-
-       if (_lu_running())
-       {
-               res = lu_bootparams_getent();
-               recycle_bootparams(tdata, res);
-               return (struct bootparamsent *)tdata->lu_entry;
-       }
-
        return NULL;
 }
 
 void
 bootparams_setent(void)
 {
-       if (_lu_running()) lu_bootparams_setent();
 }
 
 void
 bootparams_endent(void)
 {
-       if (_lu_running()) lu_bootparams_endent();
 }
index 725255b4e7739c5866985caf07ba173c6ac446ad..05f7624c873680d588a40f3a8a5b4ef1a258b574 100644 (file)
 #include <mach/mach.h>
 #include <stdio.h>
 #include <string.h>
-#include <rpc/types.h>
-#include <rpc/xdr.h>
 #include <fstab.h>
 #include <pthread.h>
-
-#include "lookup.h"
-#include "_lu_types.h"
 #include "lu_utils.h"
 #include "lu_overrides.h"
 
+#define ENTRY_SIZE sizeof(struct fstab)
+#define ENTRY_KEY _li_data_key_fstab
+
 static pthread_mutex_t _fstab_lock = PTHREAD_MUTEX_INITIALIZER;
 
 #define FS_GET_SPEC 1
 #define FS_GET_FILE 2
 #define FS_GET_ENT 3
 
-static void
-free_fstab_data(struct fstab *f)
+static struct fstab *
+copy_fstab(struct fstab *in)
 {
-       if (f == NULL) return;
+       if (in == NULL) return NULL;
 
-       if (f->fs_spec != NULL) free(f->fs_spec);
-       if (f->fs_file != NULL) free(f->fs_file);
-       if (f->fs_vfstype != NULL) free(f->fs_vfstype);
-       if (f->fs_mntops != NULL) free(f->fs_mntops);
-       if (f->fs_type != NULL) free(f->fs_type);
+       return (struct fstab *)LI_ils_create("sssss44", in->fs_spec, in->fs_file, in->fs_vfstype, in->fs_mntops, in->fs_type, in->fs_freq, in->fs_passno);
 }
 
-static void
-free_fstab(struct fstab *f)
-{
-       if (f == NULL) return;
-       free_fstab_data(f);
-       free(f);
-}
-
-static void
-free_lu_thread_info_fstab(void *x)
+/*
+ * Extract the next fstab entry from a kvarray.
+ */
+static void *
+extract_fstab(kvarray_t *in)
 {
-       struct lu_thread_info *tdata;
-
-       if (x == NULL) return;
-
-       tdata = (struct lu_thread_info *)x;
-       
-       if (tdata->lu_entry != NULL)
-       {
-               free_fstab((struct fstab *)tdata->lu_entry);
-               tdata->lu_entry = NULL;
-       }
+       struct fstab tmp;
+       uint32_t d, k, kcount;
 
-       _lu_data_free_vm_xdr(tdata);
-
-       free(tdata);
-}
+       if (in == NULL) return NULL;
 
-static struct fstab *
-extract_fstab(XDR *xdr)
-{
-       int i, j, nkeys, nvals, status;
-       char *key, **vals;
-       struct fstab *f;
+       d = in->curr;
+       in->curr++;
 
-       if (xdr == NULL) return NULL;
+       if (d >= in->count) return NULL;
 
-       if (!xdr_int(xdr, &nkeys)) return NULL;
+       memset(&tmp, 0, ENTRY_SIZE);
 
-       f = (struct fstab *)calloc(1, sizeof(struct fstab));
+       kcount = in->dict[d].kcount;
 
-       for (i = 0; i < nkeys; i++)
+       for (k = 0; k < kcount; k++)
        {
-               key = NULL;
-               vals = NULL;
-               nvals = 0;
-
-               status = _lu_xdr_attribute(xdr, &key, &vals, &nvals);
-               if (status < 0)
+               if (!strcmp(in->dict[d].key[k], "fs_spec"))
                {
-                       free_fstab(f);
-                       return NULL;
-               }
+                       if (tmp.fs_spec != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
 
-               if (nvals == 0)
-               {
-                       free(key);
-                       continue;
+                       tmp.fs_spec = (char *)in->dict[d].val[k][0];
                }
-
-               j = 0;
-
-               if ((f->fs_spec == NULL) && (!strcmp("name", key)))
+               else if (!strcmp(in->dict[d].key[k], "fs_file"))
                {
-                       f->fs_spec = vals[0];
-                       j = 1;
-               }
-               else if ((f->fs_file == NULL) && (!strcmp("dir", key)))
-               {
-                       f->fs_file = vals[0];
-                       j = 1;
-               }
-               else if ((f->fs_vfstype == NULL) && (!strcmp("vfstype", key)))
-               {
-                       f->fs_vfstype = vals[0];
-                       j = 1;
+                       if (tmp.fs_file != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
+
+                       tmp.fs_file = (char *)in->dict[d].val[k][0];
                }
-               else if ((f->fs_mntops == NULL) && (!strcmp("opts", key)))
+               else if (!strcmp(in->dict[d].key[k], "fs_vfstype"))
                {
-                       f->fs_mntops = vals[0];
-                       j = 1;
+                       if (tmp.fs_vfstype != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
+
+                       tmp.fs_vfstype = (char *)in->dict[d].val[k][0];
                }
-               else if ((f->fs_type == NULL) && (!strcmp("type", key)))
+               else if (!strcmp(in->dict[d].key[k], "fs_mntops"))
                {
-                       f->fs_type = vals[0];
-                       j = 1;
+                       if (tmp.fs_mntops != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
+
+                       tmp.fs_mntops = (char *)in->dict[d].val[k][0];
                }
-               else if (!strcmp("freq", key))
+               else if (!strcmp(in->dict[d].key[k], "fs_type"))
                {
-                       f->fs_freq = atoi(vals[0]);
+                       if (tmp.fs_type != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
+
+                       tmp.fs_type = (char *)in->dict[d].val[k][0];
                }
-               else if (!strcmp("passno", key))
+               else if (!strcmp(in->dict[d].key[k], "fs_freq"))
                {
-                       f->fs_passno = atoi(vals[0]);
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       tmp.fs_freq = atoi(in->dict[d].val[k][0]);
                }
-
-               free(key);
-               if (vals != NULL)
+               else if (!strcmp(in->dict[d].key[k], "fs_passno"))
                {
-                       for (; j < nvals; j++) free(vals[j]);
-                       free(vals);
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       tmp.fs_passno = atoi(in->dict[d].val[k][0]);
                }
        }
 
-       if (f->fs_spec == NULL) f->fs_spec = strdup("");
-       if (f->fs_file == NULL) f->fs_file = strdup("");
-       if (f->fs_vfstype == NULL) f->fs_vfstype = strdup("");
-       if (f->fs_mntops == NULL) f->fs_mntops = strdup("");
-       if (f->fs_type == NULL) f->fs_type = strdup("");
-
-       return f;
-}
-
-static struct fstab *
-copy_fstab(struct fstab *in)
-{
-       struct fstab *f;
-
-       if (in == NULL) return NULL;
-
-       f = (struct fstab *)calloc(1, sizeof(struct fstab));
-
-       f->fs_spec = LU_COPY_STRING(in->fs_spec);
-       f->fs_file = LU_COPY_STRING(in->fs_file);
-       f->fs_vfstype = LU_COPY_STRING(in->fs_vfstype);
-       f->fs_mntops = LU_COPY_STRING(in->fs_mntops);
-       f->fs_type = LU_COPY_STRING(in->fs_type);
-
-       f->fs_freq = in->fs_freq;
-       f->fs_passno = in->fs_passno;
-
-       return f;
-}
-
-static void
-recycle_fstab(struct lu_thread_info *tdata, struct fstab *in)
-{
-       struct fstab *f;
-
-       if (tdata == NULL) return;
-       f = (struct fstab *)tdata->lu_entry;
-
-       if (in == NULL)
-       {
-               free_fstab(f);
-               tdata->lu_entry = NULL;
-       }
-
-       if (tdata->lu_entry == NULL)
-       {
-               tdata->lu_entry = in;
-               return;
-       }
-
-       free_fstab_data(f);
-
-       f->fs_spec = in->fs_spec;
-       f->fs_file = in->fs_file;
-       f->fs_vfstype = in->fs_vfstype;
-       f->fs_mntops = in->fs_mntops;
-       f->fs_type = in->fs_type;
-       f->fs_freq = in->fs_freq;
-       f->fs_passno = in->fs_passno;
+       if (tmp.fs_spec == NULL) tmp.fs_spec = "";
+       if (tmp.fs_file == NULL) tmp.fs_file = "";
+       if (tmp.fs_vfstype == NULL) tmp.fs_vfstype = "";
+       if (tmp.fs_mntops == NULL) tmp.fs_mntops = "";
+       if (tmp.fs_type == NULL) tmp.fs_type = "";
 
-       free(in);
+       return copy_fstab(&tmp);
 }
 
 static struct fstab *
-lu_getfsspec(const char *name)
+ds_getfsspec(const char *name)
 {
-       struct fstab *f;
-       unsigned datalen;
-       char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT];
-       XDR outxdr;
-       XDR inxdr;
        static int proc = -1;
-       char *lookup_buf;
-       int count;
-
-       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, (_lu_string *)&name))
-       {
-               xdr_destroy(&outxdr);
-               return NULL;
-       }
-
-       datalen = 0;
-       lookup_buf = NULL;
-
-       if (_lookup_all(_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;
-       if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
-
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
-
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       f = extract_fstab(&inxdr);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-
-       return f;
+       return (struct fstab *)LI_getone("getfsbyname", &proc, extract_fstab, "name", name);
 }
 
 static void
-lu_endfsent(void)
+ds_endfsent(void)
 {
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_fstab, free_lu_thread_info_fstab);
-       _lu_data_free_vm_xdr(tdata);
+       LI_data_free_kvarray(LI_data_find_key(ENTRY_KEY));
 }
 
 static int
-lu_setfsent(void)
+ds_setfsent(void)
 {
-       lu_endfsent();
+       ds_endfsent();
        return 1;
 }
 
 static struct fstab *
-lu_getfsent()
+ds_getfsent()
 {
        static int proc = -1;
-       struct lu_thread_info *tdata;
-       struct fstab *f;
 
-       tdata = _lu_data_create_key(_lu_data_key_fstab, free_lu_thread_info_fstab);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_fstab, tdata);
-       }
-
-       if (tdata->lu_vm == NULL)
-       {
-               if (proc < 0)
-               {
-                       if (_lookup_link(_lu_port, "getfsent", &proc) != KERN_SUCCESS)
-                       {
-                               lu_endfsent();
-                               return NULL;
-                       }
-               }
-
-               if (_lookup_all(_lu_port, proc, NULL, 0, &(tdata->lu_vm), &(tdata->lu_vm_length)) != KERN_SUCCESS)
-               {
-                       lu_endfsent();
-                       return NULL;
-               }
-
-               /* mig stubs measure size in words (4 bytes) */
-               tdata->lu_vm_length *= 4;
-
-               if (tdata->lu_xdr != NULL)
-               {
-                       xdr_destroy(tdata->lu_xdr);
-                       free(tdata->lu_xdr);
-               }
-               tdata->lu_xdr = (XDR *)calloc(1, sizeof(XDR));
-
-               xdrmem_create(tdata->lu_xdr, tdata->lu_vm, tdata->lu_vm_length, XDR_DECODE);
-               if (!xdr_int(tdata->lu_xdr, &tdata->lu_vm_cursor))
-               {
-                       lu_endfsent();
-                       return NULL;
-               }
-       }
-
-       if (tdata->lu_vm_cursor == 0)
-       {
-               lu_endfsent();
-               return NULL;
-       }
-
-       f = extract_fstab(tdata->lu_xdr);
-       if (f == NULL)
-       {
-               lu_endfsent();
-               return NULL;
-       }
-
-       tdata->lu_vm_cursor--;
-       
-       return f;
+       return (struct fstab *)LI_getent("getfsent", &proc, extract_fstab, ENTRY_KEY, ENTRY_SIZE);
 }
 
 static struct fstab *
-lu_getfsfile(const char *name)
+ds_getfsfile(const char *name)
 {
        struct fstab *fs;
 
-       if (name == NULL) return (struct fstab *)NULL;
+       if (name == NULL) return NULL;
 
-       setfsent();
-       for (fs = lu_getfsent(); fs != NULL; fs = lu_getfsent())
+       ds_setfsent();
+
+       for (fs = ds_getfsent(); fs != NULL; fs = ds_getfsent())
+       {
                if (!strcmp(fs->fs_file, name)) return fs;
+       }
 
-       endfsent();
-       return (struct fstab *)NULL;
+       ds_endfsent();
+
+       return NULL;
 }
 
 static struct fstab *
 getfs(const char *spec, const char *file, int source)
 {
        struct fstab *res = NULL;
-       struct lu_thread_info *tdata;
+       struct li_thread_info *tdata;
 
-       tdata = _lu_data_create_key(_lu_data_key_fstab, free_lu_thread_info_fstab);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_fstab, tdata);
-       }
+       tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
+       if (tdata == NULL) return NULL;
 
-       if (_lu_running())
+       if (_ds_running())
        {
                switch (source)
                {
                        case FS_GET_SPEC:
-                               res = lu_getfsspec(spec);
+                               res = ds_getfsspec(spec);
                                break;
                        case FS_GET_FILE:
-                               res = lu_getfsfile(file);
+                               res = ds_getfsfile(file);
                                break;
                        case FS_GET_ENT:
-                               res = lu_getfsent();
-                               break;
+                               res = ds_getfsent();
+                       break;
                        default: res = NULL;
                }
        }
        else
        {
                pthread_mutex_lock(&_fstab_lock);
+
                switch (source)
                {
                        case FS_GET_SPEC:
@@ -434,11 +220,12 @@ getfs(const char *spec, const char *file, int source)
                                break;
                        default: res = NULL;
                }
+
                pthread_mutex_unlock(&_fstab_lock);
        }
 
-       recycle_fstab(tdata, res);
-       return (struct fstab *)tdata->lu_entry;
+       LI_data_recycle(tdata, res, ENTRY_SIZE);
+       return (struct fstab *)tdata->li_entry;
 }
 
 
@@ -469,14 +256,13 @@ getfsent(void)
 int
 setfsent(void)
 {
-       if (_lu_running()) return (lu_setfsent());
+       if (_ds_running()) return (ds_setfsent());
        return (_old_setfsent());
 }
 
 void
 endfsent(void)
 {
-       if (_lu_running()) lu_endfsent();
+       if (_ds_running()) ds_endfsent();
        else _old_endfsent();
 }
-
index 844cd3c09c854e6fd72937717b7a669d48b960f9..05d7aca6bdbcc12a099d9e6254730ff001b6df00 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2007 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -31,9 +31,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
-#include <rpc/types.h>
-#include <rpc/xdr.h>
-#include <grp.h>
 #include <pwd.h>
 #include <netinet/in.h>
 #include <sys/param.h>
 #include <pthread.h>
 #include <errno.h>
 #include <servers/bootstrap.h>
-
-#include "_lu_types.h"
-#include "lookup.h"
+#include <sys/syscall.h>
 #include "lu_utils.h"
 #include "lu_overrides.h"
 
+#define ENTRY_SIZE sizeof(struct group)
+#define ENTRY_KEY _li_data_key_group
 #define GROUP_CACHE_SIZE 10
-#define DEFAULT_GROUP_CACHE_TTL 10
 
 static pthread_mutex_t _group_cache_lock = PTHREAD_MUTEX_INITIALIZER;
-static void *_group_cache[GROUP_CACHE_SIZE] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
-static unsigned int _group_cache_best_before[GROUP_CACHE_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+static void *_group_cache[GROUP_CACHE_SIZE] = { NULL };
 static unsigned int _group_cache_index = 0;
-static unsigned int _group_cache_ttl = DEFAULT_GROUP_CACHE_TTL;
+static unsigned int _group_cache_init = 0;
 
 static pthread_mutex_t _group_lock = PTHREAD_MUTEX_INITIALIZER;
 
+/*
+ * Note that we don't include grp.h and define struct group privately in here
+ * to avoid needing to produce a variant version of setgrent, which changed
+ * for UXIX03 conformance.
+ */
+struct group
+{
+       char *gr_name;
+       char *gr_passwd;
+       gid_t gr_gid;
+       char **gr_mem;
+};
+
+/* forward */
+int setgrent(void);
+struct group *getgrent(void);
+void endgrent(void);
+
 /*
  * Support for memberd calls
  */
 #define MEMBERD_NAME "com.apple.memberd"
-static mach_port_t mbr_port = MACH_PORT_NULL;
 typedef uint32_t GIDArray[16];
-extern kern_return_t _mbr_GetGroups(mach_port_t server, uint32_t uid, uint32_t *numGroups, GIDArray gids, security_token_t *token);
+extern kern_return_t memberdDSmig_GetGroups(mach_port_t server, uint32_t uid, uint32_t *numGroups, GIDArray gids, audit_token_t *token);
+extern kern_return_t memberdDSmig_GetAllGroups(mach_port_t server, uint32_t uid, uint32_t *numGroups, gid_t **gids, uint32_t *gidsCnt, audit_token_t *token);
+__private_extern__ uid_t audit_token_uid(audit_token_t a);
 
 #define GR_GET_NAME 1
 #define GR_GET_GID 2
 #define GR_GET_ENT 3
 
-static void 
-free_group_data(struct group *g)
+static struct group *
+copy_group(struct group *in)
 {
-       char **mem;
-
-       if (g == NULL) return;
-
-       if (g->gr_name != NULL) free(g->gr_name);
-       if (g->gr_passwd != NULL) free(g->gr_passwd);
+       if (in == NULL) return NULL;
 
-       mem = g->gr_mem;
-       if (mem != NULL)
-       {
-               while (*mem != NULL) free(*mem++);
-               free(g->gr_mem);
-       }
+       return (struct group *)LI_ils_create("ss4*", in->gr_name, in->gr_passwd, in->gr_gid, in->gr_mem);
 }
 
-static void 
-free_group(struct group *g)
-{
-       if (g == NULL) return;
-       free_group_data(g);
-       free(g);
- }
-
-static void
-free_lu_thread_info_group(void *x)
+/*
+ * Extract the next group entry from a kvarray.
+ */
+static void *
+extract_group(kvarray_t *in)
 {
-       struct lu_thread_info *tdata;
-
-       if (x == NULL) return;
+       struct group tmp;
+       uint32_t d, k, kcount;
+       char *empty[1];
 
-       tdata = (struct lu_thread_info *)x;
+       if (in == NULL) return NULL;
 
-       if (tdata->lu_entry != NULL)
-       {
-               free_group((struct group *)tdata->lu_entry);
-               tdata->lu_entry = NULL;
-       }
+       d = in->curr;
+       in->curr++;
 
-       _lu_data_free_vm_xdr(tdata);
+       if (d >= in->count) return NULL;
 
-       free(tdata);
-}
+       empty[0] = NULL;
+       memset(&tmp, 0, ENTRY_SIZE);
 
-static struct group *
-extract_group(XDR *xdr)
-{
-       int i, j, nkeys, nvals, status;
-       char *key, **vals;
-       struct group *g;
-
-       if (xdr == NULL) return NULL;
+       tmp.gr_gid = -2;
 
-       if (!xdr_int(xdr, &nkeys)) return NULL;
+       kcount = in->dict[d].kcount;
 
-       g = (struct group *)calloc(1, sizeof(struct group));
-       g->gr_gid = -2;
-
-       for (i = 0; i < nkeys; i++)
+       for (k = 0; k < kcount; k++)
        {
-               key = NULL;
-               vals = NULL;
-               nvals = 0;
-
-               status = _lu_xdr_attribute(xdr, &key, &vals, &nvals);
-               if (status < 0)
+               if (!strcmp(in->dict[d].key[k], "gr_name"))
                {
-                       free_group(g);
-                       return NULL;
-               }
+                       if (tmp.gr_name != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
 
-               if (nvals == 0)
-               {
-                       free(key);
-                       continue;
+                       tmp.gr_name = (char *)in->dict[d].val[k][0];
                }
-
-               j = 0;
-
-               if ((g->gr_name == NULL) && (!strcmp("name", key)))
+               else if (!strcmp(in->dict[d].key[k], "gr_passwd"))
                {
-                       g->gr_name = vals[0];
-                       j = 1;
-               }
-               else if ((g->gr_passwd == NULL) && (!strcmp("passwd", key)))
-               {
-                       g->gr_passwd = vals[0];
-                       j = 1;
+                       if (tmp.gr_passwd != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
+
+                       tmp.gr_passwd = (char *)in->dict[d].val[k][0];
                }
-               else if ((g->gr_gid == (gid_t)-2) && (!strcmp("gid", key)))
+               else if (!strcmp(in->dict[d].key[k], "gr_gid"))
                {
-                       g->gr_gid = atoi(vals[0]);
-                       if ((g->gr_gid == 0) && (strcmp(vals[0], "0"))) g->gr_gid = -2;
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       tmp.gr_gid = atoi(in->dict[d].val[k][0]);
                }
-               else if ((g->gr_mem == NULL) && (!strcmp("users", key)))
+               else if (!strcmp(in->dict[d].key[k], "gr_mem"))
                {
-                       g->gr_mem = vals;
-                       j = nvals;
-                       vals = NULL;
-               }
+                       if (tmp.gr_mem != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
 
-               free(key);
-               if (vals != NULL)
-               {
-                       for (; j < nvals; j++) free(vals[j]);
-                       free(vals);
+                       tmp.gr_mem = (char **)in->dict[d].val[k];
                }
        }
 
-       if (g->gr_name == NULL) g->gr_name = strdup("");
-       if (g->gr_passwd == NULL) g->gr_passwd = strdup("");
-       if (g->gr_mem == NULL) g->gr_mem = (char **)calloc(1, sizeof(char *));
+       if (tmp.gr_name == NULL) tmp.gr_name = "";
+       if (tmp.gr_passwd == NULL) tmp.gr_passwd = "";
+       if (tmp.gr_mem == NULL) tmp.gr_mem = empty;
 
-       return g;
-}
-
-static struct group *
-copy_group(struct group *in)
-{
-       struct group *g;
-       int i, len;
-
-       if (in == NULL) return NULL;
-
-       g = (struct group *)calloc(1, sizeof(struct group));
-
-       g->gr_name = LU_COPY_STRING(in->gr_name);
-       g->gr_passwd = LU_COPY_STRING(in->gr_passwd);
-       g->gr_gid = in->gr_gid;
-
-       len = 0;
-       if (in->gr_mem != NULL)
-       {
-               for (len = 0; in->gr_mem[len] != NULL; len++);
-       }
-
-       g->gr_mem = (char **)calloc(len + 1, sizeof(char *));
-       for (i = 0; i < len; i++)
-       {
-               g->gr_mem[i] = strdup(in->gr_mem[i]);
-       }
-
-       return g;
+       return copy_group(&tmp);
 }
 
 static int
@@ -298,110 +234,75 @@ copy_group_r(struct group *in, struct group *out, char *buffer, int buflen)
 }
 
 static void
-recycle_group(struct lu_thread_info *tdata, struct group *in)
+cache_group(struct group *gr)
 {
-       struct group *g;
+       struct group *grcache;
 
-       if (tdata == NULL) return;
-       g = (struct group *)tdata->lu_entry;
+       if (gr == NULL) return;
 
-       if (in == NULL)
-       {
-               free_group(g);
-               tdata->lu_entry = NULL;
-       }
+       pthread_mutex_lock(&_group_cache_lock);
 
-       if (tdata->lu_entry == NULL)
-       {
-               tdata->lu_entry = in;
-               return;
-       }
+       grcache = copy_group(gr);
 
-       free_group_data(g);
+       if (_group_cache[_group_cache_index] != NULL) LI_ils_free(_group_cache[_group_cache_index], ENTRY_SIZE);
 
-       g->gr_name = in->gr_name;
-       g->gr_passwd = in->gr_passwd;
-       g->gr_gid = in->gr_gid;
-       g->gr_mem = in->gr_mem;
+       _group_cache[_group_cache_index] = grcache;
+       _group_cache_index = (_group_cache_index + 1) % GROUP_CACHE_SIZE;
 
-       free(in);
-}
+       _group_cache_init = 1;
 
-__private_extern__ unsigned int
-get_group_cache_ttl()
-{
-       return _group_cache_ttl;
+       pthread_mutex_unlock(&_group_cache_lock);
 }
 
-__private_extern__ void
-set_group_cache_ttl(unsigned int ttl)
+static int
+group_cache_check()
 {
-       int i;
-
-       pthread_mutex_lock(&_group_cache_lock);
+       uint32_t i, status;
 
-       _group_cache_ttl = ttl;
+       /* don't consult cache if it has not been initialized */
+       if (_group_cache_init == 0) return 1;
 
-       if (ttl == 0)
-       {
-               for (i = 0; i < GROUP_CACHE_SIZE; i++)
-               {
-                       if (_group_cache[i] == NULL) continue;
+       status = LI_L1_cache_check(ENTRY_KEY);
 
-                       free_group((struct group *)_group_cache[i]);
-                       _group_cache[i] = NULL;
-                       _group_cache_best_before[i] = 0;
-               }
-       }
+       /* don't consult cache if it is disabled or if we can't validate */
+       if ((status == LI_L1_CACHE_DISABLED) || (status == LI_L1_CACHE_FAILED)) return 1;
 
-       pthread_mutex_unlock(&_group_cache_lock);
-}
-
-static void
-cache_group(struct group *gr)
-{
-       struct timeval now;
-       struct group *grcache;
-
-       if (_group_cache_ttl == 0) return;
-       if (gr == NULL) return;
+       /* return 0 if cache is OK */
+       if (status == LI_L1_CACHE_OK) return 0;
 
+       /* flush cache */
        pthread_mutex_lock(&_group_cache_lock);
 
-       grcache = copy_group(gr);
-
-       gettimeofday(&now, NULL);
+       for (i = 0; i < GROUP_CACHE_SIZE; i++)
+       {
+               LI_ils_free(_group_cache[i], ENTRY_SIZE);
+               _group_cache[i] = NULL;
+       }
 
-       if (_group_cache[_group_cache_index] != NULL)
-               free_group((struct group *)_group_cache[_group_cache_index]);
-
-       _group_cache[_group_cache_index] = grcache;
-       _group_cache_best_before[_group_cache_index] = now.tv_sec + _group_cache_ttl;
-       _group_cache_index = (_group_cache_index + 1) % GROUP_CACHE_SIZE;
+       _group_cache_index = 0;
 
        pthread_mutex_unlock(&_group_cache_lock);
+
+       /* don't consult cache - it's now empty */
+       return 1;
 }
 
+
 static struct group *
 cache_getgrnam(const char *name)
 {
        int i;
        struct group *gr, *res;
-       struct timeval now;
 
-       if (_group_cache_ttl == 0) return NULL;
        if (name == NULL) return NULL;
+       if (group_cache_check() != 0) return NULL;
 
        pthread_mutex_lock(&_group_cache_lock);
 
-       gettimeofday(&now, NULL);
-
        for (i = 0; i < GROUP_CACHE_SIZE; i++)
        {
-               if (_group_cache_best_before[i] == 0) continue;
-               if ((unsigned int)now.tv_sec > _group_cache_best_before[i]) continue;
-
                gr = (struct group *)_group_cache[i];
+               if (gr == NULL) continue;
 
                if (gr->gr_name == NULL) continue;
 
@@ -422,20 +323,15 @@ cache_getgrgid(int gid)
 {
        int i;
        struct group *gr, *res;
-       struct timeval now;
 
-       if (_group_cache_ttl == 0) return NULL;
+       if (group_cache_check() != 0) return NULL;
 
        pthread_mutex_lock(&_group_cache_lock);
 
-       gettimeofday(&now, NULL);
-
        for (i = 0; i < GROUP_CACHE_SIZE; i++)
        {
-               if (_group_cache_best_before[i] == 0) continue;
-               if ((unsigned int)now.tv_sec > _group_cache_best_before[i]) continue;
-
                gr = (struct group *)_group_cache[i];
+               if (gr == NULL) continue;
 
                if ((gid_t)gid == gr->gr_gid)
                {
@@ -450,122 +346,21 @@ cache_getgrgid(int gid)
 }
 
 static struct group *
-lu_getgrgid(int gid)
+ds_getgrgid(int gid)
 {
-       struct group *g;
-       unsigned int datalen;
-       XDR inxdr;
        static int proc = -1;
-       int count;
-       char *lookup_buf;
-
-       if (proc < 0)
-       {
-               if (_lookup_link(_lu_port, "getgrgid", &proc) != KERN_SUCCESS)
-               {
-                       return NULL;
-               }
-       }
-
-       gid = htonl(gid);
-       datalen = 0;
-       lookup_buf = NULL;
-
-       if (_lookup_all(_lu_port, proc, (unit *)&gid, 1, &lookup_buf, &datalen) != KERN_SUCCESS)
-       {
-               return NULL;
-       }
+       char val[16];
 
-       datalen *= BYTES_PER_XDR_UNIT;
-       if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
-
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
-
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       g = extract_group(&inxdr);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-
-       return g;
+       snprintf(val, sizeof(val), "%d", gid);
+       return (struct group *)LI_getone("getgrgid", &proc, extract_group, "gid", val);
 }
 
 static struct group *
-lu_getgrnam(const char *name)
+ds_getgrnam(const char *name)
 {
-       struct group *g;
-       unsigned int datalen;
-       char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT];
-       XDR outxdr;
-       XDR inxdr;
        static int proc = -1;
-       int count;
-       char *lookup_buf;
-
-       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, (_lu_string *)&name))
-       {
-               xdr_destroy(&outxdr);
-               return NULL;
-       }
 
-       datalen = 0;
-       lookup_buf = NULL;
-
-       if (_lookup_all(_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;
-       if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
-
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
-
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       g = extract_group(&inxdr);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-
-       return g;
+       return (struct group *)LI_getone("getgrnam", &proc, extract_group, "name", name);
 }
 
 /*
@@ -577,50 +372,69 @@ lu_getgrnam(const char *name)
  * returns -1 if adding the gid would overflow the list
  *
  */
-static int
-_add_group(int gid, int *list, int *listcount, int max, int dupok, int laststatus)
+static void
+_add_group(gid_t g, gid_t **list, uint32_t *count, int dupok)
 {
-       int i, n, addit, status;
-
-       if (laststatus != 0) return laststatus;
+       uint32_t i, n, addit;
 
-       status = 0;
        addit = 1;
-       n = *listcount;
+
+       if (list == NULL) return;
+       if (*list == NULL) *count = 0;
+
+       n = *count;
 
        if (dupok == 0) 
        {
                for (i = 0; (i < n) && (addit == 1); i++)
                {
-                       if (list[i] == gid) addit = 0;
+                       if ((*list)[i] == g) addit = 0;
                }
        }
 
-       if (addit == 0) return 0;
-       if (n >= max) return -1;
+       if (addit == 0) return;
 
-       list[n] = gid;
-       *listcount = n + 1;
-       return 0;
+       if (*list == NULL) *list = (gid_t *)calloc(1, sizeof(gid_t));
+       else *list = (gid_t *)realloc(*list, (n + 1) * sizeof(gid_t));
+
+       if (*list == NULL)
+       {
+               *count = 0;
+               return;
+       }
+
+       (*list)[n] = g;
+       *count = n + 1;
 }
 
 int
 _old_getgrouplist(const char *uname, int basegid, int *groups, int *grpcnt)
 {
        struct group *grp;
-       int i, status, maxgroups;
+       int i, status;
+       uint32_t maxgroups, gg_count;
+       gid_t *gg_list;
 
        status = 0;
-       maxgroups = *grpcnt;
+       maxgroups = (uint32_t)*grpcnt;
        *grpcnt = 0;
 
+       gg_list = NULL;
+       gg_count = 0;
+
        /*
         * 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.
         */
-       status = _add_group(basegid, groups, grpcnt, maxgroups, 0, status);
-       status = _add_group(basegid, groups, grpcnt, maxgroups, 1, status);
+       _add_group(basegid, &gg_list, &gg_count, 0);
+       _add_group(basegid, &gg_list, &gg_count, 1);
+
+       if (gg_list == NULL)
+       {
+               errno = ENOMEM;
+               return 0;
+       }
 
        /*
         * Scan the group file to find additional groups.
@@ -634,25 +448,31 @@ _old_getgrouplist(const char *uname, int basegid, int *groups, int *grpcnt)
                {
                        if (!strcmp(grp->gr_mem[i], uname))
                        {
-                               status = _add_group(grp->gr_gid, groups, grpcnt, maxgroups, 0, status);
+                               _add_group(grp->gr_gid, &gg_list, &gg_count, 0);
                                break;
                        }
                }
        }
 
        endgrent();
-       return status;
-}
 
-static int
-_mbr_running()
-{
-       kern_return_t status;
+       if (gg_list == NULL)
+       {
+               errno = ENOMEM;
+               return 0;
+       }
 
-       status = bootstrap_look_up(bootstrap_port, MEMBERD_NAME, &mbr_port);
-       if (status != KERN_SUCCESS) return 0;
-       if (mbr_port == MACH_PORT_NULL) return 0;
-       return 1;
+       /* return -1 if the user-supplied list is too short */
+       status = 0;
+       if (gg_count > maxgroups) status = -1;
+
+       /* copy at most maxgroups gids from gg_list to groups */
+       for (i = 0; (i < maxgroups) && (i < gg_count); i++) groups[i] = gg_list[i];
+
+       *grpcnt = gg_count;
+       free(gg_list);
+
+       return status;
 }
 
 /*
@@ -665,243 +485,250 @@ _mbr_running()
  * This adds to 6533 bytes (until one of the constants changes)
  */
 #define MAXPWBUF (MAXLOGNAME + 1 + _PASSWORD_LEN + 1 + MAXPATHLEN + 1 + MAXPATHLEN + 1 + 4098)
+
+/*
+ * This is the "old" client side routine from memberd.
+ * It now talks to DirectoryService, but it retains the old style where
+ * the caller provides an array for the output gids.  It fetches the 
+ * user's gids from DS, then copies as many as possible into the
+ * caller-supplied array.
+ */
 static int
 mbr_getgrouplist(const char *name, int basegid, int *groups, int *grpcnt, int dupbase)
 {
        struct passwd p, *res;
        char buf[MAXPWBUF];
        kern_return_t kstatus;
-       uint32_t i, count;
+       uint32_t i, maxgroups, count, gidptrCnt, gg_count;
        int pwstatus;
        GIDArray gids;
-       int status, maxgroups;
-       security_token_t token;
+       gid_t *gidptr, *gg_list;
+       int status, do_dealloc;
+       audit_token_t token;
 
-       status = 0;
-
-       if (mbr_port == MACH_PORT_NULL) return status;
-       if (name == NULL) return status;
-       if (groups == NULL) return status;
-       if (grpcnt == NULL) return status;
+       if (_ds_port == MACH_PORT_NULL) return 0;
+       if (name == NULL) return 0;
+       if (groups == NULL) return 0;
+       if (grpcnt == NULL) return 0;
 
-       maxgroups = *grpcnt;
+       maxgroups = (uint32_t)(*grpcnt);
+       do_dealloc = 0;
        *grpcnt = 0;
+       gidptr = NULL;
+       gidptrCnt = 0;
+       gg_list = NULL;
+       gg_count = 0;
+       
+       _add_group(basegid, &gg_list, &gg_count, 0);
+       if (dupbase != 0) _add_group(basegid, &gg_list, &gg_count, 1);
 
-       status = _add_group(basegid, groups, grpcnt, maxgroups, 0, status);
-       if (dupbase != 0) status = _add_group(basegid, groups, grpcnt, maxgroups, 1, status);
-
-       if (status != 0) return status;
+       if (gg_list == NULL)
+       {
+               errno = ENOMEM;
+               return 0;
+       }
 
        memset(&p, 0, sizeof(struct passwd));
        memset(buf, 0, sizeof(buf));
        res = NULL;
 
        pwstatus = getpwnam_r(name, &p, buf, MAXPWBUF, &res);
-       if (pwstatus != 0) return status;
-       if (res == NULL) return status;
-
-       token.val[0] = -1;
-       token.val[1] = -1;
+       if (pwstatus != 0) return 0;
+       if (res == NULL) return 0;
 
        count = 0;
-       kstatus = _mbr_GetGroups(mbr_port, p.pw_uid, &count, gids, &token);
-       if (kstatus != KERN_SUCCESS) return status;
-       if (token.val[0] != 0) return KERN_FAILURE;
+       memset(&token, 0, sizeof(audit_token_t));
+
+       kstatus = 0;
+       if (maxgroups > 16)
+       {
+               kstatus = memberdDSmig_GetAllGroups(_ds_port, p.pw_uid, &count, &gidptr, &gidptrCnt, &token);
+               do_dealloc = 1;
+       }
+       else
+       {
+               kstatus = memberdDSmig_GetGroups(_ds_port, p.pw_uid, &count, gids, &token);
+               gidptr = (gid_t *)gids;
+       }
+
+       if (kstatus != KERN_SUCCESS) return 0;
+       if (audit_token_uid(token) != 0)
+       {
+               if (gg_list != NULL) free(gg_list);
+               return 0;
+       }
+
+       for (i = 0; i < count; i++) _add_group(gidptr[i], &gg_list, &gg_count, 0);
+
+       if ((do_dealloc == 1) && (gidptr != NULL)) vm_deallocate(mach_task_self(), (vm_address_t)gidptr, gidptrCnt);
 
-       for (i = 0; (i < count) && (status == 0); i++) 
+       if (gg_list == NULL)
        {
-               status = _add_group(gids[i], groups, grpcnt, maxgroups, 0, status);
+               errno = ENOMEM;
+               return 0;
        }
 
+       /* return -1 if the user-supplied list is too short */
+       status = 0;
+       if (gg_count > maxgroups) status = -1;
+
+       /* copy at most maxgroups gids from gg_list to groups */
+       for (i = 0; (i < maxgroups) && (i < gg_count); i++) groups[i] = gg_list[i];
+
+       *grpcnt = gg_count;
+       free(gg_list);
+
        return status;
 }
 
-static int
-lu_getgrouplist(const char *name, int basegid, int *groups, int *grpcnt, int dupbase)
+/*
+ * This is the "modern" routine for fetching the group list for a user.
+ * The grplist output parameter is allocated and filled with the gids
+ * of the specified user's groups.  Returns the number of gids in the
+ * list or -1 on failure.  Caller must free() the returns grplist.
+ */
+static int32_t
+ds_getgrouplist(const char *name, gid_t basegid, gid_t **grplist, int dupbase)
 {
-       unsigned int datalen;
-       XDR outxdr;
-       XDR inxdr;
-       static int proc = -1;
-       char *lookup_buf;
-       char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT];
-       int gid;
-       int i, count;
-       int status, maxgroups;
-
-       status = 0;
+       struct passwd p, *res;
+       char buf[MAXPWBUF];
+       kern_return_t kstatus;
+       uint32_t i, count, gidptrCnt, out_count;
+       int pwstatus;
+       gid_t *gidptr, *out_list;
+       audit_token_t token;
 
-       if (name == NULL) return status;
-       if (groups == NULL) return status;
-       if (grpcnt == NULL) return status;
+       if (_ds_port == MACH_PORT_NULL) return -1;
+       if (name == NULL) return -1;
+       if (grplist == NULL) return -1;
 
-       maxgroups = *grpcnt;
-       *grpcnt = 0;
+       gidptr = NULL;
+       gidptrCnt = 0;
+       out_list = NULL;
+       out_count = 0;
 
-       status = _add_group(basegid, groups, grpcnt, maxgroups, 0, status);
-       if (dupbase != 0) status = _add_group(basegid, groups, grpcnt, maxgroups, 1, status);
+       _add_group(basegid, &out_list, &out_count, 0);
+       if (dupbase != 0) _add_group(basegid, &out_list, &out_count, 1);
 
-       if (status != 0) return status;
+       if (out_list == NULL) return -1;
 
-       if (proc < 0)
+       memset(&p, 0, sizeof(struct passwd));
+       memset(buf, 0, sizeof(buf));
+       res = NULL;
+       
+       pwstatus = getpwnam_r(name, &p, buf, MAXPWBUF, &res);
+       if (pwstatus != 0) return -1;
+       if (res == NULL) return -1;
+       
+       count = 0;
+       memset(&token, 0, sizeof(audit_token_t));
+       
+       kstatus = memberdDSmig_GetAllGroups(_ds_port, p.pw_uid, &count, &gidptr, &gidptrCnt, &token);
+       if (kstatus != KERN_SUCCESS)
        {
-               if (_lookup_link(_lu_port, "initgroups", &proc) != KERN_SUCCESS) return status;
+               if (out_list != NULL) free(out_list);
+               return -1;
        }
 
-       xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE);
-       if (!xdr__lu_string(&outxdr, (_lu_string *)&name))
+       if (audit_token_uid(token) != 0)
        {
-               xdr_destroy(&outxdr);
-               return status;
+               if (out_list != NULL) free(out_list);
+               if (gidptr != NULL) vm_deallocate(mach_task_self(), (vm_address_t)gidptr, gidptrCnt);
+               return -1;
        }
 
-       datalen = 0;
-       lookup_buf = NULL;
+       for (i = 0; i < count; i++) _add_group(gidptr[i], &out_list, &out_count, 0);
 
-       if (_lookup_all(_lu_port, proc, (unit *)namebuf, xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, &lookup_buf, &datalen) != KERN_SUCCESS)
-       {
-               xdr_destroy(&outxdr);
-               return status;
-       }
+       if (gidptr != NULL) vm_deallocate(mach_task_self(), (vm_address_t)gidptr, gidptrCnt);
 
-       xdr_destroy(&outxdr);
-
-       datalen *= BYTES_PER_XDR_UNIT;
-       if ((lookup_buf == NULL) || (datalen == 0)) return 0;
+       *grplist = out_list;
+       return out_count;
+}
 
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
+static int
+getgrouplist_internal(const char *name, int basegid, int *groups, int *grpcnt, int dupbase)
+{
+       int status, in_grpcnt;
 
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return status;
-       }
+       /*
+        * The man page says that the grpcnt parameter will be set to the actual number
+        * of groups that were found.  Unfortunately, older impementations of this API
+        * have always set grpcnt to the number of groups that are being returned.
+        * To prevent regressions in callers of this API, we respect the old and 
+        * incorrect implementation.
+        */
 
-       for (i = 0; (i < count) && (status == 0); i++)
-       {
-               if (!xdr_int(&inxdr, &gid)) break;
-               status = _add_group(gid, groups, grpcnt, maxgroups, 0, status);
-       }
+       in_grpcnt = *grpcnt;
+       status = 0;
 
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
+       if (_ds_running()) status = mbr_getgrouplist(name, basegid, groups, grpcnt, dupbase);
+       else status = _old_getgrouplist(name, basegid, groups, grpcnt);
 
+       if ((status < 0) && (*grpcnt > in_grpcnt)) *grpcnt = in_grpcnt;
        return status;
 }
 
-static int
-getgrouplist_internal(const char *name, int basegid, int *groups, int *grpcnt, int dupbase)
+static int32_t
+getgrouplist_internal_2(const char *name, gid_t basegid, gid_t **gid_list, int dupbase)
 {
-       if (_mbr_running())
-       {
-               return mbr_getgrouplist(name, basegid, groups, grpcnt, dupbase);
-       }
+       int status;
+       uint32_t gid_count;
 
-       if (_lu_running())
-       {
-               return lu_getgrouplist(name, basegid, groups, grpcnt, dupbase);
-       }
+       if (name == NULL) return -1;
+       if (gid_list == NULL) return -1;
 
-       return _old_getgrouplist(name, basegid, groups, grpcnt);
+       *gid_list = NULL;
+
+       if (_ds_running()) return ds_getgrouplist(name, basegid, gid_list, dupbase);
+
+       gid_count = NGROUPS + 1;
+       *gid_list = (gid_t *)calloc(gid_count, sizeof(gid_t));
+       if (*gid_list == NULL) return -1;
+
+       status = _old_getgrouplist(name, basegid, (int *)gid_list, (int *)&gid_count);
+       if (status < 0) return -1;
+       return gid_count;
 }
 
 int
 getgrouplist(const char *uname, int agroup, int *groups, int *grpcnt)
 {
-       return getgrouplist_internal(uname, agroup, groups, grpcnt, 1);
+       return getgrouplist_internal(uname, agroup, groups, grpcnt, 0);
 }
 
-static void
-lu_endgrent(void)
+int32_t
+getgrouplist_2(const char *uname, gid_t agroup, gid_t **groups)
 {
-       struct lu_thread_info *tdata;
+       return getgrouplist_internal_2(uname, agroup, groups, 0);
+}
 
-       tdata = _lu_data_create_key(_lu_data_key_group, free_lu_thread_info_group);
-       _lu_data_free_vm_xdr(tdata);
+static void
+ds_endgrent(void)
+{
+       LI_data_free_kvarray(LI_data_find_key(ENTRY_KEY));
 }
 
-static int
-lu_setgrent(void)
+static void
+ds_setgrent(void)
 {
-       lu_endgrent();
-       return 1;
+       ds_endgrent();
 }
 
 static struct group *
-lu_getgrent()
+ds_getgrent()
 {
-       struct group *g;
        static int proc = -1;
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_group, free_lu_thread_info_group);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_group, tdata);
-       }
-
-       if (tdata->lu_vm == NULL)
-       {
-               if (proc < 0)
-               {
-                       if (_lookup_link(_lu_port, "getgrent", &proc) != KERN_SUCCESS)
-                       {
-                               lu_endgrent();
-                               return NULL;
-                       }
-               }
-
-               if (_lookup_all(_lu_port, proc, NULL, 0, &(tdata->lu_vm), &(tdata->lu_vm_length)) != KERN_SUCCESS)
-               {
-                       lu_endgrent();
-                       return NULL;
-               }
 
-               /* mig stubs measure size in words (4 bytes) */
-               tdata->lu_vm_length *= 4;
-
-               if (tdata->lu_xdr != NULL)
-               {
-                       xdr_destroy(tdata->lu_xdr);
-                       free(tdata->lu_xdr);
-               }
-               tdata->lu_xdr = (XDR *)calloc(1, sizeof(XDR));
-
-               xdrmem_create(tdata->lu_xdr, tdata->lu_vm, tdata->lu_vm_length, XDR_DECODE);
-               if (!xdr_int(tdata->lu_xdr, &tdata->lu_vm_cursor))
-               {
-                       lu_endgrent();
-                       return NULL;
-               }
-       }
-
-       if (tdata->lu_vm_cursor == 0)
-       {
-               lu_endgrent();
-               return NULL;
-       }
-
-       g = extract_group(tdata->lu_xdr);
-       if (g == NULL)
-       {
-               lu_endgrent();
-               return NULL;
-       }
-
-       tdata->lu_vm_cursor--;
-
-       return g;
+       return (struct group *)LI_getent("getgrent", &proc, extract_group, ENTRY_KEY, ENTRY_SIZE);
 }
 
 static struct group *
 getgr_internal(const char *name, gid_t gid, int source)
 {
        struct group *res = NULL;
-       int from_cache;
+       int add_to_cache;
 
-       from_cache = 0;
+       add_to_cache = 0;
        res = NULL;
 
        switch (source)
@@ -917,27 +744,29 @@ getgr_internal(const char *name, gid_t gid, int source)
 
        if (res != NULL)
        {
-               from_cache = 1;
        }
-       else if (_lu_running())
+       else if (_ds_running())
        {
                switch (source)
                {
                        case GR_GET_NAME:
-                               res = lu_getgrnam(name);
+                               res = ds_getgrnam(name);
                                break;
                        case GR_GET_GID:
-                               res = lu_getgrgid(gid);
+                               res = ds_getgrgid(gid);
                                break;
                        case GR_GET_ENT:
-                               res = lu_getgrent();
+                               res = ds_getgrent();
                                break;
                        default: res = NULL;
                }
+
+               if (res != NULL) add_to_cache = 1;
        }
        else
        {
                pthread_mutex_lock(&_group_lock);
+
                switch (source)
                {
                        case GR_GET_NAME:
@@ -951,10 +780,11 @@ getgr_internal(const char *name, gid_t gid, int source)
                                break;
                        default: res = NULL;
                }
+
                pthread_mutex_unlock(&_group_lock);
        }
 
-       if (from_cache == 0) cache_group(res);
+       if (add_to_cache == 1) cache_group(res);
 
        return res;
 }
@@ -963,19 +793,15 @@ static struct group *
 getgr(const char *name, gid_t gid, int source)
 {
        struct group *res = NULL;
-       struct lu_thread_info *tdata;
+       struct li_thread_info *tdata;
 
-       tdata = _lu_data_create_key(_lu_data_key_group, free_lu_thread_info_group);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_group, tdata);
-       }
+       tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
+       if (tdata == NULL) return NULL;
 
        res = getgr_internal(name, gid, source);
 
-       recycle_group(tdata, res);
-       return (struct group *)tdata->lu_entry;
+       LI_data_recycle(tdata, res, ENTRY_SIZE);
+       return (struct group *)tdata->li_entry;
 }
 
 static int
@@ -985,19 +811,15 @@ getgr_r(const char *name, gid_t gid, int source, struct group *grp, char *buffer
        int status;
 
        *result = NULL;
-       errno = 0;
 
        res = getgr_internal(name, gid, source);
-       if (res == NULL) return -1;
+       if (res == NULL) return 0;
 
        status = copy_group_r(res, grp, buffer, bufsize);
-       free_group(res);
 
-       if (status != 0)
-       {
-               errno = ERANGE;
-               return -1;
-       }
+       LI_ils_free(res, ENTRY_SIZE);
+
+       if (status != 0) return ERANGE;
 
        *result = grp;
        return 0;
@@ -1006,14 +828,28 @@ getgr_r(const char *name, gid_t gid, int source, struct group *grp, char *buffer
 int
 initgroups(const char *name, int basegid)
 {
-       int status, ngroups, groups[NGROUPS];
+       int status, pwstatus, ngroups, groups[NGROUPS];
+       struct passwd p, *res;
+       char buf[MAXPWBUF];
+
+       /* get the UID for this user */
+       memset(&p, 0, sizeof(struct passwd));
+       memset(buf, 0, sizeof(buf));
+       res = NULL;
+
+       pwstatus = getpwnam_r(name, &p, buf, MAXPWBUF, &res);
+       if (pwstatus != 0) return -1;
+       if (res == NULL) return -1;
 
        ngroups = NGROUPS;
 
        status = getgrouplist_internal(name, basegid, groups, &ngroups, 0);
        if (status < 0) return status;
 
-       return setgroups(ngroups, groups);
+       status = syscall(SYS_initgroups, ngroups, groups, p.pw_uid);
+       if (status < 0) return -1;
+
+       return 0;
 }
 
 struct group *
@@ -1037,7 +873,7 @@ getgrent(void)
 int
 setgrent(void)
 {
-       if (_lu_running()) lu_setgrent();
+       if (_ds_running()) ds_setgrent();
        else _old_setgrent();
        return 1;
 }
@@ -1045,7 +881,7 @@ setgrent(void)
 void
 endgrent(void)
 {
-       if (_lu_running()) lu_endgrent();
+       if (_ds_running()) ds_endgrent();
        else _old_endgrent();
 }
 
index d9d178efaf23be50c2ffef851ddb1b1a074d94e4..d671afa0ac00adc5cb83e1f2bd90bb257974431a 100644 (file)
 #include <ifaddrs.h>
 #include <sys/types.h>
 #include <netinet/if_ether.h>
-
-#include "_lu_types.h"
-#include "lookup.h"
 #include "lu_host.h"
-#include "lu_utils.h"
 
-#define HOST_CACHE_SIZE 10
-#define DEFAULT_HOST_CACHE_TTL 10
+#define ENTRY_SIZE sizeof(struct hostent)
+#define ENTRY_KEY _li_data_key_host
+#define HOST_CACHE_SIZE 20
 
 #define CACHE_BYNAME 0
 #define CACHE_BYADDR 1
 
 static pthread_mutex_t _host_cache_lock = PTHREAD_MUTEX_INITIALIZER;
-static unsigned int _host_cache_ttl = DEFAULT_HOST_CACHE_TTL;
 
-static void *_host_byname_cache[HOST_CACHE_SIZE] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
-static int _host_byname_cache_flavor[HOST_CACHE_SIZE] = { WANT_NOTHING, WANT_NOTHING, WANT_NOTHING, WANT_NOTHING, WANT_NOTHING, WANT_NOTHING, WANT_NOTHING, WANT_NOTHING, WANT_NOTHING, WANT_NOTHING };
-static unsigned int _host_byname_cache_best_before[HOST_CACHE_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+static void *_host_byname_cache[HOST_CACHE_SIZE] = { NULL };
+static int _host_byname_cache_flavor[HOST_CACHE_SIZE] = { WANT_NOTHING };
 static unsigned int _host_byname_cache_index = 0;
 
-static void *_host_byaddr_cache[HOST_CACHE_SIZE] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
-static int _host_byaddr_cache_flavor[HOST_CACHE_SIZE] = { WANT_NOTHING, WANT_NOTHING, WANT_NOTHING, WANT_NOTHING, WANT_NOTHING, WANT_NOTHING, WANT_NOTHING, WANT_NOTHING, WANT_NOTHING, WANT_NOTHING };
-static unsigned int _host_byaddr_cache_best_before[HOST_CACHE_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+static void *_host_byaddr_cache[HOST_CACHE_SIZE] = { NULL };
+static int _host_byaddr_cache_flavor[HOST_CACHE_SIZE] = { WANT_NOTHING };
 static unsigned int _host_byaddr_cache_index = 0;
 
+static unsigned int _host_cache_init = 0;
+
 static pthread_mutex_t _host_lock = PTHREAD_MUTEX_INITIALIZER;
 
-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();
+__private_extern__ struct hostent *LI_files_gethostbyname(const char *name);
+__private_extern__ struct hostent *LI_files_gethostbyname2(const char *name, int af);
+__private_extern__ struct hostent *LI_files_gethostbyaddr(const void *addr, socklen_t len, int type);
+__private_extern__ struct hostent *LI_files_gethostent();
+__private_extern__ void LI_files_sethostent(int stayopen);
+__private_extern__ void LI_files_endhostent();
 
 extern int _old_ether_hostton(const char *, struct ether_addr *);
 extern int _old_ether_ntohost(char *, const struct ether_addr *);
 
-extern mach_port_t _lu_port;
-extern int _lu_running(void);
-
 extern int h_errno;
 
 #define IPV6_ADDR_LEN 16
 #define IPV4_ADDR_LEN 4
 
-__private_extern__ void
-free_host_data(struct hostent *h)
+void
+freehostent(struct hostent *h)
 {
        char **aliases;
        int i;
 
-       if (h == NULL) return;
+       if (LI_ils_free(h, ENTRY_SIZE) == 0) return;
 
        if (h->h_name != NULL) free(h->h_name);
 
@@ -105,431 +98,399 @@ free_host_data(struct hostent *h)
                for (i = 0; h->h_addr_list[i] != NULL; i++) free(h->h_addr_list[i]);
                free(h->h_addr_list);
        }
+       free(h);
 }
 
-void
-freehostent(struct hostent *h)
+static struct hostent *
+copy_host(struct hostent *in)
 {
-       if (h == NULL) return;
-       free_host_data(h);
-       free(h);
+       if (in == NULL) return NULL;
+
+       if (in->h_addrtype == AF_INET)
+               return (struct hostent *)LI_ils_create("s*44a", in->h_name, in->h_aliases, in->h_addrtype, in->h_length, in->h_addr_list);
+
+       if (in->h_addrtype == AF_INET6)
+               return (struct hostent *)LI_ils_create("s*44c", in->h_name, in->h_aliases, in->h_addrtype, in->h_length, in->h_addr_list);
+
+       return NULL;
 }
 
 static void
-free_lu_thread_info_host(void *x)
+_free_addr_list(char **l)
 {
-       struct lu_thread_info *tdata;
+       int i;
 
-       if (x == NULL) return;
+       if (l == NULL) return;
+       for (i = 0; l[i] != NULL; i++) free(l[i]);
+       free(l);
+}
 
-       tdata = (struct lu_thread_info *)x;
-       
-       if (tdata->lu_entry != NULL)
+/* map ipv4 addresses and append to v6 list */
+static int 
+_map_v4(char ***v6, uint32_t n6, char **v4, uint32_t n4)
+{
+       struct in6_addr a6;
+       uint32_t i;
+
+       a6.__u6_addr.__u6_addr32[0] = 0x00000000;
+       a6.__u6_addr.__u6_addr32[1] = 0x00000000;
+       a6.__u6_addr.__u6_addr32[2] = htonl(0x0000ffff);
+
+       if (*v6 == NULL)
+       {
+               *v6 = (char **)calloc(n4 + 1, sizeof(char *));
+       }
+       else
        {
-               freehostent((struct hostent *)tdata->lu_entry);
-               tdata->lu_entry = NULL;
+               *v6 = (char **)reallocf(*v6, (n6 + n4 + 1) * sizeof(char *));
        }
 
-       _lu_data_free_vm_xdr(tdata);
+       if (*v6 == NULL) return -1;
+
+       for (i = 0; i < n4; i++)
+       {
+               (*v6)[n6] = (char *)calloc(1, IPV6_ADDR_LEN);
+               if ((*v6)[n6] == NULL) return -1;
 
-       free(tdata);
+               memcpy(&(a6.__u6_addr.__u6_addr32[3]), v4[i], IPV4_ADDR_LEN);
+               memcpy((*v6)[n6], &(a6.__u6_addr.__u6_addr32[0]), IPV6_ADDR_LEN);
+
+               n6++;
+       }
+
+       return 0;
 }
 
 __private_extern__ struct hostent *
-extract_host(XDR *xdr, int want, int *err)
+extract_host(kvarray_t *in, int want)
 {
-       struct hostent *h;
-       int i, j, nvals, nkeys, status, addr_len;
-       int family, addr_count, map_count;
-       struct in_addr addr;
-       struct in6_addr addr6;
-       char *key, **vals, **mapvals;
-
-       mapvals = NULL;
-       map_count = 0;
+       struct hostent tmp, *out;
+       uint32_t i, d, k, kcount, vcount, v4count, v6count;
+       int status, addr_len;
+       int family, addr_count;
+       struct in_addr a4;
+       struct in6_addr a6;
+       char **v4addrs, **v6addrs;
+       char *empty[1];
+
+       v4addrs = NULL;
+       v6addrs = NULL;
+       v4count = 0;
+       v6count = 0;
        addr_count = 0;
-       addr_len = sizeof(u_long *);
+       addr_len = sizeof(void *);
 
-       if (xdr == NULL)
-       {
-               *err = NO_RECOVERY;
-               return NULL;
-       }
+       if (in == NULL) return NULL;
 
-       if (!xdr_int(xdr, &nkeys))
-       {
-               *err = NO_RECOVERY;
-               return NULL;
-       }
+       d = in->curr;
+       in->curr++;
 
-       h = (struct hostent *)calloc(1, sizeof(struct hostent));
+       if (d >= in->count) return NULL;
+
+       empty[0] = NULL;
+       memset(&tmp, 0, ENTRY_SIZE);
 
        family = AF_INET;
-       h->h_length = IPV4_ADDR_LEN;
+       tmp.h_length = IPV4_ADDR_LEN;
 
-       if (want > WANT_A4_ONLY)
+       if (want != WANT_A4_ONLY)
        {
                family = AF_INET6;
-               h->h_length = IPV6_ADDR_LEN;
+               tmp.h_length = IPV6_ADDR_LEN;
        }
 
-       h->h_addrtype = family; 
-
-       for (i = 0; i < nkeys; i++)
-       {
-               key = NULL;
-               vals = NULL;
-               nvals = 0;
+       tmp.h_addrtype = family;
 
-               status = _lu_xdr_attribute(xdr, &key, &vals, &nvals);
-               if (status < 0)
-               {
-                       freehostent(h);
-                       *err = NO_RECOVERY;
-                       return NULL;
-               }
+       kcount = in->dict[d].kcount;
 
-               if (nvals == 0)
+       for (k = 0; k < kcount; k++)
+       {
+               if (!strcmp(in->dict[d].key[k], "h_name"))
                {
-                       free(key);
-                       continue;
-               }
+                       if (tmp.h_name != NULL) continue;
 
-               j = 0;
+                       vcount = in->dict[d].vcount[k];
+                       if (vcount == 0) continue;
 
-               if ((h->h_name == NULL) && (!strcmp("name", key)))
-               {
-                       h->h_name = vals[0];
-                       if (nvals > 1)
-                       {
-                               h->h_aliases = (char **)calloc(nvals, sizeof(char *));
-                               for (j = 1; j < nvals; j++) h->h_aliases[j-1] = vals[j];
-                       }
-                       j = nvals;
+                       tmp.h_name = (char *)in->dict[d].val[k][0];
                }
-               else if ((family == AF_INET) && (h->h_addr_list == NULL) && (!strcmp("ip_address", key)))
+               else if (!strcmp(in->dict[d].key[k], "h_aliases"))
                {
-                       addr_count = nvals;
-                       h->h_addr_list = (char **)calloc(nvals + 1, addr_len);
+                       if (tmp.h_aliases != NULL) continue;
 
-                       for (j = 0; j < nvals; j++)
-                       {
-                               addr.s_addr = 0;
-                               inet_aton(vals[j], &addr);
-                               h->h_addr_list[j] = (char *)calloc(1, IPV4_ADDR_LEN);
-                               memmove(h->h_addr_list[j], &(addr.s_addr), IPV4_ADDR_LEN);
-                       }
+                       vcount = in->dict[d].vcount[k];
+                       if (vcount == 0) continue;
 
-                       h->h_addr_list[nvals] = NULL;
-                       j = 0;
+                       tmp.h_aliases = (char **)in->dict[d].val[k];
                }
-               else if ((family == AF_INET6) && (h->h_addr_list == NULL) && (!strcmp("ipv6_address", key)))
+               else if (!strcmp(in->dict[d].key[k], "h_ipv4_addr_list"))
                {
-                       addr_count = nvals;
-                       h->h_addr_list = (char **)calloc(nvals + 1, addr_len);
+                       if (v4addrs != NULL) continue;
+
+                       v4count = in->dict[d].vcount[k];
+                       if (v4count == 0) continue;
 
-                       for (j = 0; j < nvals; j++)
+                       v4addrs = (char **)calloc(v4count + 1, sizeof(char *));
+                       if (v4addrs == NULL)
                        {
-                               memset(&addr6, 0, sizeof(struct in6_addr));
-                               inet_pton(family, vals[j], &addr6);
-                               h->h_addr_list[j] = (char *)calloc(1, IPV6_ADDR_LEN);
-                               memmove(h->h_addr_list[j], &(addr6.__u6_addr.__u6_addr32[0]), IPV6_ADDR_LEN);
+                               _free_addr_list(v6addrs);
+                               return NULL;
                        }
 
-                       h->h_addr_list[nvals] = NULL;
-                       j = 0;
-               }
-               else if ((family == AF_INET6) && (mapvals == NULL) && (!strcmp("ip_address", key)))
-               {
-                       map_count = nvals;
-                       mapvals = vals;
-                       vals = NULL;
+                       for (i = 0; i < v4count; i++)
+                       {
+                               v4addrs[i] = calloc(1, IPV4_ADDR_LEN);
+                               if (v4addrs[i] == NULL)
+                               {
+                                       _free_addr_list(v4addrs);
+                                       _free_addr_list(v6addrs);
+                                       return NULL;
+                               }
+
+                               memset(&a4, 0, sizeof(struct in_addr));
+                               status = inet_pton(AF_INET, in->dict[d].val[k][i], &a4);
+                               if (status != 1)
+                               {
+                                       _free_addr_list(v4addrs);
+                                       _free_addr_list(v6addrs);
+                                       return NULL;
+                               }
+
+                               memcpy(v4addrs[i], &a4, IPV4_ADDR_LEN);
+                       }
                }
-
-               free(key);
-               if (vals != NULL)
+               else if (!strcmp(in->dict[d].key[k], "h_ipv6_addr_list"))
                {
-                       for (; j < nvals; j++) free(vals[j]);
-                       free(vals);
-               }
-       }
+                       if (v6addrs != NULL) continue;
 
-       if ((mapvals != NULL) && (want > WANT_A6_ONLY))
-       {
-               addr6.__u6_addr.__u6_addr32[0] = 0x00000000;
-               addr6.__u6_addr.__u6_addr32[1] = 0x00000000;
-               addr6.__u6_addr.__u6_addr32[2] = htonl(0x0000ffff);
+                       v6count = in->dict[d].vcount[k];
+                       if (v6count == 0) continue;
 
-               if (addr_count == 0)
-               {
-                       h->h_addr_list = (char **)calloc(map_count + 1, addr_len);
-               }
-               else
-               {
-                       h->h_addr_list = (char **)realloc(h->h_addr_list, (addr_count + map_count + 1) * addr_len);
-               }
+                       v6addrs = (char **)calloc(v6count + 1, sizeof(char *));
+                       if (v6addrs == NULL)
+                       {
+                               _free_addr_list(v4addrs);
+                               return NULL;
+                       }
 
-               for (i = 0; i < map_count; i++)
-               {
-                       addr.s_addr = 0;
-                       inet_aton(mapvals[i], &addr);
-                       h->h_addr_list[addr_count] = (char *)calloc(1, IPV6_ADDR_LEN);
-                       memmove(&(addr6.__u6_addr.__u6_addr32[3]), &(addr.s_addr), IPV4_ADDR_LEN);
-                       memcpy(h->h_addr_list[addr_count++], &(addr6.__u6_addr.__u6_addr32[0]), IPV6_ADDR_LEN);
+                       for (i = 0; i < v6count; i++)
+                       {
+                               v6addrs[i] = calloc(1, IPV6_ADDR_LEN);
+                               if (v6addrs[i] == NULL)
+                               {
+                                       _free_addr_list(v4addrs);
+                                       _free_addr_list(v6addrs);
+                                       return NULL;
+                               }
+
+                               memset(&a6, 0, sizeof(struct in6_addr));
+                               status = inet_pton(AF_INET6, in->dict[d].val[k][i], &a6);
+                               if (status != 1)
+                               {
+                                       _free_addr_list(v4addrs);
+                                       _free_addr_list(v6addrs);
+                                       return NULL;
+                               }
+
+                               memcpy(v6addrs[i], &(a6.__u6_addr.__u6_addr32[0]), IPV6_ADDR_LEN);
+                       }
                }
-
-               h->h_addr_list[addr_count] = NULL;
        }
 
-       if (mapvals != NULL)
-       {
-               for (i = 0; i < map_count; i++) free(mapvals[i]);
-               free(mapvals);
-       }
+       if (tmp.h_name == NULL) tmp.h_name = "";
+       if (tmp.h_aliases == NULL) tmp.h_aliases = empty;
 
-       if (h->h_addr_list == NULL) 
+       if (want == WANT_A4_ONLY)
        {
-               freehostent(h);
-               *err = NO_DATA;
-               return NULL;
-       }
-
-       if (h->h_name == NULL) h->h_name = strdup("");
-       if (h->h_aliases == NULL) h->h_aliases = (char **)calloc(1, sizeof(char *));
-
-       return h;
-}
-
-static struct hostent *
-copy_host(struct hostent *in)
-{
-       int i, len, addr_len;
-       struct hostent *h;
+               _free_addr_list(v6addrs);
+               if (v4addrs == NULL) return NULL;
 
-       if (in == NULL) return NULL;
-
-       h = (struct hostent *)calloc(1, sizeof(struct hostent));
-
-       h->h_name = LU_COPY_STRING(in->h_name);
+               tmp.h_addr_list = v4addrs;
+               out = copy_host(&tmp);
+               _free_addr_list(v4addrs);
 
-       len = 0;
-       if (in->h_aliases != NULL)
-       {
-               for (len = 0; in->h_aliases[len] != NULL; len++);
+               return out;
        }
-
-       h->h_aliases = (char **)calloc(len + 1, sizeof(char *));
-       for (i = 0; i < len; i++)
+       else if ((want == WANT_A6_ONLY) || ((want == WANT_A6_OR_MAPPED_A4_IF_NO_A6) && (v6count > 0)))
        {
-               h->h_aliases[i] = strdup(in->h_aliases[i]);
-       }
+               _free_addr_list(v4addrs);
+               if (v6addrs == NULL) return NULL;
 
-       h->h_addrtype = in->h_addrtype;
-       h->h_length = in->h_length;
+               tmp.h_addr_list = v6addrs;
+               out = copy_host(&tmp);
+               _free_addr_list(v6addrs);
 
-       len = 0;
-       if (in->h_addr_list != NULL)
-       {
-               for (len = 0; in->h_addr_list[len] != NULL; len++);
-       }
-
-       addr_len = sizeof(u_long *);
-       h->h_addr_list = (char **)calloc(len + 1, addr_len);
-       for (i = 0; i < len; i++)
-       {
-               h->h_addr_list[i] = (char *)malloc(h->h_length);
-               memmove(h->h_addr_list[i], in->h_addr_list[i], h->h_length);
+               return out;
        }
 
-       return h;
-}
-
-static void
-recycle_host(struct lu_thread_info *tdata, struct hostent *in)
-{
-       struct hostent *h;
-
-       if (tdata == NULL) return;
-       h = (struct hostent *)tdata->lu_entry;
+       /*
+        * At this point, want is WANT_A6_PLUS_MAPPED_A4, WANT_MAPPED_A4_ONLY,
+        * or WANT_A6_OR_MAPPED_A4_IF_NO_A6.  In the last case, there are no ipv6
+        * addresses, so that case degenerates into WANT_MAPPED_A4_ONLY.
+        */
+       if (want == WANT_A6_OR_MAPPED_A4_IF_NO_A6) want = WANT_MAPPED_A4_ONLY;
 
-       if (in == NULL)
+       if (want == WANT_MAPPED_A4_ONLY)
        {
-               freehostent(h);
-               tdata->lu_entry = NULL;
+               _free_addr_list(v6addrs);
+               v6addrs = NULL;
+               v6count = 0;
        }
 
-       if (tdata->lu_entry == NULL)
+       status = _map_v4(&v6addrs, v6count, v4addrs, v4count);
+       _free_addr_list(v4addrs);
+       if (status != 0)
        {
-               tdata->lu_entry = in;
-               return;
+               _free_addr_list(v6addrs);
+               return NULL;
        }
 
-       free_host_data(h);
+       if (v6addrs == NULL) return NULL;
 
-       h->h_name = in->h_name;
-       h->h_aliases = in->h_aliases;
-       h->h_addrtype = in->h_addrtype;
-       h->h_length = in->h_length;
-       h->h_addr_list = in->h_addr_list;
+       tmp.h_addr_list = v6addrs;
+       out = copy_host(&tmp);
+       _free_addr_list(v6addrs);
 
-       free(in);
+       return out;
 }
 
 __private_extern__ struct hostent *
 fake_hostent(const char *name, struct in_addr addr)
 {
-       int addr_len;
-       struct hostent *h;
+       struct hostent tmp;
+       char *addrs[2];
+       char *aliases[1];
 
        if (name == NULL) return NULL;
 
-       h = (struct hostent *)calloc(1, sizeof(struct hostent));
-
-       h->h_name = strdup(name);
-
-       h->h_aliases = (char **)calloc(1, sizeof(char *));
+       memset(&tmp, 0, ENTRY_SIZE);
 
-       h->h_addrtype = AF_INET;
-       h->h_length = sizeof(long);
+       tmp.h_name = (char *)name;
+       tmp.h_addrtype = AF_INET;
+       tmp.h_length = IPV4_ADDR_LEN;
+       tmp.h_addr_list = addrs;
+       addrs[0] = (char *)&(addr.s_addr);
+       addrs[1] = NULL;
+       tmp.h_aliases = aliases;
+       aliases[0] = NULL;
 
-       addr_len = sizeof(u_long *);
-       h->h_addr_list = (char **)calloc(2, addr_len);
-
-       h->h_addr_list[0] = (char *)malloc(h->h_length);
-       memmove(h->h_addr_list[0], &(addr.s_addr), h->h_length);
-
-       return h;
+       return copy_host(&tmp);
 }
 
 __private_extern__ struct hostent *
 fake_hostent6(const char *name, struct in6_addr addr)
 {
-       int addr_len;
-       struct hostent *h;
+       struct hostent tmp;
+       char *addrs[2];
+       char *aliases[1];
 
        if (name == NULL) return NULL;
 
-       h = (struct hostent *)calloc(1, sizeof(struct hostent));
-
-       h->h_name = strdup(name);
-
-       h->h_aliases = (char **)calloc(1, sizeof(char *));
-
-       h->h_addrtype = AF_INET6;
-       h->h_length = 16;
+       memset(&tmp, 0, ENTRY_SIZE);
 
-       addr_len = sizeof(u_long *);
-       h->h_addr_list = (char **)calloc(2, addr_len);
+       tmp.h_name = (char *)name;
+       tmp.h_addrtype = AF_INET6;
+       tmp.h_length = IPV6_ADDR_LEN;
+       tmp.h_addr_list = addrs;
+       addrs[0] = (char *)&(addr.__u6_addr.__u6_addr32[0]);
+       addrs[1] = NULL;
+       tmp.h_aliases = aliases;
+       aliases[0] = NULL;
 
-       h->h_addr_list[0] = (char *)malloc(h->h_length);
-       memmove(h->h_addr_list[0], &(addr.__u6_addr.__u6_addr32[0]), h->h_length);
-
-       return h;
-}
-
-__private_extern__ unsigned int
-get_host_cache_ttl()
-{
-       return _host_cache_ttl;
-}
-
-__private_extern__ void
-set_host_cache_ttl(unsigned int ttl)
-{
-       int i;
-
-       pthread_mutex_lock(&_host_cache_lock);
-
-       _host_cache_ttl = ttl;
-
-       if (ttl == 0)
-       {
-               for (i = 0; i < HOST_CACHE_SIZE; i++)
-               {
-                       if (_host_byname_cache[i] == NULL) continue;
-
-                       freehostent((struct hostent *)_host_byname_cache[i]);
-                       _host_byname_cache[i] = NULL;
-                       _host_byname_cache_flavor[i] = WANT_NOTHING;
-                       _host_byname_cache_best_before[i] = 0;
-               }
-
-               for (i = 0; i < HOST_CACHE_SIZE; i++)
-               {
-                       if (_host_byaddr_cache[i] == NULL) continue;
-
-                       freehostent((struct hostent *)_host_byaddr_cache[i]);
-                       _host_byaddr_cache[i] = NULL;
-                       _host_byaddr_cache_flavor[i] = WANT_NOTHING;
-                       _host_byaddr_cache_best_before[i] = 0;
-               }
-       }
-
-       pthread_mutex_unlock(&_host_cache_lock);
+       return copy_host(&tmp);
 }
 
 static void
 cache_host(struct hostent *h, int want, int how)
 {
-       struct timeval now;
        struct hostent *hcache;
 
-       if (_host_cache_ttl == 0) return;
        if (h == NULL) return;
 
        pthread_mutex_lock(&_host_cache_lock);
 
        hcache = copy_host(h);
 
-       gettimeofday(&now, NULL);
-
        if (how == CACHE_BYNAME)
        {
-               if (_host_byname_cache[_host_byname_cache_index] != NULL)
-                       freehostent((struct hostent *)_host_byname_cache[_host_byname_cache_index]);
+               if (_host_byname_cache[_host_byname_cache_index] != NULL) LI_ils_free(_host_byname_cache[_host_byname_cache_index], ENTRY_SIZE);
 
                _host_byname_cache[_host_byname_cache_index] = hcache;
                _host_byname_cache_flavor[_host_byname_cache_index] = want;
-               _host_byname_cache_best_before[_host_byname_cache_index] = now.tv_sec + _host_cache_ttl;
                _host_byname_cache_index = (_host_byname_cache_index + 1) % HOST_CACHE_SIZE;
        }
        else
        {
-               if (_host_byaddr_cache[_host_byaddr_cache_index] != NULL)
-                       freehostent((struct hostent *)_host_byaddr_cache[_host_byaddr_cache_index]);
+               if (_host_byaddr_cache[_host_byaddr_cache_index] != NULL) LI_ils_free(_host_byaddr_cache[_host_byaddr_cache_index], ENTRY_SIZE);
 
                _host_byaddr_cache[_host_byaddr_cache_index] = hcache;
                _host_byaddr_cache_flavor[_host_byaddr_cache_index] = want;
-               _host_byaddr_cache_best_before[_host_byaddr_cache_index] = now.tv_sec + _host_cache_ttl;
                _host_byaddr_cache_index = (_host_byaddr_cache_index + 1) % HOST_CACHE_SIZE;
        }
 
+       _host_cache_init = 1;
+
        pthread_mutex_unlock(&_host_cache_lock);
 }
 
+static int
+host_cache_check()
+{
+       uint32_t i, status;
+
+       /* don't consult cache if it has not been initialized */
+       if (_host_cache_init == 0) return 1;
+
+       status = LI_L1_cache_check(ENTRY_KEY);
+
+       /* don't consult cache if it is disabled or if we can't validate */
+       if ((status == LI_L1_CACHE_DISABLED) || (status == LI_L1_CACHE_FAILED)) return 1;
+
+       /* return 0 if cache is OK */
+       if (status == LI_L1_CACHE_OK) return 0;
+
+       /* flush cache */
+       pthread_mutex_lock(&_host_cache_lock);
+
+       for (i = 0; i < HOST_CACHE_SIZE; i++)
+       {
+               LI_ils_free(_host_byname_cache[i], ENTRY_SIZE);
+               _host_byname_cache[i] = NULL;
+               _host_byname_cache_flavor[i] = WANT_NOTHING;
+
+               LI_ils_free(_host_byaddr_cache[i], ENTRY_SIZE);
+               _host_byaddr_cache[i] = NULL;
+               _host_byaddr_cache_flavor[i] = WANT_NOTHING;
+       }
+
+       _host_byname_cache_index = 0;
+       _host_byaddr_cache_index = 0;
+
+       pthread_mutex_unlock(&_host_cache_lock);
+
+       /* don't consult cache - it's now empty */
+       return 1;
+}
+
+
 static struct hostent *
 cache_gethostbyname(const char *name, int want)
 {
        int i;
        struct hostent *h, *res;
        char **aliases;
-       struct timeval now;
 
-       if (_host_cache_ttl == 0) return NULL;
        if (name == NULL) return NULL;
+       if (host_cache_check() != 0) return NULL;
 
        pthread_mutex_lock(&_host_cache_lock);
 
-       gettimeofday(&now, NULL);
-
        for (i = 0; i < HOST_CACHE_SIZE; i++)
        {
-               if (_host_byname_cache_best_before[i] == 0) continue;
-               if ((unsigned int)now.tv_sec > _host_byname_cache_best_before[i]) continue;
-
                if (_host_byname_cache_flavor[i] != want) continue;
 
                h = (struct hostent *)_host_byname_cache[i];
+               if (h == NULL) continue;
 
                if (h->h_name != NULL) 
                {
@@ -568,26 +529,21 @@ cache_gethostbyaddr(const char *addr, int want)
 {
        int i, j, len;
        struct hostent *h, *res;
-       struct timeval now;
 
        if (addr == NULL) return NULL;
-       if (_host_cache_ttl == 0) return NULL;
+       if (host_cache_check() != 0) return NULL;
 
        pthread_mutex_lock(&_host_cache_lock);
 
-       gettimeofday(&now, NULL);
-
        len = IPV4_ADDR_LEN;
        if (want > WANT_A4_ONLY) len = IPV6_ADDR_LEN;
 
        for (i = 0; i < HOST_CACHE_SIZE; i++)
        {
-               if (_host_byaddr_cache_best_before[i] == 0) continue;
-               if ((unsigned int)now.tv_sec > _host_byaddr_cache_best_before[i]) continue;
-
                if (_host_byaddr_cache_flavor[i] != want) continue;
 
                h = (struct hostent *)_host_byaddr_cache[i];
+               if (h == NULL) continue;
 
                if (h->h_addr_list == NULL) continue;
 
@@ -607,316 +563,277 @@ cache_gethostbyaddr(const char *addr, int want)
 }
 
 static struct hostent *
-lu_gethostbyaddr(const char *addr, int want, int *err)
+ds_gethostbyaddr(const char *paddr, uint32_t family, int *err)
 {
-       struct hostent *h;
-       unsigned int datalen;
-       XDR inxdr;
-       static int proc4 = -1;
-       static int proc6 = -1;
-       char *lookup_buf, *address;
-       int proc, count, len, family;
+       struct hostent *entry;
+       kvbuf_t *request;
+       kvarray_t *reply;
+       kern_return_t status;
+       static int proc = -1;
        struct in_addr addr4;
        struct in6_addr addr6;
+       char tmp[64];
+       int want;
 
-       family = AF_INET;
-       len = IPV4_ADDR_LEN;
-       if ((want == WANT_A6_ONLY) || (want == WANT_A6_PLUS_MAPPED_A4))
+       if (paddr == NULL)
        {
-               family = AF_INET6;
-               len = IPV6_ADDR_LEN;
+               if (err != NULL) *err = NO_RECOVERY;
+               return NULL;
        }
 
-       if ((family == AF_INET) && (proc4 < 0))
+       if (proc < 0)
        {
-               if (_lookup_link(_lu_port, "gethostbyaddr", &proc4) != KERN_SUCCESS)
+               status = LI_DSLookupGetProcedureNumber("gethostbyaddr", &proc);
+               if (status != KERN_SUCCESS)
                {
-                       *err = NO_RECOVERY;
+                       if (err != NULL) *err = NO_RECOVERY;
                        return NULL;
                }
        }
-       else if ((family == AF_INET6) && (proc6 < 0))
+
+       memset(&addr4, 0, sizeof(struct in_addr));
+       memset(&addr6, 0, sizeof(struct in6_addr));
+       memset(tmp, 0, sizeof(tmp));
+       want = WANT_A4_ONLY;
+
+       if (family == AF_INET)
        {
-               if (_lookup_link(_lu_port, "getipv6nodebyaddr", &proc6) != KERN_SUCCESS)
+               want = WANT_A4_ONLY;
+               memcpy(&(addr4.s_addr), paddr, IPV4_ADDR_LEN);
+               if (inet_ntop(family, &addr4, tmp, sizeof(tmp)) == NULL)
                {
-                       *err = NO_RECOVERY;
+                       if (err != NULL) *err = NO_RECOVERY;
                        return NULL;
                }
        }
-
-       address = NULL;
-
-       if (family == AF_INET)
+       else if (family == AF_INET6)
        {
-               memmove(&(addr4.s_addr), addr, IPV4_ADDR_LEN);
-               address = (char *)&(addr4.s_addr);
-               proc = proc4;
+               want = WANT_A6_ONLY;
+               memcpy(addr6.s6_addr, paddr, IPV6_ADDR_LEN);
+               if (inet_ntop(family, &addr6, tmp, sizeof(tmp)) == NULL)
+               {
+                       if (err != NULL) *err = NO_RECOVERY;
+                       return NULL;
+               }
        }
        else
        {
-               memmove(&(addr6.__u6_addr.__u6_addr32[0]), addr, IPV6_ADDR_LEN);
-               addr6.__u6_addr.__u6_addr32[0] = htonl(addr6.__u6_addr.__u6_addr32[0]);
-               addr6.__u6_addr.__u6_addr32[1] = htonl(addr6.__u6_addr.__u6_addr32[1]);
-               addr6.__u6_addr.__u6_addr32[2] = htonl(addr6.__u6_addr.__u6_addr32[2]);
-               addr6.__u6_addr.__u6_addr32[3] = htonl(addr6.__u6_addr.__u6_addr32[3]);
-               address = (char *)&(addr6.__u6_addr.__u6_addr32[0]);
-               proc = proc6;
-       }
-               
-       datalen = 0;
-       lookup_buf = NULL;
-
-       if (_lookup_all(_lu_port, proc, (unit *)address, len / BYTES_PER_XDR_UNIT, &lookup_buf, &datalen) != KERN_SUCCESS)
-       {
-               *err = HOST_NOT_FOUND;
+               if (err != NULL) *err = NO_RECOVERY;
                return NULL;
        }
 
-       datalen *= BYTES_PER_XDR_UNIT;
-       if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
-
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
-
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
+       request = kvbuf_query("ksku", "address", tmp, "family", family);
+       if (request == NULL)
        {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               *err = NO_RECOVERY;
+               if (err != NULL) *err = NO_RECOVERY;
                return NULL;
        }
 
-       if (count == 0)
+       reply = NULL;
+       status = LI_DSLookupQuery(proc, request, &reply);
+       kvbuf_free(request);
+
+       if (status != KERN_SUCCESS)
        {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               *err = HOST_NOT_FOUND;
+               if (err != NULL) *err = NO_RECOVERY;
                return NULL;
        }
 
-       *err = 0;
+       if (err != NULL) *err = 0;
+       entry = extract_host(reply, want);
 
-       h = extract_host(&inxdr, want, err);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
+       if ((entry == NULL) && (err != NULL)) *err = HOST_NOT_FOUND;
+       kvarray_free(reply);
 
-       return h;
+       return entry;
 }
 
 static struct hostent *
-lu_gethostbyname(const char *name, int want, int *err)
+ds_gethostbyname(const char *name, uint32_t want, int *err)
 {
-       struct hostent *h;
-       unsigned int datalen;
-       char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT];
-       XDR outxdr;
-       XDR inxdr;
-       static int proc4 = -1;
-       static int proc6 = -1;
-       char *lookup_buf;
-       int proc, count, family;
+       struct hostent *entry;
+       kvbuf_t *request;
+       kvarray_t *reply;
+       kern_return_t status;
+       static int proc = -1;
+       uint32_t want4, want6;
 
-       family = AF_INET;
-       if (want > WANT_A4_ONLY) family = AF_INET6;
+       want4 = 1;
+       want6 = 1;
+
+       if (want == WANT_A4_ONLY) want6 = 0;
+       else if (want == WANT_A6_ONLY) want4 = 0;
+       else if (WANT_MAPPED_A4_ONLY) want6 = 0;
 
-       if (((want == WANT_MAPPED_A4_ONLY) || (family == AF_INET)) && (proc4 < 0))
+       if (name == NULL)
        {
-               if (_lookup_link(_lu_port, "gethostbyname", &proc4) != KERN_SUCCESS)
-               {
-                       *err = NO_RECOVERY;
-                       return NULL;
-               }
+               if (err != NULL) *err = NO_RECOVERY;
+               return NULL;
        }
-       else if ((family == AF_INET6) && (proc6 < 0))
+
+       if (proc < 0)
        {
-               if (_lookup_link(_lu_port, "getipv6nodebyname", &proc6) != KERN_SUCCESS)
+               status = LI_DSLookupGetProcedureNumber("gethostbyname", &proc);
+               if (status != KERN_SUCCESS)
                {
-                       *err = NO_RECOVERY;
+                       if (err != NULL) *err = NO_RECOVERY;
                        return NULL;
                }
        }
 
-       proc = proc4;
-       if ((family == AF_INET6) && (want != WANT_MAPPED_A4_ONLY)) proc = proc6;
-
-       xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE);
-       if (!xdr__lu_string(&outxdr, (_lu_string *)&name))
+       request = kvbuf_query("kskuku", "name", name, "ipv4", want4, "ipv6", want6);
+       if (request == NULL)
        {
-               xdr_destroy(&outxdr);
-               *err = NO_RECOVERY;
+               if (err != NULL) *err = NO_RECOVERY;
                return NULL;
        }
 
-       datalen = 0;
-       lookup_buf = NULL;
+       reply = NULL;
+       status = LI_DSLookupQuery(proc, request, &reply);
+       kvbuf_free(request);
 
-       if (_lookup_all(_lu_port, proc, (unit *)namebuf, xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, &lookup_buf, &datalen) != KERN_SUCCESS)
+       if (status != KERN_SUCCESS)
        {
-               xdr_destroy(&outxdr);
-               *err = HOST_NOT_FOUND;
+               if (err != NULL) *err = NO_RECOVERY;
                return NULL;
        }
 
-       xdr_destroy(&outxdr);
-
-       datalen *= BYTES_PER_XDR_UNIT;
-       if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
-
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
+       if (err != NULL) *err = 0;
+       entry = extract_host(reply, want);
+       if ((entry == NULL) && (err != NULL)) *err = HOST_NOT_FOUND;
+       kvarray_free(reply);
 
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               *err = NO_RECOVERY;
-               return NULL;
-       }
-
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               *err = HOST_NOT_FOUND;
-               return NULL;
-       }
-
-       *err = 0;
-
-       h = extract_host(&inxdr, want, err);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-
-       return h;
+       return entry;
 }
 
 static void
-lu_endhostent()
+ds_endhostent()
 {
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_host, free_lu_thread_info_host);
-       _lu_data_free_vm_xdr(tdata);
+       LI_data_free_kvarray(LI_data_find_key(ENTRY_KEY));
 }
 
 static void
-lu_sethostent()
+ds_sethostent()
 {
-       lu_endhostent();
+       ds_endhostent();
 }
 
 static struct hostent *
-lu_gethostent(int want, int *err)
+ds_gethostent(int *err)
 {
+       struct hostent *entry;
+       struct li_thread_info *tdata;
+       kvarray_t *reply, *vma;
+       kern_return_t status;
        static int proc = -1;
-       struct lu_thread_info *tdata;
-       struct hostent *h;
 
-       tdata = _lu_data_create_key(_lu_data_key_host, free_lu_thread_info_host);
+       tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
        if (tdata == NULL)
        {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_host, tdata);
+               if (err != NULL) *err = NO_RECOVERY;
+               return NULL;
        }
 
-       if (tdata->lu_vm == NULL)
+       if (tdata->li_vm == NULL)
        {
                if (proc < 0)
                {
-                       if (_lookup_link(_lu_port, "gethostent", &proc) != KERN_SUCCESS)
+                       status = LI_DSLookupGetProcedureNumber("gethostent", &proc);
+                       if (status != KERN_SUCCESS)
                        {
-                               lu_endhostent();
-                               *err = NO_RECOVERY;
+                               if (err != NULL) *err = NO_RECOVERY;
+                               LI_data_free_kvarray(tdata);
+                               tdata->li_vm = NULL;
                                return NULL;
                        }
                }
 
-               if (_lookup_all(_lu_port, proc, NULL, 0, &(tdata->lu_vm), &(tdata->lu_vm_length)) != KERN_SUCCESS)
+               reply = NULL;
+               status = LI_DSLookupQuery(proc, NULL, &reply);
+
+               if (status != KERN_SUCCESS)
                {
-                       lu_endhostent();
-                       *err = HOST_NOT_FOUND;
+                       if (err != NULL) *err = NO_RECOVERY;
+                       LI_data_free_kvarray(tdata);
+                       tdata->li_vm = NULL;
                        return NULL;
                }
 
-               /* mig stubs measure size in words (4 bytes) */
-               tdata->lu_vm_length *= 4;
+               tdata->li_vm = (char *)reply;
+       }
 
-               if (tdata->lu_xdr != NULL)
-               {
-                       xdr_destroy(tdata->lu_xdr);
-                       free(tdata->lu_xdr);
-               }
-               tdata->lu_xdr = (XDR *)calloc(1, sizeof(XDR));
+       if (err != NULL) *err = 0;
 
-               xdrmem_create(tdata->lu_xdr, tdata->lu_vm, tdata->lu_vm_length, XDR_DECODE);
-               if (!xdr_int(tdata->lu_xdr, &tdata->lu_vm_cursor))
-               {
-                       lu_endhostent();
-                       *err = NO_RECOVERY;
-                       return NULL;
-               }
+       vma = (kvarray_t *)(tdata->li_vm);
+       if (vma == NULL)
+       {
+               if (err != NULL) *err = HOST_NOT_FOUND;
+               return NULL;
        }
 
-       if (tdata->lu_vm_cursor == 0)
+       /*
+        * gethostent only returns IPv4 addresses, but the reply
+        * from Directory Service may contain a mix of IPv4 and Ipv6
+        * entries.  extract_host will return NULL if the current
+        * dictionary is not the family we want, so we loop until
+        * we get the next IPv4 entry or we run out of entries.
+        */
+       entry = NULL;
+       while ((vma->curr < vma->count) && (entry == NULL))
        {
-               lu_endhostent();
-               *err = HOST_NOT_FOUND;
-               return NULL;
+               entry = extract_host(vma, WANT_A4_ONLY);
        }
 
-       h = extract_host(tdata->lu_xdr, want, err);
-       if (h == NULL)
+       if (entry == NULL)
        {
-               lu_endhostent();
-               *err = HOST_NOT_FOUND;
+               if (err != NULL) *err = HOST_NOT_FOUND;
+               LI_data_free_kvarray(tdata);
+               tdata->li_vm = NULL;
                return NULL;
        }
 
-       *err = 0;
-       tdata->lu_vm_cursor--;
-       
-       return h;
+       return entry;
 }
 
 static struct hostent *
-gethostbyaddrerrno(const char *addr, int len, int type, int *err)
+gethostbyaddrerrno(const char *addr, int len, uint32_t family, int *err)
 {
        struct hostent *res = NULL;
-       int want, from_cache;
+       int want, add_to_cache;
 
-       *err = 0;
+       if (err != NULL) *err = 0;
 
        want = WANT_A4_ONLY;
-       if (type == AF_INET6) want = WANT_A6_ONLY;
+       if (family == AF_INET6) want = WANT_A6_ONLY;
 
-       if ((type == AF_INET6) && (len == 16) && (is_a4_mapped((const char *)addr) || is_a4_compat((const char *)addr)))
+       if ((family == AF_INET6) && (len == IPV6_ADDR_LEN) && (is_a4_mapped((const char *)addr) || is_a4_compat((const char *)addr)))
        {
                addr += 12;
                len = 4;
-               type = AF_INET;
+               family = AF_INET;
                want = WANT_MAPPED_A4_ONLY;
        }
 
-       from_cache = 0;
+       add_to_cache = 0;
        res = cache_gethostbyaddr(addr, want);
 
        if (res != NULL)
        {
-               from_cache = 1;
        }
-       else if (_lu_running())
+       else if (_ds_running())
        {
-               res = lu_gethostbyaddr(addr, want, err);
+               res = ds_gethostbyaddr(addr, family, err);
+               if (res != NULL) add_to_cache = 1;
        }
        else
        {
                pthread_mutex_lock(&_host_lock);
-               res = copy_host(_old_gethostbyaddr(addr, len, type));
-               *err = h_errno;
+               res = copy_host(LI_files_gethostbyaddr(addr, len, family));
+               if (err != NULL) *err = h_errno;
                pthread_mutex_unlock(&_host_lock);
        }
 
-       if (from_cache == 0) cache_host(res, want, CACHE_BYADDR);
+       if (add_to_cache == 1) cache_host(res, want, CACHE_BYADDR);
 
        return res;
 }
@@ -925,33 +842,26 @@ struct hostent *
 gethostbyaddr(const void *addr, socklen_t len, int type)
 {
        struct hostent *res;
-       struct lu_thread_info *tdata;
+       struct li_thread_info *tdata;
 
        res = gethostbyaddrerrno(addr, len, type, &h_errno);
-       if (res == NULL)
-       {
-               return NULL;
-       }
+       if (res == NULL) return NULL;
 
-       tdata = _lu_data_create_key(_lu_data_key_host, free_lu_thread_info_host);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_host, tdata);
-       }
+       tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
+       if (tdata == NULL) return NULL;
 
-       recycle_host(tdata, res);
-       return (struct hostent *)tdata->lu_entry;
+       LI_data_recycle(tdata, res, ENTRY_SIZE);
+       return (struct hostent *)tdata->li_entry;
 }
-       
+
 struct hostent *
 gethostbynameerrno(const char *name, int *err)
 {
        struct hostent *res = NULL;
        struct in_addr addr;
-       int i, is_addr, from_cache;
+       int i, is_addr, add_to_cache;
 
-       *err = 0;
+       if (err != NULL) *err = 0;
 
        /* 
         * If name is all dots and digits without a trailing dot, 
@@ -962,13 +872,13 @@ gethostbynameerrno(const char *name, int *err)
         */
        if (name == NULL)
        {
-               *err = HOST_NOT_FOUND;
+               if (err != NULL) *err = HOST_NOT_FOUND;
                return NULL;
        }
 
        if (name[0] == '\0')
        {
-               *err = HOST_NOT_FOUND;
+               if (err != NULL) *err = HOST_NOT_FOUND;
                return NULL;
        }
 
@@ -984,13 +894,13 @@ gethostbynameerrno(const char *name, int *err)
        if ((is_addr == 1) && (name[i-1] == '.')) is_addr = 0;
 
        res = NULL;
-       from_cache = 0;
+       add_to_cache = 0;
 
        if (is_addr == 1)
        {
                if (inet_aton(name, &addr) == 0)
                {
-                       *err = HOST_NOT_FOUND;
+                       if (err != NULL) *err = HOST_NOT_FOUND;
                        return NULL;
                }
                res = fake_hostent(name, addr);
@@ -1003,17 +913,17 @@ gethostbynameerrno(const char *name, int *err)
 
        if (res != NULL)
        {
-               from_cache = 1;
        }
-       else if (_lu_running())
+       else if (_ds_running())
        {
-               res = lu_gethostbyname(name, WANT_A4_ONLY, err);
+               res = ds_gethostbyname(name, WANT_A4_ONLY, err);
+               if (res != NULL) add_to_cache = 1;
        }
        else
        {
                pthread_mutex_lock(&_host_lock);
-               res = copy_host(_old_gethostbyname(name));
-               *err = h_errno;
+               res = copy_host(LI_files_gethostbyname(name));
+               if (err != NULL) *err = h_errno;
                pthread_mutex_unlock(&_host_lock);
        }
 
@@ -1021,7 +931,7 @@ gethostbynameerrno(const char *name, int *err)
        {
                if (inet_aton(name, &addr) == 0)
                {
-                       *err = HOST_NOT_FOUND;
+                       if (err != NULL) *err = HOST_NOT_FOUND;
                        return NULL;
                }
 
@@ -1032,7 +942,7 @@ gethostbynameerrno(const char *name, int *err)
                }
        }
 
-       if (from_cache == 0) cache_host(res, WANT_A4_ONLY, CACHE_BYNAME);
+       if (add_to_cache == 1) cache_host(res, WANT_A4_ONLY, CACHE_BYNAME);
 
        return res;
 }
@@ -1041,89 +951,74 @@ struct hostent *
 gethostbyname(const char *name)
 {
        struct hostent *res;
-       struct lu_thread_info *tdata;
+       struct li_thread_info *tdata;
 
        res = gethostbynameerrno(name, &h_errno);
-       if (res == NULL)
-       {
-               return NULL;
-       }
+       if (res == NULL) return NULL;
 
-       tdata = _lu_data_create_key(_lu_data_key_host, free_lu_thread_info_host);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_host, tdata);
-       }
+       tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
+       if (tdata == NULL) return NULL;
 
-       recycle_host(tdata, res);
-       return (struct hostent *)tdata->lu_entry;
+       LI_data_recycle(tdata, res, ENTRY_SIZE);
+       return (struct hostent *)tdata->li_entry;
 }
 
 struct hostent *
-gethostbyname2(const char *name, int af)
+gethostbyname2(const char *name, int family)
 {
        struct hostent *res;
-       struct lu_thread_info *tdata;
+       struct li_thread_info *tdata;
 
-       res = getipnodebyname(name, af, 0, &h_errno);
+       res = getipnodebyname(name, family, 0, &h_errno);
        if (res == NULL)
        {
                errno = EAFNOSUPPORT;
                return NULL;
        }
 
-       tdata = _lu_data_create_key(_lu_data_key_host, free_lu_thread_info_host);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_host, tdata);
-       }
+       tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
+       if (tdata == NULL) return NULL;
 
-       recycle_host(tdata, res);
-       return (struct hostent *)tdata->lu_entry;
+       LI_data_recycle(tdata, res, ENTRY_SIZE);
+       return (struct hostent *)tdata->li_entry;
 }
 
 struct hostent *
 gethostent(void)
 {
        struct hostent *res = NULL;
-       struct lu_thread_info *tdata;
+       struct li_thread_info *tdata;
 
-       tdata = _lu_data_create_key(_lu_data_key_host, free_lu_thread_info_host);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_host, tdata);
-       }
+       tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
+       if (tdata == NULL) return NULL;
 
-       if (_lu_running()) 
+       if (_ds_running()) 
        {
-               res = lu_gethostent(WANT_A4_ONLY, &h_errno);
+               res = ds_gethostent(&h_errno);
        }
        else
        {
                pthread_mutex_lock(&_host_lock);
-               res = copy_host(_old_gethostent());
+               res = copy_host(LI_files_gethostent());
                pthread_mutex_unlock(&_host_lock);
        }
 
-       recycle_host(tdata, res);
-       return (struct hostent *)tdata->lu_entry;
+       LI_data_recycle(tdata, res, ENTRY_SIZE);
+       return (struct hostent *)tdata->li_entry;
 }
 
 void
 sethostent(int stayopen)
 {
-       if (_lu_running()) lu_sethostent();
-       else _old_sethostent(stayopen);
+       if (_ds_running()) ds_sethostent();
+       else LI_files_sethostent(stayopen);
 }
 
 void
 endhostent(void)
 {
-       if (_lu_running()) lu_endhostent();
-       else _old_endhostent();
+       if (_ds_running()) ds_endhostent();
+       else LI_files_endhostent();
 }
 
 __private_extern__ int
@@ -1148,7 +1043,7 @@ is_a4_mapped(const char *s)
 
        return 1;
 }
-       
+
 __private_extern__ int
 is_a4_compat(const char *s)
 {
@@ -1180,17 +1075,14 @@ is_a4_compat(const char *s)
 }
 
 struct hostent *
-getipnodebyaddr(const void *src, size_t len, int af, int *err)
+getipnodebyaddr(const void *src, size_t len, int family, int *err)
 {
        struct hostent *res;
 
-       *err = 0;
+       if (err != NULL) *err = 0;
 
-       res = gethostbyaddrerrno((const char *)src, len, af, err);
-       if (res == NULL)
-       {
-               return NULL;
-       }
+       res = gethostbyaddrerrno((const char *)src, len, family, err);
+       if (res == NULL) return NULL;
 
        if (res->h_name == NULL)
        {
@@ -1202,9 +1094,9 @@ getipnodebyaddr(const void *src, size_t len, int af, int *err)
 }
 
 struct hostent *
-getipnodebyname(const char *name, int af, int flags, int *err)
+getipnodebyname(const char *name, int family, int flags, int *err)
 {
-       int status, want, really_want, if4, if6, from_cache;
+       int status, want, if4, if6, add_to_cache;
        struct hostent *res;
        struct ifaddrs *ifa, *ifap;
        struct in_addr addr4;
@@ -1213,9 +1105,9 @@ getipnodebyname(const char *name, int af, int flags, int *err)
        memset(&addr4, 0, sizeof(struct in_addr));
        memset(&addr6, 0, sizeof(struct in6_addr));
 
-       *err = 0;
+       if (err != NULL) *err = 0;
 
-       if (af == AF_INET)
+       if (family == AF_INET)
        {
                status = inet_aton(name, &addr4);
                if (status == 1)
@@ -1225,21 +1117,22 @@ getipnodebyname(const char *name, int af, int flags, int *err)
                        return res;
                }
        }
-       else if (af == AF_INET6)
+       else if (family == AF_INET6)
        {
-               status = inet_pton(af, name, &addr6);
+               status = inet_pton(family, name, &addr6);
                if (status == 1)
                {
                        /* return a fake hostent */
                        res = fake_hostent6(name, addr6);
                        return res;
                }
+
                status = inet_aton(name, &addr4);
                if (status == 1)
                {
                        if (!(flags & (AI_V4MAPPED|AI_V4MAPPED_CFG)))
                        {
-                               *err = HOST_NOT_FOUND;
+                               if (err != NULL) *err = HOST_NOT_FOUND;
                                return NULL;
                        }
 
@@ -1255,7 +1148,7 @@ getipnodebyname(const char *name, int af, int flags, int *err)
        }
        else
        {
-               *err = NO_RECOVERY;
+               if (err != NULL) *err = NO_RECOVERY;
                return NULL;
        }
 
@@ -1270,7 +1163,7 @@ getipnodebyname(const char *name, int af, int flags, int *err)
        {
                if (getifaddrs(&ifa) < 0)
                {
-                       *err = NO_RECOVERY;
+                       if (err != NULL) *err = NO_RECOVERY;
                        return NULL;
                }
 
@@ -1287,7 +1180,7 @@ getipnodebyname(const char *name, int af, int flags, int *err)
                /* Bail out if there are no interfaces */
                if ((if4 == 0) && (if6 == 0))
                {
-                       *err = NO_ADDRESS;
+                       if (err != NULL) *err = NO_ADDRESS;
                        return NULL;
                }
        }
@@ -1297,184 +1190,215 @@ getipnodebyname(const char *name, int af, int flags, int *err)
         * If user asked for AF_INET, we only want V4 addresses.
         */
        want = WANT_A4_ONLY;
-       really_want = want;
 
-       if (af == AF_INET)
+       if (family == AF_INET)
        {
-               want = WANT_A4_ONLY;
                if ((flags & AI_ADDRCONFIG) && (if4 == 0))
                {
-                       *err = NO_ADDRESS;
+                       if (err != NULL) *err = NO_ADDRESS;
                        return NULL;
                }
        }
        else
        {
-               /* af == AF_INET6 */
+               /* family == AF_INET6 */
                want = WANT_A6_ONLY;
-               really_want = want;
-               if (flags & (AI_V4MAPPED|AI_V4MAPPED_CFG))
+
+               if (flags & (AI_V4MAPPED | AI_V4MAPPED_CFG))
                {
                        if (flags & AI_ALL)
                        {
                                want = WANT_A6_PLUS_MAPPED_A4;
-                               really_want = want;
                        }
                        else
                        {
-                               want = WANT_A6_ONLY;
-                               really_want = WANT_A6_OR_MAPPED_A4_IF_NO_A6;
+                               want = WANT_A6_OR_MAPPED_A4_IF_NO_A6;
                        }
                }
                else
                {
                        if ((flags & AI_ADDRCONFIG) && (if6 == 0)) 
                        {
-                               *err = NO_ADDRESS;
+                               if (err != NULL) *err = NO_ADDRESS;
                                return NULL;
                        }
                }
        }
 
-       from_cache = 0;
+       add_to_cache = 0;
        res = cache_gethostbyname(name, want);
 
        if (res != NULL)
        {
-               from_cache = 1;
        }
-       else if (_lu_running())
+       else if (_ds_running())
        {
-               res = lu_gethostbyname(name, want, err);
-               if ((res == NULL) && 
-                   ((really_want == WANT_A6_OR_MAPPED_A4_IF_NO_A6) ||
-                    (really_want == WANT_A6_PLUS_MAPPED_A4       )))
-               {
-                       res = lu_gethostbyname(name, WANT_MAPPED_A4_ONLY, err);
-               }
+               res = ds_gethostbyname(name, want, err);
+               if (res != NULL) add_to_cache = 1;
        }
        else
        {
                pthread_mutex_lock(&_host_lock);
-               res = copy_host(_old_gethostbyname(name));
-               *err = h_errno;
+               res = copy_host(LI_files_gethostbyname2(name, family));
+               if (err != NULL) *err = h_errno;
                pthread_mutex_unlock(&_host_lock);
        }
 
        if (res == NULL)
        {
-               *err = HOST_NOT_FOUND;
+               if (err != NULL) *err = HOST_NOT_FOUND;
                return NULL;
        }
 
-       if (from_cache == 0) cache_host(res, want, CACHE_BYNAME);
+       if (add_to_cache == 1) cache_host(res, want, CACHE_BYNAME);
 
        return res;
 }
 
+static int
+ether_extract_mac(kvarray_t *in, struct ether_addr *e)
+{
+       uint32_t d, k, kcount, t[6];
+       int i;
+
+       if (in == NULL) return -1;
+       if (e == NULL) return -1;
+
+       d = in->curr;
+       in->curr++;
+
+       if (d >= in->count) return -1;
+
+       kcount = in->dict[d].kcount;
+
+       for (k = 0; k < kcount; k++)
+       {
+               if (!strcmp(in->dict[d].key[k], "mac"))
+               {
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       i = sscanf(in->dict[d].val[k][0], " %x:%x:%x:%x:%x:%x", &t[0], &t[1], &t[2], &t[3], &t[4], &t[5]);
+                       if (i != 6) return -1;
+                       for (i = 0; i < 6; i++) e->ether_addr_octet[i] = t[i];
+                       return 0;
+               }
+       }
+
+       return -1;
+}
+
 /*
  * Given a host's name, this routine returns its 48 bit ethernet address.
  * Returns zero if successful, non-zero otherwise.
  */
-int
-lu_ether_hostton(const char *host, struct ether_addr *e)
+static int
+ds_ether_hostton(const char *host, struct ether_addr *e)
 {
-       unsigned int i, n, j, x[6];
-       ni_proplist *q, **r;
-       char *s;
-       
+       static int proc = -1;
+       kvbuf_t *request;
+       kvarray_t *reply;
+       kern_return_t status;
+
        if (host == NULL) return -1;
-       if (e == NULL) return -1;
-       
-       q = lookupd_make_query("2", "kvk", "name", host, "en_address");
-       if (q == NULL) return -1;
-       
-       n = lookupd_query(q, &r);
-       ni_proplist_free(q);
-       free(q);
-       
-       if (n == 0) return -1;
-       if (r[0] == NULL) return -1;
-       
-       i = ni_proplist_match(*r[0], "en_address", NULL);
-       if (i == (unsigned int)NI_INDEX_NULL) return -1;
-       
-       if (r[0]->ni_proplist_val[i].nip_val.ni_namelist_len == 0) return -1;
-       
-       s = r[0]->ni_proplist_val[i].nip_val.ni_namelist_val[0];
-       j = sscanf(s, " %x:%x:%x:%x:%x:%x", &x[0], &x[1], &x[2], &x[3], &x[4], &x[5]);
-       if (j != 6)
-       {
-               for (i = 0; i < n; i++)
-               {
-                       ni_proplist_free(r[i]);
-                       free(r[i]);
-               }
-               free(r);
-               return -1;
+
+       if (proc < 0)
+       {
+               status = LI_DSLookupGetProcedureNumber("getmacbyname", &proc);
+               if (status != KERN_SUCCESS) return -1;
        }
-       
-       for (i = 0; i < 6; i++) e->ether_addr_octet[i] = x[i];
-       
-       for (i = 0; i < n; i++)
+
+       request = kvbuf_query_key_val("name", host);
+       if (request == NULL) return -1;
+
+       reply = NULL;
+       status = LI_DSLookupQuery(proc, request, &reply);
+       kvbuf_free(request);
+
+       if (status != KERN_SUCCESS) return -1;
+
+       status = ether_extract_mac(reply, e);
+       kvarray_free(reply);
+
+       return status;
+}
+
+static int
+ether_extract_name(kvarray_t *in, char *name)
+{
+       uint32_t d, k, kcount;
+
+       if (in == NULL) return -1;
+       if (name == NULL) return -1;
+
+       d = in->curr;
+       in->curr++;
+
+       if (d >= in->count) return -1;
+
+       kcount = in->dict[d].kcount;
+
+       for (k = 0; k < kcount; k++)
        {
-               ni_proplist_free(r[i]);
-               free(r[i]);
+               if (!strcmp(in->dict[d].key[k], "name"))
+               {
+                       memcpy(name, in->dict[d].val[k][0], strlen(in->dict[d].val[k][0]) + 1);
+                       return 0;
+               }
        }
-       
-       free(r);
-       return 0;
+
+       return -1;
 }
 
 /*
  * Given a 48 bit ethernet address, this routine return its host name.
  * Returns zero if successful, non-zero otherwise.
  */
-int
-lu_ether_ntohost(char *host, const struct ether_addr *e)
+static int
+ds_ether_ntohost(char *host, const struct ether_addr *e)
 {
-       unsigned int i, n, len, x[6];
-       ni_proplist *q, **r;
+       uint32_t i, x[6];
        char str[256];
-       
+       static int proc = -1;
+       kvbuf_t *request;
+       kvarray_t *reply;
+       kern_return_t status;
+
        if (host == NULL) return -1;
        if (e == NULL) return -1;
-       
+
+       if (proc < 0)
+       {
+               status = LI_DSLookupGetProcedureNumber("gethostbymac", &proc);
+               if (status != KERN_SUCCESS) return -1;
+       }
+
        for (i = 0; i < 6; i++) x[i] = e->ether_addr_octet[i];
        sprintf(str, "%x:%x:%x:%x:%x:%x", x[0], x[1], x[2], x[3], x[4], x[5]);
-       
-       q = lookupd_make_query("2", "kv", "en_address", str);
-       if (q == NULL) return -1;
-       
-       n = lookupd_query(q, &r);
-       ni_proplist_free(q);
-       free(q);
-       if (n == 0) return -1;
-       if (r[0] == NULL) return -1;
-       
-       i = ni_proplist_match(*r[0], "name", NULL);
-       if (i == (unsigned int)NI_INDEX_NULL) return -1;
-       
-       if (r[0]->ni_proplist_val[i].nip_val.ni_namelist_len == 0) return -1;
-       
-       len = strlen(r[0]->ni_proplist_val[i].nip_val.ni_namelist_val[0]) + 1;
-       memcpy(host, r[0]->ni_proplist_val[i].nip_val.ni_namelist_val[0], len);
-       
-       for (i = 0; i < n; i++) ni_proplist_free(r[i]);
-       free(r);
-       return 0;
+
+       request = kvbuf_query_key_val("mac", str);
+       if (request == NULL) return -1;
+
+       reply = NULL;
+       status = LI_DSLookupQuery(proc, request, &reply);
+       kvbuf_free(request);
+
+       if (status != KERN_SUCCESS) return -1;
+
+       status = ether_extract_name(reply, host);
+       kvarray_free(reply);
+
+       return status;
 }
 
 int
 ether_hostton(const char *host, struct ether_addr *e)
 {
-       if (_lu_running()) return lu_ether_hostton(host, e);
+       if (_ds_running()) return ds_ether_hostton(host, e);
        return _old_ether_hostton(host, e);
 }
 
 int
 ether_ntohost(char *host, const struct ether_addr *e)
 {
-       if (_lu_running()) return lu_ether_ntohost(host, e);
+       if (_ds_running()) return ds_ether_ntohost(host, e);
        return _old_ether_ntohost(host, e);
 }
index 3261116e7c84be718b8ac4b1d8e7088ecbd01ba2..109fb71bf64434365c9338c585625e91209151f5 100644 (file)
 #define _LU_HOST_H_
 
 #include <sys/cdefs.h>
+#include "lu_utils.h"
 
-
-#define WANT_NOTHING 0xfeedface
-#define WANT_A4_ONLY 0
-#define WANT_A6_ONLY 1
-#define WANT_A6_PLUS_MAPPED_A4 2
-#define WANT_MAPPED_A4_ONLY 3
+#define WANT_NOTHING 0
+#define WANT_A4_ONLY 1
+#define WANT_A6_ONLY 2
+#define WANT_A6_PLUS_MAPPED_A4 3
+#define WANT_MAPPED_A4_ONLY 4
 
 /* ONLY TO BE USED BY getipv6nodebyaddr */
-#define WANT_A6_OR_MAPPED_A4_IF_NO_A6 -1
+#define WANT_A6_OR_MAPPED_A4_IF_NO_A6 5
 
 
 __BEGIN_DECLS
 
 void free_host_data(struct hostent *h);
-struct hostent * extract_host(XDR *xdr, int want, int *err);
-struct hostent * fake_hostent(const char *name, struct in_addr addr);
-struct hostent * fake_hostent6(const char *name, struct in6_addr addr);
+struct hostent *extract_host(kvarray_t *in, int want);
+struct hostent *fake_hostent(const char *name, struct in_addr addr);
+struct hostent *fake_hostent6(const char *name, struct in6_addr addr);
 int is_a4_mapped(const char *s);
 int is_a4_compat(const char *s);
 
index 6b5047133024b67331d85985a02a8ae7b7edbe76..14a0eca0d8dca56c1979d49277d915c1cd63ff2f 100644 (file)
  */
 
 #include <netdb.h>
-/* async gethostbyXXX function prototypes */
 #include <netdb_async.h>
 #include <pthread.h>
 #include <stdlib.h>
 #include <mach/mach.h>
-#include <netinfo/_lu_types.h>
-#include <netinfo/lookup.h>
-#include <rpc/types.h>
-#include <rpc/xdr.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <ifaddrs.h>
 #include <net/if.h>
-#include <libkern/OSByteOrder.h>
+#include <errno.h>
 
 #include "lu_host.h"
 #include "lu_utils.h"
 
-extern mach_port_t _lu_port;
-extern int _lu_running(void);
+#define IPV6_ADDR_LEN 16
+#define IPV4_ADDR_LEN 4
 
-extern int h_errno;
-
-#define msgh_request_port msgh_remote_port
-#define msgh_reply_port msgh_local_port
-
-
-typedef union
+typedef struct
 {
-       gethostbyaddr_async_callback hostAddr;
-       gethostbyname_async_callback hostName;
-       getipnodebyaddr_async_callback nodeAddr;
-       getipnodebyname_async_callback nodeName;
-} a_request_callout_t;
-
-typedef struct a_requests
-{
-       struct a_requests *next;
-       int retry;
-       struct
-       {
-               int proc;
-               ooline_data data;
-               unsigned int dataLen;
-               int want;
-       } request;
-       mach_port_t replyPort;
-       a_request_callout_t callout;
-       void *context;
-       struct hostent *hent;           /* if reply known in XXX_start() */
-} a_requests_t;
-
-static a_requests_t *a_requests = NULL;
-static pthread_mutex_t a_requests_lock = PTHREAD_MUTEX_INITIALIZER;
-
-#define MAX_LOOKUP_ATTEMPTS 10
+       void *user_context;
+       int want;
+} my_context_t;
 
-static kern_return_t
-_lookup_all_tx(mach_port_t server, int proc, ooline_data indata, mach_msg_type_number_t indataCnt, mach_port_t *replyPort)
+mach_port_t
+gethostbyaddr_async_start(const char *addr, int len, int family, gethostbyaddr_async_callback callback, void *context)
 {
-       typedef struct
-       {
-               mach_msg_header_t Head;
-               NDR_record_t NDR;
-               int proc;
-               mach_msg_type_number_t indataCnt;
-               unit indata[4096];
-       } Request;
-
-       Request In;
-       register Request *InP = &In;
-       mach_msg_return_t mr;
-       unsigned int msgh_size;
-
-       if (indataCnt > 4096) return MIG_ARRAY_TOO_LARGE;
-
-       if (*replyPort == MACH_PORT_NULL)
-       {
-               mr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, replyPort);
-               if (mr != KERN_SUCCESS) return mr;
-       }
-
-       msgh_size = (sizeof(Request) - 16384) + ((4 * indataCnt));
-       InP->Head.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND_ONCE);
-//     InP->Head.msgh_size = msgh_size;        /* msgh_size passed as argument */
-       InP->Head.msgh_request_port = server;
-       InP->Head.msgh_reply_port = *replyPort;
-       InP->Head.msgh_id = 4241776;
-       InP->NDR = NDR_record;
-       InP->proc = proc;
-       InP->indataCnt = indataCnt;
-       memcpy((char *)InP->indata, (const char *)indata, 4 * indataCnt);
-
-       mr = mach_msg(&InP->Head,       /* msg */
-               MACH_SEND_MSG,          /* options */
-               msgh_size,              /* send_size */
-               0,                      /* rcv_size */
-               MACH_PORT_NULL,         /* rcv_name */
-               MACH_MSG_TIMEOUT_NONE,  /* timeout */
-               MACH_PORT_NULL);        /* notify */
-
-       switch (mr)
-       {
-               case MACH_MSG_SUCCESS:
-                       mr = KERN_SUCCESS;
-                       break;
-               case MACH_SEND_INVALID_REPLY :
-                       (void)mach_port_mod_refs(mach_task_self(), *replyPort, MACH_PORT_RIGHT_RECEIVE, -1);
-                       *replyPort = MACH_PORT_NULL;
-                       break;
-               default:
-                       break;
-       }
-
-       return mr;
-}
+       static int proc = 1;
+       int32_t want, status;
+       kvbuf_t *request;
+       mach_port_t mp;
+       my_context_t *my_context;
 
-static kern_return_t
-_lookup_all_rx(void *msg, ooline_data *outdata, mach_msg_type_number_t *outdataCnt, security_token_t *token)
-{
-       typedef struct
-       {
-               mach_msg_header_t Head;
-               mach_msg_body_t msgh_body;
-               mach_msg_ool_descriptor_t outdata;
-               NDR_record_t NDR;
-               mach_msg_type_number_t outdataCnt;
-               mach_msg_format_0_trailer_t trailer;
-       } Reply;
+       mp = MACH_PORT_NULL;
 
-       /*
-        * typedef struct {
-        * mach_msg_header_t Head;
-        * NDR_record_t NDR;
-        * kern_return_t RetCode;
-        * } mig_reply_error_t;
-        */
+       if (addr == NULL) return MACH_PORT_NULL;
+       if (len == 0) return MACH_PORT_NULL;
+       if ((family != AF_INET) && (family != AF_INET6)) return MACH_PORT_NULL;
 
-       register Reply *OutP = msg;
-       mach_msg_format_0_trailer_t *TrailerP;
-       boolean_t msgh_simple;
+       want = WANT_A4_ONLY;
+       if (family == AF_INET6) want = WANT_A6_ONLY;
 
-       if (OutP->Head.msgh_id != (4241776 + 100))
+       if ((family == AF_INET6) && (len == IPV6_ADDR_LEN) && (is_a4_mapped((const char *)addr) || is_a4_compat((const char *)addr)))
        {
-               if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) return MIG_SERVER_DIED;
-               else return MIG_REPLY_MISMATCH;
+               addr += 12;
+               len = 4;
+               family = AF_INET;
+               want = WANT_MAPPED_A4_ONLY;
        }
 
-       msgh_simple = !(OutP->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX);
-
-       TrailerP = (mach_msg_format_0_trailer_t *)((vm_offset_t)OutP + round_msg(OutP->Head.msgh_size));
-       if (TrailerP->msgh_trailer_type != MACH_MSG_TRAILER_FORMAT_0) return MIG_TRAILER_ERROR;
-
-       if (OutP->NDR.int_rep != NDR_record.int_rep)
+       if (proc < 0)
        {
-               if (msgh_simple)
-               {
-                       ((mig_reply_error_t *)OutP)->RetCode = OSReadSwapInt32(&(((mig_reply_error_t *)OutP)->RetCode), 0);
-               }
-               else
-               {
-                       OutP->outdataCnt = OSReadSwapInt32(&(OutP->outdataCnt), 0);
-               }
+               status = LI_DSLookupGetProcedureNumber("gethostbyaddr", &proc);
+               if (status != KERN_SUCCESS) return MACH_PORT_NULL;
        }
 
-       if (msgh_simple && ((mig_reply_error_t *)OutP)->RetCode != KERN_SUCCESS) return ((mig_reply_error_t *)OutP)->RetCode;
-
-       *outdata = (ooline_data)(OutP->outdata.address);
-       *outdataCnt = OutP->outdataCnt;
-
-       *token = TrailerP->msgh_sender;
-
-       return KERN_SUCCESS;
-}
+       request = kvbuf_query("ksku", "address", addr, "family", want);
+       if (request == NULL) return MACH_PORT_NULL;
 
-static a_requests_t *
-request_extract(mach_port_t port)
-{
-       a_requests_t *request0, *request;
+       my_context = (my_context_t *)calloc(1, sizeof(my_context_t));
+       if (my_context == NULL) return MACH_PORT_NULL;
 
-       pthread_mutex_lock(&a_requests_lock);
+       my_context->user_context = context;
+       my_context->want = want;
 
-       request0 = NULL;
-       request = a_requests;
+       status = LI_async_start(&mp, proc, request, (void *)callback, my_context);
 
-       while (request != NULL)
-       {
-               if (port == request->replyPort)
-               {
-                       /* request found, remove from list */
-                       if (request0 != NULL)
-                       {
-                               request0->next = request->next;
-                       }
-                       else
-                       {
-                               a_requests = request->next;
-                       }
-
-                       break;
-               }
-               else
-               {
-                       /* not this request, skip to next */
-                       request0 = request;
-                       request = request->next;
-               }
-       }
-
-       pthread_mutex_unlock(&a_requests_lock);
-
-       return request;
+       kvbuf_free(request);
+       return mp;
 }
 
-static void
-request_queue(a_requests_t *request)
+void
+gethostbyaddr_async_cancel(mach_port_t port)
 {
-       pthread_mutex_lock(&a_requests_lock);
+       my_context_t *my_context;
 
-       request->next = a_requests;
-       a_requests = request;
+       my_context = NULL;
 
-       pthread_mutex_unlock(&a_requests_lock);
+       LI_async_call_cancel(port, (void **)&my_context);
 
-       return;
+       if (my_context != NULL) free(my_context);
 }
 
-static boolean_t
-sendCannedReply(a_requests_t *request, int *error)
+void
+gethostbyaddr_async_handleReply(void *msg)
 {
-       /*
-        * typedef struct {
-        * mach_msg_header_t Head;
-        * NDR_record_t NDR;
-        * kern_return_t RetCode;
-        * } mig_reply_error_t;
-        */
-
-       mig_reply_error_t Out;
-       register mig_reply_error_t *OutP = &Out;
-       kern_return_t kr;
-       mach_msg_return_t mr;
-       unsigned int msgh_size;
+       gethostbyaddr_async_callback callback;
+       struct hostent *out;
+       uint32_t len, want;
+       int status;
+       kvarray_t *reply;
+       my_context_t *my_context;
+       void *context;
 
-       mach_port_t sendPort;
-       mach_msg_type_name_t sendType;
+       callback = (gethostbyaddr_async_callback)NULL;
+       my_context = NULL;
+       context = NULL;
+       len = 0;
+       reply = NULL;
 
-       /*
-        * allocate reply port
-        */
-       kr = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &request->replyPort);
-       if (kr != KERN_SUCCESS)
+       status = LI_async_handle_reply(msg, &reply, (void **)&callback, (void **)&my_context);
+       if ((status != KERN_SUCCESS) || (reply == NULL))
        {
-               *error = NO_RECOVERY;
-               return FALSE;
+               if (status == MIG_REPLY_MISMATCH) return;
+               if (callback != NULL)
+               {
+                       if (my_context != NULL) context = my_context->user_context;
+                       callback(NULL, context);
+                       free(my_context);
+                       return;
+               }
        }
 
-       kr = mach_port_extract_right(mach_task_self(), request->replyPort, MACH_MSG_TYPE_MAKE_SEND_ONCE, &sendPort, &sendType);
-       if (kr != KERN_SUCCESS)
+       want = WANT_A4_ONLY;
+       if (my_context != NULL)
        {
-               (void)mach_port_destroy(mach_task_self(), request->replyPort);
-               request->replyPort = MACH_PORT_NULL;
-               *error = NO_RECOVERY;
-               return FALSE;
+               context = my_context->user_context;
+               want = my_context->want;
+               free(my_context);
        }
 
-       /*
-        * queue reply message
-        */
-       msgh_size = sizeof(Out);
-       OutP->Head.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MOVE_SEND_ONCE, 0);
-//     OutP->Head.msgh_size = msgh_size;       /* msgh_size passed as argument */
-       OutP->Head.msgh_request_port = sendPort;
-       OutP->Head.msgh_reply_port = MACH_PORT_NULL;
-       OutP->Head.msgh_id = 4241776 + 100;
-       OutP->RetCode = MIG_REMOTE_ERROR;
-       OutP->NDR = NDR_record;
-
-       mr = mach_msg(&OutP->Head, MACH_SEND_MSG, msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
-       if (mr != MACH_MSG_SUCCESS)
-       {
-               if (mr == MACH_SEND_INVALID_REPLY)
-               {
-                       (void)mach_port_destroy(mach_task_self(), request->replyPort);
-                       request->replyPort = MACH_PORT_NULL;
-               }
-
-               *error = NO_RECOVERY;
-               return FALSE;
-       }
+       out = extract_host(reply, want);
+       kvarray_free(reply);
 
-       return TRUE;
+       callback(out, context);
 }
 
-static void
-_async_cancel(mach_port_t port)
+mach_port_t
+getipnodebyaddr_async_start(const void *addr, size_t len, int family, int *error, getipnodebyaddr_async_callback callback, void *context)
 {
-       a_requests_t *request;
-
-       request = request_extract(port);
-       if (request)
-       {
-               (void)mach_port_mod_refs(mach_task_self(), request->replyPort, MACH_PORT_RIGHT_RECEIVE, -1);
-               if (request->request.data) free(request->request.data);
-               if (request->hent) freehostent(request->hent);
-               free(request);
-       }
+       static int proc = 1;
+       int32_t want, status;
+       kvbuf_t *request;
+       mach_port_t mp;
+       my_context_t *my_context;
 
-       return;
-}
+       mp = MACH_PORT_NULL;
 
-static mach_port_t
-_gethostbyaddr_async_start(const char *addr, int len, int type, a_request_callout_t callout, void *context, int *error)
-{
-       void *address;
-       int proc;
-       a_requests_t *request;
-       int want;
-       static int proc4 = -1;
-       struct in_addr *v4addr;
-       static int proc6 = -1;
-       struct in6_addr *v6addr;
+       if (addr == NULL) return MACH_PORT_NULL;
+       if (len == 0) return MACH_PORT_NULL;
+       if ((family != AF_INET) && (family != AF_INET6)) return MACH_PORT_NULL;
 
        want = WANT_A4_ONLY;
-       if (type == AF_INET6) want = WANT_A6_ONLY;
+       if (family == AF_INET6) want = WANT_A6_ONLY;
 
-       if ((type == AF_INET6) && (len == 16) && (is_a4_mapped((const char *)addr) || is_a4_compat((const char *)addr)))
+       if ((family == AF_INET6) && (len == IPV6_ADDR_LEN) && (is_a4_mapped((const char *)addr) || is_a4_compat((const char *)addr)))
        {
                addr += 12;
                len = 4;
-               type = AF_INET;
+               family = AF_INET;
                want = WANT_MAPPED_A4_ONLY;
        }
 
-       switch (type)
+       if (proc < 0)
        {
-               case AF_INET:
-               {
-                       if (proc4 < 0)
-                       {
-                               if (_lookup_link(_lu_port, "gethostbyaddr", &proc4) != KERN_SUCCESS)
-                               {
-                                       *error = NO_RECOVERY;
-                                       return MACH_PORT_NULL;
-                               }
-                       }
-
-                       if (len != sizeof(struct in_addr))
-                       {
-                               *error = NO_RECOVERY;
-                               return MACH_PORT_NULL;
-                       }
-
-                       v4addr = malloc(len);
-                       memmove(v4addr, addr, len);
-
-                       address = (void *)v4addr;
-                       proc = proc4;
-                       break;
-               }
-
-               case AF_INET6:
-               {
-                       if (proc6 < 0)
-                       {
-                               if (_lookup_link(_lu_port, "getipv6nodebyaddr", &proc6) != KERN_SUCCESS)
-                               {
-                                       *error = NO_RECOVERY;
-                                       return MACH_PORT_NULL;
-                               }
-                       }
-
-                       if (len != sizeof(struct in6_addr))
-                       {
-                               *error = NO_RECOVERY;
-                               return MACH_PORT_NULL;
-                       }
-
-                       v6addr = malloc(len);
-                       memmove(v6addr, addr, len);
-                       v6addr->__u6_addr.__u6_addr32[0] = htonl(v6addr->__u6_addr.__u6_addr32[0]);
-                       v6addr->__u6_addr.__u6_addr32[1] = htonl(v6addr->__u6_addr.__u6_addr32[1]);
-                       v6addr->__u6_addr.__u6_addr32[2] = htonl(v6addr->__u6_addr.__u6_addr32[2]);
-                       v6addr->__u6_addr.__u6_addr32[3] = htonl(v6addr->__u6_addr.__u6_addr32[3]);
-
-                       address = (void *)v6addr;
-                       proc = proc6;
-                       break;
-               }
-
-               default:
-               *error = NO_RECOVERY;
-               return MACH_PORT_NULL;
+               status = LI_DSLookupGetProcedureNumber("gethostbyaddr", &proc);
+               if (status != KERN_SUCCESS) return MACH_PORT_NULL;
        }
 
-       request = malloc(sizeof(a_requests_t));
-       request->next = NULL;
-       request->retry = MAX_LOOKUP_ATTEMPTS;
-       request->request.proc = proc;
-       request->request.data = (ooline_data)address;
-       request->request.dataLen = len / BYTES_PER_XDR_UNIT;
-       request->request.want = want;
-       request->replyPort = MACH_PORT_NULL;
-       request->callout = callout;
-       request->context = context;
-       request->hent = NULL;
-
-       /*
-        * allocate reply port, send query to lookupd
-        */
-       if (_lookup_all_tx(_lu_port, request->request.proc, request->request.data, request->request.dataLen, &request->replyPort) == KERN_SUCCESS)
-       {
-               request_queue(request);
-       }
-       else
-       {
-               if (request->request.data) free(request->request.data);
-               free(request);
-               *error = NO_RECOVERY;
-               return MACH_PORT_NULL;
-       }
+       request = kvbuf_query("ksku", "address", addr, "family", want);
+       if (request == NULL) return MACH_PORT_NULL;
 
-       return request->replyPort;
-}
+       my_context = (my_context_t *)calloc(1, sizeof(my_context_t));
+       if (my_context == NULL) return MACH_PORT_NULL;
 
-static boolean_t
-_gethostbyaddr_async_handleReply(void *replyMsg, a_requests_t **requestP, struct hostent **he, int *error)
-{
-       int count;
-       ooline_data data;
-       unsigned int datalen;
-       XDR inxdr;
-       mach_msg_header_t *msg = (mach_msg_header_t *)replyMsg;
-       a_requests_t *request;
-       kern_return_t status;
-       security_token_t token;
-
-       request = request_extract(msg->msgh_local_port);
-       if (!request)
-       {
-               /* excuse me, what happenned to the request info? */
-               return FALSE;
-       }
+       my_context->user_context = context;
+       my_context->want = want;
 
-       *requestP = request;
-       *he = NULL;
-       *error = 0;
+       status = LI_async_start(&mp, proc, request, (void *)callback, my_context);
 
-       /* unpack the reply */
-       status = _lookup_all_rx(replyMsg, &data, &datalen, &token);
-       switch (status)
-       {
-               case KERN_SUCCESS:
-                       break;
-
-               case MIG_SERVER_DIED:
-                       if (--request->retry > 0)
-                       {
-                               /* retry the request */
-                               if (_lookup_all_tx(_lu_port, request->request.proc, request->request.data, request->request.dataLen, &request->replyPort) == KERN_SUCCESS)
-                               {
-                                       request_queue(request);
-                                       return FALSE;
-                               }
-                       }
-                       /* fall through */
-
-               default:
-                       *error = HOST_NOT_FOUND;
-                       return TRUE;
-       }
-
-       datalen *= BYTES_PER_XDR_UNIT;
-
-       if (token.val[0] != 0)
-       {
-               vm_deallocate(mach_task_self(), (vm_address_t)data, datalen);
-               *error = NO_RECOVERY;
-               return TRUE;
-       }
-
-       xdrmem_create(&inxdr, data, datalen, XDR_DECODE);
-
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)data, datalen);
-               *error = NO_RECOVERY;
-               return TRUE;
-       }
-
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)data, datalen);
-               *error = HOST_NOT_FOUND;
-               *he = NULL;
-               return TRUE;
-       }
-
-       *he = extract_host(&inxdr, request->request.want, error);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)data, datalen);
-       return TRUE;
-}
-
-mach_port_t
-gethostbyaddr_async_start(const char *addr, int len, int type, gethostbyaddr_async_callback callout, void *context)
-{
-       a_request_callout_t cb;
-       mach_port_t mp;
-
-       if (!_lu_running())
-       {
-               h_errno = NO_RECOVERY;
-               return MACH_PORT_NULL;
-       }
-
-       cb.hostAddr = callout;
-       mp = _gethostbyaddr_async_start(addr, len, type, cb, context, &h_errno);
-       return mp;
-}
-
-void
-gethostbyaddr_async_cancel(mach_port_t port)
-{
-       _async_cancel(port);
-       return;
-}
-
-void
-gethostbyaddr_async_handleReply(void *replyMsg)
-{
-       int error = 0;
-       struct hostent *he = NULL;
-       a_requests_t *request = NULL;
-
-       if (_gethostbyaddr_async_handleReply(replyMsg, &request, &he, &error))
-       {
-               /* if we have an answer to provide */
-               h_errno = error;
-               (request->callout.hostAddr)(he, request->context);
-
-               (void)mach_port_mod_refs(mach_task_self(), request->replyPort, MACH_PORT_RIGHT_RECEIVE, -1);
-               if (request->request.data) free(request->request.data);
-               free(request);
-               if (he != NULL) freehostent(he);
-       }
-
-       return;
-}
-
-mach_port_t
-getipnodebyaddr_async_start(const void *addr, size_t len, int af, int *error, getipnodebyaddr_async_callback callout, void *context)
-{
-       a_request_callout_t cb;
-       mach_port_t mp;
-
-       if (!_lu_running())
-       {
-               *error = NO_RECOVERY;
-               return MACH_PORT_NULL;
-       }
-
-       cb.nodeAddr = callout;
-       mp = _gethostbyaddr_async_start(addr, len, af, cb, context, error);
+       kvbuf_free(request);
        return mp;
 }
 
 void
 getipnodebyaddr_async_cancel(mach_port_t port)
 {
-       _async_cancel(port);
-       return;
-}
+       my_context_t *my_context;
 
-void
-getipnodebyaddr_async_handleReply(void *replyMsg)
-{
-       int error = 0;
-       struct hostent *he = NULL;
-       a_requests_t *request = NULL;
+       my_context = NULL;
 
-       if (_gethostbyaddr_async_handleReply(replyMsg, &request, &he, &error))
-       {
-               /* if we have an answer to provide */
-               (request->callout.nodeAddr)(he, error, request->context);
-
-               (void)mach_port_mod_refs(mach_task_self(), request->replyPort, MACH_PORT_RIGHT_RECEIVE, -1);
-               if (request->request.data) free(request->request.data);
-               free(request);
-               /*
-                * Note: it is up to the callback function to call
-                * freehostent().
-                */
-       }
+       LI_async_call_cancel(port, (void **)&my_context);
 
-       return;
+       if (my_context != NULL) free(my_context);
 }
 
-static mach_port_t
-_gethostbyname_async_start(const char *name, int want, int *error, a_request_callout_t callout, void *context)
+void
+getipnodebyaddr_async_handleReply(void *msg)
 {
-       int af;
-       boolean_t is_addr = FALSE;
-       mach_port_t mp = MACH_PORT_NULL;
-       XDR outxdr;
-       static int proc;
-       a_requests_t *request;
-       static int proc4 = -1;
-       static int proc6 = -1;
-       struct in_addr v4addr;
-       struct in6_addr v6addr;
-
-       if ((name == NULL) || (name[0] == '\0'))
-       {
-               *error = NO_DATA;
-               return MACH_PORT_NULL;
-       }
-
-       af = (want == WANT_A4_ONLY) ? AF_INET: AF_INET6;
-
-       if ((af == AF_INET) || (want == WANT_MAPPED_A4_ONLY))
-       {
-               if (proc4 < 0)
-               {
-                       if (_lookup_link(_lu_port, "gethostbyname", &proc4) != KERN_SUCCESS)
-                       {
-                               *error = NO_RECOVERY;
-                               return MACH_PORT_NULL;
-                       }
-               }
-               proc = proc4;
-       }
-       else /* if (af == AF_INET6) */
-       {
-               if (proc6 < 0)
-               {
-                       if (_lookup_link(_lu_port, "getipv6nodebyname", &proc6) != KERN_SUCCESS)
-                       {
-                               *error = NO_RECOVERY;
-                               return MACH_PORT_NULL;
-                       }
-               }
-               proc = proc6;
-       }
-
-       request = malloc(sizeof(a_requests_t));
-       request->next = NULL;
-       request->retry = MAX_LOOKUP_ATTEMPTS;
-       request->request.proc = proc;
-       request->request.data = NULL;
-       request->request.dataLen = 0;
-       request->request.want = want;
-       request->replyPort = MACH_PORT_NULL;
-       request->callout = callout;
-       request->context = context;
-       request->hent = NULL;
-
-       switch (af)
-       {
-               case AF_INET:
-               {
-                       memset(&v4addr, 0, sizeof(struct in_addr));
-                       if (inet_aton(name, &v4addr) == 1)
-                       {
-                               /* return a fake hostent */
-                               request->hent = fake_hostent(name, v4addr);
-                               is_addr = TRUE;
-                       }
-                       break;
-               }
-
-               case AF_INET6:
-               {
-                       memset(&v6addr, 0, sizeof(struct in6_addr));
-                       if (inet_pton(af, name, &v6addr) == 1)
-                       {
-                               /* return a fake hostent */
-                               request->hent = fake_hostent6(name, v6addr);
-                               is_addr = TRUE;
-                               break;
-                       } 
-
-                       memset(&v4addr, 0, sizeof(struct in_addr));
-                       if (inet_aton(name, &v4addr) == 1)
-                       {
-                               if (want == WANT_A4_ONLY)
-                               {
-                                       free(request);
-                                       *error = HOST_NOT_FOUND;
-                                       return MACH_PORT_NULL;
-                               }
-
-                               v6addr.__u6_addr.__u6_addr32[0] = 0x00000000;
-                               v6addr.__u6_addr.__u6_addr32[1] = 0x00000000;
-                               v6addr.__u6_addr.__u6_addr32[2] = htonl(0x0000ffff);
-                               memmove(&(v6addr.__u6_addr.__u6_addr32[3]), &(v4addr.s_addr), sizeof(struct in_addr));
-
-                               /* return a fake hostent */
-                               request->hent = fake_hostent6(name, v6addr);
-                               is_addr = TRUE;
-                       }
-                       break;
-               }
+       getipnodebyaddr_async_callback callback;
+       struct hostent *out;
+       uint32_t len, want;
+       int status;
+       kvarray_t *reply;
+       my_context_t *my_context;
+       void *context;
 
-               default:
-               free(request);
-               *error = NO_RECOVERY;
-               return MACH_PORT_NULL;
-       }
+       callback = (getipnodebyaddr_async_callback)NULL;
+       my_context = NULL;
+       context = NULL;
+       len = 0;
+       reply = NULL;
 
-       if (is_addr)
+       status = LI_async_handle_reply(msg, &reply, (void **)&callback, (void **)&my_context);
+       if ((status != KERN_SUCCESS) || (reply == NULL))
        {
-               /*
-                * queue reply message
-                */
-               if (sendCannedReply(request, error))
+               if (status == MIG_REPLY_MISMATCH) return;
+               if (callback != NULL)
                {
-                       request_queue(request);
-                       return request->replyPort;
-               }
-               else
-               {
-                       freehostent(request->hent);
-                       free(request);
-                       return MACH_PORT_NULL;
+                       if (my_context != NULL) context = my_context->user_context;
+                       callback(NULL, NO_RECOVERY, context);
+                       free(my_context);
+                       return;
                }
        }
 
-       request->request.dataLen = _LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT;
-       request->request.data = malloc(request->request.dataLen);
-
-       xdrmem_create(&outxdr, request->request.data, request->request.dataLen, XDR_ENCODE);
-       if (!xdr__lu_string(&outxdr, (_lu_string *)&name))
+       want = WANT_A4_ONLY;
+       if (my_context != NULL)
        {
-               xdr_destroy(&outxdr);
-               free(request->request.data);
-               free(request);
-               *error = NO_RECOVERY;
-               return MACH_PORT_NULL;
+               context = my_context->user_context;
+               want = my_context->want;
+               free(my_context);
        }
 
-       request->request.dataLen = xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT;
+       out = extract_host(reply, want);
+       kvarray_free(reply);
 
-       /*
-        * allocate reply port, send query to lookupd
-        */
-       if (_lookup_all_tx(_lu_port, request->request.proc, request->request.data, request->request.dataLen, &request->replyPort) == KERN_SUCCESS)
-       {
-               request_queue(request);
-               mp = request->replyPort;
-       }
-       else
+       if (out == NULL)
        {
-               free(request->request.data);
-               free(request);
-               *error = NO_RECOVERY;
-               mp = MACH_PORT_NULL;
+               callback(NULL, HOST_NOT_FOUND, context);
+               return;
        }
 
-       xdr_destroy(&outxdr);
-       return mp;
+       callback(out, 0, context);
 }
 
-static boolean_t
-_gethostbyname_async_handleReply(void *replyMsg, a_requests_t **requestP, struct hostent **he, int *error)
+mach_port_t
+gethostbyname_async_start(const char *name, gethostbyname_async_callback callback, void *context)
 {
-       int count;
-       unsigned int datalen;
-       XDR inxdr;
-       ooline_data data;
-       mach_msg_header_t *msg = (mach_msg_header_t *)replyMsg;
-       a_requests_t *request;
-       kern_return_t status;
-       security_token_t token;
-       int want;
-
-       request = request_extract(msg->msgh_local_port);
-       if (!request)
-       {
-               /* excuse me, what happenned to the request info? */
-               return FALSE;
-       }
-
-       *requestP = request;
-       *he = NULL;
-       *error = 0;
-
-       if (request->hent)
-       {
-               /*
-                * if the reply was already available when the
-                * request was made
-                */
-               *he = request->hent;
-               return TRUE;
-       }
-
-       /* unpack the reply */
-       status = _lookup_all_rx(replyMsg, &data, &datalen, &token);
-       switch (status)
-       {
-               case KERN_SUCCESS:
-                       break;
-
-               case MIG_SERVER_DIED:
-                       if (--request->retry > 0)
-                       {
-                               /*
-                                * retry the request
-                                */
-                               if (_lookup_all_tx(_lu_port, request->request.proc, request->request.data, request->request.dataLen, &request->replyPort) == KERN_SUCCESS)
-                               {
-                                       request_queue(request);
-                                       return FALSE;
-                               }
-                       }
-                       /* fall through */
-
-               default:
-                       *error = HOST_NOT_FOUND;
-                       return TRUE;
-       }
-
-       datalen *= BYTES_PER_XDR_UNIT;
+       static int proc = 1;
+       int32_t status;
+       kvbuf_t *request;
+       mach_port_t mp;
 
-       if (token.val[0] != 0)
-       {
-               vm_deallocate(mach_task_self(), (vm_address_t)data, datalen);
-               *error = NO_RECOVERY;
-               return TRUE;
-       }
+       mp = MACH_PORT_NULL;
 
-       xdrmem_create(&inxdr, data, datalen, XDR_DECODE);
+       if (name == NULL) return MACH_PORT_NULL;
 
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
+       if (proc < 0)
        {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)data, datalen);
-               *error = NO_RECOVERY;
-               return TRUE;
+               status = LI_DSLookupGetProcedureNumber("gethostbyname", &proc);
+               if (status != KERN_SUCCESS) return MACH_PORT_NULL;
        }
 
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)data, datalen);
-               *error = HOST_NOT_FOUND;
-               return TRUE;
-       }
+       request = kvbuf_query("ksksks", "name", name, "ipv4", "1", "ipv6", "0");
+       if (request == NULL) return MACH_PORT_NULL;
 
-       want = request->request.want;
-       if (want == WANT_A6_OR_MAPPED_A4_IF_NO_A6) want = WANT_A6_ONLY;
-
-       *he = extract_host(&inxdr, want, error);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)data, datalen);
-       return TRUE;
-}
-
-mach_port_t
-gethostbyname_async_start(const char *name, gethostbyname_async_callback callout, void *context)
-{
-       a_request_callout_t cb;
-       int error;
-       mach_port_t mp = MACH_PORT_NULL;
-
-       if (!_lu_running())
-       {
-               h_errno = NO_RECOVERY;
-               return MACH_PORT_NULL;
-       }
-
-       cb.hostName = callout;
-       mp = _gethostbyname_async_start(name, WANT_A4_ONLY, &error, cb, context);
-       if (mp == MACH_PORT_NULL)
-       {
-               h_errno = error;
-       }
+       status = LI_async_start(&mp, proc, request, (void *)callback, context);
 
+       kvbuf_free(request);
        return mp;
 }
 
 void
 gethostbyname_async_cancel(mach_port_t port)
 {
-       _async_cancel(port);
-       return;
+       LI_async_call_cancel(port, NULL);
 }
 
 void
-gethostbyname_async_handleReply(void *replyMsg)
+gethostbyname_async_handleReply(void *msg)
 {
-       int error;
-       struct hostent *he;
-       a_requests_t *request;
+       gethostbyname_async_callback callback;
+       struct hostent *out;
+       uint32_t len;
+       int status;
+       kvarray_t *reply;
+       void *context;
+
+       callback = (gethostbyname_async_callback)NULL;
+       context = NULL;
+       len = 0;
+       reply = NULL;
 
-       if (_gethostbyname_async_handleReply(replyMsg, &request, &he, &error))
+       status = LI_async_handle_reply(msg, &reply, (void **)&callback, (void **)&context);
+       if ((status != KERN_SUCCESS) || (reply == NULL))
        {
-               /* if we have an answer to provide */
-               h_errno = error;
-               (request->callout.hostAddr)(he, request->context);
-
-               (void)mach_port_mod_refs(mach_task_self(), request->replyPort, MACH_PORT_RIGHT_RECEIVE, -1);
-               if (request->request.data) free(request->request.data);
-               free(request);
-               if (he != NULL) freehostent(he);
+               if (status == MIG_REPLY_MISMATCH) return;
+               if (callback != NULL)
+               {
+                       callback(NULL, context);
+                       return;
+               }
        }
 
-       return;
+       out = extract_host(reply, AF_INET);
+       kvarray_free(reply);
+
+       callback(out, context);
 }
 
 mach_port_t
-getipnodebyname_async_start(const char *name, int af, int flags, int *error, getipnodebyname_async_callback callout, void *context)
+getipnodebyname_async_start(const char *name, int family, int flags, int *err, getipnodebyname_async_callback callback, void *context)
 {
-       a_request_callout_t cb;
-       int if4 = 0;
-       int if6 = 0;
-       mach_port_t mp = MACH_PORT_NULL;
-       int want = WANT_A4_ONLY;
+       static int proc = 1;
+       int32_t status, want, want4, want6, if4, if6;
+       kvbuf_t *request;
+       mach_port_t mp;
        struct ifaddrs *ifa, *ifap;
+       struct in_addr addr4;
+       struct in6_addr addr6;
+       my_context_t *my_context;
 
-       if (!_lu_running())
-       {
-               h_errno = NO_RECOVERY;
-               return MACH_PORT_NULL;
-       }
+       if (name == NULL) return MACH_PORT_NULL;
+
+       if (err != NULL) *err = 0;
+
+       if4 = 0;
+       if6 = 0;
+       mp = MACH_PORT_NULL;
+       memset(&addr4, 0, sizeof(struct in_addr));
+       memset(&addr6, 0, sizeof(struct in6_addr));
 
-       /*
-        * IF AI_ADDRCONFIG is set, we need to know what interface flavors we really have.
-        */
        if (flags & AI_ADDRCONFIG)
        {
                if (getifaddrs(&ifa) < 0)
                {
-                       *error = NO_RECOVERY;
+                       if (err != NULL) *err = NO_RECOVERY;
                        return MACH_PORT_NULL;
                }
 
@@ -970,14 +357,8 @@ getipnodebyname_async_start(const char *name, int af, int flags, int *error, get
                {
                        if (ifap->ifa_addr == NULL) continue;
                        if ((ifap->ifa_flags & IFF_UP) == 0) continue;
-                       if (ifap->ifa_addr->sa_family == AF_INET)
-                       {
-                               if4++;
-                       }
-                       else if (ifap->ifa_addr->sa_family == AF_INET6)
-                       {
-                               if6++;
-                       }
+                       if (ifap->ifa_addr->sa_family == AF_INET) if4++;
+                       else if (ifap->ifa_addr->sa_family == AF_INET6) if6++;
                }
 
                freeifaddrs(ifa);
@@ -985,7 +366,7 @@ getipnodebyname_async_start(const char *name, int af, int flags, int *error, get
                /* Bail out if there are no interfaces */
                if ((if4 == 0) && (if6 == 0))
                {
-                       *error = NO_ADDRESS;
+                       if (err != NULL) *err = NO_RECOVERY;
                        return MACH_PORT_NULL;
                }
        }
@@ -994,108 +375,133 @@ getipnodebyname_async_start(const char *name, int af, int flags, int *error, get
         * Figure out what we want.
         * If user asked for AF_INET, we only want V4 addresses.
         */
-       switch (af)
+       want = WANT_A4_ONLY;
+
+       if (family == AF_INET)
        {
-               case AF_INET:
+               if ((flags & AI_ADDRCONFIG) && (if4 == 0))
                {
-                       want = WANT_A4_ONLY;
-                       if ((flags & AI_ADDRCONFIG) && (if4 == 0))
-                       {
-                               *error = NO_ADDRESS;
-                               return MACH_PORT_NULL;
-                       }
+                       if (err != NULL) *err = NO_RECOVERY;
+                       return MACH_PORT_NULL;
                }
-               break;
+       }
+       else
+       {
+               /* family == AF_INET6 */
+               want = WANT_A6_ONLY;
 
-               case AF_INET6:
+               if (flags & (AI_V4MAPPED | AI_V4MAPPED_CFG))
                {
-                       want = WANT_A6_ONLY;
-                       if (flags & (AI_V4MAPPED|AI_V4MAPPED_CFG))
+                       if (flags & AI_ALL)
                        {
-                               if (flags & AI_ALL)
-                               {
-                                       want = WANT_A6_PLUS_MAPPED_A4;
-                               }
-                               else
-                               {
-                                       want = WANT_A6_OR_MAPPED_A4_IF_NO_A6;
-                               }
+                               want = WANT_A6_PLUS_MAPPED_A4;
                        }
                        else
                        {
-                               if ((flags & AI_ADDRCONFIG) && (if6 == 0))
-                               {
-                                       *error = NO_ADDRESS;
-                                       return MACH_PORT_NULL;
-                               }
+                               want = WANT_A6_OR_MAPPED_A4_IF_NO_A6;
+                       }
+               }
+               else
+               {
+                       if ((flags & AI_ADDRCONFIG) && (if6 == 0)) 
+                       {
+                               if (err != NULL) *err = NO_RECOVERY;
+                               return MACH_PORT_NULL;
                        }
                }
-               break;
        }
 
-       cb.nodeName = callout;
-       mp = _gethostbyname_async_start(name, want, &h_errno, cb, context);
+       if (proc < 0)
+       {
+               status = LI_DSLookupGetProcedureNumber("gethostbyname", &proc);
+               if (status != KERN_SUCCESS) return MACH_PORT_NULL;
+       }
+
+       my_context = (my_context_t *)calloc(1, sizeof(my_context_t));
+       if (my_context == NULL)
+       {
+               *err = NO_RECOVERY;
+               return MACH_PORT_NULL;
+       }
+
+       my_context->user_context = context;
+       my_context->want = want;
+
+       want4 = 1;
+       want6 = 1;
+
+       if (want == WANT_A4_ONLY) want6 = 0;
+       else if (want == WANT_A6_ONLY) want4 = 0;
+       else if (WANT_MAPPED_A4_ONLY) want6 = 0;
+
+       request = kvbuf_query("kskuku", "name", name, "ipv4", want4, "ipv6", want6);
+       if (request == NULL) return MACH_PORT_NULL;
+
+       status = LI_async_start(&mp, proc, request, (void *)callback, my_context);
+
+       kvbuf_free(request);
        return mp;
 }
 
 void
 getipnodebyname_async_cancel(mach_port_t port)
 {
-       _async_cancel(port);
-       return;
+       my_context_t *my_context;
+
+       my_context = NULL;
+
+       LI_async_call_cancel(port, (void **)&my_context);
+
+       if (my_context != NULL) free(my_context);
 }
 
 void
-getipnodebyname_async_handleReply(void *replyMsg)
+getipnodebyname_async_handleReply(void *msg)
 {
-       int error = 0;
-       struct hostent *he = NULL;
-       a_requests_t *request = NULL;
-       static int proc4 = -1;
+       getipnodebyname_async_callback callback;
+       struct hostent *out;
+       uint32_t len, want;
+       int status, err;
+       kvarray_t *reply;
+       my_context_t *my_context;
+       void *context;
+
+       callback = (getipnodebyname_async_callback)NULL;
+       my_context = NULL;
+       context = NULL;
+       len = 0;
+       reply = NULL;
 
-       if (_gethostbyname_async_handleReply(replyMsg, &request, &he, &error))
+       status = LI_async_handle_reply(msg, &reply, (void **)&callback, (void **)&my_context);
+       if ((status != KERN_SUCCESS) || (reply == NULL))
        {
-               /*
-                * we have an answer to provide
-                */
-               if ((he == NULL) && (error == HOST_NOT_FOUND) && ((request->request.want == WANT_A6_PLUS_MAPPED_A4) || (request->request.want == WANT_A6_OR_MAPPED_A4_IF_NO_A6)))
+               if (status == MIG_REPLY_MISMATCH) return;
+               if (callback != NULL)
                {
-                       /*
-                        * no host found (yet), if requested we send a
-                        * followup query to lookupd.
-                        */
-                       if (proc4 < 0)
-                       {
-                               if (_lookup_link(_lu_port, "gethostbyname", &proc4) != KERN_SUCCESS)
-                               {
-                                       error = NO_RECOVERY;
-                                       goto answer;
-                               }
-                       }
-
-                       request->request.proc = proc4;
-                       request->request.want = WANT_MAPPED_A4_ONLY;
-                       if (_lookup_all_tx(_lu_port, request->request.proc, request->request.data, request->request.dataLen, &request->replyPort) == KERN_SUCCESS)
-                       {
-                               request_queue(request);
-                               return;
-                       }
-                       else
-                       {
-                               error = NO_RECOVERY;
-                       }
+                       if (my_context != NULL) context = my_context->user_context;
+                       callback(NULL, NO_RECOVERY, context);
+                       free(my_context);
+                       return;
                }
+       }
+
+       want = WANT_A4_ONLY;
+       if (my_context != NULL)
+       {
+               context = my_context->user_context;
+               want = my_context->want;
+               free(my_context);
+       }
 
-answer:
-               (request->callout.nodeName)(he, error, request->context);
-               (void)mach_port_mod_refs(mach_task_self(), request->replyPort, MACH_PORT_RIGHT_RECEIVE, -1);
-               if (request->request.data != NULL) free(request->request.data);
-               free(request);
-               /*
-                * Note: it is up to the callback function to call
-                * freehostent().
-                */
+       out = extract_host(reply, want);
+       kvarray_free(reply);
+
+       if (out == NULL)
+       {
+               err = HOST_NOT_FOUND;
+               callback(NULL, err, context);
+               return;
        }
 
-       return;
+       callback(out, 0, context);
 }
index 1badf4807d5f2108c0482677f3ea18b93f362c90..f140a038be287fa8e5c1263218b88c22da762979 100644 (file)
  * Netgroup lookup
  * Copyright (C) 1989 by NeXT, Inc.
  */
-#include <netgr.h>
+#include <netdb.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 : (_lu_string *)&(x))
-
-struct lu_netgrent
+struct li_netgrent
 {
        char *ng_host;
        char *ng_user;
        char *ng_domain;
 };
 
-static void 
-free_netgroup_data(struct lu_netgrent *ng)
+#define ENTRY_SIZE sizeof(struct li_netgrent)
+#define ENTRY_KEY _li_data_key_netgroup
+
+static struct li_netgrent *
+copy_netgroup(struct li_netgrent *in)
 {
-       if (ng == NULL) return;
+       if (in == NULL) return NULL;
 
-       if (ng->ng_host != NULL) free(ng->ng_host);
-       if (ng->ng_user != NULL) free(ng->ng_user);
-       if (ng->ng_domain != NULL) free(ng->ng_domain);
+       return (struct li_netgrent *)LI_ils_create("sss", in->ng_host, in->ng_user, in->ng_domain);
 }
 
-static void 
-free_netgroup(struct lu_netgrent *ng)
-{
-       if (ng == NULL) return;
-       free_netgroup_data(ng);
-       free(ng);
- }
-
-static void
-free_lu_thread_info_netgroup(void *x)
+/*
+ * Extract the next netgroup entry from a kvarray.
+ */
+static struct li_netgrent *
+extract_netgroup(kvarray_t *in)
 {
-       struct lu_thread_info *tdata;
+       struct li_netgrent tmp;
+       uint32_t d, k, kcount;
 
-       if (x == NULL) return;
-
-       tdata = (struct lu_thread_info *)x;
-       
-       if (tdata->lu_entry != NULL)
-       {
-               free_netgroup((struct lu_netgrent *)tdata->lu_entry);
-               tdata->lu_entry = NULL;
-       }
+       if (in == NULL) return NULL;
 
-       _lu_data_free_vm_xdr(tdata);
+       d = in->curr;
+       in->curr++;
 
-       free(tdata);
-}
-
-static struct lu_netgrent *
-extract_netgroup(XDR *xdr)
-{
-       char *h, *u, *d;
-       struct lu_netgrent *ng;
+       if (d >= in->count) return NULL;
 
-       if (xdr == NULL) return NULL;
+       memset(&tmp, 0, ENTRY_SIZE);
 
-       h = NULL;
-       u = NULL;
-       d = NULL;
+       kcount = in->dict[d].kcount;
 
-       if (!xdr_string(xdr, &h, LU_LONG_STRING_LENGTH))
+       for (k = 0; k < kcount; k++)
        {
-               return NULL;
-       }
+               if (!strcmp(in->dict[d].key[k], "user"))
+               {
+                       if (tmp.ng_user != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
 
-       if (!xdr_string(xdr, &u, LU_LONG_STRING_LENGTH))
-       {
-               free(h);
-               return NULL;
-       }
+                       tmp.ng_user = (char *)in->dict[d].val[k][0];
+               }
+               else if (!strcmp(in->dict[d].key[k], "host"))
+               {
+                       if (tmp.ng_host != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
 
-       if (!xdr_string(xdr, &d, LU_LONG_STRING_LENGTH))
-       {
-               free(h);
-               free(u);
-               return NULL;
-       }
+                       tmp.ng_host = (char *)in->dict[d].val[k][0];
+               }
+               else if (!strcmp(in->dict[d].key[k], "domain"))
+               {
+                       if (tmp.ng_domain != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
 
-       ng = (struct lu_netgrent *)calloc(1, sizeof(struct lu_netgrent));
+                       tmp.ng_domain = (char *)in->dict[d].val[k][0];
+               }
+       }
 
-       ng->ng_host = h;
-       ng->ng_user = u;
-       ng->ng_domain = d;
+       if (tmp.ng_user == NULL) tmp.ng_user = "";
+       if (tmp.ng_host == NULL) tmp.ng_host = "";
+       if (tmp.ng_domain == NULL) tmp.ng_domain = "";
 
-       return ng;
+       return copy_netgroup(&tmp);
 }
 
-#ifdef NOTDEF
-static struct lu_netgrent *
-copy_netgroup(struct lu_netgrent *in)
+static int
+check_innetgr(kvarray_t *in)
 {
-       struct lu_netgrent *ng;
-
-       if (in == NULL) return NULL;
-
-       ng = (struct group *)calloc(1, sizeof(struct lu_netgrent));
-
-       ng->ng_host = LU_COPY_STRING(in->ng_host);
-       ng->ng_user = LU_COPY_STRING(in->ng_user);
-       ng->ng_domain = LU_COPY_STRING(in->ng_domain);
+       uint32_t d, k, kcount;
 
-       return ng;
-}
-#endif
+       if (in == NULL) return 0;
 
-static void
-recycle_netgroup(struct lu_thread_info *tdata, struct lu_netgrent *in)
-{
-       struct lu_netgrent *ng;
-
-       if (tdata == NULL) return;
-       ng = (struct lu_netgrent *)tdata->lu_entry;
+       d = in->curr;
+       if (d >= in->count) return 0;
 
-       if (in == NULL)
-       {
-               free_netgroup(ng);
-               tdata->lu_entry = NULL;
-       }
+       kcount = in->dict[d].kcount;
 
-       if (tdata->lu_entry == NULL)
+       for (k = 0; k < kcount; k++)
        {
-               tdata->lu_entry = in;
-               return;
+               if (!strcmp(in->dict[d].key[k], "result"))
+               {
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       return atoi(in->dict[d].val[k][0]);
+               }
        }
 
-       free_netgroup_data(ng);
-
-       ng->ng_host = in->ng_host;
-       ng->ng_user = in->ng_user;
-       ng->ng_domain = in->ng_domain;
-
-       free(in);
+       return 0;
 }
 
-
 static int
-lu_innetgr(const char *group, const char *host, const char *user,
-       const char *domain)
+ds_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];
+       int is_innetgr;
+       kvbuf_t *request;
+       kvarray_t *reply;
+       kern_return_t status;
        static int proc = -1;
-       int size;
-       int res;
-       _lu_innetgr_args args;
-       char *lookup_buf;
 
        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;
+               status = LI_DSLookupGetProcedureNumber("innetgr", &proc);
+               if (status != KERN_SUCCESS) return 0;
        }
 
-       size = xdr_getpos(&xdr) / BYTES_PER_XDR_UNIT;
-       xdr_destroy(&xdr);
+       /* Encode NULL */
+       if (group == NULL) group = "";
+       if (host == NULL) host = "";
+       if (user == NULL) user = "";
+       if (domain == NULL) domain = "";
 
-       datalen = 0;
-       lookup_buf = NULL;
+       request = kvbuf_query("ksksksks", "netgroup", group, "host", host, "user", user, "domain", domain);
+       if (request == NULL) return 0;
 
-       if (_lookup_all(_lu_port, proc, (unit *)namebuf, size, &lookup_buf, &datalen) != KERN_SUCCESS)
-       {
-               return 0;
-       }
-
-       datalen *= BYTES_PER_XDR_UNIT;
-       if ((lookup_buf == NULL) || (datalen == 0)) return 0;
+       reply = NULL;
+       status = LI_DSLookupQuery(proc, request, &reply);
+       kvbuf_free(request);
 
-       xdrmem_create(&xdr, lookup_buf, datalen, XDR_DECODE);
-       if (!xdr_int(&xdr, &res))
-       {
-               xdr_destroy(&xdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return 0;
-       }
+       if (status != KERN_SUCCESS) return 0;
 
-       xdr_destroy(&xdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
+       is_innetgr = check_innetgr(reply);
+       kvarray_free(reply);
 
-       return 1;
+       return is_innetgr;
 }
 
 static void
-lu_endnetgrent(void)
+ds_endnetgrent(void)
 {
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_netgroup, free_lu_thread_info_netgroup);
-       _lu_data_free_vm_xdr(tdata);
+       LI_data_free_kvarray(LI_data_find_key(ENTRY_KEY));
 }
 
-
 /* 
  * This is different than the other setXXXent routines
  * since this is really more like getnetgrbyname() than
  * getnetgrent().
  */ 
 static void
-lu_setnetgrent(const char *name)
+ds_setnetgrent(const char *name)
 {
-       unsigned datalen;
-       char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT];
-       XDR outxdr;
+       struct li_thread_info *tdata;
+       kvbuf_t *request;
+       kvarray_t *reply;
+       kern_return_t status;
        static int proc = -1;
-       struct lu_thread_info *tdata;
 
-       tdata = _lu_data_create_key(_lu_data_key_netgroup, free_lu_thread_info_netgroup);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_netgroup, tdata);
-       }
+       tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
+       if (tdata == NULL) return;
 
-       lu_endnetgrent();
+       if (tdata->li_vm != NULL) return;
 
        if (proc < 0)
        {
-               if (_lookup_link(_lu_port, "getnetgrent", &proc) != KERN_SUCCESS)
+               status = LI_DSLookupGetProcedureNumber("getnetgrent", &proc);
+               if (status != KERN_SUCCESS)
                {
-                       lu_endnetgrent();
+                       LI_data_free_kvarray(tdata);
                        return;
                }
        }
 
-       xdrmem_create(&outxdr, namebuf, sizeof(namebuf), XDR_ENCODE);
-       if (!xdr__lu_string(&outxdr, (_lu_string *)&name))
-       {
-               xdr_destroy(&outxdr);
-               lu_endnetgrent();
-               return;
-       }
-       
-       datalen = xdr_getpos(&outxdr);
-       xdr_destroy(&outxdr);
-       if (_lookup_all(_lu_port, proc, (unit *)namebuf, datalen / BYTES_PER_XDR_UNIT, &(tdata->lu_vm), &(tdata->lu_vm_length)) != KERN_SUCCESS)
-       {
-               lu_endnetgrent();
-               return;
-       }
+       request = kvbuf_query_key_val("netgroup", name);
+       if (request == NULL) return;
 
-       /* mig stubs measure size in words (4 bytes) */
-       tdata->lu_vm_length *= 4;
+       reply = NULL;
+       status = LI_DSLookupQuery(proc, request, &reply);
+       kvbuf_free(request);
 
-       if (tdata->lu_xdr != NULL)
-       {       
-               xdr_destroy(tdata->lu_xdr);
-               free(tdata->lu_xdr);
+       if (status != KERN_SUCCESS)
+       {
+               LI_data_free_kvarray(tdata);
+               return;
        }
-       tdata->lu_xdr = (XDR *)calloc(1, sizeof(XDR));
 
-       xdrmem_create(tdata->lu_xdr, tdata->lu_vm, tdata->lu_vm_length, XDR_DECODE);
-       if (!xdr_int(tdata->lu_xdr, &tdata->lu_vm_cursor)) lu_endnetgrent();
+       tdata->li_vm = (char *)reply;
 }
 
 
-static struct lu_netgrent *
-lu_getnetgrent(void)
+static struct li_netgrent *
+ds_getnetgrent(void)
 {
-       struct lu_netgrent *ng;
-       struct lu_thread_info *tdata;
+       struct li_netgrent *entry;
+       struct li_thread_info *tdata;
 
-       tdata = _lu_data_create_key(_lu_data_key_netgroup, free_lu_thread_info_netgroup);
+       tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
        if (tdata == NULL) return NULL;
 
-       if (tdata->lu_vm_cursor == 0)
-       {
-               lu_endnetgrent();
-               return NULL;
-       }
-
-       ng = extract_netgroup(tdata->lu_xdr);
-       if (ng == NULL)
+       entry = extract_netgroup((kvarray_t *)(tdata->li_vm));
+       if (entry == NULL)
        {
-               lu_endnetgrent();
+               ds_endnetgrent();
                return NULL;
        }
 
-       tdata->lu_vm_cursor--;
-       
-       return ng;
+       return entry;
 }
 
 int 
 innetgr(const char *group, const char *host, const char *user,
        const char *domain)
 {
-       if (_lu_running()) return (lu_innetgr(group, host, user, domain));
+       if (_ds_running()) return (ds_innetgr(group, host, user, domain));
        return 0;
 }
 
 int
 getnetgrent(char **host, char **user, char **domain)
 {
-       struct lu_netgrent *res = NULL;
-       struct lu_thread_info *tdata;
+       struct li_netgrent *res = NULL;
+       struct li_thread_info *tdata;
 
-       tdata = _lu_data_create_key(_lu_data_key_netgroup, free_lu_thread_info_netgroup);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_netgroup, tdata);
-       }
+       tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
+       if (tdata == NULL) return 0;
 
        res = NULL;
-       if (_lu_running()) res = lu_getnetgrent();
+       if (_ds_running()) res = ds_getnetgrent();
 
-       recycle_netgroup(tdata, res);
+       LI_data_recycle(tdata, res, ENTRY_SIZE);
        if (res == NULL) return 0;
 
        if (host != NULL) *host = res->ng_host;
@@ -370,11 +267,11 @@ getnetgrent(char **host, char **user, char **domain)
 void
 setnetgrent(const char *name)
 {
-       if (_lu_running()) lu_setnetgrent(name);
+       if (_ds_running()) ds_setnetgrent(name);
 }
 
 void
 endnetgrent(void)
 {
-       if (_lu_running()) lu_endnetgrent();
+       if (_ds_running()) ds_endnetgrent();
 }
index 8f9a5519d1198127b51d86b20abd3271049e0f8d..4f743946de853ac742e1450826d65329a35e83be 100644 (file)
 #include <mach/mach.h>
 #include <stdio.h>
 #include <string.h>
-#include <rpc/types.h>
-#include <rpc/xdr.h>
 #include <netdb.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <pthread.h>
-
-#include "_lu_types.h"
-#include "lookup.h"
 #include "lu_utils.h"
 
 static pthread_mutex_t _network_lock = PTHREAD_MUTEX_INITIALIZER;
@@ -55,409 +50,146 @@ extern struct netent *_old_getnetent();
 extern void _old_setnetent();
 extern void _old_endnetent();
 
-extern mach_port_t _lu_port;
-extern int _lu_running(void);
+#define ENTRY_SIZE sizeof(struct netent)
+#define ENTRY_KEY _li_data_key_network
 
-static void
-free_network_data(struct netent *n)
+static struct netent *
+copy_network(struct netent *in)
 {
-       char **aliases;
-
-       if (n == NULL) return;
-
-       free(n->n_name);
-
-       aliases = n->n_aliases;
-       if (aliases != NULL)
-       {
-               while (*aliases != NULL) free(*aliases++);
-               free(n->n_aliases);
-       }
-}
+       if (in == NULL) return NULL;
 
-static void
-free_network(struct netent *n)
-{
-       if (n == NULL) return;
-       free_network_data(n);
-       free(n);
+       return (struct netent *)LI_ils_create("s*44", in->n_name, in->n_aliases, in->n_addrtype, in->n_net);
 }
 
-static void
-free_lu_thread_info_network(void *x)
+/*
+ * Extract the next network entry from a kvarray.
+ */
+static void *
+extract_network(kvarray_t *in)
 {
-       struct lu_thread_info *tdata;
-
-       if (x == NULL) return;
+       struct netent tmp;
+       uint32_t d, k, kcount;
+       char *empty[1];
 
-       tdata = (struct lu_thread_info *)x;
-       
-       if (tdata->lu_entry != NULL)
-       {
-               free_network((struct netent *)tdata->lu_entry);
-               tdata->lu_entry = NULL;
-       }
-
-       _lu_data_free_vm_xdr(tdata);
-
-       free(tdata);
-}
+       if (in == NULL) return NULL;
 
-static struct netent *
-extract_network(XDR *xdr)
-{
-       struct netent *n;
-       int i, j, nvals, nkeys, status;
-       char *key, **vals;
+       d = in->curr;
+       in->curr++;
 
-       if (xdr == NULL) return NULL;
+       if (d >= in->count) return NULL;
 
-       if (!xdr_int(xdr, &nkeys)) return NULL;
+       empty[0] = NULL;
+       memset(&tmp, 0, ENTRY_SIZE);
 
-       n = (struct netent *)calloc(1, sizeof(struct netent));
+       tmp.n_addrtype = AF_INET;
 
-       n->n_addrtype = AF_INET;
+       kcount = in->dict[d].kcount;
 
-       for (i = 0; i < nkeys; i++)
+       for (k = 0; k < kcount; k++)
        {
-               key = NULL;
-               vals = NULL;
-               nvals = 0;
-
-               status = _lu_xdr_attribute(xdr, &key, &vals, &nvals);
-               if (status < 0)
+               if (!strcmp(in->dict[d].key[k], "n_name"))
                {
-                       free_network(n);
-                       return NULL;
-               }
+                       if (tmp.n_name != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
 
-               if (nvals == 0)
-               {
-                       free(key);
-                       continue;
+                       tmp.n_name = (char *)in->dict[d].val[k][0];
                }
-
-               j = 0;
-
-               if ((n->n_name == NULL) && (!strcmp("name", key)))
+               else if (!strcmp(in->dict[d].key[k], "n_net"))
                {
-                       n->n_name = vals[0];
-                       if (nvals > 1)
-                       {
-                               n->n_aliases = (char **)calloc(nvals, sizeof(char *));
-                               for  (j = 1; j < nvals; j++) n->n_aliases[j-1] = vals[j];
-                       }
-                       j = nvals;
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       tmp.n_net = inet_network(in->dict[d].val[k][0]);
                }
-               else if (!strcmp("address", key))
+               else if (!strcmp(in->dict[d].key[k], "n_addrtype"))
                {
-                       n->n_net = inet_network(vals[0]);
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       tmp.n_addrtype = atoi(in->dict[d].val[k][0]);
                }
-       
-               free(key);
-               if (vals != NULL)
+               else if (!strcmp(in->dict[d].key[k], "n_aliases"))
                {
-                       for (; j < nvals; j++) free(vals[j]);
-                       free(vals);
-               }
-       }
-
-       if (n->n_name == NULL) n->n_name = strdup("");
-       if (n->n_aliases == NULL) n->n_aliases = (char **)calloc(1, sizeof(char *));
+                       if (tmp.n_aliases != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
 
-       return n;
-}
-
-static struct netent *
-copy_network(struct netent *in)
-{
-       int i, len;
-       struct netent *n;
-
-       if (in == NULL) return NULL;
-
-       n = (struct netent *)calloc(1, sizeof(struct netent));
-
-       n->n_name = LU_COPY_STRING(in->n_name);
-
-       len = 0;
-       if (in->n_aliases != NULL)
-       {
-               for (len = 0; in->n_aliases[len] != NULL; len++);
-       }
-
-       n->n_aliases = (char **)calloc(len + 1, sizeof(char *));
-       for (i = 0; i < len; i++)
-       {
-               n->n_aliases[i] = strdup(in->n_aliases[i]);
-       }
-
-       n->n_addrtype = in->n_addrtype;
-       n->n_net = in->n_net;
-
-       return n;
-}
-
-static void
-recycle_network(struct lu_thread_info *tdata, struct netent *in)
-{
-       struct netent *n;
-
-       if (tdata == NULL) return;
-       n = (struct netent *)tdata->lu_entry;
-
-       if (in == NULL)
-       {
-               free_network(n);
-               tdata->lu_entry = NULL;
-       }
-
-       if (tdata->lu_entry == NULL)
-       {
-               tdata->lu_entry = in;
-               return;
+                       tmp.n_aliases = (char **)in->dict[d].val[k];
+               }
        }
 
-       free_network_data(n);
+       if (tmp.n_name == NULL) tmp.n_name = "";
+       if (tmp.n_aliases == NULL) tmp.n_aliases = empty;
 
-       n->n_name = in->n_name;
-       n->n_aliases = in->n_aliases;
-       n->n_addrtype = in->n_addrtype;
-       n->n_net = in->n_net;
-
-       free(in);
+       return copy_network(&tmp);
 }
 
 static struct netent *
-lu_getnetbyaddr(long addr, int type)
+ds_getnetbyaddr(uint32_t addr, int type)
 {
-       struct netent *n;
-       unsigned datalen;
-       XDR inxdr;
        static int proc = -1;
-       char *lookup_buf;
-       int count;
+       unsigned char f1, f2, f3;
+       char val[64];
 
        if (type != AF_INET) return NULL;
 
-       if (proc < 0)
-       {
-               if (_lookup_link(_lu_port, "getnetbyaddr", &proc) != KERN_SUCCESS)
-               {
-                       return NULL;
-               }
-       }
-
-       addr = htonl(addr);
-       datalen = 0;
-       lookup_buf = NULL;
-
-       if (_lookup_all(_lu_port, proc, (unit *)&addr, 1, &lookup_buf, &datalen) != KERN_SUCCESS)
-       {
-               return NULL;
-       }
-
-       datalen *= BYTES_PER_XDR_UNIT;
-       if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
-
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
-
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
+       f1 = addr & 0xff;
+       addr >>= 8;
+       f2 = addr & 0xff;
+       addr >>= 8;
+       f3 = addr & 0xff;
 
-       n = extract_network(&inxdr);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
+       if (f3 != 0) snprintf(val, sizeof(val), "%u.%u.%u", f3, f2, f1);
+       else if (f2 != 0) snprintf(val, sizeof(val), "%u.%u", f2, f1);
+       else snprintf(val, sizeof(val), "%u", f1);
 
-       return n;
+       return (struct netent *)LI_getone("getnetbyaddr", &proc, extract_network, "net", val);
 }
 
 static struct netent *
-lu_getnetbyname(const char *name)
+ds_getnetbyname(const char *name)
 {
-       struct netent *n;
-       unsigned datalen;
-       char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT];
-       XDR outxdr;
-       XDR inxdr;
        static int proc = -1;
-       char *lookup_buf;
-       int count;
-
-       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, (_lu_string *)&name))
-       {
-               xdr_destroy(&outxdr);
-               return NULL;
-       }
-
-       datalen = 0;
-       lookup_buf = NULL;
-
-       if (_lookup_all(_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;
-       if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
-
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
-
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
 
-       n = extract_network(&inxdr);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-
-       return n;
+       return (struct netent *)LI_getone("getnetbyname", &proc, extract_network, "name", name);
 }
 
 static void
-lu_endnetent()
+ds_endnetent()
 {
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_network, free_lu_thread_info_network);
-       _lu_data_free_vm_xdr(tdata);
+       LI_data_free_kvarray(LI_data_find_key(ENTRY_KEY));
 }
 
 static void
-lu_setnetent()
+ds_setnetent()
 {
-       lu_endnetent();
+       ds_endnetent();
 }
 
 static struct netent *
-lu_getnetent()
+ds_getnetent()
 {
        static int proc = -1;
-       struct lu_thread_info *tdata;
-       struct netent *n;
-
-       tdata = _lu_data_create_key(_lu_data_key_network, free_lu_thread_info_network);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_network, tdata);
-       }
-
-       if (tdata->lu_vm == NULL)
-       {
-               if (proc < 0)
-               {
-                       if (_lookup_link(_lu_port, "getnetent", &proc) != KERN_SUCCESS)
-                       {
-                               lu_endnetent();
-                               return NULL;
-                       }
-               }
-
-               if (_lookup_all(_lu_port, proc, NULL, 0, &(tdata->lu_vm), &(tdata->lu_vm_length)) != KERN_SUCCESS)
-               {
-                       lu_endnetent();
-                       return NULL;
-               }
-
-               /* mig stubs measure size in words (4 bytes) */
-               tdata->lu_vm_length *= 4;
-
-               if (tdata->lu_xdr != NULL)
-               {
-                       xdr_destroy(tdata->lu_xdr);
-                       free(tdata->lu_xdr);
-               }
-               tdata->lu_xdr = (XDR *)calloc(1, sizeof(XDR));
-
-               xdrmem_create(tdata->lu_xdr, tdata->lu_vm, tdata->lu_vm_length, XDR_DECODE);
-               if (!xdr_int(tdata->lu_xdr, &tdata->lu_vm_cursor))
-               {
-                       lu_endnetent();
-                       return NULL;
-               }
-       }
-
-       if (tdata->lu_vm_cursor == 0)
-       {
-               lu_endnetent();
-               return NULL;
-       }
-
-       n = extract_network(tdata->lu_xdr);
-       if (n == NULL)
-       {
-               lu_endnetent();
-               return NULL;
-       }
 
-       tdata->lu_vm_cursor--;
-       
-       return n;
+       return (struct netent *)LI_getent("getnetent", &proc, extract_network, ENTRY_KEY, ENTRY_SIZE);
 }
 
 static struct netent *
-getnet(const char *name, long addr, int type, int source)
+getnet(const char *name, uint32_t addr, int type, int source)
 {
        struct netent *res = NULL;
-       struct lu_thread_info *tdata;
+       struct li_thread_info *tdata;
 
-       tdata = _lu_data_create_key(_lu_data_key_network, free_lu_thread_info_network);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_network, tdata);
-       }
+       tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
+       if (tdata == NULL) return NULL;
 
-       if (_lu_running())
+       if (_ds_running())
        {
                switch (source)
                {
                        case N_GET_NAME:
-                               res = lu_getnetbyname(name);
+                               res = ds_getnetbyname(name);
                                break;
                        case N_GET_ADDR:
-                               res = lu_getnetbyaddr(addr, type);
+                               res = ds_getnetbyaddr(addr, type);
                                break;
                        case N_GET_ENT:
-                               res = lu_getnetent();
+                               res = ds_getnetent();
                                break;
                        default: res = NULL;
                }
@@ -465,6 +197,7 @@ getnet(const char *name, long addr, int type, int source)
        else
        {
                pthread_mutex_lock(&_network_lock);
+
                switch (source)
                {
                        case N_GET_NAME:
@@ -478,11 +211,12 @@ getnet(const char *name, long addr, int type, int source)
                                break;
                        default: res = NULL;
                }
+
                pthread_mutex_unlock(&_network_lock);
        }
 
-       recycle_network(tdata, res);
-       return (struct netent *)tdata->lu_entry;
+       LI_data_recycle(tdata, res, ENTRY_SIZE);
+       return (struct netent *)tdata->li_entry;
 }
 
 struct netent *
@@ -506,13 +240,13 @@ getnetent(void)
 void
 setnetent(int stayopen)
 {
-       if (_lu_running()) lu_setnetent();
+       if (_ds_running()) ds_setnetent();
        else _old_setnetent(stayopen);
 }
 
 void
 endnetent(void)
 {
-       if (_lu_running()) lu_endnetent();
+       if (_ds_running()) ds_endnetent();
        else _old_endnetent();
 }
index c7134b24298001eafe07ab4f12912feccbd50dfd..a83713e12bc656d511dcad2c1756be420f9a9fcd 100644 (file)
 #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();
index e455b4cc1ded4607f15da93f2c1b79ad901966d7..0b7d1950859f4dff559598594877b8714893ba12 100644 (file)
 #include <mach/mach.h>
 #include <stdio.h>
 #include <string.h>
-#include <rpc/types.h>
-#include <rpc/xdr.h>
 #include <pthread.h>
-
-#include "_lu_types.h"
-#include "lookup.h"
 #include "printerdb.h"
 #include "lu_utils.h"
 
-static pthread_mutex_t _printer_lock = PTHREAD_MUTEX_INITIALIZER;
-
-#define P_GET_NAME 1
-#define P_GET_ENT 2
-
-extern prdb_ent *_old_prdb_get();
-extern prdb_ent *_old_prdb_getbyname();
-extern void _old_prdb_set();
-extern void _old_prdb_end();
-
-static void 
-free_printer_data(prdb_ent *p)
-{
-       char **names;
-       int i;
-
-       if (p == NULL) return;
-
-       names = p->pe_name;
-       if (names != NULL)
-       {
-               while (*names) free(*names++);
-               free(p->pe_name);
-       }
-
-       for (i = 0; i < p->pe_nprops; i++)
-       {
-               free(p->pe_prop[i].pp_key);
-               free(p->pe_prop[i].pp_value);
-       }
-
-       free(p->pe_prop);
-}
-
-static void 
-free_printer(prdb_ent *p)
-{
-       if (p == NULL) return;
-       free_printer_data(p);
-       free(p);
-}
-
-static void
-free_lu_thread_info_printer(void *x)
-{
-       struct lu_thread_info *tdata;
-
-       if (x == NULL) return;
-
-       tdata = (struct lu_thread_info *)x;
-       
-       if (tdata->lu_entry != NULL)
-       {
-               free_printer((prdb_ent *)tdata->lu_entry);
-               tdata->lu_entry = NULL;
-       }
-
-       _lu_data_free_vm_xdr(tdata);
-
-       free(tdata);
-}
-
-static prdb_ent *
-extract_printer(XDR *xdr)
-{
-       prdb_ent *p;
-       int i, j, nvals, nkeys, status;
-       char *key, **vals;
-
-       if (xdr == NULL) return NULL;
-
-       if (!xdr_int(xdr, &nkeys)) return NULL;
-
-       p = (prdb_ent *)calloc(1, sizeof(prdb_ent));
-
-       for (i = 0; i < nkeys; i++)
-       {
-               key = NULL;
-               vals = NULL;
-               nvals = 0;
-
-               status = _lu_xdr_attribute(xdr, &key, &vals, &nvals);
-               if (status < 0)
-               {
-                       free_printer(p);
-                       return NULL;
-               }
-
-               j = 0;
-
-               if ((p->pe_name == NULL) && (!strcmp("name", key)))
-               {
-                       free(key);
-                       p->pe_name = vals;
-                       j = nvals;
-                       vals = NULL;
-               }
-               else
-               {
-                       if (p->pe_nprops == 0)
-                       {
-                               p->pe_prop = (prdb_property *)calloc(1, sizeof(prdb_property));
-                       }
-                       else
-                       {
-                               p->pe_prop = (prdb_property *)realloc(p->pe_prop, (p->pe_nprops + 1) * sizeof(prdb_property));
-                       }
-                       p->pe_prop[p->pe_nprops].pp_key = key;
-                       p->pe_prop[p->pe_nprops].pp_value = NULL;
-                       if (nvals > 0)
-                       {
-                               p->pe_prop[p->pe_nprops].pp_value = vals[0];
-                               j = 1;
-                       }
-                       else
-                       {
-                               p->pe_prop[p->pe_nprops].pp_value = strdup("");
-                       }
-                       p->pe_nprops++;
-               }
-       
-               if (vals != NULL)
-               {
-                       for (; j < nvals; j++) free(vals[j]);
-                       free(vals);
-               }
-       }
-
-       if (p->pe_name == NULL) p->pe_name = (char **)calloc(1, sizeof(char *));
-       if (p->pe_prop == NULL) p->pe_prop = (prdb_property *)calloc(1, sizeof(prdb_property));
-
-       return p;
-}
-
-static prdb_ent *
-copy_printer(prdb_ent *in)
-{
-       int i;
-       prdb_ent *p;
-
-       if (in == NULL) return NULL;
-
-       p = (prdb_ent *)calloc(1, sizeof(prdb_ent));
-
-       if (in->pe_name != NULL)
-       {
-               for (i = 0; in->pe_name[i] != NULL; i++);       
-               p->pe_name = (char **)calloc(i, sizeof(char *));
-               for (i = 0; p->pe_name[i] != NULL; i++) p->pe_name[i] = strdup(in->pe_name[i]);
-       }
-       else
-       {
-               p->pe_name = (char **)calloc(1, sizeof(char *));
-       }
-
-       if (in->pe_nprops > 0)
-       {
-               p->pe_prop = (struct prdb_property *)calloc(in->pe_nprops, sizeof(struct prdb_property));
-               
-               for (i = 0; in->pe_nprops; i++)
-               {
-                       p->pe_prop[i].pp_key = strdup(in->pe_prop[i].pp_key);
-                       p->pe_prop[i].pp_value = NULL;
-                       if (in->pe_prop[i].pp_value != NULL) p->pe_prop[i].pp_value = strdup(in->pe_prop[i].pp_value);
-               }
-       }
-       else
-       {
-               p->pe_prop = (prdb_property *)calloc(1, sizeof(prdb_property));
-       }
-
-       return p;
-}
-
-static void
-recycle_printer(struct lu_thread_info *tdata, struct prdb_ent *in)
-{
-       struct prdb_ent *p;
-
-       if (tdata == NULL) return;
-       p = (struct prdb_ent *)tdata->lu_entry;
-
-       if (in == NULL)
-       {
-               free_printer(p);
-               tdata->lu_entry = NULL;
-       }
-
-       if (tdata->lu_entry == NULL)
-       {
-               tdata->lu_entry = in;
-               return;
-       }
-
-       free_printer_data(p);
-
-       p->pe_name = in->pe_name;
-       p->pe_nprops = in->pe_nprops;
-       p->pe_prop = in->pe_prop;
-
-       free(in);
-}
-
-static prdb_ent *
-lu_prdb_getbyname(const char *name)
-{
-       prdb_ent *p;
-       unsigned datalen;
-       char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT];
-       XDR outxdr;
-       XDR inxdr;
-       static int proc = -1;
-       char *lookup_buf;
-       int count;
-
-       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, (_lu_string *)&name))
-       {
-               xdr_destroy(&outxdr);
-               return NULL;
-       }
-       
-       datalen = 0;
-       lookup_buf = NULL;
-
-       if (_lookup_all(_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;
-       if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
-
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
-
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       p = extract_printer(&inxdr);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-
-       return p;
-}
-
-static void
-lu_prdb_end()
-{
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_printer, free_lu_thread_info_printer);
-       _lu_data_free_vm_xdr(tdata);
-}
-
-static void
-lu_prdb_set()
-{
-       lu_prdb_end();
-}
-
-static prdb_ent *
-lu_prdb_get()
-{
-       prdb_ent *p;
-       static int proc = -1;
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_printer, free_lu_thread_info_printer);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_printer, tdata);
-       }
-
-       if (tdata->lu_vm == NULL)
-       {
-               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, &(tdata->lu_vm), &(tdata->lu_vm_length)) != KERN_SUCCESS)
-               {
-                       lu_prdb_end();
-                       return NULL;
-               }
-
-               /* mig stubs measure size in words (4 bytes) */
-               tdata->lu_vm_length *= 4;
-
-               if (tdata->lu_xdr != NULL)
-               {
-                       xdr_destroy(tdata->lu_xdr);
-                       free(tdata->lu_xdr);
-               }
-               tdata->lu_xdr = (XDR *)calloc(1, sizeof(XDR));
-
-               xdrmem_create(tdata->lu_xdr, tdata->lu_vm, tdata->lu_vm_length, XDR_DECODE);
-               if (!xdr_int(tdata->lu_xdr, &tdata->lu_vm_cursor))
-               {
-                       lu_prdb_end();
-                       return NULL;
-               }
-       }
-
-       if (tdata->lu_vm_cursor == 0)
-       {
-               lu_prdb_end();
-               return NULL;
-       }
-
-       p = extract_printer(tdata->lu_xdr);
-       if (p == NULL)
-       {
-               lu_prdb_end();
-               return NULL;
-       }
-
-       tdata->lu_vm_cursor--;
-       
-       return p;
-}
-
-static prdb_ent *
-getprinter(const char *name, int source)
-{
-       prdb_ent *res = NULL;
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_printer, free_lu_thread_info_printer);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_printer, tdata);
-       }
-
-       if (_lu_running())
-       {
-               switch (source)
-               {
-                       case P_GET_NAME:
-                               res = lu_prdb_getbyname(name);
-                               break;
-                       case P_GET_ENT:
-                               res = lu_prdb_get();
-                               break;
-                       default: res = NULL;
-               }
-       }
-       else
-       {
-               pthread_mutex_lock(&_printer_lock);
-               switch (source)
-               {
-                       case P_GET_NAME:
-                               res = copy_printer(_old_prdb_getbyname(name));
-                               break;
-                       case P_GET_ENT:
-                               res = copy_printer(_old_prdb_get());
-                               break;
-                       default: res = NULL;
-               }
-               pthread_mutex_unlock(&_printer_lock);
-       }
-
-       recycle_printer(tdata, res);
-       return (prdb_ent *)tdata->lu_entry;
-}
-
 const prdb_ent *
 prdb_getbyname(const char *name)
 {
-       return (const prdb_ent *)getprinter(name, P_GET_NAME);
+       return NULL;
 }
 
 const prdb_ent *
 prdb_get(void)
 {
-       return (const prdb_ent *)getprinter(NULL, P_GET_ENT);
+       return NULL;
 }
 
 void
 prdb_set(const char *name)
 {
-       if (_lu_running()) lu_prdb_set();
-       else _old_prdb_set();
 }
 
 void
 prdb_end(void)
 {
-       if (_lu_running()) lu_prdb_end();
-       else _old_prdb_end();
 }
index e91932d9dce1ac2a40ed03812c4737ac8c91362f..ac7810953388df39c6d787c5cadddd5baa5d74aa 100644 (file)
 #include <mach/mach.h>
 #include <stdio.h>
 #include <string.h>
-#include <rpc/types.h>
-#include <rpc/xdr.h>
 #include <netdb.h>
 #include <netinet/in.h>
-
-#include "_lu_types.h"
-#include "lookup.h"
+#include <pthread.h>
 #include "lu_utils.h"
 
 extern struct protoent *_old_getprotobynumber();
@@ -44,410 +40,150 @@ extern struct protoent *_old_getprotoent();
 extern void _old_setprotoent();
 extern void _old_endprotoent();
 
+static pthread_mutex_t _protocol_lock = PTHREAD_MUTEX_INITIALIZER;
+
 #define PROTO_GET_NAME 1
 #define PROTO_GET_NUM 2
 #define PROTO_GET_ENT 3
 
-static void
-free_protocol_data(struct protoent *p)
-{
-       char **aliases;
-
-       if (p == NULL) return;
-
-       if (p->p_name != NULL) free(p->p_name);
-       aliases = p->p_aliases;
-       if (aliases != NULL)
-       {
-               while (*aliases != NULL) free(*aliases++);
-               free(p->p_aliases);
-       }
-}
+#define ENTRY_SIZE sizeof(struct protoent)
+#define ENTRY_KEY _li_data_key_protocol
 
-static void
-free_protocol(struct protoent *p)
+static struct protoent *
+copy_protocol(struct protoent *in)
 {
-       if (p == NULL) return;
-       free_protocol_data(p);
-       free(p);
+       if (in == NULL) return NULL;
+
+       return (struct protoent *)LI_ils_create("s*4", in->p_name, in->p_aliases, in->p_proto);
 }
 
-static void
-free_lu_thread_info_protocol(void *x)
+/*
+ * Extract the next protocol entry from a kvarray.
+ */
+static void *
+extract_protocol(kvarray_t *in)
 {
-       struct lu_thread_info *tdata;
-
-       if (x == NULL) return;
+       struct protoent tmp;
+       uint32_t d, k, kcount;
+       char *empty[1];
 
-       tdata = (struct lu_thread_info *)x;
-       
-       if (tdata->lu_entry != NULL)
-       {
-               free_protocol((struct protoent *)tdata->lu_entry);
-               tdata->lu_entry = NULL;
-       }
-
-       _lu_data_free_vm_xdr(tdata);
-
-       free(tdata);
-}
+       if (in == NULL) return NULL;
 
-static struct protoent *
-extract_protocol(XDR *xdr)
-{
-       struct protoent *p;
-       int i, j, nvals, nkeys, status;
-       char *key, **vals;
+       d = in->curr;
+       in->curr++;
 
-       if (xdr == NULL) return NULL;
+       if (d >= in->count) return NULL;
 
-       if (!xdr_int(xdr, &nkeys)) return NULL;
+       empty[0] = NULL;
+       memset(&tmp, 0, ENTRY_SIZE);
 
-       p = (struct protoent *)calloc(1, sizeof(struct protoent));
+       kcount = in->dict[d].kcount;
 
-       for (i = 0; i < nkeys; i++)
+       for (k = 0; k < kcount; k++)
        {
-               key = NULL;
-               vals = NULL;
-               nvals = 0;
-
-               status = _lu_xdr_attribute(xdr, &key, &vals, &nvals);
-               if (status < 0)
+               if (!strcmp(in->dict[d].key[k], "p_name"))
                {
-                       free_protocol(p);
-                       return NULL;
-               }
+                       if (tmp.p_name != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
 
-               if (nvals == 0)
-               {
-                       free(key);
-                       continue;
+                       tmp.p_name = (char *)in->dict[d].val[k][0];
                }
-
-               j = 0;
-
-               if ((p->p_name == NULL) && (!strcmp("name", key)))
+               else if (!strcmp(in->dict[d].key[k], "p_proto"))
                {
-                       p->p_name = vals[0];
-                       if (nvals > 1)
-                       {
-                               p->p_aliases = (char **)calloc(nvals, sizeof(char *));
-                               for (j = 1; j < nvals; j++) p->p_aliases[j-1] = vals[j];
-                       }
-                       j = nvals;
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       tmp.p_proto = atoi(in->dict[d].val[k][0]);
                }
-               else if (!strcmp("number", key))
+               else if (!strcmp(in->dict[d].key[k], "p_aliases"))
                {
-                       p->p_proto = atoi(vals[0]);
-               }
+                       if (tmp.p_aliases != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
 
-               free(key);
-               if (vals != NULL)
-               {
-                       for (; j < nvals; j++) free(vals[j]);
-                       free(vals);
+                       tmp.p_aliases = (char **)in->dict[d].val[k];
                }
        }
 
-       if (p->p_name == NULL) p->p_name = strdup("");
-       if (p->p_aliases == NULL) p->p_aliases = (char **)calloc(1, sizeof(char *));
-
-       return p;
-}
-
-static struct protoent *
-copy_protocol(struct protoent *in)
-{
-       int i, len;
-       struct protoent *p;
-
-       if (in == NULL) return NULL;
-
-       p = (struct protoent *)calloc(1, sizeof(struct protoent));
-
-       p->p_proto = in->p_proto;
-       p->p_name = LU_COPY_STRING(in->p_name);
-
-       len = 0;
-       if (in->p_aliases != NULL)
-       {
-               for (len = 0; in->p_aliases[len] != NULL; len++);
-       }
-
-       p->p_aliases = (char **)calloc(len + 1, sizeof(char *));
-       for (i = 0; i < len; i++)
-       {
-               p->p_aliases[i] = strdup(in->p_aliases[i]);
-       }
+       if (tmp.p_name == NULL) tmp.p_name = "";
+       if (tmp.p_aliases == NULL) tmp.p_aliases = empty;
 
-       return p;
-}
-
-static void
-recycle_protocol(struct lu_thread_info *tdata, struct protoent *in)
-{
-       struct protoent *p;
-
-       if (tdata == NULL) return;
-       p = (struct protoent *)tdata->lu_entry;
-
-       if (in == NULL)
-       {
-               free_protocol(p);
-               tdata->lu_entry = NULL;
-       }
-
-       if (tdata->lu_entry == NULL)
-       {
-               tdata->lu_entry = in;
-               return;
-       }
-
-       free_protocol_data(p);
-
-       p->p_proto = in->p_proto;
-       p->p_name = in->p_name;
-       p->p_aliases = in->p_aliases;
-
-       free(in);
+       return copy_protocol(&tmp);
 }
 
+/*
+ * Send a query to the system information daemon.
+ */
 static struct protoent *
-lu_getprotobynumber(long number)
+ds_getprotobynumber(uint32_t number)
 {
-       struct protoent *p;
-       unsigned int datalen;
-       XDR inxdr;
        static int proc = -1;
-       char *lookup_buf;
-       int count;
-
-       if (proc < 0)
-       {
-               if (_lookup_link(_lu_port, "getprotobynumber", &proc) != KERN_SUCCESS)
-               {
-                       return NULL;
-               }
-       }
+       char val[16];
 
-       number = htonl(number);
-       datalen = 0;
-       lookup_buf = NULL;
-
-       if (_lookup_all(_lu_port, proc, (unit *)&number, 1, &lookup_buf, &datalen)
-               != KERN_SUCCESS)
-       {
-               return NULL;
-       }
-
-       datalen *= BYTES_PER_XDR_UNIT;
-       if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
-
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
-
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       p = extract_protocol(&inxdr);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-
-       return p;
+       snprintf(val, sizeof(val), "%u", number);
+       return (struct protoent *)LI_getone("getprotobynumber", &proc, extract_protocol, "number", val);
 }
 
+/*
+ * Send a query to the system information daemon.
+ */
 static struct protoent *
-lu_getprotobyname(const char *name)
+ds_getprotobyname(const char *name)
 {
-       struct protoent *p;
-       unsigned int datalen;
-       char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT];
-       XDR outxdr;
-       XDR inxdr;
        static int proc = -1;
-       char *lookup_buf;
-       int count;
 
-       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, (_lu_string *)&name))
-       {
-               xdr_destroy(&outxdr);
-               return NULL;
-       }
-
-       datalen = 0;
-       lookup_buf = NULL;
-
-       if (_lookup_all(_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;
-       if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
-
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
-
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       p = extract_protocol(&inxdr);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-
-       return p;
+       return (struct protoent *)LI_getone("getprotobyname", &proc, extract_protocol, "name", name);
 }
 
+/*
+ * Clean up / initialize / reinitialize the kvarray used to hold a list of all protocol entries.
+ */
 static void
-lu_endprotoent()
+ds_endprotoent()
 {
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_protocol, free_lu_thread_info_protocol);
-       _lu_data_free_vm_xdr(tdata);
+       LI_data_free_kvarray(LI_data_find_key(ENTRY_KEY));
 }
 
 static void
-lu_setprotoent()
+ds_setprotoent()
 {
-       lu_endprotoent();
+       ds_endprotoent();
 }
 
-
 static struct protoent *
-lu_getprotoent()
+ds_getprotoent()
 {
-       struct protoent *p;
        static int proc = -1;
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_protocol, free_lu_thread_info_protocol);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_protocol, tdata);
-       }
-
-       if (tdata->lu_vm == NULL)
-       {
-               if (proc < 0)
-               {
-                       if (_lookup_link(_lu_port, "getprotoent", &proc) != KERN_SUCCESS)
-                       {
-                               lu_endprotoent();
-                               return NULL;
-                       }
-               }
-
-               if (_lookup_all(_lu_port, proc, NULL, 0, &(tdata->lu_vm), &(tdata->lu_vm_length)) != KERN_SUCCESS)
-               {
-                       lu_endprotoent();
-                       return NULL;
-               }
-
-               /* mig stubs measure size in words (4 bytes) */
-               tdata->lu_vm_length *= 4;
 
-               if (tdata->lu_xdr != NULL)
-               {
-                       xdr_destroy(tdata->lu_xdr);
-                       free(tdata->lu_xdr);
-               }
-               tdata->lu_xdr = (XDR *)calloc(1, sizeof(XDR));
-
-               xdrmem_create(tdata->lu_xdr, tdata->lu_vm, tdata->lu_vm_length, XDR_DECODE);
-               if (!xdr_int(tdata->lu_xdr, &tdata->lu_vm_cursor))
-               {
-                       lu_endprotoent();
-                       return NULL;
-               }
-       }
-
-       if (tdata->lu_vm_cursor == 0)
-       {
-               lu_endprotoent();
-               return NULL;
-       }
-
-       p = extract_protocol(tdata->lu_xdr);
-       if (p == NULL)
-       {
-               lu_endprotoent();
-               return NULL;
-       }
-
-       tdata->lu_vm_cursor--;
-       
-       return p;
+       return (struct protoent *)LI_getent("getprotoent", &proc, extract_protocol, ENTRY_KEY, ENTRY_SIZE);
 }
 
 static struct protoent *
 getproto(const char *name, int number, int source)
 {
        struct protoent *res = NULL;
-       struct lu_thread_info *tdata;
+       struct li_thread_info *tdata;
 
-       tdata = _lu_data_create_key(_lu_data_key_protocol, free_lu_thread_info_protocol);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_protocol, tdata);
-       }
+       tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
+       if (tdata == NULL) return NULL;
 
-       if (_lu_running())
+       if (_ds_running())
        {
                switch (source)
                {
                        case PROTO_GET_NAME:
-                               res = lu_getprotobyname(name);
+                               res = ds_getprotobyname(name);
                                break;
                        case PROTO_GET_NUM:
-                               res = lu_getprotobynumber(number);
+                               res = ds_getprotobynumber(number);
                                break;
                        case PROTO_GET_ENT:
-                               res = lu_getprotoent();
+                               res = ds_getprotoent();
                                break;
                        default: res = NULL;
                }
        }
        else
        {
+               pthread_mutex_lock(&_protocol_lock);
+
                switch (source)
                {
                        case PROTO_GET_NAME:
@@ -461,10 +197,12 @@ getproto(const char *name, int number, int source)
                                break;
                        default: res = NULL;
                }
+
+               pthread_mutex_unlock(&_protocol_lock);
        }
 
-       recycle_protocol(tdata, res);
-       return (struct protoent *)tdata->lu_entry;
+       LI_data_recycle(tdata, res, ENTRY_SIZE);
+       return (struct protoent *)tdata->li_entry;
 }
 
 struct protoent *
@@ -488,13 +226,13 @@ getprotoent(void)
 void
 setprotoent(int stayopen)
 {
-       if (_lu_running()) lu_setprotoent();
+       if (_ds_running()) ds_setprotoent();
        else _old_setprotoent(stayopen);
 }
 
 void
 endprotoent(void)
 {
-       if (_lu_running()) lu_endprotoent();
+       if (_ds_running()) ds_endprotoent();
        else _old_endprotoent();
 }
index 53812017bf847b9d4951ef1cf33b75914c398d7a..5919e097e953f565c60c4e3ae618598cd4d7f096 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include <mach/mach.h>
 #include <stdio.h>
 #include <string.h>
+#include <stdint.h>
 #include <netinet/in.h>
 #include <pthread.h>
-
-#include "_lu_types.h"
-#include "lookup.h"
 #include "lu_utils.h"
 #include "lu_overrides.h"
 
@@ -46,400 +44,147 @@ static pthread_mutex_t _rpc_lock = PTHREAD_MUTEX_INITIALIZER;
 #define RPC_GET_NUM 2
 #define RPC_GET_ENT 3
 
-static void
-free_rpc_data(struct rpcent *r)
-{
-       char **aliases;
-
-       if (r == NULL) return;
-
-       if (r->r_name != NULL) free(r->r_name);
+#define ENTRY_SIZE sizeof(struct rpcent)
+#define ENTRY_KEY _li_data_key_rpc
 
-       aliases = r->r_aliases;
-       if (aliases != NULL)
-       {
-               while (*aliases != NULL) free(*aliases++);
-               free(r->r_aliases);
-       }
-}
-
-static void
-free_rpc(struct rpcent *r)
+static struct rpcent *
+copy_rpc(struct rpcent *in)
 {
-       if (r == NULL) return;
-       free_rpc_data(r);
-       free(r);
+       if (in == NULL) return NULL;
+
+       return (struct rpcent *)LI_ils_create("s*4", in->r_name, in->r_aliases, in->r_number);
 }
 
-static void
-free_lu_thread_info_rpc(void *x)
+/*
+ * Extract the next rpc entry from a kvarray.
+ */
+static void *
+extract_rpc(kvarray_t *in)
 {
-       struct lu_thread_info *tdata;
+       struct rpcent tmp;
+       uint32_t d, k, kcount;
+       char *empty[1];
 
-       if (x == NULL) return;
-
-       tdata = (struct lu_thread_info *)x;
-       
-       if (tdata->lu_entry != NULL)
-       {
-               free_rpc((struct rpcent *)tdata->lu_entry);
-               tdata->lu_entry = NULL;
-       }
+       if (in == NULL) return NULL;
 
-       _lu_data_free_vm_xdr(tdata);
+       d = in->curr;
+       in->curr++;
 
-       free(tdata);
-}
+       if (d >= in->count) return NULL;
 
-static struct rpcent *
-extract_rpc(XDR *xdr)
-{
-       struct rpcent *r;
-       int i, j, nvals, nkeys, status;
-       char *key, **vals;
+       empty[0] = NULL;
+       memset(&tmp, 0, ENTRY_SIZE);
 
-       if (xdr == NULL) return NULL;
+       kcount = in->dict[d].kcount;
 
-       if (!xdr_int(xdr, &nkeys)) return NULL;
-
-       r = (struct rpcent *)calloc(1, sizeof(struct rpcent));
-
-       for (i = 0; i < nkeys; i++)
+       for (k = 0; k < kcount; k++)
        {
-               key = NULL;
-               vals = NULL;
-               nvals = 0;
-
-               status = _lu_xdr_attribute(xdr, &key, &vals, &nvals);
-               if (status < 0)
+               if (!strcmp(in->dict[d].key[k], "r_name"))
                {
-                       free_rpc(r);
-                       return NULL;
-               }
+                       if (tmp.r_name != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
 
-               if (nvals == 0)
-               {
-                       free(key);
-                       continue;
+                       tmp.r_name = (char *)in->dict[d].val[k][0];
                }
-
-               j = 0;
-
-               if ((r->r_name == NULL) && (!strcmp("name", key)))
+               else if (!strcmp(in->dict[d].key[k], "r_number"))
                {
-                       r->r_name = vals[0];
-                       if (nvals > 1)
-                       {
-                               r->r_aliases = (char **)calloc(nvals, sizeof(char *));
-                               for (j = 1; j < nvals; j++) r->r_aliases[j-1] = vals[j];
-                       }
-                       j = nvals;
-               }               
-               else if (!strcmp("number", key))
-               {
-                       r->r_number= atoi(vals[0]);
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       tmp.r_number = atoi(in->dict[d].val[k][0]);
                }
-
-               free(key);
-               if (vals != NULL)
+               else if (!strcmp(in->dict[d].key[k], "r_aliases"))
                {
-                       for (; j < nvals; j++) free(vals[j]);
-                       free(vals);
-               }
-       }
+                       if (tmp.r_aliases != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
 
-       if (r->r_name == NULL) r->r_name = strdup("");
-       if (r->r_aliases == NULL) r->r_aliases = (char **)calloc(1, sizeof(char *));
-
-       return r;
-}
-
-static struct rpcent *
-copy_rpc(struct rpcent *in)
-{
-       int i, len;
-       struct rpcent *r;
-
-       if (in == NULL) return NULL;
-
-       r = (struct rpcent *)calloc(1, sizeof(struct rpcent));
-
-       r->r_name = LU_COPY_STRING(in->r_name);
-
-       len = 0;
-       if (in->r_aliases != NULL)
-       {
-               for (len = 0; in->r_aliases[len] != NULL; len++);
-       }
-
-       r->r_aliases = (char **)calloc(len + 1, sizeof(char *));
-       for (i = 0; i < len; i++)
-       {
-               r->r_aliases[i] = strdup(in->r_aliases[i]);
-       }
-
-       r->r_number = in->r_number;
-
-       return r;
-}
-
-static void
-recycle_rpc(struct lu_thread_info *tdata, struct rpcent *in)
-{
-       struct rpcent *r;
-
-       if (tdata == NULL) return;
-       r = (struct rpcent *)tdata->lu_entry;
-
-       if (in == NULL)
-       {
-               free_rpc(r);
-               tdata->lu_entry = NULL;
-       }
-
-       if (tdata->lu_entry == NULL)
-       {
-               tdata->lu_entry = in;
-               return;
+                       tmp.r_aliases = (char **)in->dict[d].val[k];
+               }
        }
 
-       free_rpc_data(r);
+       if (tmp.r_name == NULL) tmp.r_name = "";
+       if (tmp.r_aliases == NULL) tmp.r_aliases = empty;
 
-       r->r_name = in->r_name;
-       r->r_aliases = in->r_aliases;
-       r->r_number = in->r_number;
-
-       free(in);
+       return copy_rpc(&tmp);
 }
 
+/*
+ * Send a query to the system information daemon.
+ */
 static struct rpcent *
-lu_getrpcbynumber(long number)
+ds_getrpcbynumber(uint32_t number)
 {
-       struct rpcent *r;
-       unsigned datalen;
-       XDR inxdr;
        static int proc = -1;
-       char *lookup_buf;
-       int count;
-
-       if (proc < 0)
-       {
-               if (_lookup_link(_lu_port, "getrpcbynumber", &proc) != KERN_SUCCESS)
-               {
-                       return NULL;
-               }
-       }
-
-       number = htonl(number);
-       datalen = 0;
-       lookup_buf = NULL;
+       char val[16];
 
-       if (_lookup_all(_lu_port, proc, (unit *)&number, 1, &lookup_buf, &datalen)
-               != KERN_SUCCESS)
-       {
-               return NULL;
-       }
-
-       datalen *= BYTES_PER_XDR_UNIT;
-       if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
-
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
-
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       r = extract_rpc(&inxdr);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-
-       return r;
+       snprintf(val, sizeof(val), "%u", number);
+       return (struct rpcent *)LI_getone("getrpcbynumber", &proc, extract_rpc, "number", val);
 }
 
+/*
+ * Send a query to the system information daemon.
+ */
 static struct rpcent *
-lu_getrpcbyname(const char *name)
+ds_getrpcbyname(const char *name)
 {
-       struct rpcent *r;
-       unsigned datalen;
-       char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT];
-       XDR outxdr, inxdr;
        static int proc = -1;
-       char *lookup_buf;
-       int count;
-
-       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, (_lu_string *)&name))
-       {
-               xdr_destroy(&outxdr);
-               return NULL;
-       }
-
-       datalen = 0;
-       lookup_buf = NULL;
-
-       if (_lookup_all(_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;
-       if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
-
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
-
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       r = extract_rpc(&inxdr);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
 
-       return r;
+       return (struct rpcent *)LI_getone("getrpcbyname", &proc, extract_rpc, "name", name);
 }
 
+/*
+ * Clean up / initialize / reinitialize the kvarray used to hold a list of all rpc entries.
+ */
 static void
-lu_endrpcent(void)
+ds_endrpcent(void)
 {
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_rpc, free_lu_thread_info_rpc);
-       _lu_data_free_vm_xdr(tdata);
+       LI_data_free_kvarray(LI_data_find_key(ENTRY_KEY));
 }
 
 static void
-lu_setrpcent()
+ds_setrpcent(void)
 {
-       lu_endrpcent();
+       ds_endrpcent();
 }
 
+/*
+ * Get an entry from the getrpcent kvarray.
+ * Calls the system information daemon if the list doesn't exist (first call),
+ * or extracts the next entry if the list has been fetched.
+ */
 static struct rpcent *
-lu_getrpcent()
+ds_getrpcent(void)
 {
-       struct rpcent *r;
        static int proc = -1;
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_rpc, free_lu_thread_info_rpc);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_rpc, tdata);
-       }
-
-       if (tdata->lu_vm == NULL)
-       {
-               if (proc < 0)
-               {
-                       if (_lookup_link(_lu_port, "getrpcent", &proc) != KERN_SUCCESS)
-                       {
-                               lu_endrpcent();
-                               return NULL;
-                       }
-               }
-
-               if (_lookup_all(_lu_port, proc, NULL, 0, &(tdata->lu_vm), &(tdata->lu_vm_length)) != KERN_SUCCESS)
-               {
-                       lu_endrpcent();
-                       return NULL;
-               }
-
-               /* mig stubs measure size in words (4 bytes) */
-               tdata->lu_vm_length *= 4;
-
-               if (tdata->lu_xdr != NULL)
-               {
-                       xdr_destroy(tdata->lu_xdr);
-                       free(tdata->lu_xdr);
-               }
-               tdata->lu_xdr = (XDR *)calloc(1, sizeof(XDR));
-
-               xdrmem_create(tdata->lu_xdr, tdata->lu_vm, tdata->lu_vm_length, XDR_DECODE);
-               if (!xdr_int(tdata->lu_xdr, &tdata->lu_vm_cursor))
-               {
-                       lu_endrpcent();
-                       return NULL;
-               }
-       }
-
-       if (tdata->lu_vm_cursor == 0)
-       {
-               lu_endrpcent();
-               return NULL;
-       }
-
-       r = extract_rpc(tdata->lu_xdr);
-       if (r == NULL)
-       {
-               lu_endrpcent();
-               return NULL;
-       }
 
-       tdata->lu_vm_cursor--;
-       
-       return r;
+       return (struct rpcent *)LI_getent("getrpcent", &proc, extract_rpc, ENTRY_KEY, ENTRY_SIZE);
 }
 
+/*
+ * Checks if the system information daemon is running.
+ * If so, calls the appropriate fetch routine.
+ * If not, calls the appropriate "_old" routine.
+ * Places the result in thread-specific memory.
+ */
 static struct rpcent *
-getrpc(const char *name, long number, int source)
+getrpc(const char *name, uint32_t number, int source)
 {
        struct rpcent *res = NULL;
-       struct lu_thread_info *tdata;
+       struct li_thread_info *tdata;
 
-       tdata = _lu_data_create_key(_lu_data_key_rpc, free_lu_thread_info_rpc);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_rpc, tdata);
-       }
+       tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
+       if (tdata == NULL) return NULL;
 
-       if (_lu_running())
+       if (_ds_running())
        {
                switch (source)
                {
                        case RPC_GET_NAME:
-                               res = lu_getrpcbyname(name);
+                               res = ds_getrpcbyname(name);
                                break;
                        case RPC_GET_NUM:
-                               res = lu_getrpcbynumber(number);
+                               res = ds_getrpcbynumber(number);
                                break;
                        case RPC_GET_ENT:
-                               res = lu_getrpcent();
+                               res = ds_getrpcent();
                                break;
                        default: res = NULL;
                }
@@ -447,6 +192,7 @@ getrpc(const char *name, long number, int source)
        else
        {
                pthread_mutex_lock(&_rpc_lock);
+
                switch (source)
                {
                        case RPC_GET_NAME:
@@ -460,11 +206,12 @@ getrpc(const char *name, long number, int source)
                                break;
                        default: res = NULL;
                }
+
                pthread_mutex_unlock(&_rpc_lock);
        }
 
-       recycle_rpc(tdata, res);
-       return (struct rpcent *)tdata->lu_entry;
+       LI_data_recycle(tdata, res, ENTRY_SIZE);
+       return (struct rpcent *)tdata->li_entry;
 }
 
 struct rpcent *
@@ -474,9 +221,16 @@ getrpcbyname(const char *name)
 }
 
 struct rpcent *
+#ifdef __LP64__
+getrpcbynumber(int number)
+#else
 getrpcbynumber(long number)
+#endif
 {
-       return getrpc(NULL, number, RPC_GET_NUM);
+       uint32_t n;
+
+       n = number;
+       return getrpc(NULL, n, RPC_GET_NUM);
 }
 
 struct rpcent *
@@ -488,13 +242,13 @@ getrpcent(void)
 void
 setrpcent(int stayopen)
 {
-       if (_lu_running()) lu_setrpcent();
+       if (_ds_running()) ds_setrpcent();
        else _old_setrpcent(stayopen);
 }
 
 void
 endrpcent(void)
 {
-       if (_lu_running()) lu_endrpcent();
+       if (_ds_running()) ds_endrpcent();
        else _old_endrpcent();
 }
index 58b3996af4f0f209951510d6b1855947b0b33ed5..f249e966e83edc3c677a84552a5c5013fb529770 100644 (file)
 #include <mach/mach.h>
 #include <stdio.h>
 #include <string.h>
-#include <rpc/types.h>
-#include <rpc/xdr.h>
 #include <netdb.h>
 #include <netinet/in.h>
 #include <pthread.h>
-
-#include "_lu_types.h"
-#include "lookup.h"
 #include "lu_utils.h"
 
 #define SERVICE_CACHE_SIZE 10
-#define DEFAULT_SERVICE_CACHE_TTL 10
 
 static pthread_mutex_t _service_cache_lock = PTHREAD_MUTEX_INITIALIZER;
 static void *_service_cache[SERVICE_CACHE_SIZE] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
-static unsigned int _service_cache_best_before[SERVICE_CACHE_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
 static unsigned int _service_cache_index = 0;
-static unsigned int _service_cache_ttl = DEFAULT_SERVICE_CACHE_TTL;
+static unsigned int _service_cache_init = 0;
 
 static pthread_mutex_t _service_lock = PTHREAD_MUTEX_INITIALIZER;
 
@@ -61,264 +54,146 @@ extern void _old_setservent();
 extern void _old_endservent();
 extern void _old_setservfile();
 
-static void
-free_service_data(struct servent *s)
-{
-       char **aliases;
-
-       if (s == NULL) return;
-
-       if (s->s_name != NULL) free(s->s_name);
-       if (s->s_proto != NULL) free(s->s_proto);
-
-       aliases = s->s_aliases;
-       if (aliases != NULL)
-       {
-               while (*aliases != NULL) free(*aliases++);
-               free(s->s_aliases);
-       }
-}
+#define ENTRY_SIZE sizeof(struct servent)
+#define ENTRY_KEY _li_data_key_service
 
-static void
-free_service(struct servent *s)
+static struct servent *
+copy_service(struct servent *in)
 {
-       if (s == NULL) return;
-       free_service_data(s);
-       free(s);
+       if (in == NULL) return NULL;
+
+       return LI_ils_create("s*4s", in->s_name, in->s_aliases, in->s_port, in->s_proto);
 }
 
-static void
-free_lu_thread_info_service(void *x)
+/*
+ * Extract the next service entry from a kvarray.
+ */
+static void *
+extract_service(kvarray_t *in)
 {
-       struct lu_thread_info *tdata;
-
-       if (x == NULL) return;
+       struct servent tmp;
+       uint32_t d, k, kcount;
+       char *empty[1];
 
-       tdata = (struct lu_thread_info *)x;
-       
-       if (tdata->lu_entry != NULL)
-       {
-               free_service((struct servent *)tdata->lu_entry);
-               tdata->lu_entry = NULL;
-       }
+       if (in == NULL) return NULL;
 
-       _lu_data_free_vm_xdr(tdata);
+       d = in->curr;
+       in->curr++;
 
-       free(tdata);
-}
+       if (d >= in->count) return NULL;
 
-static struct servent *
-extract_service(XDR *xdr, const char *proto)
-{
-       struct servent *s;
-       int i, j, nvals, nkeys, status;
-       char *key, **vals;
+       empty[0] = NULL;
+       memset(&tmp, 0, ENTRY_SIZE);
 
-       if (xdr == NULL) return NULL;
+       kcount = in->dict[d].kcount;
 
-       if (!xdr_int(xdr, &nkeys)) return NULL;
-
-       s = (struct servent *)calloc(1, sizeof(struct servent));
-
-       for (i = 0; i < nkeys; i++)
+       for (k = 0; k < kcount; k++)
        {
-               key = NULL;
-               vals = NULL;
-               nvals = 0;
-
-               status = _lu_xdr_attribute(xdr, &key, &vals, &nvals);
-               if (status < 0)
+               if (!strcmp(in->dict[d].key[k], "s_name"))
                {
-                       free_service(s);
-                       return NULL;
-               }
+                       if (tmp.s_name != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
 
-               if (nvals == 0)
-               {
-                       free(key);
-                       continue;
+                       tmp.s_name = (char *)in->dict[d].val[k][0];
                }
-
-               j = 0;
-
-               if ((s->s_name == NULL) && (!strcmp("name", key)))
-               {
-                       s->s_name = vals[0];
-                       if (nvals > 1)
-                       {
-                               s->s_aliases = (char **)calloc(nvals, sizeof(char *));
-                               for (j = 1; j < nvals; j++) s->s_aliases[j-1] = vals[j];
-                       }
-                       j = nvals;
-               }               
-               else if ((s->s_proto == NULL) && (!strcmp("protocol", key)))
+               else if (!strcmp(in->dict[d].key[k], "s_aliases"))
                {
-                       if ((proto == NULL) || (proto[0] == '\0'))
-                       {
-                               s->s_proto = vals[0];
-                               j = 1;
-                       }
-                       else
-                       {
-                               s->s_proto = strdup(proto);
-                       }
+                       if (tmp.s_aliases != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
+
+                       tmp.s_aliases = (char **)in->dict[d].val[k];
                }
-               else if ((s->s_port == 0) && (!strcmp("port", key)))
+               else if (!strcmp(in->dict[d].key[k], "s_port"))
                {
-                       s->s_port = htons(atoi(vals[0]));
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       tmp.s_port = htons(atoi(in->dict[d].val[k][0]));
                }
-               
-               free(key);
-               if (vals != NULL)
+               else if (!strcmp(in->dict[d].key[k], "s_proto"))
                {
-                       for (; j < nvals; j++) free(vals[j]);
-                       free(vals);
+                       if (tmp.s_proto != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
+
+                       tmp.s_proto = (char *)in->dict[d].val[k][0];
                }
        }
 
-       if (s->s_name == NULL) s->s_name = strdup("");
-       if (s->s_proto == NULL) s->s_proto = strdup("");
-       if (s->s_aliases == NULL) s->s_aliases = (char **)calloc(1, sizeof(char *));
+       if (tmp.s_name == NULL) tmp.s_name = "";
+       if (tmp.s_proto == NULL) tmp.s_proto = "";
+       if (tmp.s_aliases == NULL) tmp.s_aliases = empty;
 
-       return s;
+       return copy_service(&tmp);
 }
 
-static struct servent *
-copy_service(struct servent *in)
+static void
+cache_service(struct servent *s)
 {
-       int i, len;
-       struct servent *s;
-
-       if (in == NULL) return NULL;
-
-       s = (struct servent *)calloc(1, sizeof(struct servent));
+       struct servent *scache;
 
-       s->s_name = LU_COPY_STRING(in->s_name);
+       if (s == NULL) return;
 
-       len = 0;
-       if (in->s_aliases != NULL)
-       {
-               for (len = 0; in->s_aliases[len] != NULL; len++);
-       }
+       pthread_mutex_lock(&_service_cache_lock);
 
-       s->s_aliases = (char **)calloc(len + 1, sizeof(char *));
-       for (i = 0; i < len; i++)
-       {
-               s->s_aliases[i] = strdup(in->s_aliases[i]);
-       }
+       scache = copy_service(s);
+        
+       if (_service_cache[_service_cache_index] != NULL) LI_ils_free(_service_cache[_service_cache_index], ENTRY_SIZE);
+       _service_cache[_service_cache_index] = scache;
+       _service_cache_index = (_service_cache_index + 1) % SERVICE_CACHE_SIZE;
 
-       s->s_proto = LU_COPY_STRING(in->s_proto);
-       s->s_port = in->s_port;
+       _service_cache_init = 1;
 
-       return s;
+       pthread_mutex_unlock(&_service_cache_lock);
 }
 
-static void
-recycle_service(struct lu_thread_info *tdata, struct servent *in)
+static int
+service_cache_check()
 {
-       struct servent *s;
-
-       if (tdata == NULL) return;
-       s = (struct servent *)tdata->lu_entry;
+       uint32_t i, status;
 
-       if (in == NULL)
-       {
-               free_service(s);
-               tdata->lu_entry = NULL;
-       }
+       /* don't consult cache if it has not been initialized */
+       if (_service_cache_init == 0) return 1;
 
-       if (tdata->lu_entry == NULL)
-       {
-               tdata->lu_entry = in;
-               return;
-       }
+       status = LI_L1_cache_check(ENTRY_KEY);
 
-       free_service_data(s);
+       /* don't consult cache if it is disabled or if we can't validate */
+       if ((status == LI_L1_CACHE_DISABLED) || (status == LI_L1_CACHE_FAILED)) return 1;
 
-       s->s_name = in->s_name;
-       s->s_aliases = in->s_aliases;
-       s->s_proto = in->s_proto;
-       s->s_port = in->s_port;
-
-       free(in);
-}
-
-__private_extern__ unsigned int
-get_service_cache_ttl()
-{
-       return _service_cache_ttl;
-}
-
-__private_extern__ void
-set_service_cache_ttl(unsigned int ttl)
-{
-       int i;
+       /* return 0 if cache is OK */
+       if (status == LI_L1_CACHE_OK) return 0;
 
+       /* flush cache */
        pthread_mutex_lock(&_service_cache_lock);
 
-       _service_cache_ttl = ttl;
-
-       if (ttl == 0)
+       for (i = 0; i < SERVICE_CACHE_SIZE; i++)
        {
-               for (i = 0; i < SERVICE_CACHE_SIZE; i++)
-               {
-                       if (_service_cache[i] == NULL) continue;
-
-                       free_service((struct servent *)_service_cache[i]);
-                       _service_cache[i] = NULL;
-                       _service_cache_best_before[i] = 0;
-               }
+               LI_ils_free(_service_cache[i], ENTRY_SIZE);
+               _service_cache[i] = NULL;
        }
 
-       pthread_mutex_unlock(&_service_cache_lock);
-}
-
-static void
-cache_service(struct servent *s)
-{
-       struct timeval now;
-       struct servent *scache;
-
-       if (_service_cache_ttl == 0) return;
-       if (s == NULL) return;
-
-       pthread_mutex_lock(&_service_cache_lock);
-
-       scache = copy_service(s);
-
-       gettimeofday(&now, NULL);
-        
-       if (_service_cache[_service_cache_index] != NULL)
-               free_service((struct servent *)_service_cache[_service_cache_index]);
-
-       _service_cache[_service_cache_index] = scache;
-       _service_cache_best_before[_service_cache_index] = now.tv_sec + _service_cache_ttl;
-       _service_cache_index = (_service_cache_index + 1) % SERVICE_CACHE_SIZE;
+       _service_cache_index = 0;
 
        pthread_mutex_unlock(&_service_cache_lock);
+
+       /* don't consult cache - it's now empty */
+       return 1;
 }
 
+
 static struct servent *
 cache_getservbyname(const char *name, const char *proto)
 {
        int i;
        struct servent *s, *res;
-       struct timeval now;
        char **aliases;
 
-       if (_service_cache_ttl == 0) return NULL;
        if (name == NULL) return NULL;
+       if (service_cache_check() != 0) return NULL;
 
        pthread_mutex_lock(&_service_cache_lock);
 
-       gettimeofday(&now, NULL);
-
        for (i = 0; i < SERVICE_CACHE_SIZE; i++)
        {
-               if (_service_cache_best_before[i] == 0) continue;
-               if ((unsigned int)now.tv_sec > _service_cache_best_before[i]) continue;
-
                s = (struct servent *)_service_cache[i];
+               if (s == NULL) continue;
 
                if (s->s_name != NULL) 
                {
@@ -363,20 +238,15 @@ cache_getservbyport(int port, const char *proto)
 {
        int i;
        struct servent *s, *res;
-       struct timeval now;
 
-       if (_service_cache_ttl == 0) return NULL;
+       if (service_cache_check() != 0) return NULL;
 
        pthread_mutex_lock(&_service_cache_lock);
 
-       gettimeofday(&now, NULL);
-
        for (i = 0; i < SERVICE_CACHE_SIZE; i++)
        {
-               if (_service_cache_best_before[i] == 0) continue;
-               if ((unsigned int)now.tv_sec > _service_cache_best_before[i]) continue;
-
                s = (struct servent *)_service_cache[i];
+               if (s == NULL) continue;
 
                if (port == s->s_port)
                {
@@ -394,258 +264,108 @@ cache_getservbyport(int port, const char *proto)
 }
 
 static struct servent *
-lu_getservbyport(int port, const char *proto)
+ds_getservbyport(int port, const char *proto)
 {
-       struct servent *s;
-       unsigned int datalen;
-       XDR outxdr, inxdr;
+       struct servent *entry;
+       kvbuf_t *request;
+       kvarray_t *reply;
+       kern_return_t status;
        static int proc = -1;
-       char output_buf[_LU_MAXLUSTRLEN + 3 * BYTES_PER_XDR_UNIT];
-       char *lookup_buf;
-       int count;
+       uint16_t sport;
+       char val[16];
 
        if (proc < 0)
        {
-               if (_lookup_link(_lu_port, "getservbyport", &proc) != KERN_SUCCESS)
-               {
-                       return NULL;
-               }
+               status = LI_DSLookupGetProcedureNumber("getservbyport", &proc);
+               if (status != KERN_SUCCESS) return NULL;
        }
 
-       /* Encode NULL for xmission to lookupd. */
-       if (proto == NULL) proto = "";  
-
-       /* convert to host order */
-       port = ntohs(port);
-
-       xdrmem_create(&outxdr, output_buf, sizeof(output_buf), XDR_ENCODE);
-       if (!xdr_int(&outxdr, &port) || !xdr__lu_string(&outxdr, (_lu_string *)&proto))
-       {
-               xdr_destroy(&outxdr);
-               return NULL;
-       }
-
-       datalen = 0;
-       lookup_buf = NULL;
-
-       if (_lookup_all(_lu_port, proc, (unit *)output_buf, 
-               xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, &lookup_buf, &datalen)
-               != KERN_SUCCESS)
-       {
-               xdr_destroy(&outxdr);
-               return NULL;
-       }
+       /* Encode NULL */
+       if (proto == NULL) proto = "";
 
-       xdr_destroy(&outxdr);
+       sport = port;
+       snprintf(val, sizeof(val), "%d", ntohs(sport));
 
-       datalen *= BYTES_PER_XDR_UNIT;
-       if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
+       request = kvbuf_query("ksks", "port", val, "proto", proto);
+       if (request == NULL) return NULL;
 
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
+       reply = NULL;
+       status = LI_DSLookupQuery(proc, request, &reply);
+       kvbuf_free(request);
 
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
+       if (status != KERN_SUCCESS) return NULL;
 
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
+       entry = extract_service(reply);
+       kvarray_free(reply);
 
-       /*
-        * lookupd will only send back a reply for a service with the protocol specified
-        * if it finds a match.  We pass the protocol name to extract_service, which
-        * copies the requested protocol name into the returned servent.  This is a
-        * bit of a kludge, but since NetInfo / lookupd treat services as single entities
-        * with multiple protocols, we are forced to do some special-case handling. 
-        */
-       s = extract_service(&inxdr, proto);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-
-       return s;
+       return entry;
 }
 
 static struct servent *
-lu_getservbyname(const char *name, const char *proto)
+ds_getservbyname(const char *name, const char *proto)
 {
-       struct servent *s;
-       unsigned int datalen;
-       char *lookup_buf;
-       char output_buf[2 * (_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT)];
-       XDR outxdr, inxdr;
+       struct servent *entry;
+       kvbuf_t *request;
+       kvarray_t *reply;
+       kern_return_t status;
        static int proc = -1;
-       int count;
 
        if (proc < 0)
        {
-               if (_lookup_link(_lu_port, "getservbyname", &proc) != KERN_SUCCESS)
-               {
-                   return NULL;
-               }
+               status = LI_DSLookupGetProcedureNumber("getservbyname", &proc);
+               if (status != KERN_SUCCESS) return NULL;
        }
 
-       /* Encode NULL for xmission to lookupd. */
+       /* Encode NULL */
+       if (name == NULL) name = "";
        if (proto == NULL) proto = "";
 
-       xdrmem_create(&outxdr, output_buf, sizeof(output_buf), XDR_ENCODE);
-       if (!xdr__lu_string(&outxdr, (_lu_string *)&name) ||
-           !xdr__lu_string(&outxdr, (_lu_string *)&proto))
-       {
-               xdr_destroy(&outxdr);
-               return NULL;
-       }
-
-       datalen = 0;
-       lookup_buf = NULL;
-
-       if (_lookup_all(_lu_port, proc, (unit *)output_buf,
-               xdr_getpos(&outxdr) / BYTES_PER_XDR_UNIT, &lookup_buf, &datalen)
-               != KERN_SUCCESS)
-       {
-               xdr_destroy(&outxdr);
-               return NULL;
-       }
+       request = kvbuf_query("ksks", "name", name, "proto", proto);
+       if (request == NULL) return NULL;
 
-       xdr_destroy(&outxdr);
+       reply = NULL;
+       status = LI_DSLookupQuery(proc, request, &reply);
+       kvbuf_free(request);
 
-       datalen *= BYTES_PER_XDR_UNIT;
-       if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
+       if (status != KERN_SUCCESS) return NULL;
 
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
+       entry = extract_service(reply);
+       kvarray_free(reply);
 
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       /*
-        * lookupd will only send back a reply for a service with the protocol specified
-        * if it finds a match.  We pass the protocol name to extract_service, which
-        * copies the requested protocol name into the returned servent.  This is a
-        * bit of a kludge, but since NetInfo / lookupd treat services as single entities
-        * with multiple protocols, we are forced to do some special-case handling. 
-        */
-       s = extract_service(&inxdr, proto);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-
-       return s;
+       return entry;
 }
 
 static void
-lu_endservent()
+ds_endservent()
 {
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_service, free_lu_thread_info_service);
-       _lu_data_free_vm_xdr(tdata);
+       LI_data_free_kvarray(LI_data_find_key(ENTRY_KEY));
 }
 
 static void
-lu_setservent()
+ds_setservent()
 {
-       lu_endservent();
+       ds_endservent();
 }
 
 static struct servent *
-lu_getservent()
+ds_getservent()
 {
-       struct servent *s;
        static int proc = -1;
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_service, free_lu_thread_info_service);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_service, tdata);
-       }
-
-       if (tdata->lu_vm == NULL)
-       {
-               if (proc < 0)
-               {
-                       if (_lookup_link(_lu_port, "getservent", &proc) != KERN_SUCCESS)
-                       {
-                               lu_endservent();
-                               return NULL;
-                       }
-               }
-
-               if (_lookup_all(_lu_port, proc, NULL, 0, &(tdata->lu_vm), &(tdata->lu_vm_length)) != KERN_SUCCESS)
-               {
-                       lu_endservent();
-                       return NULL;
-               }
 
-               /* mig stubs measure size in words (4 bytes) */
-               tdata->lu_vm_length *= 4;
-
-               if (tdata->lu_xdr != NULL)
-               {
-                       xdr_destroy(tdata->lu_xdr);
-                       free(tdata->lu_xdr);
-               }
-               tdata->lu_xdr = (XDR *)calloc(1, sizeof(XDR));
-
-               xdrmem_create(tdata->lu_xdr, tdata->lu_vm, tdata->lu_vm_length, XDR_DECODE);
-               if (!xdr_int(tdata->lu_xdr, &tdata->lu_vm_cursor))
-               {
-                       lu_endservent();
-                       return NULL;
-               }
-       }
-
-       if (tdata->lu_vm_cursor == 0)
-       {
-               lu_endservent();
-               return NULL;
-       }
-
-       s = extract_service(tdata->lu_xdr, NULL);
-       if (s == NULL)
-       {
-               lu_endservent();
-               return NULL;
-       }
-
-       tdata->lu_vm_cursor--;
-       
-       return s;
+       return (struct servent *)LI_getent("getservent", &proc, extract_service, ENTRY_KEY, ENTRY_SIZE);
 }
 
 static struct servent *
 getserv(const char *name, const char *proto, int port, int source)
 {
        struct servent *res = NULL;
-       struct lu_thread_info *tdata;
-       int from_cache;
+       struct li_thread_info *tdata;
+       int add_to_cache;
 
-       tdata = _lu_data_create_key(_lu_data_key_service, free_lu_thread_info_service);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_service, tdata);
-       }
+       tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
+       if (tdata == NULL) return NULL;
 
-       from_cache = 0;
+       add_to_cache = 0;
        res = NULL;
 
        switch (source)
@@ -661,23 +381,24 @@ getserv(const char *name, const char *proto, int port, int source)
 
        if (res != NULL)
        {
-               from_cache = 1;
        }
-       else if (_lu_running())
+       else if (_ds_running())
        {
                switch (source)
                {
                        case S_GET_NAME:
-                               res = lu_getservbyname(name, proto);
+                               res = ds_getservbyname(name, proto);
                                break;
                        case S_GET_PORT:
-                               res = lu_getservbyport(port, proto);
+                               res = ds_getservbyport(port, proto);
                                break;
                        case S_GET_ENT:
-                               res = lu_getservent();
+                               res = ds_getservent();
                                break;
                        default: res = NULL;
                }
+
+               if (res != NULL) add_to_cache = 1;
        }
        else
        {
@@ -698,10 +419,10 @@ getserv(const char *name, const char *proto, int port, int source)
                pthread_mutex_unlock(&_service_lock);
        }
 
-       if (from_cache == 0) cache_service(res);
+       if (add_to_cache == 1) cache_service(res);
 
-       recycle_service(tdata, res);
-       return (struct servent *)tdata->lu_entry;
+       LI_data_recycle(tdata, res, ENTRY_SIZE);
+       return (struct servent *)tdata->li_entry;
 }
 
 struct servent *
@@ -725,13 +446,13 @@ getservent(void)
 void
 setservent(int stayopen)
 {
-       if (_lu_running()) lu_setservent();
+       if (_ds_running()) ds_setservent();
        else _old_setservent();
 }
 
 void
 endservent(void)
 {
-       if (_lu_running()) lu_endservent();
+       if (_ds_running()) ds_endservent();
        else _old_endservent();
 }
index e7f92af4067e22d6ff12b8861408bd4577f56338..b44cd41a88776f62aa9910d09cb957425fd9e566 100644 (file)
 #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 <pthread.h>
 #include <errno.h>
 #include <unistd.h>
-
-#include "_lu_types.h"
-#include "lookup.h"
 #include "lu_utils.h"
 #include "lu_overrides.h"
 
 #define USER_CACHE_SIZE 10
-#define DEFAULT_USER_CACHE_TTL 10
 
 static pthread_mutex_t _user_cache_lock = PTHREAD_MUTEX_INITIALIZER;
-static void *_user_cache[USER_CACHE_SIZE] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
-static unsigned int _user_cache_best_before[USER_CACHE_SIZE] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
+static void *_user_cache[USER_CACHE_SIZE] = { NULL };
 static unsigned int _user_cache_index = 0;
-static unsigned int _user_cache_ttl = DEFAULT_USER_CACHE_TTL;
+static unsigned int _user_cache_init = 0;
 
 static pthread_mutex_t _user_lock = PTHREAD_MUTEX_INITIALIZER;
 
@@ -57,172 +50,120 @@ static pthread_mutex_t _user_lock = PTHREAD_MUTEX_INITIALIZER;
 #define PW_GET_UID 2
 #define PW_GET_ENT 3
 
-static void
-free_user_data(struct passwd *p)
-{
-       if (p == NULL) return;
-
-       if (p->pw_name != NULL) free(p->pw_name);
-       if (p->pw_passwd != NULL) free(p->pw_passwd);
-       if (p->pw_class != NULL) free(p->pw_class);
-       if (p->pw_gecos != NULL) free(p->pw_gecos);
-       if (p->pw_dir != NULL) free(p->pw_dir);
-       if (p->pw_shell != NULL) free(p->pw_shell);
-}
+#define ENTRY_SIZE sizeof(struct passwd)
+#define ENTRY_KEY _li_data_key_user
 
-static void
-free_user(struct passwd *p)
-{
-       if (p == NULL) return;
-       free_user_data(p);
-       free(p);
-}
+__private_extern__ struct passwd *LI_files_getpwent();
+__private_extern__ struct passwd *LI_files_getpwnam(const char *name);
+__private_extern__ struct passwd *LI_files_getpwuid(uid_t uid);
+__private_extern__ void LI_files_setpwent();
+__private_extern__ void LI_files_endpwent();
 
-static void
-free_lu_thread_info_user(void *x)
+static struct passwd *
+copy_user(struct passwd *in)
 {
-       struct lu_thread_info *tdata;
-
-       if (x == NULL) return;
-
-       tdata = (struct lu_thread_info *)x;
-       
-       if (tdata->lu_entry != NULL)
-       {
-               free_user((struct passwd *)tdata->lu_entry);
-               tdata->lu_entry = NULL;
-       }
-
-       _lu_data_free_vm_xdr(tdata);
+       if (in == NULL) return NULL;
 
-       free(tdata);
+       return (struct passwd *)LI_ils_create("ss44LssssL", in->pw_name, in->pw_passwd, in->pw_uid, in->pw_gid, in->pw_change, in->pw_class, in->pw_gecos, in->pw_dir, in->pw_shell, in->pw_expire);
 }
 
-static struct passwd *
-extract_user(XDR *xdr)
+/*
+ * Extract the next user entry from a kvarray.
+ */
+static void *
+extract_user(kvarray_t *in)
 {
-       int i, j, nvals, nkeys, status;
-       char *key, **vals;
-       struct passwd *p;
+       struct passwd tmp;
+       uint32_t d, k, kcount;
 
-       if (xdr == NULL) return NULL;
+       if (in == NULL) return NULL;
 
-       if (!xdr_int(xdr, &nkeys)) return NULL;
+       d = in->curr;
+       in->curr++;
 
-       p = (struct passwd *)calloc(1, sizeof(struct passwd));
+       if (d >= in->count) return NULL;
 
-       p->pw_uid = -2;
-       p->pw_gid = -2;
+       memset(&tmp, 0, ENTRY_SIZE);
 
-       for (i = 0; i < nkeys; i++)
-       {
-               key = NULL;
-               vals = NULL;
-               nvals = 0;
+       tmp.pw_uid = -2;
+       tmp.pw_gid = -2;
 
-               status = _lu_xdr_attribute(xdr, &key, &vals, &nvals);
-               if (status < 0)
-               {
-                       free_user(p);
-                       return NULL;
-               }
+       kcount = in->dict[d].kcount;
 
-               if (nvals == 0)
+       for (k = 0; k < kcount; k++)
+       {
+               if (!strcmp(in->dict[d].key[k], "pw_name"))
                {
-                       free(key);
-                       continue;
-               }
-
-               j = 0;
+                       if (tmp.pw_name != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
 
-               if ((p->pw_name == NULL) && (!strcmp("name", key)))
-               {
-                       p->pw_name = vals[0];
-                       j = 1;
+                       tmp.pw_name = (char *)in->dict[d].val[k][0];
                }
-               else if ((p->pw_passwd == NULL) && (!strcmp("passwd", key)))
+               else if (!strcmp(in->dict[d].key[k], "pw_passwd"))
                {
-                       p->pw_passwd = vals[0];
-                       j = 1;
+                       if (tmp.pw_passwd != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
+
+                       tmp.pw_passwd = (char *)in->dict[d].val[k][0];
                }
-               else if ((p->pw_class == NULL) && (!strcmp("class", key)))
+               else if (!strcmp(in->dict[d].key[k], "pw_uid"))
                {
-                       p->pw_class = vals[0];
-                       j = 1;
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       tmp.pw_uid = atoi(in->dict[d].val[k][0]);
                }
-               else if ((p->pw_gecos == NULL) && (!strcmp("realname", key)))
+               else if (!strcmp(in->dict[d].key[k], "pw_gid"))
                {
-                       p->pw_gecos = vals[0];
-                       j = 1;
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       tmp.pw_gid = atoi(in->dict[d].val[k][0]);
                }
-               else if ((p->pw_dir == NULL) && (!strcmp("home", key)))
+               else if (!strcmp(in->dict[d].key[k], "pw_change"))
                {
-                       p->pw_dir = vals[0];
-                       j = 1;
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       tmp.pw_change = atol(in->dict[d].val[k][0]);
                }
-               else if ((p->pw_shell == NULL) && (!strcmp("shell", key)))
+               else if (!strcmp(in->dict[d].key[k], "pw_expire"))
                {
-                       p->pw_shell = vals[0];
-                       j = 1;
+                       if (in->dict[d].vcount[k] == 0) continue;
+                       tmp.pw_expire = atol(in->dict[d].val[k][0]);
                }
-               else if ((p->pw_uid == (uid_t)-2) && (!strcmp("uid", key)))
+               else if (!strcmp(in->dict[d].key[k], "pw_class"))
                {
-                       p->pw_uid = atoi(vals[0]);
-                       if ((p->pw_uid == 0) && (strcmp(vals[0], "0"))) p->pw_uid = -2;
+                       if (tmp.pw_class != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
+
+                       tmp.pw_class = (char *)in->dict[d].val[k][0];
                }
-               else if ((p->pw_gid == (gid_t)-2) && (!strcmp("gid", key)))
+               else if (!strcmp(in->dict[d].key[k], "pw_gecos"))
                {
-                       p->pw_gid = atoi(vals[0]);
-                       if ((p->pw_gid == 0) && (strcmp(vals[0], "0"))) p->pw_gid = -2;
+                       if (tmp.pw_gecos != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
+
+                       tmp.pw_gecos = (char *)in->dict[d].val[k][0];
                }
-               else if (!strcmp("change", key))
-               {
-                       p->pw_change = atoi(vals[0]);
-               }               
-               else if (!strcmp("expire", key))
+               else if (!strcmp(in->dict[d].key[k], "pw_dir"))
                {
-                       p->pw_expire = atoi(vals[0]);
-               }
+                       if (tmp.pw_dir != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
 
-               free(key);
-               if (vals != NULL)
+                       tmp.pw_dir = (char *)in->dict[d].val[k][0];
+               }
+               else if (!strcmp(in->dict[d].key[k], "pw_shell"))
                {
-                       for (; j < nvals; j++) free(vals[j]);
-                       free(vals);
+                       if (tmp.pw_shell != NULL) continue;
+                       if (in->dict[d].vcount[k] == 0) continue;
+
+                       tmp.pw_shell = (char *)in->dict[d].val[k][0];
                }
        }
 
-       if (p->pw_name == NULL) p->pw_name = strdup("");
-       if (p->pw_passwd == NULL) p->pw_passwd = strdup("");
-       if (p->pw_class == NULL) p->pw_class = strdup("");
-       if (p->pw_gecos == NULL) p->pw_gecos = strdup("");
-       if (p->pw_dir == NULL) p->pw_dir = strdup("");
-       if (p->pw_shell == NULL) p->pw_shell = strdup("");
+       if (tmp.pw_name == NULL) tmp.pw_name = "";
+       if (tmp.pw_passwd == NULL) tmp.pw_passwd = "";
+       if (tmp.pw_class == NULL) tmp.pw_class = "";
+       if (tmp.pw_gecos == NULL) tmp.pw_gecos = "";
+       if (tmp.pw_dir == NULL) tmp.pw_dir = "";
+       if (tmp.pw_shell == NULL) tmp.pw_shell = "";
 
-       return p;
-}
-
-static struct passwd *
-copy_user(struct passwd *in)
-{
-       struct passwd *p;
-
-       if (in == NULL) return NULL;
-
-       p = (struct passwd *)calloc(1, sizeof(struct passwd));
-
-       p->pw_name = LU_COPY_STRING(in->pw_name);
-       p->pw_passwd = LU_COPY_STRING(in->pw_passwd);
-       p->pw_uid = in->pw_uid;
-       p->pw_gid = in->pw_gid;
-       p->pw_change = in->pw_change;
-       p->pw_class = LU_COPY_STRING(in->pw_class);
-       p->pw_gecos = LU_COPY_STRING(in->pw_gecos);
-       p->pw_dir = LU_COPY_STRING(in->pw_dir);
-       p->pw_shell = LU_COPY_STRING(in->pw_shell);
-       p->pw_expire = in->pw_expire;
-
-       return p;
+       return copy_user(&tmp);
 }
 
 static int
@@ -317,117 +258,74 @@ copy_user_r(struct passwd *in, struct passwd *out, char *buffer, int buflen)
 }
 
 static void
-recycle_user(struct lu_thread_info *tdata, struct passwd *in)
+cache_user(struct passwd *pw)
 {
-       struct passwd *p;
+       struct passwd *pwcache;
 
-       if (tdata == NULL) return;
-       p = (struct passwd *)tdata->lu_entry;
+       if (pw == NULL) return;
 
-       if (in == NULL)
-       {
-               free_user(p);
-               tdata->lu_entry = NULL;
-       }
+       pthread_mutex_lock(&_user_cache_lock);
 
-       if (tdata->lu_entry == NULL)
-       {
-               tdata->lu_entry = in;
-               return;
-       }
+       pwcache = copy_user(pw);
 
-       free_user_data(p);
+       if (_user_cache[_user_cache_index] != NULL) LI_ils_free(_user_cache[_user_cache_index], ENTRY_SIZE);
 
-       p->pw_name = in->pw_name;
-       p->pw_passwd = in->pw_passwd;
-       p->pw_uid = in->pw_uid;
-       p->pw_gid = in->pw_gid;
-       p->pw_change = in->pw_change;
-       p->pw_class = in->pw_class;
-       p->pw_gecos = in->pw_gecos;
-       p->pw_dir = in->pw_dir;
-       p->pw_shell = in->pw_shell;
-       p->pw_expire = in->pw_expire;
+       _user_cache[_user_cache_index] = pwcache;
+       _user_cache_index = (_user_cache_index + 1) % USER_CACHE_SIZE;
 
-       free(in);
-}
+       _user_cache_init = 1;
 
-__private_extern__ unsigned int
-get_user_cache_ttl()
-{
-       return _user_cache_ttl;
+       pthread_mutex_unlock(&_user_cache_lock);
 }
 
-__private_extern__ void
-set_user_cache_ttl(unsigned int ttl)
+static int
+user_cache_check()
 {
-       int i;
-
-       pthread_mutex_lock(&_user_cache_lock);
+       uint32_t i, status;
 
-       _user_cache_ttl = ttl;
-
-       if (ttl == 0)
-       {
-               for (i = 0; i < USER_CACHE_SIZE; i++)
-               {
-                       if (_user_cache[i] == NULL) continue;
+       /* don't consult cache if it has not been initialized */
+       if (_user_cache_init == 0) return 1;
 
-                       free_user((struct passwd *)_user_cache[i]);
-                       _user_cache[i] = NULL;
-                       _user_cache_best_before[i] = 0;
-               }
-       }
-
-       pthread_mutex_unlock(&_user_cache_lock);
-}
+       status = LI_L1_cache_check(ENTRY_KEY);
 
-static void
-cache_user(struct passwd *pw)
-{
-       struct timeval now;
-       struct passwd *pwcache;
+       /* don't consult cache if it is disabled or if we can't validate */
+       if ((status == LI_L1_CACHE_DISABLED) || (status == LI_L1_CACHE_FAILED)) return 1;
 
-       if (_user_cache_ttl == 0) return;
-       if (pw == NULL) return;
+       /* return 0 if cache is OK */
+       if (status == LI_L1_CACHE_OK) return 0;
 
+       /* flush cache */
        pthread_mutex_lock(&_user_cache_lock);
 
-       pwcache = copy_user(pw);
-
-       gettimeofday(&now, NULL);
+       for (i = 0; i < USER_CACHE_SIZE; i++)
+       {
+               LI_ils_free(_user_cache[i], ENTRY_SIZE);
+               _user_cache[i] = NULL;
+       }
 
-       if (_user_cache[_user_cache_index] != NULL)
-               free_user((struct passwd *)_user_cache[_user_cache_index]);
-
-       _user_cache[_user_cache_index] = pwcache;
-       _user_cache_best_before[_user_cache_index] = now.tv_sec + _user_cache_ttl;
-       _user_cache_index = (_user_cache_index + 1) % USER_CACHE_SIZE;
+       _user_cache_index = 0;
 
        pthread_mutex_unlock(&_user_cache_lock);
+
+       /* don't consult cache - it's now empty */
+       return 1;
 }
 
 static struct passwd *
 cache_getpwnam(const char *name)
 {
-       int i;
+       uint32_t i;
        struct passwd *pw, *res;
-       struct timeval now;
 
-       if (_user_cache_ttl == 0) return NULL;
        if (name == NULL) return NULL;
+       if (user_cache_check() != 0) return NULL;
 
        pthread_mutex_lock(&_user_cache_lock);
 
-       gettimeofday(&now, NULL);
-
        for (i = 0; i < USER_CACHE_SIZE; i++)
        {
-               if (_user_cache_best_before[i] == 0) continue;
-               if ((unsigned int)now.tv_sec > _user_cache_best_before[i]) continue;
-
                pw = (struct passwd *)_user_cache[i];
-
+               if (pw == NULL) continue;
                if (pw->pw_name == NULL) continue;
 
                if (!strcmp(name, pw->pw_name))
@@ -443,26 +341,21 @@ cache_getpwnam(const char *name)
 }
 
 static struct passwd *
-cache_getpwuid(int uid)
+cache_getpwuid(uid_t uid)
 {
-       int i;
+       uint32_t i;
        struct passwd *pw, *res;
-       struct timeval now;
 
-       if (_user_cache_ttl == 0) return NULL;
+       if (user_cache_check() != 0) return NULL;
 
        pthread_mutex_lock(&_user_cache_lock);
 
-       gettimeofday(&now, NULL);
-
        for (i = 0; i < USER_CACHE_SIZE; i++)
        {
-               if (_user_cache_best_before[i] == 0) continue;
-               if ((unsigned int)now.tv_sec > _user_cache_best_before[i]) continue;
-
                pw = (struct passwd *)_user_cache[i];
+               if (pw == NULL) continue;
 
-               if ((uid_t)uid == pw->pw_uid)
+               if (uid == pw->pw_uid)
                {
                        res = copy_user(pw);
                        pthread_mutex_unlock(&_user_cache_lock);
@@ -471,274 +364,56 @@ cache_getpwuid(int uid)
        }
 
        pthread_mutex_unlock(&_user_cache_lock);
+
        return NULL;
 }
 
 static struct passwd *
-lu_getpwuid(int uid)
+ds_getpwuid(uid_t uid)
 {
-       struct passwd *p;
-       unsigned int datalen;
-       XDR inxdr;
        static int proc = -1;
-       int count;
-       char *lookup_buf;
+       char val[16];
 
-       if (proc < 0)
-       {
-               if (_lookup_link(_lu_port, "getpwuid_A", &proc) != KERN_SUCCESS)
-               {
-                       return NULL;
-               }
-       }
-
-       uid = htonl(uid);
-       datalen = 0;
-       lookup_buf = NULL;
-
-       if (_lookup_all(_lu_port, proc, (unit *)&uid, 1, &lookup_buf, &datalen)
-               != KERN_SUCCESS)
-       {
-               return NULL;
-       }
-
-       datalen *= BYTES_PER_XDR_UNIT;
-       if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
-
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
-
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       p = extract_user(&inxdr);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-
-       return p;
+       snprintf(val, sizeof(val), "%d", (int)uid);
+       return (struct passwd *)LI_getone("getpwuid", &proc, extract_user, "uid", val);
 }
 
 static struct passwd *
-lu_getpwnam(const char *name)
+ds_getpwnam(const char *name)
 {
-       struct passwd *p;
-       unsigned int datalen;
-       char namebuf[_LU_MAXLUSTRLEN + BYTES_PER_XDR_UNIT];
-       XDR outxdr;
-       XDR inxdr;
        static int proc = -1;
-       int count;
-       char *lookup_buf;
-
-       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, (_lu_string *)&name))
-       {
-               xdr_destroy(&outxdr);
-               return NULL;
-       }
-       
-       datalen = 0;
-       lookup_buf = NULL;
-
-       if (_lookup_all(_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;
-       if ((lookup_buf == NULL) || (datalen == 0)) return NULL;
 
-       xdrmem_create(&inxdr, lookup_buf, datalen, XDR_DECODE);
-
-       count = 0;
-       if (!xdr_int(&inxdr, &count))
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       if (count == 0)
-       {
-               xdr_destroy(&inxdr);
-               vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-               return NULL;
-       }
-
-       p = extract_user(&inxdr);
-       xdr_destroy(&inxdr);
-       vm_deallocate(mach_task_self(), (vm_address_t)lookup_buf, datalen);
-
-
-       return p;
+       return (struct passwd *)LI_getone("getpwnam", &proc, extract_user, "login", name);
 }
 
 static void
-lu_endpwent(void)
+ds_endpwent(void)
 {
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_user, free_lu_thread_info_user);
-       _lu_data_free_vm_xdr(tdata);
+       LI_data_free_kvarray(LI_data_find_key(ENTRY_KEY));
 }
 
 static int
-lu_setpwent(void)
+ds_setpwent(void)
 {
-       lu_endpwent();
+       ds_endpwent();
        return 1;
 }
 
 static struct passwd *
-lu_getpwent()
+ds_getpwent()
 {
-       struct passwd *p;
        static int proc = -1;
-       struct lu_thread_info *tdata;
-
-       tdata = _lu_data_create_key(_lu_data_key_user, free_lu_thread_info_user);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_user, tdata);
-       }
-
-       if (tdata->lu_vm == NULL)
-       {
-               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, &(tdata->lu_vm), &(tdata->lu_vm_length)) != KERN_SUCCESS)
-               {
-                       lu_endpwent();
-                       return NULL;
-               }
-
-               /* mig stubs measure size in words (4 bytes) */
-               tdata->lu_vm_length *= 4;
-
-               if (tdata->lu_xdr != NULL)
-               {
-                       xdr_destroy(tdata->lu_xdr);
-                       free(tdata->lu_xdr);
-               }
-               tdata->lu_xdr = (XDR *)calloc(1, sizeof(XDR));
-
-               xdrmem_create(tdata->lu_xdr, tdata->lu_vm, tdata->lu_vm_length, XDR_DECODE);
-               if (!xdr_int(tdata->lu_xdr, &tdata->lu_vm_cursor))
-               {
-                       lu_endpwent();
-                       return NULL;
-               }
-       }
-
-       if (tdata->lu_vm_cursor == 0)
-       {
-               lu_endpwent();
-               return NULL;
-       }
-
-       p = extract_user(tdata->lu_xdr);
-       if (p == NULL)
-       {
-               lu_endpwent();
-               return NULL;
-       }
-
-       tdata->lu_vm_cursor--;
-       
-       return p;
+       return (struct passwd *)LI_getent("getpwent", &proc, extract_user, ENTRY_KEY, ENTRY_SIZE);
 }
 
 static struct passwd *
 getpw_internal(const char *name, uid_t uid, int source)
 {
-       static char *loginName = NULL;
-       static struct passwd *loginEnt  = NULL;
        struct passwd *res;
-       char *l;
-       int from_cache;
+       int add_to_cache;
 
-       if (loginName == NULL)
-       {
-               l = getlogin();
-               if ((l != NULL) && (strcmp("root", l) != 0))
-               {
-                       pthread_mutex_lock(&_user_lock);
-                       if ((loginEnt == NULL) && (l != NULL) && (*l != '\0'))
-                       {
-                               if (_lu_running())
-                               {
-                                       loginEnt = lu_getpwnam(l);
-                               }
-                               else
-                               {
-                                       loginEnt = copy_user(_old_getpwnam(l));
-                               }
-       
-                               loginName = l;
-                       }
-                       pthread_mutex_unlock(&_user_lock);
-               }
-       }
-
-       if (loginEnt != NULL)
-       {
-               switch (source)
-               {
-                       case PW_GET_NAME:
-                               if (strcmp(name, loginEnt->pw_name) == 0)
-                               {
-                                       name = loginName;
-                               }
-                               if (strcmp(name, loginEnt->pw_gecos) == 0)
-                               {
-                                       name = loginName;
-                               }
-                               break;
-                       case PW_GET_UID:
-                               if (uid == loginEnt->pw_uid)
-                               {
-                                       source = PW_GET_NAME;
-                                       name = loginName;
-                               }
-                               break;
-                       default:
-                               break;
-               }
-       }
-
-       from_cache = 0;
+       add_to_cache = 0;
        res = NULL;
 
        switch (source)
@@ -754,44 +429,47 @@ getpw_internal(const char *name, uid_t uid, int source)
 
        if (res != NULL)
        {
-               from_cache = 1;
        }
-       else if (_lu_running())
+       else if (_ds_running())
        {
                switch (source)
                {
                        case PW_GET_NAME:
-                               res = lu_getpwnam(name);
+                               res = ds_getpwnam(name);
                                break;
                        case PW_GET_UID:
-                               res = lu_getpwuid(uid);
+                               res = ds_getpwuid(uid);
                                break;
                        case PW_GET_ENT:
-                               res = lu_getpwent();
+                               res = ds_getpwent();
                                break;
                        default: res = NULL;
                }
+
+               if (res != NULL) add_to_cache = 1;
        }
        else
        {
                pthread_mutex_lock(&_user_lock);
+
                switch (source)
                {
                        case PW_GET_NAME:
-                               res = copy_user(_old_getpwnam(name));
+                               res = copy_user(LI_files_getpwnam(name));
                                break;
                        case PW_GET_UID:
-                               res = copy_user(_old_getpwuid(uid));
+                               res = copy_user(LI_files_getpwuid(uid));
                                break;
                        case PW_GET_ENT:
-                               res = copy_user(_old_getpwent());
+                               res = copy_user(LI_files_getpwent());
                                break;
                        default: res = NULL;
                }
+
                pthread_mutex_unlock(&_user_lock);
        }
 
-       if (from_cache == 0) cache_user(res);
+       if (add_to_cache == 1) cache_user(res);
 
        return res;
 }
@@ -800,20 +478,15 @@ static struct passwd *
 getpw(const char *name, uid_t uid, int source)
 {
        struct passwd *res = NULL;
-       struct lu_thread_info *tdata;
+       struct li_thread_info *tdata;
 
-       tdata = _lu_data_create_key(_lu_data_key_user, free_lu_thread_info_user);
-       if (tdata == NULL)
-       {
-               tdata = (struct lu_thread_info *)calloc(1, sizeof(struct lu_thread_info));
-               _lu_data_set_key(_lu_data_key_user, tdata);
-       }
+       tdata = LI_data_create_key(ENTRY_KEY, ENTRY_SIZE);
+       if (tdata == NULL) return NULL;
 
        res = getpw_internal(name, uid, source);
 
-       recycle_user(tdata, res);
-
-       return (struct passwd *)tdata->lu_entry;
+       LI_data_recycle(tdata, res, ENTRY_SIZE);
+       return (struct passwd *)tdata->li_entry;
 }
 
 static int
@@ -823,19 +496,15 @@ getpw_r(const char *name, uid_t uid, int source, struct passwd *pwd, char *buffe
        int status;
 
        *result = NULL;
-       errno = 0;
 
        res = getpw_internal(name, uid, source);
-       if (res == NULL) return -1;
+       if (res == NULL) return 0;
 
        status = copy_user_r(res, pwd, buffer, bufsize);
-       free_user(res);
 
-       if (status != 0)
-       {
-               errno = ERANGE;
-               return -1;
-       }
+       LI_ils_free(res, ENTRY_SIZE);
+
+       if (status != 0) return ERANGE;
 
        *result = pwd;
        return 0;
@@ -859,19 +528,18 @@ getpwent(void)
        return getpw(NULL, -2, PW_GET_ENT);
 }
 
-int
+void
 setpwent(void)
 {
-       if (_lu_running()) lu_setpwent();
-       else _old_setpwent();
-       return 1;
+       if (_ds_running()) ds_setpwent();
+       else LI_files_setpwent();
 }
 
 void
 endpwent(void)
 {
-       if (_lu_running()) lu_endpwent();
-       else _old_endpwent();
+       if (_ds_running()) ds_endpwent();
+       else LI_files_endpwent();
 }
 
 int
index 5970cf20bbf63e14c2ca5a6b74624f5aabc2b80f..02e8d14bd5e135ff699e49a06e09b7e14ea65745 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999-2002 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2006 Apple Computer, Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
 
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <mach/mach.h>
+#include <servers/bootstrap.h>
 #include <pthread.h>
-#ifdef DEBUG
+#include <errno.h>
+#include <notify.h>
 #include <syslog.h>
+#include <unistd.h>
+#ifdef DEBUG
+#include <asl.h>
 #endif
-#include "_lu_types.h"
-#include "lookup.h"
 #include "lu_utils.h"
 #include "netdb_async.h"
+#include "DSlibinfoMIG.h"
+#include "DSlibinfoMIGAsyncReply.h"
 
 #define MAX_LOOKUP_ATTEMPTS 10
 #define _LU_MAXLUSTRLEN 256
-#define QBUF_SIZE 4096
+#define QBUF_SIZE 16384
+#define KVBUF_START_SIZE 128
+
+#define LI_MESSAGE_SEND_ID  4241776
+#define LI_MESSAGE_REPLY_ID 4241876
+
+#define ILS_MAGIC_SIZE 8
+#define ILS_MAGIC "ILSMAGIC"
 
-#define LU_MESSAGE_SEND_ID 4241776
-#define LU_MESSAGE_REPLY_ID 4241876
+#define L1_CACHE_NOTIFICATION_KEY_GLOBAL  "com.apple.system.DirectoryService.InvalidateCache"
+#define L1_CACHE_NOTIFICATION_KEY_GROUP   "com.apple.system.DirectoryService.InvalidateCache.group"
+#define L1_CACHE_NOTIFICATION_KEY_HOST    "com.apple.system.DirectoryService.InvalidateCache.host"
+#define L1_CACHE_NOTIFICATION_KEY_SERVICE "com.apple.system.DirectoryService.InvalidateCache.service"
+#define L1_CACHE_NOTIFICATION_KEY_USER    "com.apple.system.DirectoryService.InvalidateCache.user"
+
+/* GLOBAL */
+uint32_t gL1CacheEnabled = 1;
+
+static const uint32_t align_32[] = { 0, 1, 2, 0, 4, 0, 0, 0, 4 };
+static const uint32_t align_64[] = { 0, 1, 2, 0, 4, 0, 0, 0, 8 };
 
 static pthread_key_t _info_key = 0;
 static pthread_once_t _info_key_initialized = PTHREAD_ONCE_INIT;
 
-struct _lu_data_s
+static pthread_mutex_t _notify_lock = PTHREAD_MUTEX_INITIALIZER;
+static int _L1_notify_token[] =
+{
+       -1, /* global */
+       -1, /* group */
+       -1, /* host */
+       -1, /* service */
+       -1  /* user */
+};
+
+struct _li_data_s
 {
-       unsigned int icount;
-       unsigned int *ikey;
+       uint32_t icount;
+       uint32_t *ikey;
        void **idata;
-       void (**idata_destructor)(void *);
 };
 
-typedef struct _lu_async_request_s
+typedef struct _li_async_request_s
 {
        mach_port_t reply_port;
        uint32_t retry;
        uint32_t proc;
        void *context;
        void *callback;
-       ooline_data request_buffer;
-       mach_msg_type_number_t request_buffer_len;
-       struct _lu_async_request_s *next;
-} _lu_async_request_t;
+       char request[MAX_MIG_INLINE_DATA];
+       mach_msg_type_number_t requestCnt;
+       char reply[MAX_MIG_INLINE_DATA];
+       mach_msg_type_number_t replyCnt;
+       vm_address_t ooreply;
+       mach_msg_type_number_t ooreplyCnt;
+       security_token_t token;
+       struct _li_async_request_s *next;
+} _li_async_request_t;
 
-typedef struct
-{
-       mach_msg_header_t head;
-       NDR_record_t NDR;
-       int proc;
-       mach_msg_type_number_t query_data_len;
-       unit query_data[QBUF_SIZE];
-} _lu_query_msg_t;
-
-typedef struct
-{
-       mach_msg_header_t head;
-       mach_msg_body_t msgh_body;
-       mach_msg_ool_descriptor_t reply_data;
-       NDR_record_t NDR;
-       mach_msg_type_number_t reply_data_len;
-       mach_msg_format_0_trailer_t trailer;
-} _lu_reply_msg_t;
-
-static pthread_mutex_t _lu_worklist_lock = PTHREAD_MUTEX_INITIALIZER;
-static _lu_async_request_t *_lu_worklist = NULL;
-
-/* Send an asynchronous query message to lookupd */
+static pthread_mutex_t _li_worklist_lock = PTHREAD_MUTEX_INITIALIZER;
+static _li_async_request_t *_li_worklist = NULL;
+
+/* Send an asynchronous query message. */
 static kern_return_t
-_lu_async_send(_lu_async_request_t *r)
+_LI_async_send(_li_async_request_t *r)
 {
-       _lu_query_msg_t in;
-       register _lu_query_msg_t *inp = &in;
        mach_msg_return_t status;
-       unsigned int msgh_size;
+       mach_vm_address_t cb;
 
        if (r == NULL) return KERN_FAILURE;
 
        if (r->retry == 0) return MIG_SERVER_DIED;
        r->retry--;
 
-       if (r->request_buffer_len > QBUF_SIZE) return MIG_ARRAY_TOO_LARGE;
-
-       msgh_size = (sizeof(_lu_query_msg_t) - 16384) + ((4 * r->request_buffer_len));
-       inp->head.msgh_bits = MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE);
-       inp->head.msgh_remote_port = _lu_port;
-       inp->head.msgh_local_port = r->reply_port;
-       inp->head.msgh_id = LU_MESSAGE_SEND_ID;
-       inp->NDR = NDR_record;
-       inp->proc = r->proc;
-       inp->query_data_len = r->request_buffer_len;
-       memcpy(inp->query_data, r->request_buffer, 4 * r->request_buffer_len);
-
-       status = mach_msg(&inp->head, MACH_SEND_MSG, msgh_size, 0, MACH_PORT_NULL, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL);
-       if (status == MACH_MSG_SUCCESS) return KERN_SUCCESS;
+       cb = (mach_vm_address_t)(r->callback);
+       status = libinfoDSmig_Query_async(_ds_port, r->reply_port, r->proc, r->request, r->requestCnt, cb);
 
        if (status == MACH_SEND_INVALID_REPLY)
        {
@@ -124,25 +127,25 @@ _lu_async_send(_lu_async_request_t *r)
        return status;
 }
 
-static _lu_async_request_t *
-_lu_worklist_remove(mach_port_t p)
+static _li_async_request_t *
+_LI_worklist_remove(mach_port_t p)
 {
-       _lu_async_request_t *r, *n;
+       _li_async_request_t *r, *n;
 
        if (p == MACH_PORT_NULL) return NULL;
-       if (_lu_worklist == NULL) return NULL;
+       if (_li_worklist == NULL) return NULL;
 
-       pthread_mutex_lock(&_lu_worklist_lock);
+       pthread_mutex_lock(&_li_worklist_lock);
 
-       if (_lu_worklist->reply_port == p)
+       if (_li_worklist->reply_port == p)
        {
-               r = _lu_worklist;
-               _lu_worklist = r->next;
-               pthread_mutex_unlock(&_lu_worklist_lock);
+               r = _li_worklist;
+               _li_worklist = r->next;
+               pthread_mutex_unlock(&_li_worklist_lock);
                return r;
        }
 
-       for (r = _lu_worklist; r != NULL; r = r->next)
+       for (r = _li_worklist; r != NULL; r = r->next)
        {
                n = r->next;
                if (n == NULL) break;
@@ -150,167 +153,223 @@ _lu_worklist_remove(mach_port_t p)
                if (n->reply_port == p)
                {
                        r->next = n->next;
-                       pthread_mutex_unlock(&_lu_worklist_lock);
+                       pthread_mutex_unlock(&_li_worklist_lock);
                        return n;
                }
        }
 
-       pthread_mutex_unlock(&_lu_worklist_lock);
+       pthread_mutex_unlock(&_li_worklist_lock);
        return NULL;
 }
 
-static _lu_async_request_t *
-_lu_worklist_find(mach_port_t p)
+static _li_async_request_t *
+_LI_worklist_find(mach_port_t p)
 {
-       _lu_async_request_t *r;
+       _li_async_request_t *r;
 
        if (p == MACH_PORT_NULL) return NULL;
-       if (_lu_worklist == NULL) return NULL;
+       if (_li_worklist == NULL) return NULL;
 
-       pthread_mutex_lock(&_lu_worklist_lock);
+       pthread_mutex_lock(&_li_worklist_lock);
 
-       for (r = _lu_worklist; r != NULL; r = r->next)
+       for (r = _li_worklist; r != NULL; r = r->next)
        {
                if (r->reply_port == p)
                {
-                       pthread_mutex_unlock(&_lu_worklist_lock);
+                       pthread_mutex_unlock(&_li_worklist_lock);
                        return r;
                }
        }
 
-       pthread_mutex_unlock(&_lu_worklist_lock);
+       pthread_mutex_unlock(&_li_worklist_lock);
        return NULL;
 }
 
 static void
-_lu_free_request(_lu_async_request_t *r)
+_LI_free_request(_li_async_request_t *r)
 {
        if (r == NULL) return;
 
-       if (r->request_buffer != NULL) free(r->request_buffer);
-       r->request_buffer = NULL;
-
-       if (r->reply_port != MACH_PORT_NULL) mach_port_destroy(mach_task_self(), r->reply_port);
+       if (r->reply_port != MACH_PORT_NULL) mach_port_mod_refs(mach_task_self(), r->reply_port, MACH_PORT_RIGHT_RECEIVE, -1);
        r->reply_port = MACH_PORT_NULL;
 
        free(r);
 }
 
-/* Receive an asynchronous reply message from lookupd */
+/*
+ * This is a callback for DSLibinfoMIGAsyncReplyServer.c
+ */
+__private_extern__ kern_return_t
+libinfoDSmig_do_Response_async(mach_port_t server, char *reply, mach_msg_type_number_t replyCnt, vm_offset_t ooreply, mach_msg_type_number_t ooreplyCnt, mach_vm_address_t callbackAddr, security_token_t servertoken)
+{
+       _li_async_request_t *r;
+
+       r = _LI_worklist_find(server);
+
+       if (r != NULL)
+       {
+               r->ooreply = ooreply;
+               r->ooreplyCnt = ooreplyCnt;
+               if (replyCnt > 0) memcpy(r->reply, reply, replyCnt);
+               r->replyCnt = replyCnt;
+               r->token = servertoken;
+       }
+       else if (ooreplyCnt != 0)
+       {
+               vm_deallocate(mach_task_self(), ooreply, ooreplyCnt);
+       }
+
+       return KERN_SUCCESS;
+}
+
+/* Receive an asynchronous reply message. */
 kern_return_t
-lu_async_receive(mach_port_t p, char **buf, uint32_t *len)
+LI_async_receive(mach_port_t p, kvarray_t **reply)
 {
-       _lu_reply_msg_t *r;
        kern_return_t status;
-       uint32_t size;
-       _lu_async_request_t *req;
-       boolean_t msgh_simple;
+       _li_async_request_t *r;
+       kvbuf_t *out;
+       int flags;
 
-       size = sizeof(_lu_reply_msg_t);
+       flags = MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) | MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0);
 
-       r = (_lu_reply_msg_t *)calloc(1, size);
-       if (r == NULL) return KERN_RESOURCE_SHORTAGE;
+       /* use mach_msg_server_once to do the work here */
+       status = mach_msg_server_once(DSlibinfoMIGAsyncReply_server, 65536, p, flags);
 
-       r->head.msgh_local_port = p;
-       r->head.msgh_size = size;
-       status = mach_msg(&(r->head), MACH_RCV_MSG, 0, size, r->head.msgh_local_port, 0, MACH_PORT_NULL);
-       if (status != KERN_SUCCESS)
-       {
-               free(r);
-               return status;
-       }
+       if (status != KERN_SUCCESS) return status;
 
-       msgh_simple = !(r->head.msgh_bits & MACH_MSGH_BITS_COMPLEX);
+       r = _LI_worklist_remove(p);
+       if (r == NULL) return KERN_FAILURE;
 
-       req = _lu_worklist_remove(r->head.msgh_local_port);
-       if (req == NULL)
+       out = (kvbuf_t *)calloc(1, sizeof(kvbuf_t));
+       if (out == NULL)
        {
-               free(r);
+               if (r->ooreplyCnt > 0) vm_deallocate(mach_task_self(), r->ooreply, r->ooreplyCnt);
                return KERN_FAILURE;
        }
 
-       if (msgh_simple && ((mig_reply_error_t *) r)->RetCode != KERN_SUCCESS)
+       if (r->ooreplyCnt > 0)
        {
-               _lu_free_request(req);
-               status = ((mig_reply_error_t *) r)->RetCode;
-               free(r);
-               return status;
+               out->datalen = r->ooreplyCnt;
+               out->databuf = malloc(r->ooreplyCnt);
+               if (out->databuf == NULL)
+               {
+                       free(out);
+                       *reply = NULL;
+                       vm_deallocate(mach_task_self(), r->ooreply, r->ooreplyCnt);
+                       return KERN_FAILURE;
+               }
+
+               memcpy(out->databuf, (char *)r->ooreply, r->ooreplyCnt);
+               vm_deallocate(mach_task_self(), r->ooreply, r->ooreplyCnt);
        }
+       else if (r->replyCnt > 0)
+       {
+               out->datalen = r->replyCnt;
+               out->databuf = malloc(r->replyCnt);
+               if (out->databuf == NULL)
+               {
+                       free(out);
+                       *reply = NULL;
+                       return KERN_FAILURE;
+               }
 
-       *buf = r->reply_data.address;
-       *len = r->reply_data.size;
+               memcpy(out->databuf, r->reply, r->replyCnt);
+       }
 
-       free(r);
+       *reply = kvbuf_decode(out);
+       if (*reply == NULL)
+       {
+               /* DS returned no data */
+               free(out->databuf);
+               free(out);
+       }
+       
+       _LI_free_request(r);
 
-       _lu_free_request(req);
        return KERN_SUCCESS;
 }
 
 static void
-_lu_worklist_append(_lu_async_request_t *r)
+_LI_worklist_append(_li_async_request_t *r)
 {
-       _lu_async_request_t *p;
+       _li_async_request_t *p;
 
        if (r == NULL) return;
 
-       pthread_mutex_lock(&_lu_worklist_lock);
+       pthread_mutex_lock(&_li_worklist_lock);
 
-       if (_lu_worklist == NULL)
+       if (_li_worklist == NULL)
        {
-               _lu_worklist = r;
-               pthread_mutex_unlock(&_lu_worklist_lock);
+               _li_worklist = r;
+               pthread_mutex_unlock(&_li_worklist_lock);
                return;
        }
 
-       for (p = _lu_worklist; p->next != NULL; p = p->next);
+       for (p = _li_worklist; p->next != NULL; p = p->next);
        p->next = r;
 
-       pthread_mutex_unlock(&_lu_worklist_lock);
+       pthread_mutex_unlock(&_li_worklist_lock);
 }
 
 void
-lu_async_call_cancel(mach_port_t p)
+LI_async_call_cancel(mach_port_t p, void **context)
 {
-       _lu_async_request_t *req;
+       _li_async_request_t *req;
 
-       req = _lu_worklist_remove(p);
-       if (req != NULL) _lu_free_request(req);
-       else if (p != MACH_PORT_NULL) mach_port_destroy(mach_task_self(), p);
+       req = _LI_worklist_remove(p);
+
+       if (req != NULL)
+       {
+               if (context != NULL) *context = req->context;
+               _LI_free_request(req);
+       }
+       else if (p != MACH_PORT_NULL)
+       {
+               mach_port_mod_refs(mach_task_self(), p, MACH_PORT_RIGHT_RECEIVE, -1);
+       }
+}
+
+void
+lu_async_call_cancel(mach_port_t p)
+{
+       LI_async_call_cancel(p, NULL);
 }
 
-static _lu_async_request_t *
-_lu_create_request(uint32_t proc, const char *buf, uint32_t len, void *callback, void *context)
+static _li_async_request_t *
+_LI_create_request(uint32_t proc, kvbuf_t *query, void *callback, void *context)
 {
-       _lu_async_request_t *r;
+       _li_async_request_t *r;
        kern_return_t status;
+       mach_port_t target;
 
-       if (_lu_port == MACH_PORT_NULL) return NULL;
+       if (_ds_running() == 0) return NULL;
+       if (query == NULL) return NULL;
+       if (query->datalen > MAX_MIG_INLINE_DATA) return NULL;
 
-       r = (_lu_async_request_t *)calloc(1, sizeof(_lu_async_request_t));
+       r = (_li_async_request_t *)calloc(1, sizeof(_li_async_request_t));
        if (r == NULL) return NULL;
 
        status = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &(r->reply_port));
        if (status != KERN_SUCCESS)
        {
-               _lu_free_request(r);
+               _LI_free_request(r);
                return NULL;
        }
 
+       target = MACH_PORT_NULL;
+
+       /* Request no-senders notification so we can tell when server dies */
+       mach_port_request_notification(mach_task_self(), r->reply_port, MACH_NOTIFY_NO_SENDERS, 1, r->reply_port, MACH_MSG_TYPE_MAKE_SEND_ONCE, &target);
+
        r->retry = MAX_LOOKUP_ATTEMPTS;
 
        r->context = context;
        r->callback = callback;
        r->proc = proc;
 
-       r->request_buffer = malloc(len * BYTES_PER_XDR_UNIT);
-       if (r->request_buffer == NULL)
-       {
-               free(r);
-               return NULL;
-       }
-
-       memcpy(r->request_buffer, buf, len * BYTES_PER_XDR_UNIT);
-       r->request_buffer_len = len;
+       memcpy(r->request, query->databuf, query->datalen);
+       r->requestCnt = query->datalen;
 
        r->next = NULL;
 
@@ -318,9 +377,9 @@ _lu_create_request(uint32_t proc, const char *buf, uint32_t len, void *callback,
 }
 
 kern_return_t
-lu_async_start(mach_port_t *p, uint32_t proc, const char *buf, uint32_t len, void *callback, void *context)
+LI_async_start(mach_port_t *p, uint32_t proc, kvbuf_t *query, void *callback, void *context)
 {
-       _lu_async_request_t *r;
+       _li_async_request_t *r;
        kern_return_t status;
        uint32_t retry;
 
@@ -328,483 +387,167 @@ lu_async_start(mach_port_t *p, uint32_t proc, const char *buf, uint32_t len, voi
 
        *p = MACH_PORT_NULL;
 
-       if (!_lu_running()) return KERN_FAILURE;
+       if (_ds_running() == 0) return KERN_FAILURE;
+       if (_ds_port == MACH_PORT_NULL) return KERN_FAILURE;
 
        /* Make a request struct to keep track */
-       r = _lu_create_request(proc, buf, len, callback, context);
+       r = _LI_create_request(proc, query, callback, context);
        if (r == NULL) return KERN_FAILURE;
 
        status = MIG_SERVER_DIED;
        for (retry = 0; (status == MIG_SERVER_DIED) && (retry < MAX_LOOKUP_ATTEMPTS); retry++)
        {
-               /* send to lookupd */
-               status = _lu_async_send(r);
+               status = _LI_async_send(r);
        }
 
        if (status != KERN_SUCCESS)
        {
-               _lu_free_request(r);
+               _LI_free_request(r);
                return status;
        }
 
        /* Add request to worklist */
-       _lu_worklist_append(r);
+       _LI_worklist_append(r);
 
        *p = r->reply_port;
+
        return KERN_SUCCESS;
 }
 
 kern_return_t
-lu_async_send(mach_port_t *p, uint32_t proc, const char *buf, uint32_t len)
+LI_async_send(mach_port_t *p, uint32_t proc, kvbuf_t *query)
 {
-       return lu_async_start(p, proc, buf, len, NULL, NULL);
+       return LI_async_start(p, proc, query, NULL, NULL);
 }
 
-int
-lu_async_handle_reply(void *msg, char **buf, uint32_t *len, void **callback, void **context)
+kern_return_t
+LI_async_handle_reply(mach_msg_header_t *msg, kvarray_t **reply, void **callback, void **context)
 {
-       _lu_reply_msg_t *r;
-       _lu_async_request_t *req;
+       _li_async_request_t *req;
+       kvbuf_t *out;
        kern_return_t status;
        uint32_t retry;
-       boolean_t msgh_simple;
+       mig_reply_error_t *bufReply;
 
        if (msg == NULL) return -1;
-       r = (_lu_reply_msg_t *)msg;
 
        /* If reply status was an error, resend */
-       if (r->head.msgh_id != LU_MESSAGE_REPLY_ID)
-       {
-               if (r->head.msgh_id == MACH_NOTIFY_SEND_ONCE)
-               {
-                       /* if MiG server (lookupd) died */
-                       req = _lu_worklist_find(r->head.msgh_local_port);
-                       if (req == NULL) return -1;
-
-                       status = MIG_SERVER_DIED;
-                       for (retry = 0; (status == MIG_SERVER_DIED) && (retry < MAX_LOOKUP_ATTEMPTS); retry++)
-                       {
-                               /* send to lookupd */
-                               status = _lu_async_send(req);
-                       }
-
-                       if (status != KERN_SUCCESS) return -1;
-               }
-               return MIG_REPLY_MISMATCH;
-       }
-
-        msgh_simple = !(r->head.msgh_bits & MACH_MSGH_BITS_COMPLEX);
-
-       req = _lu_worklist_remove(r->head.msgh_local_port);
-       if (req == NULL) return -1;
-
-       *callback = req->callback;
-       *context = req->context;
-       _lu_free_request(req);
-       if (msgh_simple && ((mig_reply_error_t *) r)->RetCode != KERN_SUCCESS)
-       {
-               return ((mig_reply_error_t *) r)->RetCode;
-       }
-
-       *buf = r->reply_data.address;
-       *len = r->reply_data.size;
-
-       return 0;
-}
-
-ni_proplist *
-_lookupd_xdr_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));
-       if (l == NULL) return NULL;
-
-       NI_INIT(l);
-
-       l->ni_proplist_len = nkeys;
-       l->ni_proplist_val = NULL;
-       if (nkeys > 0)
-       {
-               l->ni_proplist_val = (ni_property *)calloc(nkeys, sizeof(ni_property));
-               if (l->ni_proplist_val == NULL)
-               {
-                       free(l);
-                       return NULL;
-               }
-       }
-
-       for (i = 0; i < nkeys; i++)
+       if (msg->msgh_id == MACH_NOTIFY_NO_SENDERS)
        {
-               key = NULL;
-               if (!xdr_string(inxdr, &key, -1))
-               {
-                       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)
-               {
-                       l->ni_proplist_val[i].nip_val.ni_namelist_val = (ni_name *)calloc(nvals, sizeof(ni_name));
-                       if (l->ni_proplist_val[i].nip_val.ni_namelist_val == NULL)
-                       {
-                               ni_proplist_free(l);
-                               return NULL;
-                       }
-               }
+               /* if server died */
+               req = _LI_worklist_find(msg->msgh_local_port);
+               if (req == NULL) return -1;
 
-               for (j = 0; j < nvals; j++)
+               status = MIG_SERVER_DIED;
+               for (retry = 0; (status == MIG_SERVER_DIED) && (retry < MAX_LOOKUP_ATTEMPTS); retry++)
                {
-                       val = NULL;
-                       if (!xdr_string(inxdr, &val, -1))
-                       {
-                               ni_proplist_free(l);
-                               return NULL;
-                       }
-
-                       l->ni_proplist_val[i].nip_val.ni_namelist_val[j] = val;
+                       /* send message */
+                       status = _LI_async_send(req);
                }
-       }
-
-       return l;
-}
-
-int
-lookupd_query(ni_proplist *l, ni_proplist ***out)
-{
-       unsigned datalen;
-       XDR outxdr;
-       XDR inxdr;
-       int proc;
-       char *listbuf, *s;
-       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 == MACH_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;
+               if (status != KERN_SUCCESS) return -1;
 
-       /* Encode attribute count */
-       if (!xdr_int(&outxdr, &na))
-       {
-               xdr_destroy(&outxdr);
-               return 0;
+               return MIG_REPLY_MISMATCH;
        }
 
-       for (i = 0; i < l->ni_proplist_len; i++)
-       {
-               p = &(l->ni_proplist_val[i]);
-               s = p->nip_name;
-               if (!xdr_string(&outxdr, &s, _LU_MAXLUSTRLEN))
-               {
-                       xdr_destroy(&outxdr);
-                       return 0;
-               }
-
-               if (!xdr_int(&outxdr, &(p->nip_val.ni_namelist_len)))
-               {
-                       xdr_destroy(&outxdr);
-                       return 0;
-               }
+       /* need to implement the msg_server_once type code here */
+       mach_msg_size_t reply_alloc = round_page(65536 + MAX_TRAILER_SIZE);
 
-               for (j = 0; j < p->nip_val.ni_namelist_len; j++)
-               {
-                       s = p->nip_val.ni_namelist_val[j];
-                       if (!xdr_string(&outxdr, &s, _LU_MAXLUSTRLEN))
-                       {
-                               xdr_destroy(&outxdr);
-                               return 0;
-                       }
-               }
-       }
+       status = vm_allocate(mach_task_self(), (vm_address_t *) &bufReply, reply_alloc, VM_MAKE_TAG(VM_MEMORY_MACH_MSG) | TRUE);
+       if (status != KERN_SUCCESS) return status;
 
-       listbuf = NULL;
-       datalen = 0;
+       status = DSlibinfoMIGAsyncReply_server(msg, (mach_msg_header_t *)bufReply);
 
-       n = xdr_getpos(&outxdr);
-       status = _lookup_all(_lu_port, proc, (void *)databuf, n, &listbuf, &datalen);
-       if (status != KERN_SUCCESS)
-       {
-               xdr_destroy(&outxdr);
-               return 0;
-       }
+       /* we just destroy the reply, because there isn't one */
+       if (bufReply->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) mach_msg_destroy(&bufReply->Head);
 
-       xdr_destroy(&outxdr);
-       datalen *= BYTES_PER_XDR_UNIT;
-       xdrmem_create(&inxdr, listbuf, datalen, XDR_DECODE);
+       vm_deallocate(mach_task_self(), (vm_address_t) bufReply, reply_alloc);
 
-       if (!xdr_int(&inxdr, &n))
-       {
-               xdr_destroy(&inxdr);
-               return 0;
-       }
+       if (status == FALSE) return KERN_FAILURE;
 
-       if (n == 0)
-       {
-               xdr_destroy(&inxdr);
-               return 0;
-       }
+       req = _LI_worklist_remove(msg->msgh_local_port);
+       if (req == NULL) return KERN_FAILURE;
 
-       *out = (ni_proplist **)malloc(n * sizeof(ni_proplist *));
+       *callback = req->callback;
+       *context = req->context;
+       out = (kvbuf_t *)calloc(1, sizeof(kvbuf_t));
        if (out == NULL)
        {
-               xdr_destroy(&inxdr);
-               return 0;
-       }
-
-       for (i = 0; i < n; i++)
-       {
-               (*out)[i] = _lookupd_xdr_dictionary(&inxdr);
+               if (req->ooreplyCnt > 0) vm_deallocate(mach_task_self(), req->ooreply, req->ooreplyCnt);
+               return KERN_FAILURE;
        }
 
-       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));
-       if (l == NULL) return NULL;
-
-       NI_INIT(l);
-
-       na = 0;
-       x = -1;
-
-       if (cat != NULL)
+       if (req->ooreplyCnt > 0)
        {
-               l->ni_proplist_val = (ni_property *)malloc(sizeof(ni_property));
-               if (l->ni_proplist_val == NULL)
+               out->datalen = req->ooreplyCnt;
+               out->databuf = malloc(req->ooreplyCnt);
+               if (out->databuf == NULL)
                {
-                       free(l);
-                       return NULL;
+                       free(out);
+                       *reply = NULL;
+                       vm_deallocate(mach_task_self(), req->ooreply, req->ooreplyCnt);
+                       return KERN_FAILURE;
                }
 
-               p = &(l->ni_proplist_val[0]);
-               arg = "_lookup_category";
-               p->nip_name = strdup(arg);
-               if (p->nip_name == NULL)
-               {
-                       ni_proplist_free(l);
-                       return NULL;
-               }
-               
-               p->nip_val.ni_namelist_len = 1;
-               p->nip_val.ni_namelist_val = (ni_name *)malloc(sizeof(ni_name));
-               if (p->nip_val.ni_namelist_val == NULL)
-               {
-                       ni_proplist_free(l);
-                       return NULL;
-               }
-                       
-               p->nip_val.ni_namelist_val[0] = strdup(cat);
-               if (p->nip_val.ni_namelist_val[0] == NULL)
-               {
-                       ni_proplist_free(l);
-                       return NULL;
-               }
-               
-               l->ni_proplist_len++;
-               x++;
+               memcpy(out->databuf, (char *)req->ooreply, req->ooreplyCnt);
+               vm_deallocate(mach_task_self(), req->ooreply, req->ooreplyCnt);
        }
-
-       va_start(ap, fmt);
-       for (f = fmt; (*f) != '\0'; f++)
+       else if (req->replyCnt > 0)
        {
-               arg = va_arg(ap, char *);
-               if (*f == 'k')
+               out->datalen = req->replyCnt;
+               out->databuf = malloc(req->replyCnt);
+               if (out->databuf == NULL)
                {
-                       l->ni_proplist_val = (ni_property *)reallocf(l->ni_proplist_val, (l->ni_proplist_len + 1) * sizeof(ni_property));
-                       if (l->ni_proplist_val == NULL)
-                       {
-                               ni_proplist_free(l);
-                               return NULL;
-                       }
-                       
-                       p = &(l->ni_proplist_val[l->ni_proplist_len]);
-                       p->nip_name = strdup(arg);
-                       if (p->nip_name == NULL)
-                       {
-                               ni_proplist_free(l);
-                               return NULL;
-                       }
-
-                       p->nip_val.ni_namelist_len = 0;
-                       p->nip_val.ni_namelist_val = NULL;
-
-                       l->ni_proplist_len++;
-                       x++;
+                       free(out);
+                       *reply = NULL;
+                       return KERN_FAILURE;
                }
-               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 *)reallocf(p->nip_val.ni_namelist_val, (p->nip_val.ni_namelist_len + 1) * sizeof(ni_name));
-                       }
-
-                       if (p->nip_val.ni_namelist_val == NULL)
-                       {
-                               ni_proplist_free(l);
-                               return NULL;
-                       }
-
-                       p->nip_val.ni_namelist_val[p->nip_val.ni_namelist_len] = strdup(arg);
-                       if (p->nip_val.ni_namelist_val[p->nip_val.ni_namelist_len] == NULL)
-                       {
-                               ni_proplist_free(l);
-                               return NULL;
-                       }
 
-                       p->nip_val.ni_namelist_len++;
-               }
+               memcpy(out->databuf, req->reply, req->replyCnt);
        }
-       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++)
+       *reply = kvbuf_decode(out);
+       if (*reply == NULL)
        {
-               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 *)reallocf(a->nip_val.ni_namelist_val, (a->nip_val.ni_namelist_len + 1) * sizeof(ni_name));
-                       if (a->nip_val.ni_namelist_val == NULL) return;
-
-                       a->nip_val.ni_namelist_val[a->nip_val.ni_namelist_len] = strdup(b->nip_val.ni_namelist_val[j]);
-                       if (a->nip_val.ni_namelist_val[a->nip_val.ni_namelist_len] == NULL)
-                       {
-                               free(a->nip_val.ni_namelist_val);
-                               a->nip_val.ni_namelist_val = NULL;
-                               return;
-                       }
-
-                       a->nip_val.ni_namelist_len++;
-               }
+               /* DS returned no data */
+               free(out->databuf);
+               free(out);
        }
+       
+       _LI_free_request(req);
+
+       return KERN_SUCCESS;
 }
 
-void
-ni_proplist_merge(ni_proplist *a, ni_proplist *b)
+static void
+_LI_thread_info_free(void *x)
 {
-       ni_index wa, wb;
-       int addme;
+       struct li_thread_info *tdata;
 
-       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 *)reallocf(a->ni_proplist_val, (a->ni_proplist_len + 1) * sizeof(ni_property));
-                       if (a->ni_proplist_val == NULL) return;
+       if (x == NULL) return;
 
-                       a->ni_proplist_val[a->ni_proplist_len].nip_name = strdup(b->ni_proplist_val[wb].nip_name);
-                       if (a->ni_proplist_val[a->ni_proplist_len].nip_name == NULL)
-                       {
-                               free(a->ni_proplist_val);
-                               a->ni_proplist_val = NULL;
-                               return NULL;
-                       }
-       
-                       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++;
-               }
-       }
+       tdata = (struct li_thread_info *)x;
+       LI_ils_free(tdata->li_entry, tdata->li_entry_size);
+       LI_data_free_kvarray(tdata);
 
-       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]));
-                       }
-               }
-       }
+       free(tdata);
 }
 
 static void
-_lu_data_free(void *x)
+_LI_data_free(void *x)
 {
-       struct _lu_data_s *t;
+       struct _li_data_s *t;
        int i;
 
        if (x == NULL) return;
 
-       t = (struct _lu_data_s *)x;
+       t = (struct _li_data_s *)x;
 
        for (i = 0; i < t->icount; i++)
        {
-               if ((t->idata[i] != NULL) && (t->idata_destructor[i] != NULL))
-               {
-                       (*(t->idata_destructor[i]))(t->idata[i]);
-               }
-
+               _LI_thread_info_free(t->idata[i]);
                t->idata[i] = NULL;
-               t->idata_destructor[i] = NULL;
        }
 
        if (t->ikey != NULL) free(t->ikey);
@@ -813,47 +556,44 @@ _lu_data_free(void *x)
        if (t->idata != NULL) free(t->idata);
        t->idata = NULL;
 
-       if (t->idata_destructor != NULL) free(t->idata_destructor);
-       t->idata_destructor = NULL;
-
        free(t);
 }
 
 static void
-_lu_data_init()
+_LI_data_init()
 {
-       pthread_key_create(&_info_key, _lu_data_free);
+       pthread_key_create(&_info_key, _LI_data_free);
        return;
 }
 
-static struct _lu_data_s *
-_lu_data_get()
+static struct _li_data_s *
+_LI_data_get()
 {
-       struct _lu_data_s *libinfo_data;
+       struct _li_data_s *libinfo_data;
 
        /*
         * Only one thread should create the _info_key
         */
-       pthread_once(&_info_key_initialized, _lu_data_init);
+       pthread_once(&_info_key_initialized, _LI_data_init);
 
        /* Check if this thread already created libinfo_data */
        libinfo_data = pthread_getspecific(_info_key);
        if (libinfo_data != NULL) return libinfo_data;
 
-       libinfo_data = (struct _lu_data_s *)calloc(1, sizeof(struct _lu_data_s));
+       libinfo_data = (struct _li_data_s *)calloc(1, sizeof(struct _li_data_s));
        if (libinfo_data == NULL) return NULL;
 
        pthread_setspecific(_info_key, libinfo_data);
        return libinfo_data;
 }
 
-void *
-_lu_data_create_key(unsigned int key, void (*destructor)(void *))
+__private_extern__ void *
+LI_data_find_key(uint32_t key)
 {
-       struct _lu_data_s *libinfo_data;
-       unsigned int i, n;
+       struct _li_data_s *libinfo_data;
+       uint32_t i;
 
-       libinfo_data = _lu_data_get();
+       libinfo_data = _LI_data_get();
        if (libinfo_data == NULL) return NULL;
 
        for (i = 0; i < libinfo_data->icount; i++)
@@ -861,305 +601,1861 @@ _lu_data_create_key(unsigned int key, void (*destructor)(void *))
                if (libinfo_data->ikey[i] == key) return libinfo_data->idata[i];
        }
 
-       i = libinfo_data->icount;
-       n = i + 1;
+       return NULL;
+}
+
+__private_extern__ void *
+LI_data_create_key(uint32_t key, size_t esize)
+{
+       struct _li_data_s *libinfo_data;
+       struct li_thread_info *tdata;
+       uint32_t i, n;
+
+       libinfo_data = _LI_data_get();
+       if (libinfo_data == NULL) return NULL;
+
+       for (i = 0; i < libinfo_data->icount; i++)
+       {
+               if (libinfo_data->ikey[i] == key) return libinfo_data->idata[i];
+       }
+
+       i = libinfo_data->icount;
+       n = i + 1;
 
        if (i == 0)
        {
-               libinfo_data->ikey = (unsigned int *)malloc(sizeof(unsigned int));
+               libinfo_data->ikey = (uint32_t *)malloc(sizeof(uint32_t));
                libinfo_data->idata = (void **)malloc(sizeof(void *));
-               libinfo_data->idata_destructor = (void (**)(void *))malloc(sizeof(void (*)(void *)));
        }
        else
        {
-               libinfo_data->ikey = (unsigned int *)reallocf(libinfo_data->ikey, n * sizeof(unsigned int));
+               libinfo_data->ikey = (uint32_t *)reallocf(libinfo_data->ikey, n * sizeof(uint32_t));
                libinfo_data->idata = (void **)reallocf(libinfo_data->idata, n * sizeof(void *));
-               libinfo_data->idata_destructor = (void (**)(void *))reallocf(libinfo_data->idata_destructor, n * sizeof(void (*)(void *)));
        }
 
-       if ((libinfo_data->ikey == NULL) || (libinfo_data->idata == NULL) || (libinfo_data->idata_destructor == NULL))
+       if ((libinfo_data->ikey == NULL) || (libinfo_data->idata == NULL))
        {
                if (libinfo_data->ikey != NULL) free(libinfo_data->ikey);
+               libinfo_data->ikey = NULL;
+
                if (libinfo_data->idata != NULL) free(libinfo_data->idata);
-               if (libinfo_data->idata_destructor != NULL) free(libinfo_data->idata_destructor);
+               libinfo_data->idata = NULL;
+
                return NULL;
        }
 
+       tdata = (struct li_thread_info *)calloc(1, sizeof(struct li_thread_info));
+       if (tdata == NULL) return NULL;
+
+       tdata->li_entry_size = esize;
+
        libinfo_data->ikey[i] = key;
-       libinfo_data->idata[i] = NULL;
-       libinfo_data->idata_destructor[i] = destructor;
+       libinfo_data->idata[i] = tdata;
        libinfo_data->icount++;
 
-       return NULL;
+       return tdata;
 }
 
-static unsigned int
-_lu_data_index(unsigned int key, struct _lu_data_s *libinfo_data)
+static uint32_t
+_LI_data_index(uint32_t key, struct _li_data_s *libinfo_data)
 {
-       unsigned int i;
+       uint32_t i;
 
-       if (libinfo_data == NULL) return (unsigned int)-1;
+       if (libinfo_data == NULL) return (uint32_t)-1;
 
        for (i = 0; i < libinfo_data->icount; i++)
        {
                if (libinfo_data->ikey[i] == key) return i;
        }
 
-       return (unsigned int)-1;
+       return (uint32_t)-1;
 }
 
 void
-_lu_data_set_key(unsigned int key, void *data)
+_LI_data_set_key(uint32_t key, void *data)
 {
-       struct _lu_data_s *libinfo_data;
-       unsigned int i;
+       struct _li_data_s *libinfo_data;
+       uint32_t i;
 
-       libinfo_data = _lu_data_get();
+       libinfo_data = _LI_data_get();
        if (libinfo_data == NULL) return;
 
-       i = _lu_data_index(key, libinfo_data);
-       if (i == (unsigned int)-1) return;
+       i = _LI_data_index(key, libinfo_data);
+       if (i == (uint32_t)-1) return;
 
        libinfo_data->idata[i] = data;
 }
 
 void *
-_lu_data_get_key(unsigned int key)
+_LI_data_get_key(uint32_t key)
 {
-       struct _lu_data_s *libinfo_data;
-       unsigned int i;
+       struct _li_data_s *libinfo_data;
+       uint32_t i;
 
-       libinfo_data = _lu_data_get();
+       libinfo_data = _LI_data_get();
        if (libinfo_data == NULL) return NULL;
 
-       i = _lu_data_index(key, libinfo_data);
-       if (i == (unsigned int)-1) return NULL;
+       i = _LI_data_index(key, libinfo_data);
+       if (i == (uint32_t)-1) return NULL;
 
        return libinfo_data->idata[i];
 }
 
-void
-_lu_data_free_vm_xdr(struct lu_thread_info *tdata)
+__private_extern__ void
+LI_data_free_kvarray(struct li_thread_info *tdata)
 {
        if (tdata == NULL) return;
+       if (tdata->li_vm == NULL) return;
 
-       if (tdata->lu_vm != NULL)
-       {
-               vm_deallocate(mach_task_self(), (vm_address_t)tdata->lu_vm, tdata->lu_vm_length);
-               tdata->lu_vm = NULL;
-       }
-       tdata->lu_vm_length = 0;
-       tdata->lu_vm_cursor = 0;
-
-       if (tdata->lu_xdr != NULL)
-       {
-               xdr_destroy(tdata->lu_xdr);
-               free(tdata->lu_xdr);
-               tdata->lu_xdr = NULL;
-       }
+       kvarray_free((kvarray_t *)tdata->li_vm);
+       tdata->li_vm = NULL;
 }
 
-int
-_lu_xdr_attribute(XDR *xdr, char **key, char ***val, unsigned int *count)
+__private_extern__ void
+LI_data_recycle(struct li_thread_info *tdata, void *entry, size_t entrysize)
 {
-       unsigned int i, j, len;
-       char **x, *s;
+       if (tdata == NULL) return;
 
-       if (xdr == NULL) return -1;
-       if (key == NULL) return -1;
-       if (val == NULL) return -1;
-       if (count == NULL) return -1;
+       LI_ils_free(tdata->li_entry, entrysize);
+       tdata->li_entry = entry;
+}
 
-       *key = NULL;
-       *val = NULL;
-       *count = 0;
+#define KVBUF_CHUNK 256
 
-       if (!xdr_string(xdr, key, -1)) return -1;
+/*
+ * kvbuf_t is a list of key/value dictionaries.
+ *
+ * First 4 bytes are the number of dictionaries.
+ * For each dictionary, first 4 bytes is the key / value list count.
+ * For each value list, first 4 bytes is the list length.
+ * Keys and values are a 4-byte length followed by a nul-terminated string
+ *
+ * When the databuf needs to grow, we add memory in KVBUF_CHUNK size
+ * increments to reduce malloc / realloc activity.
+ * The _size variable stores the actual allocated size.
+ * The datalen variable stores the used data size.
+ *
+ * The _dict variable holds an offset from the start of the buffer
+ * to the "current" dictionary.  kvbuf_reset() resets this,
+ * and kvbuf_next_dict() bumps the offset so that databuf + _dict
+ * points to the next dictionary.
+ *
+ * The _key variable holds an offset from the start of the buffer
+ * to the "current" key.  kvbuf_reset() resets this, and
+ * kvbuf_next_key() bumps the offset so that databuf + _key
+ * points to the next key.
+ *
+ * The _val variable holds an offset from the start of the buffer
+ * to the "current" value.  kvbuf_reset() resets this, and
+ * kvbuf_next_val() bumps the offset so that databuf + _val
+ * points to the next value.
+ *
+ * The cache_entry_list_to_kvbuf() routine contains the only
+ * code that builds an array.
+ * 
+ */
 
-       if (!xdr_int(xdr, &len))
-       {
-               free(*key);
-               *key = NULL;
-               return -1;
-       }
+/*
+ * kvbuf_query is a simple utility for constructing a
+ * kvbuf with a single dictionary.  The format string may
+ * contain the chars "k", "s", "i", and "u".  "k" denotes a key
+ * (keys are always strings), "s" denotes a string value,
+ * "i" denotes a 32 bit signed int, and "u" denotes an unsigned.
+ */
+__private_extern__ kvbuf_t *
+kvbuf_query(char *fmt, ...)
+{
+       va_list ap;
+       char *arg, *f, str[32];
+       int32_t iarg;
+       uint32_t uarg;
+       kvbuf_t *kv;
 
-       if (len == 0) return 0;
-       *count = len;
+       if (fmt == NULL) return NULL;
 
-       x = (char **)calloc(len + 1, sizeof(char *));
-       if (x == NULL) return -1;
+       kv = kvbuf_new();
+       if (kv == NULL) return NULL;
 
-       *val = x;
+       kvbuf_add_dict(kv);
 
-       for (i = 0; i < len; i++)
+       va_start(ap, fmt);
+       for (f = fmt; (*f) != '\0'; f++)
        {
-               s = NULL;
-               if (!xdr_string(xdr, &s, -1))
+               if (*f == 'k')
+               {
+                       arg = va_arg(ap, char *);
+                       kvbuf_add_key(kv, arg);
+               }
+               else if (*f == 's')
+               {
+                       arg = va_arg(ap, char *);
+                       kvbuf_add_val(kv, arg);
+               }
+               else if (*f == 'i')
                {
-                       for (j = 0; j < i; j++) free(x[j]);
-                       free(x);
-                       *val = NULL;
-                       free(*key);
-                       *key = NULL;
-                       *count = 0;
-                       return -1;
+                       iarg = va_arg(ap, int32_t);
+                       snprintf(str, sizeof(str), "%d", iarg);
+                       kvbuf_add_val(kv, str);
+               }
+               else if (*f == 'u')
+               {
+                       uarg = va_arg(ap,uint32_t);
+                       snprintf(str, sizeof(str), "%u", uarg);
+                       kvbuf_add_val(kv, str);
                }
-               x[i] = s;
        }
+       va_end(ap);
 
-       x[len] = NULL;
-
-       return 0;
+       return kv;
 }
 
-kern_return_t 
-_lookup_link(mach_port_t server, lookup_name name, int *procno)
+__private_extern__ kvbuf_t *
+kvbuf_query_key_val(const char *key, const char *val)
 {
-       kern_return_t status;
-       security_token_t token;
-       unsigned int n;
+       kvbuf_t *kv;
+       uint32_t x, kl, vl, vc;
+       char *p;
 
-       token.val[0] = -1;
-       token.val[1] = -1;
+       if (key == NULL) return NULL;
 
-       status = MIG_SERVER_DIED;
-       for (n = 0; (status == MIG_SERVER_DIED) && (n < MAX_LOOKUP_ATTEMPTS); n++)
+       kl = strlen(key) + 1;
+
+       vl = 0;
+       vc = 0;
+
+       if (val != NULL) 
        {
-               status = _lookup_link_secure(server, name, procno, &token);
+               vl = strlen(val) + 1;
+               vc = 1;
        }
 
-       if (status != KERN_SUCCESS)
+       kv = (kvbuf_t *)calloc(1, sizeof(kvbuf_t));
+       if (kv == NULL) return NULL;
+
+       kv->_size = (5 * sizeof(uint32_t)) + kl + vl;
+       kv->datalen = kv->_size;
+
+       kv->databuf = calloc(1, kv->_size);
+       if (kv->databuf == NULL)
        {
-#ifdef DEBUG
-               syslog(LOG_DEBUG, "pid %u _lookup_link %s status %u", getpid(), name, status);
-#endif
-               return status;
+               free(kv);
+               return NULL;
        }
 
-       if (token.val[0] != 0)
+       p = kv->databuf;
+
+       /* 1 dict */
+       x = htonl(1);
+       memcpy(p, &x, sizeof(uint32_t));
+       p += sizeof(uint32_t);
+
+       /* 1 key */
+       memcpy(p, &x, sizeof(uint32_t));
+       p += sizeof(uint32_t);
+
+       /* key length */
+       x = htonl(kl);
+       memcpy(p, &x, sizeof(uint32_t));
+       p += sizeof(uint32_t);
+
+       /* key */
+       memcpy(p, key, kl);
+       p += kl;
+
+       /* number of values */
+       x = htonl(vc);
+       memcpy(p, &x, sizeof(uint32_t));
+       p += sizeof(uint32_t);
+
+       if (vc > 0)
        {
-#ifdef DEBUG
-               syslog(LOG_DEBUG, "pid %u _lookup_link %s auth failure uid=%d", getpid(), name, token.val[0]);
-#endif
-               return KERN_FAILURE;
+               /* value length */
+               x = htonl(vl);
+               memcpy(p, &x, sizeof(uint32_t));
+               p += sizeof(uint32_t);
+
+               /* value */
+               memcpy(p, val, vl);
        }
 
-#ifdef DEBUG
-       syslog(LOG_DEBUG, "pid %u _lookup_link %s = %d", getpid(), name, *procno);
-#endif
-       return status;
+       return kv;
 }
 
-kern_return_t 
-_lookup_one(mach_port_t server, int proc, inline_data indata, mach_msg_type_number_t indataCnt, inline_data outdata, mach_msg_type_number_t *outdataCnt)
+__private_extern__ kvbuf_t *
+kvbuf_query_key_int(const char *key, int32_t i)
 {
-       kern_return_t status;
-       security_token_t token;
-       unsigned int n;
+       char str[32];
 
-       token.val[0] = -1;
-       token.val[1] = -1;
+       snprintf(str, sizeof(str), "%d", i);
+       return kvbuf_query_key_val(key, str);
+}
 
-       status = MIG_SERVER_DIED;
-       for (n = 0; (status == MIG_SERVER_DIED) && (n < MAX_LOOKUP_ATTEMPTS); n++)
+__private_extern__ kvbuf_t *
+kvbuf_query_key_uint(const char *key, uint32_t u)
+{
+       char str[32];
+
+       snprintf(str, sizeof(str), "%u", u);
+       return kvbuf_query_key_val(key, str);
+}
+
+kvbuf_t *
+kvbuf_new(void)
+{
+       kvbuf_t *kv;
+
+       kv = (kvbuf_t *)calloc(1, sizeof(kvbuf_t));
+       if (kv == NULL) return NULL;
+
+       kv->_size = KVBUF_START_SIZE;
+       kv->databuf = calloc(1, kv->_size);
+       if (kv->databuf == NULL)
        {
-               status = _lookup_one_secure(server, proc, indata, indataCnt, outdata, outdataCnt, &token);
+               free(kv);
+               return NULL;
        }
 
-       if (status != KERN_SUCCESS)
+       kv->datalen = sizeof(uint32_t);
+       kv->_dict = kv->datalen;
+
+       return kv;
+}
+
+kvbuf_t *
+kvbuf_init(char *buffer, uint32_t length)
+{
+       kvbuf_t *kv;
+
+       kv = (kvbuf_t *)calloc(1, sizeof(kvbuf_t));
+       if (kv == NULL) return NULL;
+
+       kv->_size = length;
+       kv->datalen = length;
+       kv->databuf = calloc(1, length);
+       if (kv->databuf == NULL)
        {
-#ifdef DEBUG
-               syslog(LOG_DEBUG, "pid %u _lookup_one %d status %u", getpid(), proc, status);
-#endif
-               return status;
+               free(kv);
+               kv = NULL;
        }
-
-       if (token.val[0] != 0)
+       else
        {
-#ifdef DEBUG
-               syslog(LOG_DEBUG, "pid %u _lookup_one %d auth failure uid=%d", getpid(), proc, token.val[0]);
-#endif
-               return KERN_FAILURE;
+               memcpy(kv->databuf, buffer, length);
        }
 
-#ifdef DEBUG
-       syslog(LOG_DEBUG, "pid %u _lookup_one %d", getpid(), proc);
-#endif
-       return status;
+       return kv;
 }
 
-kern_return_t 
-_lookup_all(mach_port_t server, int proc, inline_data indata, mach_msg_type_number_t indataCnt, ooline_data *outdata, mach_msg_type_number_t *outdataCnt)
+static void
+kvbuf_grow(kvbuf_t *kv, uint32_t delta)
 {
-       kern_return_t status;
-       security_token_t token;
-       unsigned int n;
+       uint32_t newlen, n;
+       char *p;
 
-       token.val[0] = -1;
-       token.val[1] = -1;
+       if (kv == NULL) return;
+       if (delta == 0) return;
 
-       status = MIG_SERVER_DIED;
-       for (n = 0; (status == MIG_SERVER_DIED) && (n < MAX_LOOKUP_ATTEMPTS); n++)
-       {
-               status = _lookup_all_secure(server, proc, indata, indataCnt, outdata, outdataCnt, &token);
-       }
+       if (kv->databuf == NULL) delta += sizeof(uint32_t);
 
-       if (status != KERN_SUCCESS)
+       n = (delta + KVBUF_CHUNK - 1) / KVBUF_CHUNK;
+       newlen = kv->datalen + (n * KVBUF_CHUNK);
+
+       if (newlen <= kv->_size) return;
+
+       kv->_size = newlen;
+
+       if (kv->databuf == NULL)
        {
-#ifdef DEBUG
-               syslog(LOG_DEBUG, "pid %u _lookup_all %d status %u", getpid(), proc, status);
-#endif
-               return status;
-       }
+               kv->databuf = calloc(1, kv->_size);
+               if (kv->databuf == NULL)
+               {
+                       memset(kv, 0, sizeof(kvbuf_t));
+                       return;
+               }
 
-       if (token.val[0] != 0)
+               kv->datalen = sizeof(uint32_t);
+               kv->_dict = sizeof(uint32_t);
+       }
+       else
        {
-#ifdef DEBUG
-               syslog(LOG_DEBUG, "pid %u _lookup_all %d auth failure uid=%d", getpid(), proc, token.val[0]);
-#endif
-               return KERN_FAILURE;
+               kv->databuf = reallocf(kv->databuf, kv->_size);
+               if (kv->databuf == NULL)
+               {
+                       memset(kv, 0, sizeof(kvbuf_t));
+                       return;
+               }
+
+               p = kv->databuf + kv->datalen;
+               memset(p, 0, kv->_size - kv->datalen);
        }
+}
 
-#ifdef DEBUG
-       syslog(LOG_DEBUG, "pid %u _lookup_all %d", getpid(), proc);
-#endif
-       return status;
+void
+kvbuf_add_dict(kvbuf_t *kv)
+{
+       char *p;
+       uint32_t x, dict_count;
+
+       if (kv == NULL) return;
+
+       /* Add a key count */
+       kvbuf_grow(kv, sizeof(uint32_t));
+       if (kv->databuf == NULL) return;
+
+       kv->_dict = kv->datalen;
+       kv->datalen += sizeof(uint32_t);
+
+       kv->_key = kv->datalen;
+       kv->_vlist = 0;
+       kv->_val = 0;
+
+       /* increment and rewrite the dict count */
+       p = kv->databuf;
+
+       x = 0;
+       memcpy(&x, p, sizeof(uint32_t));
+       dict_count = ntohl(x);
+
+       dict_count++;
+       x = htonl(dict_count);
+       memcpy(p, &x, sizeof(uint32_t));
 }
 
-kern_return_t 
-_lookup_ooall(mach_port_t server, int proc, ooline_data indata, mach_msg_type_number_t indataCnt, ooline_data *outdata, mach_msg_type_number_t *outdataCnt)
+void
+kvbuf_add_key(kvbuf_t *kv, const char *key)
 {
-       kern_return_t status;
-       security_token_t token;
-       unsigned int n;
+       uint32_t kl, x, key_count, delta;
+       char *p;
 
-       token.val[0] = -1;
-       token.val[1] = -1;
+       if (kv == NULL) return;
+       if (key == NULL) return;
 
-       status = MIG_SERVER_DIED;
-       for (n = 0; (status == MIG_SERVER_DIED) && (n < MAX_LOOKUP_ATTEMPTS); n++)
+       kl = strlen(key) + 1;
+
+       /* Grow to hold key len, key, and value list count. */
+       delta = (2 * sizeof(uint32_t)) + kl;
+       kvbuf_grow(kv, delta);
+
+       if (kv->databuf == NULL) return;
+
+       /* increment and rewrite the key count for the current dictionary */
+       p = kv->databuf + kv->_dict;
+
+       x = 0;
+       memcpy(&x, p, sizeof(uint32_t));
+       key_count = ntohl(x);
+
+       if (key_count == 0) kv->_key = kv->_dict + sizeof(uint32_t);
+       else kv->_key = kv->datalen;
+
+       key_count++;
+       x = htonl(key_count);
+       memcpy(p, &x, sizeof(uint32_t));
+
+       /* append key to data buffer */
+       p = kv->databuf + kv->datalen;
+
+       x = htonl(kl);
+       memcpy(p, &x, sizeof(uint32_t));
+       p += sizeof(uint32_t);
+       memcpy(p, key, kl);
+       p += kl;
+
+       kv->_vlist = kv->datalen + sizeof(uint32_t) + kl;
+
+       x = 0;
+       memcpy(p, &x, sizeof(uint32_t));
+
+       kv->datalen += delta;
+       kv->_val = kv->datalen;
+}
+
+void
+kvbuf_add_val_len(kvbuf_t *kv, const char *val, uint32_t len)
+{
+       uint32_t x, val_count, delta;
+       char *p;
+
+       if (kv == NULL) return;
+       if (val == NULL) return;
+       if (len == 0) return;
+
+       /* Grow to hold val len and value. */
+       delta = sizeof(uint32_t) + len;
+       kvbuf_grow(kv, delta);
+
+       if (kv->databuf == NULL) return;
+
+       /* increment and rewrite the value count for the value_list dictionary */
+       p = kv->databuf + kv->_vlist;
+
+       x = 0;
+       memcpy(&x, p, sizeof(uint32_t));
+       val_count = ntohl(x);
+       val_count++;
+       x = htonl(val_count);
+       memcpy(p, &x, sizeof(uint32_t));
+
+       /* append val to data buffer */
+       p = kv->databuf + kv->_val;
+
+       x = htonl(len);
+       memcpy(p, &x, sizeof(uint32_t));
+       p += sizeof(uint32_t);
+       memcpy(p, val, len);
+       p += len;
+
+       kv->datalen += delta;
+       kv->_val = kv->datalen;
+}
+
+/* 
+ * WARNING!  Kludge Alert!
+ *
+ * This call just looks for the buffer length encoded into a serialized kvbuf_t,
+ * which preceeds a pointer to a key or value.  Obviously, calling it with anything
+ * other than a pointer value which is embedded in a kvbuf_t is asking for trouble.
+ */
+uint32_t
+kvbuf_get_len(const char *p)
+{
+       uint32_t x;
+
+       x = 0;
+       memcpy(&x, p - sizeof(uint32_t), sizeof(uint32_t));
+       return ntohl(x);
+}
+
+void
+kvbuf_add_val(kvbuf_t *kv, const char *val)
+{
+       if (kv == NULL) return;
+       if (val == NULL) return;
+
+       kvbuf_add_val_len(kv, val, strlen(val) + 1);
+}
+
+void
+kvbuf_free(kvbuf_t *kv)
+{
+       if (kv == NULL) return;
+       if (kv->databuf != NULL) free(kv->databuf);
+       memset(kv, 0, sizeof(kvbuf_t));
+       free(kv);
+}
+
+/* appends a kvbuf to an existing kvbuf */
+void
+kvbuf_append_kvbuf(kvbuf_t *kv, const kvbuf_t *kv2)
+{
+       uint32_t curr_count, new_count, temp;
+
+       if (kv == NULL) return;
+       if (kv2 == NULL) return;
+
+       curr_count = 0;
+       new_count = 0;
+
+       memcpy(&temp, kv->databuf, sizeof(uint32_t));
+       curr_count = ntohl(temp);
+
+       memcpy(&temp, kv2->databuf, sizeof(uint32_t));
+       new_count = ntohl(temp);
+
+       /* nothing to do */
+       if (new_count == 0) return;
+
+       /* add the dictionary count to the current dictionary counts */
+       curr_count += new_count; 
+
+       temp = htonl(curr_count);
+       memcpy(kv->databuf, &temp, sizeof(uint32_t));
+
+       /* grow the current buffer so we can append the new buffer */
+       temp = kv2->datalen - sizeof(uint32_t);
+
+       kvbuf_grow(kv, temp);
+
+       memcpy(kv->databuf + kv->datalen, kv2->databuf + sizeof(uint32_t), temp);
+       kv->datalen += temp;
+}
+
+/* returns number of dictionaries */
+uint32_t
+kvbuf_reset(kvbuf_t *kv)
+{
+       uint32_t x;
+
+       if (kv == NULL) return 0;
+       if (kv->databuf == NULL) return 0;
+
+       kv->_dict = 0;
+       kv->_key = 0;
+       kv->_vlist = 0;
+       kv->_val = 0;
+
+       if (kv->datalen < sizeof(uint32_t)) return 0;
+
+       x = 0;
+       memcpy(&x, kv->databuf, sizeof(uint32_t));
+       return ntohl(x);
+}
+
+/* advance to next dictionary, returns key count */
+uint32_t
+kvbuf_next_dict(kvbuf_t *kv)
+{
+       uint32_t x, k, v, kcount, vcount, kl, vl;
+       char *p;
+
+       if (kv == NULL) return 0;
+       if (kv->databuf == NULL) return 0;
+
+       kv->_key = 0;
+       kv->_vlist = 0;
+       kv->_val = 0;
+
+       if (kv->_dict == 0)
        {
-               status = _lookup_ooall_secure(server, proc, indata, indataCnt, outdata, outdataCnt, &token);
+               /* first dict */
+               if (kv->datalen < sizeof(uint32_t)) return 0;
+               kv->_dict = sizeof(uint32_t);
+
+               if (kv->datalen < (kv->_dict + sizeof(uint32_t))) return 0;
+
+               p = kv->databuf + kv->_dict;
+               x = 0;
+               memcpy(&x, p, sizeof(uint32_t));
+               kcount = ntohl(x);
+
+               return kcount;
        }
 
-       if (status != KERN_SUCCESS)
+       p = kv->databuf + kv->_dict;
+
+       x = 0;
+       memcpy(&x, p, sizeof(uint32_t));
+       p += sizeof(uint32_t);
+       kv->_dict += sizeof(uint32_t);
+       kcount = ntohl(x);
+
+       for (k = 0; k < kcount; k++)
        {
-#ifdef DEBUG
-               syslog(LOG_DEBUG, "pid %u _lookup_ooall %d status %u", getpid(), proc, status);
-#endif
-               return status;
+               x = 0;
+               memcpy(&x, p, sizeof(uint32_t));
+               p += sizeof(uint32_t);
+               kv->_dict += sizeof(uint32_t);
+               kl = ntohl(x);
+               p += kl;
+               kv->_dict += kl;
+
+               x = 0;
+               memcpy(&x, p, sizeof(uint32_t));
+               p += sizeof(uint32_t);
+               kv->_dict += sizeof(uint32_t);
+               vcount = ntohl(x);
+
+               for (v = 0; v < vcount; v++)
+               {
+                       x = 0;
+                       memcpy(&x, p, sizeof(uint32_t));
+                       p += sizeof(uint32_t);
+                       kv->_dict += sizeof(uint32_t);
+                       vl = ntohl(x);
+                       p += vl;
+                       kv->_dict += vl;
+               }
        }
 
-       if (token.val[0] != 0)
+       if (kv->datalen < (kv->_dict + sizeof(uint32_t))) return 0;
+
+       p = kv->databuf + kv->_dict;
+       x = 0;
+       memcpy(&x, p, sizeof(uint32_t));
+       kcount = ntohl(x);
+
+       return kcount;
+}
+
+/* advance to next key, returns key and sets val_count */
+char *
+kvbuf_next_key(kvbuf_t *kv, uint32_t *val_count)
+{
+       uint32_t x, kl, v, vl, vc;
+       char *p, *out;
+
+       if (kv == NULL) return NULL;
+       if (val_count == NULL) return NULL;
+
+       *val_count = 0;
+
+       if (kv->databuf == NULL) return NULL;
+       if (kv->_dict == 0) return NULL;
+
+       kv->_vlist = 0;
+       kv->_val = 0;
+
+       if (kv->_key == 0)
        {
-#ifdef DEBUG
-               syslog(LOG_DEBUG, "pid %u _lookup_ooall %d auth failure uid=%d", getpid(), proc, token.val[0]);
-#endif
-               return KERN_FAILURE;
+               /* first key */
+               if (kv->datalen < (kv->_dict +  sizeof(uint32_t))) return NULL;
+               kv->_key = kv->_dict + sizeof(uint32_t);
        }
+       else
+       {
+               p = kv->databuf + kv->_key;
 
+               x = 0;
+               memcpy(&x, p, sizeof(uint32_t));
+               kl = ntohl(x);
+
+               if (kv->datalen < (kv->_key + sizeof(uint32_t) + kl)) return NULL;
+
+               p += (sizeof(uint32_t) + kl);
+               kv->_key += (sizeof(uint32_t) + kl);
+
+               /* skip over values */
+               if (kv->datalen < (kv->_key + sizeof(uint32_t))) return NULL;
+
+               x = 0;
+               memcpy(&x, p, sizeof(uint32_t));
+               vc = ntohl(x);
+
+               p += sizeof(uint32_t);
+               kv->_key += sizeof(uint32_t);
+
+               for (v = 0; v < vc; v++)
+               {
+                       if (kv->datalen < (kv->_key + sizeof(uint32_t))) return NULL;
+
+                       x = 0;
+                       memcpy(&x, p, sizeof(uint32_t));
+                       vl = ntohl(x);
+
+                       if (kv->datalen < (kv->_key + kl)) return NULL;
+
+                       p += (sizeof(uint32_t) + vl);
+                       kv->_key += (sizeof(uint32_t) + vl);
+               }
+       }
+
+       if (kv->datalen < (kv->_key + sizeof(uint32_t))) return NULL;
+
+       p = kv->databuf + kv->_key;
+       x = 0;
+       memcpy(&x, p, sizeof(uint32_t));
+       kl = ntohl(x);
+
+       p += sizeof(uint32_t);
+       out = p;
+
+       kv->_vlist = kv->_key + sizeof(uint32_t) + kl;
+       if (kv->datalen < (kv->_vlist + sizeof(uint32_t)))
+       {
+               kv->_vlist = 0;
+               return NULL;
+       }
+
+       p = kv->databuf + kv->_vlist;
+       x = 0;
+       memcpy(&x, p, sizeof(uint32_t));
+       *val_count = ntohl(x);
+
+       return out;
+}
+
+char *
+kvbuf_next_val(kvbuf_t *kv)
+{
+       return kvbuf_next_val_len(kv, NULL);
+}
+
+char *
+kvbuf_next_val_len(kvbuf_t *kv, uint32_t *len)
+{
+       uint32_t x = 0;
+       uint32_t vltemp = 0;
+       char *p;
+
+       if (kv == NULL) return NULL;
+       if (kv->databuf == NULL) return NULL;
+       if (kv->_vlist == 0) return NULL;
+
+       if (kv->_val == 0)
+       {
+               /* first val */
+               if (kv->datalen < (kv->_vlist +  sizeof(uint32_t))) return NULL;
+               kv->_val = kv->_vlist + sizeof(uint32_t);
+
+               p = kv->databuf + kv->_val;
+
+               memcpy(&x, p, sizeof(uint32_t));
+               vltemp = ntohl(x);
+       }
+       else
+       {
+               p = kv->databuf + kv->_val;
+
+               memcpy(&x, p, sizeof(uint32_t));
+               vltemp = ntohl(x);
+
+               if (kv->datalen < (kv->_val + sizeof(uint32_t) + vltemp)) return NULL;
+
+               p += (sizeof(uint32_t) + vltemp);
+               kv->_val += (sizeof(uint32_t) + vltemp);
+       }
+
+       if (kv->datalen < (kv->_val + sizeof(uint32_t))) return NULL;
+
+       if (len != NULL) (*len) = vltemp;
+       p = kv->databuf + kv->_val + sizeof(uint32_t);
+       return p;
+}
+
+/*
+ * Builds a kvarray_t / kvdict_t structure on top of a kvbuf_t. 
+ * It allocates the appropriate number of kvdict_t structures
+ * for the array, sets all the counters, and fills in pointers
+ * for keys and valuse.  The pointers are NOT to newly allocated
+ * strings: they just point into the kvbuf data buffer.
+ *
+ * To dispose of the kvarray_t and all of the associated
+ * memory AND to free the original kvbuf, clients only
+ * need to call kvarray_free().
+ */
+kvarray_t *
+kvbuf_decode(kvbuf_t *kv)
+{
+       kvarray_t *a;
+       uint32_t x, d, k, v;
+       char *p;
+
+       if (kv == NULL) return NULL;
+       if (kv->databuf == NULL) return NULL;
+
+       if (kv->datalen < sizeof(uint32_t)) return NULL;
+
+       p = kv->databuf;
+       kv->_size = kv->datalen;
+
+       /* array count */
+       x = 0;
+       memcpy(&x, p, sizeof(uint32_t));
+       p += sizeof(uint32_t);
+       kv->_size -= sizeof(uint32_t);
+       x = ntohl(x);
+
+       if (x == 0) return NULL;
+
+       a = (kvarray_t *)calloc(1, sizeof(kvarray_t));
+       if (a == NULL) return NULL;
+
+       a->count = x;
+       a->dict = (kvdict_t *)calloc(a->count, sizeof(kvdict_t));
+       if (a->dict == NULL)
+       {
+               free(a);
+               return NULL;
+       }
+
+       for (d = 0; d < a->count; d++)
+       {
+               if (kv->_size < sizeof(uint32_t))
+               {
+                       kvarray_free(a);
+                       return NULL;
+               }
+
+               /* key count */
+               x = 0;
+               memcpy(&x, p, sizeof(uint32_t));
+               p += sizeof(uint32_t);
+               kv->_size -= sizeof(uint32_t);
+               a->dict[d].kcount = ntohl(x);
+
+               if (a->dict[d].kcount > 0)
+               {
+                       a->dict[d].key = (const char **)calloc(a->dict[d].kcount, sizeof(const char *));
+                       if (a->dict[d].key == NULL)
+                       {
+                               kvarray_free(a);
+                               return NULL;
+                       }
+
+                       a->dict[d].vcount = (uint32_t *)calloc(a->dict[d].kcount, sizeof(uint32_t));
+                       if (a->dict[d].vcount == NULL)
+                       {
+                               kvarray_free(a);
+                               return NULL;
+                       }
+
+                       a->dict[d].val = (const char ***)calloc(a->dict[d].kcount, sizeof(char **));
+                       if (a->dict[d].val == NULL)
+                       {
+                               kvarray_free(a);
+                               return NULL;
+                       }
+               }
+
+               for (k = 0; k < a->dict[d].kcount; k++)
+               {
+                       /* get key */
+                       if (kv->_size < sizeof(uint32_t))
+                       {
+                               kvarray_free(a);
+                               return NULL;
+                       }
+
+                       /* key length */
+                       x = 0;
+                       memcpy(&x, p, sizeof(uint32_t));
+                       p += sizeof(uint32_t);
+                       kv->_size -= sizeof(uint32_t);
+                       x = ntohl(x);
+
+                       if (kv->_size < x)
+                       {
+                               kvarray_free(a);
+                               return NULL;
+                       }
+
+                       /* key data */
+                       a->dict[d].key[k] = p;
+
+                       p += x;
+                       kv->_size -= x;
+
+                       if (kv->_size < sizeof(uint32_t))
+                       {
+                               kvarray_free(a);
+                               return NULL;
+                       }
+
+                       /* val count */
+                       x = 0;
+                       memcpy(&x, p, sizeof(uint32_t));
+                       p += sizeof(uint32_t);
+                       kv->_size -= sizeof(uint32_t);
+                       a->dict[d].vcount[k] = ntohl(x);
+
+                       if (a->dict[d].vcount[k] > 0)
+                       {
+                               /* N.B. we add a NULL pointer at the end of the list */
+                               a->dict[d].val[k] = (const char **)calloc(a->dict[d].vcount[k] + 1, sizeof(const char *));
+                               if (a->dict[d].val[k] == NULL)
+                               {
+                                       kvarray_free(a);
+                                       return NULL;
+                               }
+                       }
+
+                       for (v = 0; v < a->dict[d].vcount[k]; v++)
+                       {
+                               /* get val */
+                               if (kv->_size < sizeof(uint32_t))
+                               {
+                                       kvarray_free(a);
+                                       return NULL;
+                               }
+
+                               /* val length */
+                               x = 0;
+                               memcpy(&x, p, sizeof(uint32_t));
+                               p += sizeof(uint32_t);
+                               kv->_size -= sizeof(uint32_t);
+                               x = ntohl(x);
+
+                               if (kv->_size < x)
+                               {
+                                       kvarray_free(a);
+                                       return NULL;
+                               }
+
+                               /* val data */
+                               a->dict[d].val[k][v] = p;
+
+                               p += x;
+                               kv->_size -= x;
+                       }
+               }
+       }
+
+       a->kv = kv;
+       return a;
+}
+
+void
+kvarray_free(kvarray_t *a)
+{
+       uint32_t d, k;
+
+       if (a == NULL) return;
+
+       for (d = 0; d < a->count; d++)
+       {
+               for (k = 0; k < a->dict[d].kcount; k++)
+               {
+                       if (a->dict[d].val == NULL) continue;
+                       if (a->dict[d].val[k] != NULL) free(a->dict[d].val[k]);
+               }
+
+               if (a->dict[d].key != NULL) free(a->dict[d].key);
+               if (a->dict[d].vcount != NULL) free(a->dict[d].vcount);
+               if (a->dict[d].val != NULL) free(a->dict[d].val);
+       }
+
+       a->count = 0;
+
+       if (a->dict != NULL) free(a->dict);
+       a->dict = NULL;
+
+       if (a->kv != NULL) kvbuf_free(a->kv);
+       a->kv = NULL;
+
+       free(a);
+}
+
+kern_return_t
+LI_DSLookupGetProcedureNumber(const char *name, int32_t *procno)
+{
+       kern_return_t status;
+       security_token_t token;
+       uint32_t n, len;
+
+       if (name == NULL) return KERN_FAILURE;
+
+       len = strlen(name) + 1;
+       if (len == 1) return KERN_FAILURE;
+
+       token.val[0] = -1;
+       token.val[1] = -1;
+
+       if (_ds_running() == 0) return KERN_FAILURE;
+       if (_ds_port == MACH_PORT_NULL) return KERN_FAILURE;
+
+       status = MIG_SERVER_DIED;
+       for (n = 0; (_ds_port != MACH_PORT_NULL) && (status == MIG_SERVER_DIED) && (n < MAX_LOOKUP_ATTEMPTS); n++)
+       {
+               status = libinfoDSmig_GetProcedureNumber(_ds_port, (char *)name, procno, &token);
+
+               if (status == MACH_SEND_INVALID_DEST)
+               {
+                       mach_port_mod_refs(mach_task_self(), _ds_port, MACH_PORT_RIGHT_SEND, -1);
+                       status = bootstrap_look_up(bootstrap_port, kDSStdMachDSLookupPortName, &_ds_port);
+                       if ((status != BOOTSTRAP_SUCCESS) && (status != BOOTSTRAP_UNKNOWN_SERVICE)) _ds_port = MACH_PORT_NULL;
+                       status = MIG_SERVER_DIED;
+               }
+       }
+
+       if (status != KERN_SUCCESS)
+       {
+#ifdef DEBUG
+               asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "_DSLookupGetProcedureNumber %s status %u", name, status);
+#endif
+               return status;
+       }
+
+       if (token.val[0] != 0)
+       {
+#ifdef DEBUG
+               asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "_DSLookupGetProcedureNumber %s auth failure uid=%d", name, token.val[0]);
+#endif
+               return KERN_FAILURE;
+       }
+
+#ifdef DEBUG
+       asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "_DSLookupGetProcedureNumber %s = %d", name, *procno);
+#endif
+       return status;
+}
+
+__private_extern__ kern_return_t
+LI_DSLookupQuery(int32_t procno, kvbuf_t *request, kvarray_t **reply)
+{
+       kern_return_t status;
+       security_token_t token;
+       uint32_t n;
+       mach_msg_type_number_t illen, oolen;
+       char ilbuf[MAX_MIG_INLINE_DATA];
+       vm_offset_t oobuf;
+       kvbuf_t *out;
+
+       if (reply == NULL) return KERN_FAILURE;
+       if ((request != NULL) && ((request->databuf == NULL) || (request->datalen == 0))) return KERN_FAILURE;
+
+       token.val[0] = -1;
+       token.val[1] = -1;
+       *reply = NULL;
+
+       if (_ds_running() == 0) return KERN_FAILURE;
+       if (_ds_port == MACH_PORT_NULL) return KERN_FAILURE;
+
+       status = MIG_SERVER_DIED;
+       for (n = 0; (_ds_port != MACH_PORT_NULL) && (status == MIG_SERVER_DIED) && (n < MAX_LOOKUP_ATTEMPTS); n++)
+       {
+               illen = 0;
+               oolen = 0;
+               oobuf = 0;
+
+               if (request != NULL)
+               {
+                       status = libinfoDSmig_Query(_ds_port, procno, request->databuf, request->datalen, ilbuf, &illen, &oobuf, &oolen, &token);
+               }
+               else
+               {
+                       status = libinfoDSmig_Query(_ds_port, procno, "", 0, ilbuf, &illen, &oobuf, &oolen, &token);
+               }
+
+               if (status == MACH_SEND_INVALID_DEST)
+               {
+                       mach_port_mod_refs(mach_task_self(), _ds_port, MACH_PORT_RIGHT_SEND, -1);
+                       status = bootstrap_look_up(bootstrap_port, kDSStdMachDSLookupPortName, &_ds_port);
+                       if ((status != BOOTSTRAP_SUCCESS) && (status != BOOTSTRAP_UNKNOWN_SERVICE)) _ds_port = MACH_PORT_NULL;
+                       status = MIG_SERVER_DIED;
+               }
+       }
+
+       if (status != KERN_SUCCESS)
+       {
+#ifdef DEBUG
+               asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "_DSLookupQuery %d status %u", procno, status);
+#endif
+               return status;
+       }
+
+       if (token.val[0] != 0)
+       {
 #ifdef DEBUG
-       syslog(LOG_DEBUG, "pid %u _lookup_ooall %d", getpid(), proc);
+               asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "_DSLookupQuery %d auth failure uid=%d", procno, token.val[0]);
+#endif
+               if (oolen > 0) vm_deallocate(mach_task_self(), (vm_address_t)oobuf, oolen);
+               return KERN_FAILURE;
+       }
+
+       out = (kvbuf_t *)calloc(1, sizeof(kvbuf_t));
+       if (out == NULL)
+       {
+               if (oolen > 0) vm_deallocate(mach_task_self(), (vm_address_t)oobuf, oolen);
+               return KERN_FAILURE;
+       }
+
+       if (oolen > 0)
+       {
+               out->datalen = oolen;
+               out->databuf = malloc(oolen);
+               if (out->databuf == NULL)
+               {
+                       free(out);
+                       *reply = NULL;
+                       vm_deallocate(mach_task_self(), (vm_address_t)oobuf, oolen);
+                       return KERN_FAILURE;
+               }
+
+               memcpy(out->databuf, (char *)oobuf, oolen);
+               vm_deallocate(mach_task_self(), (vm_address_t)oobuf, oolen);
+       }
+       else if (illen > 0)
+       {
+               out->datalen = illen;
+               out->databuf = malloc(illen);
+               if (out->databuf == NULL)
+               {
+                       free(out);
+                       *reply = NULL;
+                       return KERN_FAILURE;
+               }
+
+               memcpy(out->databuf, ilbuf, illen);
+       }
+
+       *reply = kvbuf_decode(out);
+       if (*reply == NULL)
+       {
+               /* DS returned no data */
+               free(out->databuf);
+               free(out);
+       }
+
+#ifdef DEBUG
+       asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "_DSLookupQuery %d status OK", procno);
 #endif
        return status;
 }
+
+/*
+ * Get an entry from a kvarray.
+ * Calls the system information daemon if the list doesn't exist (first call),
+ * or extracts the next entry if the list has been fetched.
+ */
+__private_extern__ void *
+LI_getent(const char *procname, int *procnum, void *(*extract)(kvarray_t *), int tkey, size_t esize)
+{
+       void *entry;
+       struct li_thread_info *tdata;
+       kvarray_t *reply;
+       kern_return_t status;
+
+       tdata = LI_data_create_key(tkey, esize);
+       if (tdata == NULL) return NULL;
+
+       if (tdata->li_vm == NULL)
+       {
+               if (*procnum < 0)
+               {
+                       status = LI_DSLookupGetProcedureNumber(procname, procnum);
+                       if (status != KERN_SUCCESS)
+                       {
+                               LI_data_free_kvarray(tdata);
+                               tdata->li_vm = NULL;
+                               return NULL;
+                       }
+               }
+
+               reply = NULL;
+               status = LI_DSLookupQuery(*procnum, NULL, &reply);
+
+               if (status != KERN_SUCCESS)
+               {
+                       LI_data_free_kvarray(tdata);
+                       tdata->li_vm = NULL;
+                       return NULL;
+               }
+
+               tdata->li_vm = (char *)reply;
+       }
+
+       entry = extract((kvarray_t *)(tdata->li_vm));
+       if (entry == NULL)
+       {
+               LI_data_free_kvarray(tdata);
+               tdata->li_vm = NULL;
+               return NULL;
+       }
+
+       return entry;
+}
+
+__private_extern__ void *
+LI_getone(const char *procname, int *procnum, void *(*extract)(kvarray_t *), const char *key, const char *val)
+{
+       void *entry;
+       kvbuf_t *request;
+       kvarray_t *reply;
+       kern_return_t status;
+
+       if (*procnum < 0)
+       {
+               status = LI_DSLookupGetProcedureNumber(procname, procnum);
+               if (status != KERN_SUCCESS) return NULL;
+       }
+
+       request = kvbuf_query_key_val(key, val);
+       if (request == NULL) return NULL;
+
+       reply = NULL;
+       status = LI_DSLookupQuery(*procnum, request, &reply);
+       kvbuf_free(request);
+
+       if (status != KERN_SUCCESS) return NULL;
+
+       entry = extract(reply);
+       kvarray_free(reply);
+
+       return entry;
+}
+
+__private_extern__
+int LI_L1_cache_check(int tkey)
+{
+       int check, x;
+       const char *notify_key;
+
+       /* check if L1 cache is disabled */
+       if (gL1CacheEnabled == 0) return LI_L1_CACHE_DISABLED;
+
+       /* Initialize on first call */
+       if (_L1_notify_token[0] == -1)
+       {
+               pthread_mutex_lock(&_notify_lock);
+               if (_L1_notify_token[0] == -1) notify_register_check(L1_CACHE_NOTIFICATION_KEY_GLOBAL, &(_L1_notify_token[0]));
+               pthread_mutex_unlock(&_notify_lock);
+       }
+
+       if (_L1_notify_token[0] == -1) return LI_L1_CACHE_FAILED;
+
+       check = 1;
+       if (notify_check(_L1_notify_token[0], &check) != 0) return LI_L1_CACHE_FAILED;
+       if (check == 1) return LI_L1_CACHE_STALE;
+
+       x = 0;
+       notify_key = NULL;
+
+       switch (tkey)
+       {
+               case _li_data_key_group:
+               {
+                       x = 1;
+                       notify_key = L1_CACHE_NOTIFICATION_KEY_GROUP;
+                       break;
+               }
+               case _li_data_key_host:
+               {
+                       x = 2;
+                       notify_key = L1_CACHE_NOTIFICATION_KEY_HOST;
+                       break;
+               }
+               case _li_data_key_service:
+               {
+                       x = 3;
+                       notify_key = L1_CACHE_NOTIFICATION_KEY_SERVICE;
+                       break;
+               }
+               case _li_data_key_user:
+               {
+                       x = 4;
+                       notify_key = L1_CACHE_NOTIFICATION_KEY_USER;
+                       break;
+               }
+               default: break;
+       }
+
+       if ((x != 0) && (notify_key != NULL))
+       {
+               /* Initialize on first call */
+               if (_L1_notify_token[x] == -1)
+               {
+                       pthread_mutex_lock(&_notify_lock);
+                       if (_L1_notify_token[x] == -1) notify_register_check(notify_key, &(_L1_notify_token[x]));
+                       pthread_mutex_unlock(&_notify_lock);
+               }
+
+               if (_L1_notify_token[x] == -1) return LI_L1_CACHE_FAILED;
+
+               check = 1;
+               if (notify_check(_L1_notify_token[x], &check) != 0) return LI_L1_CACHE_FAILED;
+               if (check == 1) return LI_L1_CACHE_STALE;
+       }
+
+       return LI_L1_CACHE_OK;
+}
+
+static uint32_t
+padsize(size_t curr, size_t item, const uint32_t *align)
+{
+       uint32_t na, diff;
+
+       if (item > 8) item = 8;
+
+       na = align[item];
+       if (na == 0) return 0;
+
+       diff = curr % na;
+       if (diff == 0) return 0;
+
+       return na - diff;
+}
+
+
+/*
+ * Create a structure using in-line memory (i.e. all one blob).
+ * This reduces malloc/free workload.
+ *
+ * Structutre components may be strings, 1, 2, 4, or 8-byte values,  
+ * lists of strings, or lists of 4, 8, or 16-byte values.
+ *
+ * Format keys:
+ *     s       NUL terminated string
+ *     1       1 byte value
+ *     2       2 byte value
+ *     4       4 byte value
+ *     8       8 byte value
+ *     L       long (32 or 64 bits, depending on architecture)
+ *     *       NULL-terminated list of strings
+ *     a       NULL-terminated list of 4-byte values
+ *     b       NULL-terminated list of 8-byte values
+ *     c       NULL-terminated list of 16-byte values
+ *
+ */
+__private_extern__ void *
+LI_ils_create(char *fmt, ...)
+{
+       va_list ap;
+       char *arg, *f;
+       char **list;
+       void *hp, *dp, *lp, *ils;
+       uint8_t u8;
+       uint16_t u16;
+       uint32_t u32, i, pad;
+       uint64_t u64;
+       unsigned long l;
+       size_t memsize, hsize, csize, slen, largest;
+       const uint32_t *align;
+
+       if (fmt == NULL) return NULL;
+
+       largest = 0;
+       align = align_32;
+       if (sizeof(char *) == 8) align = align_64;
+
+       /* first pass: calculate size */
+       memsize = ILS_MAGIC_SIZE;
+       hsize = 0;
+
+       va_start(ap, fmt);
+
+       for (f = fmt; (*f) != '\0'; f++)
+       {
+               csize = 0;
+               slen = 0;
+
+               if (*f == 's')
+               {
+                       if (largest < sizeof(char *)) largest = sizeof(char *);
+
+                       csize = sizeof(char *) + padsize(hsize, sizeof(char *), align);
+                       arg = va_arg(ap, char *);
+                       if (arg != NULL) slen = strlen(arg) + 1;
+               }
+               else if (*f == '1')
+               {
+                       if (largest < 1) largest = 1;
+
+                       csize = 1;
+                       u8 = va_arg(ap, int);
+               }
+               else if (*f == '2')
+               {
+                       if (largest < 2) largest = 2;
+
+                       csize = 2 + padsize(hsize, 2, align);
+                       u16 = va_arg(ap, int);
+               }
+               else if (*f == '4')
+               {
+                       if (largest < 4) largest = 4;
+
+                       csize = 4 + padsize(hsize, 4, align);
+                       u32 = va_arg(ap, uint32_t);
+               }
+               else if (*f == '8')
+               {
+                       if (largest < 8) largest = 8;
+
+                       csize = 8 + padsize(hsize, 8, align);
+                       u64 = va_arg(ap, uint64_t);
+               }
+               else if (*f == 'L')
+               {
+                       if (largest < sizeof(unsigned long)) largest = sizeof(unsigned long);
+
+                       csize = sizeof(unsigned long) + padsize(hsize, sizeof(unsigned long), align);
+                       l = va_arg(ap, unsigned long);
+               }
+               else if (*f == '*')
+               {
+                       /* NULL-terminated list of strings */
+                       if (largest < sizeof(char *)) largest = sizeof(char *);
+
+                       csize = sizeof(char *) + padsize(hsize, sizeof(char *), align);
+                       list = va_arg(ap, char **);
+                       if (list != NULL)
+                       {
+                               for (i = 0; list[i] != NULL; i++)
+                               {
+                                       slen += sizeof(char *);
+                                       slen += (strlen(list[i]) + 1);
+                               }
+
+                               slen += sizeof(char *);
+                       }
+               }
+               else if (*f == 'a')
+               {
+                       /* NULL-terminated list of 4-byte values */
+                       if (largest < sizeof(char *)) largest = sizeof(char *);
+
+                       csize = sizeof(char *) + padsize(hsize, sizeof(char *), align);
+                       list = va_arg(ap, char **);
+                       if (list != NULL)
+                       {
+                               for (i = 0; list[i] != NULL; i++)
+                               {
+                                       slen += sizeof(char *);
+                                       slen += 4;
+                               }
+
+                               slen += sizeof(char *);
+                       }
+               }
+               else if (*f == 'b')
+               {
+                       /* NULL-terminated list of 8-byte values */
+                       if (largest < sizeof(char *)) largest = sizeof(char *);
+
+                       csize = sizeof(char *) + padsize(hsize, sizeof(char *), align);
+                       list = va_arg(ap, char **);
+                       if (list != NULL)
+                       {
+                               for (i = 0; list[i] != NULL; i++)
+                               {
+                                       slen += sizeof(char *);
+                                       slen += 8;
+                               }
+
+                               slen += sizeof(char *);
+                       }
+               }
+               else if (*f == 'c')
+               {
+                       /* NULL-terminated list of 16-byte values */
+                       if (largest < sizeof(char *)) largest = sizeof(char *);
+
+                       csize = sizeof(char *) + padsize(hsize, sizeof(char *), align);
+                       list = va_arg(ap, char **);
+                       if (list != NULL)
+                       {
+                               for (i = 0; list[i] != NULL; i++)
+                               {
+                                       slen += sizeof(char *);
+                                       slen += 16;
+                               }
+
+                               slen += sizeof(char *);
+                       }
+               }
+               else return NULL;
+
+               memsize += csize;
+               memsize += slen;
+               hsize += csize;
+       }
+
+       va_end(ap);
+
+       pad = padsize(hsize, largest, align);
+       memsize += pad;
+       hsize += pad;
+
+       ils = malloc(memsize);
+       if (ils == NULL)
+       {
+               errno = ENOMEM;
+               return NULL;
+       }
+
+       /* insert magic cookie */
+       dp = ils + hsize;
+       memcpy(dp, ILS_MAGIC, ILS_MAGIC_SIZE);
+       dp += ILS_MAGIC_SIZE;
+
+       hp = ils;
+       hsize = 0;
+
+       /* second pass: copy data */
+       va_start(ap, fmt);
+       for (f = fmt; (*f) != '\0'; f++)
+       {
+               if (*f == 's')
+               {
+                       pad = padsize(hsize, sizeof(char *), align);
+                       if (pad != 0)
+                       {
+                               memset(hp, 0, pad);
+                               hp += pad;
+                               hsize += pad;
+                       }
+
+                       arg = va_arg(ap, char *);
+                       if (arg == NULL)
+                       {
+                               memset(hp, 0, sizeof(char *));
+                       }
+                       else
+                       {
+                               memcpy(hp, &dp, sizeof(char *));
+                               slen = strlen(arg) + 1;
+                               memcpy(dp, arg, slen);
+                               dp += slen;
+                       }
+
+                       hp += sizeof(char *);
+                       hsize += sizeof(char *);
+               }
+               else if (*f == '1')
+               {
+                       u8 = va_arg(ap, int);
+                       memcpy(hp, &u8, sizeof(uint8_t));
+                       hp += sizeof(uint8_t);
+               }
+               else if (*f == '2')
+               {
+                       pad = padsize(hsize, 2, align);
+                       if (pad != 0)
+                       {
+                               memset(hp, 0, pad);
+                               hp += pad;
+                               hsize += pad;
+                       }
+
+                       u16 = va_arg(ap, int);
+                       memcpy(hp, &u16, sizeof(uint16_t));
+
+                       hp += sizeof(uint16_t);
+                       hsize += sizeof(uint16_t);
+               }
+               else if (*f == '4')
+               {
+                       pad = padsize(hsize, 4, align);
+                       if (pad != 0)
+                       {
+                               memset(hp, 0, pad);
+                               hp += pad;
+                               hsize += pad;
+                       }
+
+                       u32 = va_arg(ap, uint32_t);
+                       memcpy(hp, &u32, sizeof(uint32_t));
+
+                       hp += sizeof(uint32_t);
+                       hsize += sizeof(uint32_t);
+               }
+               else if (*f == '8')
+               {
+                       pad = padsize(hsize, 8, align);
+                       if (pad != 0)
+                       {
+                               memset(hp, 0, pad);
+                               hp += pad;
+                               hsize += pad;
+                       }
+
+                       u64 = va_arg(ap, uint64_t);
+                       memcpy(hp, &u64, sizeof(uint64_t));
+
+                       hp += sizeof(uint64_t);
+                       hsize += sizeof(uint64_t);
+               }
+               else if (*f == 'L')
+               {
+                       pad = padsize(hsize, sizeof(unsigned long), align);
+                       if (pad != 0)
+                       {
+                               memset(hp, 0, pad);
+                               hp += pad;
+                               hsize += pad;
+                       }
+
+                       l = va_arg(ap, unsigned long);
+                       memcpy(hp, &l, sizeof(unsigned long));
+
+                       hp += sizeof(unsigned long);
+                       hsize += sizeof(unsigned long);
+               }
+               else if (*f == '*')
+               {
+                       pad = padsize(hsize, sizeof(char *), align);
+                       if (pad != 0)
+                       {
+                               memset(hp, 0, pad);
+                               hp += pad;
+                               hsize += pad;
+                       }
+
+                       list = va_arg(ap, char **);
+
+                       if (list == NULL)
+                       {
+                               memset(hp, 0, sizeof(char *));
+                       }
+                       else
+                       {
+                               memcpy(hp, &dp, sizeof(char *));
+
+                               for (i = 0; list[i] != NULL; i++);
+
+                               lp = dp;
+                               dp += ((i + 1) * sizeof(char *));
+
+                               for (i = 0; list[i] != NULL; i++)
+                               {
+                                       memcpy(lp, &dp, sizeof(char *));
+                                       lp += sizeof(char *);
+                                       slen = strlen(list[i]) + 1;
+                                       memcpy(dp, list[i], slen);
+                                       dp += slen;
+                               }
+
+                               memset(lp, 0, sizeof(char *));
+                       }
+
+                       hp += sizeof(char *);
+                       hsize += sizeof(char *);
+               }
+               else if (*f == 'a')
+               {
+                       pad = padsize(hsize, sizeof(char *), align);
+                       if (pad != 0)
+                       {
+                               memset(hp, 0, pad);
+                               hp += pad;
+                               hsize += pad;
+                       }
+
+                       list = va_arg(ap, char **);
+
+                       if (list == NULL)
+                       {
+                               memset(hp, 0, sizeof(char *));
+                       }
+                       else
+                       {
+                               memcpy(hp, &dp, sizeof(char *));
+
+                               for (i = 0; list[i] != NULL; i++);
+
+                               lp = dp;
+                               dp += ((i + 1) * sizeof(char *));
+
+                               for (i = 0; list[i] != NULL; i++)
+                               {
+                                       memcpy(lp, &dp, sizeof(char *));
+                                       lp += sizeof(char *);
+                                       slen = 4;
+                                       memcpy(dp, list[i], slen);
+                                       dp += slen;
+                               }
+
+                               memset(lp, 0, sizeof(char *));
+                       }
+
+                       hp += sizeof(char *);
+                       hsize += sizeof(char *);
+               }
+               else if (*f == 'b')
+               {
+                       pad = padsize(hsize, sizeof(char *), align);
+                       if (pad != 0)
+                       {
+                               memset(hp, 0, pad);
+                               hp += pad;
+                               hsize += pad;
+                       }
+
+                       list = va_arg(ap, char **);
+
+                       if (list == NULL)
+                       {
+                               memset(hp, 0, sizeof(char *));
+                       }
+                       else
+                       {
+                               memcpy(hp, &dp, sizeof(char *));
+
+                               for (i = 0; list[i] != NULL; i++);
+
+                               lp = dp;
+                               dp += ((i + 1) * sizeof(char *));
+
+                               for (i = 0; list[i] != NULL; i++)
+                               {
+                                       memcpy(lp, &dp, sizeof(char *));
+                                       lp += sizeof(char *);
+                                       slen = 8;
+                                       memcpy(dp, list[i], slen);
+                                       dp += slen;
+                               }
+
+                               memset(lp, 0, sizeof(char *));
+                       }
+
+                       hp += sizeof(char *);
+                       hsize += sizeof(char *);
+               }
+               else if (*f == 'c')
+               {
+                       pad = padsize(hsize, sizeof(char *), align);
+                       if (pad != 0)
+                       {
+                               memset(hp, 0, pad);
+                               hp += pad;
+                               hsize += pad;
+                       }
+
+                       list = va_arg(ap, char **);
+
+                       if (list == NULL)
+                       {
+                               memset(hp, 0, sizeof(char *));
+                       }
+                       else
+                       {
+                               memcpy(hp, &dp, sizeof(char *));
+
+                               for (i = 0; list[i] != NULL; i++);
+
+                               lp = dp;
+                               dp += ((i + 1) * sizeof(char *));
+
+                               for (i = 0; list[i] != NULL; i++)
+                               {
+                                       memcpy(lp, &dp, sizeof(char *));
+                                       lp += sizeof(char *);
+                                       slen = 16;
+                                       memcpy(dp, list[i], slen);
+                                       dp += slen;
+                               }
+
+                               memset(lp, 0, sizeof(char *));
+                       }
+
+                       hp += sizeof(char *);
+                       hsize += sizeof(char *);
+               }
+       }
+
+       va_end(ap);
+
+       pad = padsize(hsize, largest, align);
+       if (pad > 0) memset(hp, 0, pad);
+
+       return ils;
+}
+
+__private_extern__ int
+LI_ils_free(void *ils, size_t len)
+{
+       char *p;
+
+       if (ils == NULL) return 0;
+
+       p = ils + len;
+       if (memcmp(p, ILS_MAGIC, ILS_MAGIC_SIZE) != 0) return -1;
+
+       free(ils);
+
+       return 0;
+}
+
+kern_return_t 
+_lookup_link(mach_port_t server, char *name, int *procno)
+{
+       syslog(LOG_ERR, "RED ALERT!   lookupd call %s from pid %u", name, getpid());
+       return KERN_FAILURE;
+}
+
+kern_return_t 
+_lookup_one(mach_port_t server, int proc, char *indata, mach_msg_type_number_t indataCnt, char *outdata, mach_msg_type_number_t *outdataCnt)
+{
+       return KERN_FAILURE;
+}
+
+kern_return_t 
+_lookup_all(mach_port_t server, int proc, char *indata, mach_msg_type_number_t indataCnt, char **outdata, mach_msg_type_number_t *outdataCnt)
+{
+       return KERN_FAILURE;
+}
+
+kern_return_t 
+_lookup_ooall(mach_port_t server, int proc, char *indata, mach_msg_type_number_t indataCnt, char **outdata, mach_msg_type_number_t *outdataCnt)
+{
+       return KERN_FAILURE;
+}
index ae987c057522dd55fbd1c1602c0dca2d198a6f9f..77273a57c92b0b87ca58df291c694e3f346d2c45 100644 (file)
 #ifndef _LU_UTILS_H_
 #define _LU_UTILS_H_
 
-#import <netinfo/lookup_types.h>
-#include <netinfo/ni.h>
+#include "DSlibinfoMIG_types.h"
+#include "kvbuf.h"
 #include <stdarg.h>
 
-#define LU_COPY_STRING(x) strdup(((x) == NULL) ? "" : x)
+#define _li_data_key_alias       10010
+#define _li_data_key_bootp       10020
+#define _li_data_key_bootparams  10030
+#define _li_data_key_fstab       10040
+#define _li_data_key_group       10050
+#define _li_data_key_host        10060
+#define _li_data_key_netgroup    10070
+#define _li_data_key_network     10080
+#define _li_data_key_printer     10090
+#define _li_data_key_protocol    10100
+#define _li_data_key_rpc         10110
+#define _li_data_key_service     10120
+#define _li_data_key_user        10130
 
-#define LU_LONG_STRING_LENGTH 8192
-
-#define _lu_data_key_alias       10010
-#define _lu_data_key_bootp       10020
-#define _lu_data_key_bootparams  10030
-#define _lu_data_key_fstab       10040
-#define _lu_data_key_group       10050
-#define _lu_data_key_host        10060
-#define _lu_data_key_netgroup    10070
-#define _lu_data_key_network     10080
-#define _lu_data_key_printer     10090
-#define _lu_data_key_protocol    10100
-#define _lu_data_key_rpc         10110
-#define _lu_data_key_service     10120
-#define _lu_data_key_user        10130
+/*
+ * Return values for LI_L1_cache_check.
+ */
+#define LI_L1_CACHE_OK 0
+#define LI_L1_CACHE_STALE 1
+#define LI_L1_CACHE_DISABLED 2
+#define LI_L1_CACHE_FAILED 3
 
-struct lu_thread_info
+struct li_thread_info
 {
-       void *lu_entry;
-       XDR *lu_xdr;
-       char *lu_vm;
-       unsigned int lu_vm_length;
-       unsigned int lu_vm_cursor;
+       void *li_entry;
+       size_t li_entry_size;
+       char *li_vm;
+       uint32_t li_vm_length;
+       uint32_t li_vm_cursor;
+       uint32_t li_flags;
 };
 
-extern mach_port_t _lu_port;
-extern unit *_lookup_buf;
-extern int _lu_running(void);
+extern mach_port_t _ds_port;
+extern int _ds_running(void);
+
+/*
+ * Thread-local data management
+ */
+__private_extern__ void *LI_data_find_key(uint32_t key);
+__private_extern__ void *LI_data_create_key(uint32_t key, size_t esize);
+__private_extern__ void LI_data_set_key(uint32_t key, void *data);
+__private_extern__ void *LI_data_get_key(uint32_t key);
+__private_extern__ void LI_data_free_kvarray(struct li_thread_info *tdata);
+__private_extern__ void LI_data_recycle(struct li_thread_info *tdata, void *entry, size_t entrysize);
+__private_extern__ void *LI_ils_create(char *fmt, ...);
+__private_extern__ int LI_ils_free(void *ils, size_t len);
+
+kern_return_t _lookup_link(mach_port_t server, char *name, int *procno);
+kern_return_t _lookup_one(mach_port_t server, int proc, char *indata, mach_msg_type_number_t indataCnt, char *outdata, mach_msg_type_number_t *outdataCnt);
+kern_return_t _lookup_all(mach_port_t server, int proc, char *indata, mach_msg_type_number_t indataCnt, char **outdata, mach_msg_type_number_t *outdataCnt);
+kern_return_t _lookup_ooall(mach_port_t server, int proc, char *indata, mach_msg_type_number_t indataCnt,  char **outdata, mach_msg_type_number_t *outdataCnt);
+
+/*
+ * Directory Service queries
+ */
+kern_return_t LI_DSLookupGetProcedureNumber(const char *name, int *procno);
 
-void *_lu_data_create_key(unsigned int key, void (*destructor)(void *));
-void _lu_data_set_key(unsigned int key, void *data);
-void *_lu_data_get_key(unsigned int key);
-void _lu_data_free_vm_xdr(struct lu_thread_info *tdata);
+__private_extern__ kern_return_t LI_DSLookupQuery(int32_t proc, kvbuf_t *request, kvarray_t **reply);
+__private_extern__ void *LI_getent(const char *procname, int *procnum, void *(*extract)(kvarray_t *), int tkey, size_t esize);
+__private_extern__ void *LI_getone(const char *procname, int *procnum, void *(*extract)(kvarray_t *), const char *key, const char *val);
 
-int _lu_xdr_attribute(XDR *xdr, char **key, char ***val, unsigned int *count);
+/*
+ * L1 cache
+ * Takes _li_data_key_xxx as an argument.
+ * Returns 0 is the cache is valid, non-zero if it is invalid.
+ */
+__private_extern__ int LI_L1_cache_check(int tkey);
 
-ni_proplist *_lookupd_xdr_dictionary(XDR *inxdr);
-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);
+/*
+ * Async support
+ */
+void LI_async_call_cancel(mach_port_t p, void **context);
+kern_return_t LI_async_handle_reply(mach_msg_header_t *msg, kvarray_t **reply, void **callback, void **context);
+kern_return_t LI_async_receive(mach_port_t p, kvarray_t **reply);
+kern_return_t LI_async_send(mach_port_t *p, uint32_t proc, kvbuf_t *query);
+kern_return_t LI_async_start(mach_port_t *p, uint32_t proc, kvbuf_t *query, void *callback, void *context);
 
-kern_return_t _lookup_link(mach_port_t server, lookup_name name, int *procno);
-kern_return_t _lookup_one(mach_port_t server, int proc, inline_data indata, mach_msg_type_number_t indataCnt, inline_data outdata, mach_msg_type_number_t *outdataCnt);
-kern_return_t _lookup_all(mach_port_t server, int proc, inline_data indata, mach_msg_type_number_t indataCnt, ooline_data *outdata, mach_msg_type_number_t *outdataCnt);
-kern_return_t _lookup_ooall(mach_port_t server, int proc, ooline_data indata, mach_msg_type_number_t indataCnt, ooline_data *outdata, mach_msg_type_number_t *outdataCnt);
+/*
+ * kvbuf query support
+ */
+__private_extern__ kvbuf_t *kvbuf_query(char *fmt, ...);
+__private_extern__ kvbuf_t *kvbuf_query_key_int(const char *key, int32_t i);
+__private_extern__ kvbuf_t *kvbuf_query_key_uint(const char *key, uint32_t u);
+__private_extern__ kvbuf_t *kvbuf_query_key_val(const char *key, const char *val);
 
 #endif /* ! _LU_UTILS_H_ */
index 916842e9d27dfdfb05459be73f4508dda921b40c..95e485d151452125c493a81c2f53a70462ad444d 100644 (file)
@@ -81,8 +81,8 @@
 #ifndef _NETDB_H_
 #define _NETDB_H_
 
-#include <stdint.h>
 #include <_types.h>
+#include <stdint.h>
 #include <netinet/in.h>                /* IPPORT_RESERVED */
 
 #ifndef        _SIZE_T
@@ -118,9 +118,9 @@ struct      hostent {
        int     h_addrtype;     /* host address type */
        int     h_length;       /* length of address */
        char    **h_addr_list;  /* list of addresses from name server */
-#ifndef _POSIX_C_SOURCE
+#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
 #define        h_addr  h_addr_list[0]  /* address, for backward compatiblity */
-#endif /* !_POSIX_C_SOURCE */
+#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
 };
 
 /*
@@ -158,54 +158,54 @@ struct addrinfo {
        struct addrinfo *ai_next;       /* next structure in linked list */
 };
 
-#ifndef _POSIX_C_SOURCE
+#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
 struct rpcent {
         char    *r_name;        /* name of server for this rpc program */
         char    **r_aliases;    /* alias list */
         int     r_number;       /* rpc program number */
 };
-#endif /* !_POSIX_C_SOURCE */
+#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
 
 /*
  * Error return codes from gethostbyname() and gethostbyaddr()
  * (left in extern int h_errno).
  */
-#ifndef _POSIX_C_SOURCE
+#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
 #define        NETDB_INTERNAL  -1      /* see errno */
 #define        NETDB_SUCCESS   0       /* no problem */
-#endif /* !_POSIX_C_SOURCE */
+#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
 #define        HOST_NOT_FOUND  1 /* Authoritative Answer Host not found */
 #define        TRY_AGAIN       2 /* Non-Authoritative Host not found, or SERVERFAIL */
 #define        NO_RECOVERY     3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */
 #define        NO_DATA         4 /* Valid name, no data record of requested type */
-#ifndef _POSIX_C_SOURCE
+#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
 #define        NO_ADDRESS      NO_DATA         /* no address, look for MX record */
-#endif /* !_POSIX_C_SOURCE */
+#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
 /*
  * Error return codes from getaddrinfo()
  */
-#ifndef _POSIX_C_SOURCE
+#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
 #define        EAI_ADDRFAMILY   1      /* address family for hostname not supported */
-#endif /* !_POSIX_C_SOURCE */
+#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
 #define        EAI_AGAIN        2      /* temporary failure in name resolution */
 #define        EAI_BADFLAGS     3      /* invalid value for ai_flags */
 #define        EAI_FAIL         4      /* non-recoverable failure in name resolution */
 #define        EAI_FAMILY       5      /* ai_family not supported */
 #define        EAI_MEMORY       6      /* memory allocation failure */
-#ifndef _POSIX_C_SOURCE
+#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
 #define        EAI_NODATA       7      /* no address associated with hostname */
-#endif /* !_POSIX_C_SOURCE */
+#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
 #define        EAI_NONAME       8      /* hostname nor servname provided, or not known */
 #define        EAI_SERVICE      9      /* servname not supported for ai_socktype */
 #define        EAI_SOCKTYPE    10      /* ai_socktype not supported */
 #define        EAI_SYSTEM      11      /* system error returned in errno */
-#ifndef _POSIX_C_SOURCE
+#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
 #define EAI_BADHINTS   12
 #define EAI_PROTOCOL   13
 #define EAI_MAX                14
-#else  /* _POSIX_C_SOURCE */
+#else  /* (_POSIX_C_SOURCE && !_DARWIN_C_SOURCE) */
 #define EAI_OVERFLOW    14     /* An argument buffer overflowed */
-#endif /* !_POSIX_C_SOURCE */
+#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
 
 /*
  * Flag values for getaddrinfo()
@@ -214,27 +214,27 @@ struct rpcent {
 #define        AI_CANONNAME    0x00000002 /* fill ai_canonname */
 #define        AI_NUMERICHOST  0x00000004 /* prevent name resolution */
 /* valid flags for addrinfo */
-#ifndef _POSIX_C_SOURCE
+#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
 #define        AI_MASK         (AI_PASSIVE | AI_CANONNAME | AI_NUMERICHOST)
-#endif /* !_POSIX_C_SOURCE */
+#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
 #define        AI_ALL          0x00000100 /* IPv6 and IPv4-mapped (with AI_V4MAPPED) */
-#ifndef _POSIX_C_SOURCE
+#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
 #define        AI_V4MAPPED_CFG 0x00000200 /* accept IPv4-mapped if kernel supports */
-#endif /* !_POSIX_C_SOURCE */
+#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
 #define        AI_ADDRCONFIG   0x00000400 /* only if any address is assigned */
 #define        AI_V4MAPPED     0x00000800 /* accept IPv4-mapped IPv6 address */
 /* special recommended flags for getipnodebyname */
-#ifndef _POSIX_C_SOURCE
+#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
 #define        AI_DEFAULT      (AI_V4MAPPED_CFG | AI_ADDRCONFIG)
-#endif /* !_POSIX_C_SOURCE */
+#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
 
 /*
  * Constants for getnameinfo()
  */
-#ifndef _POSIX_C_SOURCE
+#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
 #define        NI_MAXHOST      1025
 #define        NI_MAXSERV      32
-#endif /* !_POSIX_C_SOURCE */
+#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
 /*
  * Flag values for getnameinfo()
  */
@@ -243,16 +243,17 @@ struct rpcent {
 #define        NI_NAMEREQD     0x00000004
 #define        NI_NUMERICSERV  0x00000008
 #define        NI_DGRAM        0x00000010
-#ifndef _POSIX_C_SOURCE
+#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
 #define NI_WITHSCOPEID 0x00000020
 
 /*
  * Scope delimit character
  */
 #define SCOPE_DELIMITER        '%'
-#endif /* !_POSIX_C_SOURCE */
+#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
 
 __BEGIN_DECLS
+
 void           endhostent(void);
 void           endnetent(void);
 void           endprotoent(void);
@@ -283,20 +284,29 @@ void              sethostent(int);
 void           setnetent(int);
 void           setprotoent(int);
 void           setservent(int);
-#ifndef _POSIX_C_SOURCE
+
+#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
 void           freehostent(struct hostent *);
 struct hostent *gethostbyname2(const char *, int);
 struct hostent *getipnodebyaddr(const void *, size_t, int, int *);
 struct hostent *getipnodebyname(const char *, int, int, int *);
 struct rpcent  *getrpcbyname(const char *name);
+#ifdef __LP64__
+struct rpcent  *getrpcbynumber(int number);
+#else
 struct rpcent  *getrpcbynumber(long number);
+#endif
 struct rpcent  *getrpcent(void);
 void           setrpcent(int stayopen);
 void           endrpcent(void);
 void           herror(const char *);
 const char     *hstrerror(int);
-int            innetgr(const char *, const char *, const char *, const char *);
-#endif /* !_POSIX_C_SOURCE */
+int                    innetgr(const char *, const char *, const char *, const char *);
+int                    getnetgrent(char **, char **, char **);
+void           endnetgrent(void);
+void           setnetgrent(const char *);
+#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
+
 __END_DECLS
 
 #endif /* !_NETDB_H_ */
index 6b721117b58c32a85e1e2ba709b26e294266e3f8..3f6b347d600da00e01bf7318946f40d5149aa615 100644 (file)
 
 __BEGIN_DECLS
 
-/*
- * Private asynchronous lookup API
- */
-
-/*
- * Cancel an outstanding call and free its resources.
- */
-extern void lu_async_call_cancel(mach_port_t p);
-
-/*
- * Make an asynchronous lookupd call.
- * Sends data buffer to lookupd and returns a port.
- * The buffer must be encoded for lookupd.
- */
-extern kern_return_t lu_async_start(mach_port_t *p, uint32_t proc, const char *buf, uint32_t len, void *callback, void *context);
-extern kern_return_t lu_async_send(mach_port_t *p, uint32_t proc, const char *buf, uint32_t len);
-
-/*
- * Receive a reply for an asynchronous lookupd call.
- * Receives the reply message and gets a raw (undecoded) data buffer.
- */
-extern kern_return_t lu_async_receive(mach_port_t p, char **buf, uint32_t *len);
-
-/*
- * Takes a reply message and provides the callback, context, and raw data buffers.
- * This routine does not invoke the callback.  Type-specific asynchronous 
- * routines built on top of this API will decode the data buffer and invoke
- * the callback routine.
- */
-extern int lu_async_handle_reply(void *msg, char **buf, uint32_t *len, void **callback, void **context);
-
-
-/*
- * Type-specific routines.
- */
  
 /*
  * getaddrinfo
@@ -83,6 +48,7 @@ int32_t getaddrinfo_async_start(mach_port_t *p, const char *nodename, const char
 int32_t getaddrinfo_async_send(mach_port_t *p, const char *nodename, const char *servname, const struct addrinfo *hints);
 int32_t getaddrinfo_async_receive(mach_port_t p, struct addrinfo **res);
 int32_t getaddrinfo_async_handle_reply(void *msg);
+void getaddrinfo_async_cancel(mach_port_t p);
 
  
 /*
@@ -93,6 +59,7 @@ int32_t getnameinfo_async_start(mach_port_t *p, const struct sockaddr *sa, size_
 int32_t getnameinfo_async_send(mach_port_t *p, const struct sockaddr *sa, size_t salen, int flags);
 int32_t getnameinfo_async_receive(mach_port_t p, char **host, char **serv);
 int32_t getnameinfo_async_handle_reply(void *msg);
+void getnameinfo_async_cancel(mach_port_t p);
 
 /*
  * DNS
@@ -102,12 +69,10 @@ int32_t dns_async_start(mach_port_t *p, const char *name, uint16_t dnsclass, uin
 int32_t dns_async_send(mach_port_t *p, const char *name, uint16_t dnsclass, uint16_t dnstype, uint32_t do_search);
 int32_t dns_async_receive(mach_port_t p, char **buf, uint32_t *len, struct sockaddr **from, uint32_t *fromlen);
 int32_t dns_async_handle_reply(void *msg);
+void dns_async_cancel(mach_port_t p);
 
 /*
- * Host lookup asynchronous API
- * These routines don't use the asynchronous lookupd access support
- * described above.  There will eventually be converted.
- * The API is syntactically similar.
+ * Host lookup
  */
 
 /*
diff --git a/lookup.subproj/netgr.h b/lookup.subproj/netgr.h
deleted file mode 100644 (file)
index a1a4cda..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A 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_
-
-#include <sys/cdefs.h>
-
-__BEGIN_DECLS
-int innetgr(const char * name, const char *host, const char *user, const char *domain);
-int    getnetgrent(char **host, char **user, char **domain);
-void endnetgrent(void);
-void setnetgrent(const char *netgroup);
-__END_DECLS
-
-#endif /* !_NETGR_H_ */
diff --git a/mdns.subproj/DNSServiceDiscovery.c b/mdns.subproj/DNSServiceDiscovery.c
deleted file mode 100644 (file)
index a311769..0000000
+++ /dev/null
@@ -1,672 +0,0 @@
-/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
- *
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A 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 "DNSServiceDiscovery.h"
-#include "DNSServiceDiscoveryDefines.h"
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <servers/bootstrap.h>
-#include <mach/mach.h>
-#include <mach/mach_error.h>
-#include <pthread.h>
-
-#include <netinet/in.h>
-
-extern struct mig_subsystem internal_DNSServiceDiscoveryReply_subsystem;
-
-extern boolean_t DNSServiceDiscoveryReply_server(
-        mach_msg_header_t *InHeadP,
-        mach_msg_header_t *OutHeadP);
-
-extern
-kern_return_t DNSServiceBrowserCreate_rpc
-(
-    mach_port_t server,
-    mach_port_t client,
-    DNSCString regtype,
-    DNSCString domain
-);
-
-extern
-kern_return_t DNSServiceDomainEnumerationCreate_rpc
-(
-    mach_port_t server,
-    mach_port_t client,
-    int registrationDomains
-);
-
-extern
-kern_return_t DNSServiceRegistrationCreate_rpc
-(
-    mach_port_t server,
-    mach_port_t client,
-    DNSCString name,
-    DNSCString regtype,
-    DNSCString domain,
-    IPPort port,
-    DNSCString txtRecord
-);
-
-extern
-kern_return_t DNSServiceResolverResolve_rpc
-(
-    mach_port_t server,
-    mach_port_t client,
-    DNSCString name,
-    DNSCString regtype,
-    DNSCString domain
-);
-
-extern
-kern_return_t DNSServiceRegistrationAddRecord_rpc
-(
-    mach_port_t server,
-    mach_port_t client,
-    int type,
-    record_data_t data,
-    mach_msg_type_number_t record_dataCnt,
-    uint32_t ttl,
-    natural_t *reference
-);
-
-extern
-int DNSServiceRegistrationUpdateRecord_rpc
-(
-    mach_port_t server,
-    mach_port_t client,
-    natural_t reference,
-    record_data_t data,
-    mach_msg_type_number_t record_dataCnt,
-    uint32_t ttl
-);
-
-extern
-kern_return_t DNSServiceRegistrationRemoveRecord_rpc
-(
-    mach_port_t server,
-    mach_port_t client,
-    natural_t reference
-);
-
-struct a_requests {
-    struct a_requests          *next;
-    mach_port_t                                client_port;
-    union {
-        DNSServiceBrowserReply                                 browserCallback;
-        DNSServiceDomainEnumerationReply       enumCallback;
-        DNSServiceRegistrationReply            regCallback;
-        DNSServiceResolverReply                        resolveCallback;
-    } callout;
-    void                                       *context;
-};
-
-static struct a_requests       *a_requests     = NULL;
-static pthread_mutex_t         a_requests_lock = PTHREAD_MUTEX_INITIALIZER;
-
-typedef struct _dns_service_discovery_t {
-    mach_port_t        port;
-} dns_service_discovery_t;
-
-mach_port_t DNSServiceDiscoveryLookupServer(void)
-{
-    static mach_port_t sndPort         = MACH_PORT_NULL;
-    kern_return_t   result;
-
-    if (sndPort != MACH_PORT_NULL) {
-        return sndPort;
-    }
-
-    result = bootstrap_look_up(bootstrap_port, DNS_SERVICE_DISCOVERY_SERVER, &sndPort);
-    if (result != KERN_SUCCESS) {
-        printf("%s(): {%s:%d} bootstrap_look_up() failed: $%x\n", __FUNCTION__, __FILE__, __LINE__, (int) result);
-        sndPort = MACH_PORT_NULL;
-    }
-
-
-    return sndPort;
-}
-
-void _increaseQueueLengthOnPort(mach_port_t port)
-{
-    mach_port_limits_t qlimits;
-    kern_return_t result;
-    
-    qlimits.mpl_qlimit = 16;
-    result = mach_port_set_attributes(mach_task_self(), port, MACH_PORT_LIMITS_INFO, (mach_port_info_t)&qlimits, MACH_PORT_LIMITS_INFO_COUNT);
-
-    if (result != KERN_SUCCESS) {
-        printf("%s(): {%s:%d} mach_port_set_attributes() failed: $%x %s\n", __FUNCTION__, __FILE__, __LINE__, (int) result, mach_error_string(result));
-    }
-}
-
-dns_service_discovery_ref DNSServiceBrowserCreate (const char *regtype, const char *domain, DNSServiceBrowserReply callBack,void *context)
-{
-    mach_port_t serverPort = DNSServiceDiscoveryLookupServer();
-    mach_port_t clientPort;
-    kern_return_t result;
-    dns_service_discovery_ref return_t;
-    struct a_requests  *request;
-    
-    if (!serverPort) {
-        return NULL;
-    }
-
-    result = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &clientPort);
-    if (result != KERN_SUCCESS) {
-        printf("Mach port receive creation failed, %s\n", mach_error_string(result));
-        return NULL;
-    }
-    result = mach_port_insert_right(mach_task_self(), clientPort, clientPort, MACH_MSG_TYPE_MAKE_SEND);
-    if (result != KERN_SUCCESS) {
-        printf("Mach port send creation failed, %s\n", mach_error_string(result));
-        mach_port_destroy(mach_task_self(), clientPort);
-        return NULL;
-    }
-    _increaseQueueLengthOnPort(clientPort);
-
-    return_t = malloc(sizeof(dns_service_discovery_t));
-    return_t->port = clientPort;
-
-    request = malloc(sizeof(struct a_requests));
-    request->client_port = clientPort;
-    request->context = context;
-    request->callout.browserCallback = callBack;
-
-    result = DNSServiceBrowserCreate_rpc(serverPort, clientPort, (char *)regtype, (char *)domain);
-
-    if (result != KERN_SUCCESS) {
-        printf("There was an error creating a browser, %s\n", mach_error_string(result));
-        free(request);
-        return NULL;
-    }
-
-    pthread_mutex_lock(&a_requests_lock);
-    request->next = a_requests;
-    a_requests = request;
-    pthread_mutex_unlock(&a_requests_lock);
-    
-    return return_t;
-}
-
-/* Service Enumeration */
-
-dns_service_discovery_ref DNSServiceDomainEnumerationCreate (int registrationDomains, DNSServiceDomainEnumerationReply callBack, void *context)
-{
-    mach_port_t serverPort = DNSServiceDiscoveryLookupServer();
-    mach_port_t clientPort;
-    kern_return_t result;
-    dns_service_discovery_ref return_t;
-    struct a_requests  *request;
-
-    if (!serverPort) {
-        return NULL;
-    }
-
-    result = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &clientPort);
-    if (result != KERN_SUCCESS) {
-        printf("Mach port receive creation failed, %s\n", mach_error_string(result));
-        return NULL;
-    }
-    result = mach_port_insert_right(mach_task_self(), clientPort, clientPort, MACH_MSG_TYPE_MAKE_SEND);
-    if (result != KERN_SUCCESS) {
-        printf("Mach port send creation failed, %s\n", mach_error_string(result));
-        mach_port_destroy(mach_task_self(), clientPort);
-        return NULL;
-    }
-    _increaseQueueLengthOnPort(clientPort);
-
-    return_t = malloc(sizeof(dns_service_discovery_t));
-    return_t->port = clientPort;
-
-    request = malloc(sizeof(struct a_requests));
-    request->client_port = clientPort;
-    request->context = context;
-    request->callout.enumCallback = callBack;
-
-    result = DNSServiceDomainEnumerationCreate_rpc(serverPort, clientPort, registrationDomains);
-
-    if (result != KERN_SUCCESS) {
-        printf("There was an error creating an enumerator, %s\n", mach_error_string(result));
-        free(request);
-        return NULL;
-    }
-    
-    pthread_mutex_lock(&a_requests_lock);
-    request->next = a_requests;
-    a_requests = request;
-    pthread_mutex_unlock(&a_requests_lock);
-
-    return return_t;
-}
-
-
-/* Service Registration */
-
-dns_service_discovery_ref DNSServiceRegistrationCreate
-(const char *name, const char *regtype, const char *domain, uint16_t port, const char *txtRecord, DNSServiceRegistrationReply callBack, void *context)
-{
-    mach_port_t serverPort = DNSServiceDiscoveryLookupServer();
-    mach_port_t clientPort;
-    kern_return_t              result;
-    dns_service_discovery_ref return_t;
-    struct a_requests  *request;
-    IPPort IpPort;
-       char *portptr = (char *)&port;
-       
-    if (!serverPort) {
-        return NULL;
-    }
-
-    if (!txtRecord) {
-      txtRecord = "";
-    }
-
-    result = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &clientPort);
-    if (result != KERN_SUCCESS) {
-        printf("Mach port receive creation failed, %s\n", mach_error_string(result));
-        return NULL;
-    }
-    result = mach_port_insert_right(mach_task_self(), clientPort, clientPort, MACH_MSG_TYPE_MAKE_SEND);
-    if (result != KERN_SUCCESS) {
-        printf("Mach port send creation failed, %s\n", mach_error_string(result));
-        mach_port_destroy(mach_task_self(), clientPort);
-        return NULL;
-    }
-    _increaseQueueLengthOnPort(clientPort);
-
-    return_t = malloc(sizeof(dns_service_discovery_t));
-    return_t->port = clientPort;
-
-    request = malloc(sizeof(struct a_requests));
-    request->client_port = clientPort;
-    request->context = context;
-    request->callout.regCallback = callBack;
-
-       // older versions of this code passed the port via mach IPC as an int.
-       // we continue to pass it as 4 bytes to maintain binary compatibility,
-       // but now ensure that the network byte order is preserved by using a struct
-       IpPort.bytes[0] = 0;
-       IpPort.bytes[1] = 0;
-       IpPort.bytes[2] = portptr[0];
-       IpPort.bytes[3] = portptr[1];
-
-    result = DNSServiceRegistrationCreate_rpc(serverPort, clientPort, (char *)name, (char *)regtype, (char *)domain, IpPort, (char *)txtRecord);
-
-    if (result != KERN_SUCCESS) {
-        printf("There was an error creating a resolve, %s\n", mach_error_string(result));
-        free(request);
-        return NULL;
-    }
-
-    pthread_mutex_lock(&a_requests_lock);
-    request->next = a_requests;
-    a_requests = request;
-    pthread_mutex_unlock(&a_requests_lock);
-
-    return return_t;
-}
-
-/* Resolver requests */
-
-dns_service_discovery_ref DNSServiceResolverResolve(const char *name, const char *regtype, const char *domain, DNSServiceResolverReply callBack, void *context)
-{
-    mach_port_t serverPort = DNSServiceDiscoveryLookupServer();
-    mach_port_t clientPort;
-    kern_return_t              result;
-    dns_service_discovery_ref return_t;
-    struct a_requests  *request;
-
-    if (!serverPort) {
-        return NULL;
-    }
-
-    result = mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &clientPort);
-    if (result != KERN_SUCCESS) {
-        printf("Mach port receive creation failed, %s\n", mach_error_string(result));
-        return NULL;
-    }
-    result = mach_port_insert_right(mach_task_self(), clientPort, clientPort, MACH_MSG_TYPE_MAKE_SEND);
-    if (result != KERN_SUCCESS) {
-        printf("Mach port send creation failed, %s\n", mach_error_string(result));
-        mach_port_destroy(mach_task_self(), clientPort);
-        return NULL;
-    }
-    _increaseQueueLengthOnPort(clientPort);
-
-    return_t = malloc(sizeof(dns_service_discovery_t));
-    return_t->port = clientPort;
-
-    request = malloc(sizeof(struct a_requests));
-    request->client_port = clientPort;
-    request->context = context;
-    request->callout.resolveCallback = callBack;
-
-    DNSServiceResolverResolve_rpc(serverPort, clientPort, (char *)name, (char *)regtype, (char *)domain);
-
-    pthread_mutex_lock(&a_requests_lock);
-    request->next = a_requests;
-    a_requests = request;
-    pthread_mutex_unlock(&a_requests_lock);
-
-    return return_t;
-}
-
-DNSRecordReference DNSServiceRegistrationAddRecord(dns_service_discovery_ref ref, uint16_t rrtype, uint16_t rdlen, const char *rdata, uint32_t ttl)
-{
-    mach_port_t serverPort = DNSServiceDiscoveryLookupServer();
-    mach_port_t clientPort;
-    natural_t reference = 0;
-    kern_return_t result = KERN_SUCCESS;
-
-    if (!serverPort) {
-        return kDNSServiceDiscoveryUnknownErr;
-    }
-
-    clientPort = DNSServiceDiscoveryMachPort(ref);
-
-    if (!clientPort) {
-        return kDNSServiceDiscoveryUnknownErr;
-    }
-
-    result = DNSServiceRegistrationAddRecord_rpc(serverPort, clientPort, rrtype, (record_data_t)rdata, rdlen, ttl, &reference);
-
-    if (result != KERN_SUCCESS) {
-        printf("The result of the registration was not successful.  Error %d, result %s\n", result, mach_error_string(result));
-    }
-    
-    return reference;
-}
-
-DNSServiceRegistrationReplyErrorType DNSServiceRegistrationUpdateRecord(dns_service_discovery_ref ref, DNSRecordReference reference, uint16_t rdlen, const char *rdata, uint32_t ttl)
-{
-    mach_port_t serverPort = DNSServiceDiscoveryLookupServer();
-    mach_port_t clientPort;
-    kern_return_t result = KERN_SUCCESS;
-
-    if (!serverPort) {
-        return kDNSServiceDiscoveryUnknownErr;
-    }
-
-    clientPort = DNSServiceDiscoveryMachPort(ref);
-
-    if (!clientPort) {
-        return kDNSServiceDiscoveryUnknownErr;
-    }
-
-    result = DNSServiceRegistrationUpdateRecord_rpc(serverPort, clientPort, (natural_t)reference, (record_data_t)rdata, rdlen, ttl);
-    if (result != KERN_SUCCESS) {
-        printf("The result of the registration was not successful.  Error %d, result %s\n", result, mach_error_string(result));
-        return result;
-    }
-
-    return kDNSServiceDiscoveryNoError;
-}
-
-
-DNSServiceRegistrationReplyErrorType DNSServiceRegistrationRemoveRecord(dns_service_discovery_ref ref, DNSRecordReference reference)
-{
-    mach_port_t serverPort = DNSServiceDiscoveryLookupServer();
-    mach_port_t clientPort;
-    kern_return_t result = KERN_SUCCESS;
-
-    if (!serverPort) {
-        return kDNSServiceDiscoveryUnknownErr;
-    }
-
-    clientPort = DNSServiceDiscoveryMachPort(ref);
-
-    if (!clientPort) {
-        return kDNSServiceDiscoveryUnknownErr;
-    }
-
-    result = DNSServiceRegistrationRemoveRecord_rpc(serverPort, clientPort, (natural_t)reference);
-
-    if (result != KERN_SUCCESS) {
-        printf("The result of the registration was not successful.  Error %d, result %s\n", result, mach_error_string(result));
-        return result;
-    }
-
-    return kDNSServiceDiscoveryNoError;
-}
-
-void DNSServiceDiscovery_handleReply(void *replyMsg)
-{
-    unsigned long                      result = 0xFFFFFFFF;
-    mach_msg_header_t *        msgSendBufPtr;
-    mach_msg_header_t *     receivedMessage;
-    unsigned                   msgSendBufLength;
-
-    msgSendBufLength = internal_DNSServiceDiscoveryReply_subsystem.maxsize;
-    msgSendBufPtr = (mach_msg_header_t *) malloc(msgSendBufLength);
-
-
-    receivedMessage = ( mach_msg_header_t * ) replyMsg;
-
-    // Call DNSServiceDiscoveryReply_server to change mig-generated message into a
-    // genuine mach message. It will then cause the callback to get called.
-    result = DNSServiceDiscoveryReply_server ( receivedMessage, msgSendBufPtr );
-    ( void ) mach_msg_send ( msgSendBufPtr );
-    free(msgSendBufPtr);
-}
-
-mach_port_t DNSServiceDiscoveryMachPort(dns_service_discovery_ref dnsServiceDiscovery)
-{
-    return dnsServiceDiscovery->port;
-}
-
-void DNSServiceDiscoveryDeallocate(dns_service_discovery_ref dnsServiceDiscovery)
-{
-    struct a_requests  *request0, *request;
-    mach_port_t reply = dnsServiceDiscovery->port;
-
-    if (dnsServiceDiscovery->port) {
-        pthread_mutex_lock(&a_requests_lock);
-        request0 = NULL;
-        request  = a_requests;
-        while (request) {
-            if (request->client_port == reply) {
-                /* request info found, remove from list */
-                if (request0) {
-                    request0->next = request->next;
-                } else {
-                    a_requests = request->next;
-                }
-                break;
-            } else {
-                /* not info for this request, skip to next */
-                request0 = request;
-                request  = request->next;
-            }
-
-        }
-        pthread_mutex_unlock(&a_requests_lock);
-
-        free(request);
-        
-        mach_port_destroy(mach_task_self(), dnsServiceDiscovery->port);
-
-        free(dnsServiceDiscovery);
-    }
-    return;
-}
-
-// reply functions, calls the users setup callbacks with function pointers
-
-kern_return_t internal_DNSServiceDomainEnumerationReply_rpc
-(
-    mach_port_t reply,
-    int resultType,
-    DNSCString replyDomain,
-    DNSServiceDiscoveryReplyFlags flags
-)
-{
-    struct a_requests  *request;
-    void *requestContext = NULL;
-    DNSServiceDomainEnumerationReply callback = NULL;
-
-    pthread_mutex_lock(&a_requests_lock);
-    request  = a_requests;
-    while (request) {
-        if (request->client_port == reply) {
-            break;
-        }
-        request = request->next;
-    }
-
-    if (request != NULL) {
-        callback = (*request->callout.enumCallback);
-        requestContext = request->context;
-    }
-    pthread_mutex_unlock(&a_requests_lock);
-
-    if (request != NULL) {
-        (callback)(resultType, replyDomain, flags, requestContext);
-    }
-    
-    return KERN_SUCCESS;
-
-}
-
-kern_return_t internal_DNSServiceBrowserReply_rpc
-(
-    mach_port_t reply,
-    int resultType,
-    DNSCString replyName,
-    DNSCString replyType,
-    DNSCString replyDomain,
-    DNSServiceDiscoveryReplyFlags flags
-)
-{
-    struct a_requests  *request;
-    void *requestContext = NULL;
-    DNSServiceBrowserReply callback = NULL;
-
-    pthread_mutex_lock(&a_requests_lock);
-    request  = a_requests;
-    while (request) {
-        if (request->client_port == reply) {
-            break;
-        }
-        request = request->next;
-    }
-    if (request != NULL) {
-        callback = (*request->callout.browserCallback);
-        requestContext = request->context;
-    }
-
-    pthread_mutex_unlock(&a_requests_lock);
-
-    if (request != NULL) {
-        (callback)(resultType, replyName, replyType, replyDomain, flags, requestContext);
-    }
-
-    return KERN_SUCCESS;
-}
-
-
-kern_return_t internal_DNSServiceRegistrationReply_rpc
-(
-    mach_port_t reply,
-    int resultType
-)
-{
-    struct a_requests  *request;
-    void *requestContext = NULL;
-    DNSServiceRegistrationReply callback = NULL;
-
-    pthread_mutex_lock(&a_requests_lock);
-    request  = a_requests;
-    while (request) {
-        if (request->client_port == reply) {
-            break;
-        }
-        request = request->next;
-    }
-    if (request != NULL) {
-        callback = (*request->callout.regCallback);
-        requestContext = request->context;
-    }
-
-    pthread_mutex_unlock(&a_requests_lock);
-    if (request != NULL) {
-        (callback)(resultType, requestContext);
-    }
-    return KERN_SUCCESS;
-}
-
-
-kern_return_t internal_DNSServiceResolverReply_rpc
-(
-    mach_port_t reply,
-    sockaddr_t interface,
-    sockaddr_t address,
-    DNSCString txtRecord,
-    DNSServiceDiscoveryReplyFlags flags
-)
-{
-    struct sockaddr  *interface_storage = NULL;
-    struct sockaddr  *address_storage = NULL;
-    struct a_requests  *request;
-    void *requestContext = NULL;
-    DNSServiceResolverReply callback = NULL;
-
-    if (interface) {
-        int len = ((struct sockaddr *)interface)->sa_len;
-        interface_storage = (struct sockaddr *)malloc(len);
-        bcopy(interface, interface_storage,len);
-    }
-
-    if (address) {
-        int len = ((struct sockaddr *)address)->sa_len;
-        address_storage = (struct sockaddr *)malloc(len);
-        bcopy(address, address_storage, len);
-    }
-
-    pthread_mutex_lock(&a_requests_lock);
-    request  = a_requests;
-    while (request) {
-        if (request->client_port == reply) {
-            break;
-        }
-        request = request->next;
-    }
-
-    if (request != NULL) {
-        callback = (*request->callout.resolveCallback);
-        requestContext = request->context;
-    }
-    pthread_mutex_unlock(&a_requests_lock);
-
-    if (request != NULL) {
-        (callback)(interface_storage, address_storage, txtRecord, flags, requestContext);
-    }
-
-    if (interface) {
-        free(interface_storage);
-    }
-    if (address) {
-        free(address_storage);
-    }
-    
-    return KERN_SUCCESS;
-}
diff --git a/mdns.subproj/DNSServiceDiscovery.h b/mdns.subproj/DNSServiceDiscovery.h
deleted file mode 100644 (file)
index 2539467..0000000
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
-* "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
- *
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef __DNS_SERVICE_DISCOVERY_H
-#define __DNS_SERVICE_DISCOVERY_H
-
-#include <mach/mach_types.h>
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/cdefs.h>
-
-#include <netinet/in.h>
-
-#include <AvailabilityMacros.h>
-
-__BEGIN_DECLS
-
-/* Opaque internal data type */
-typedef struct _dns_service_discovery_t * dns_service_discovery_ref;
-
-/* possible reply flags values */
-
-enum {
-    kDNSServiceDiscoveryNoFlags                        = 0,
-    kDNSServiceDiscoveryMoreRepliesImmediately = 1 << 0,
-};
-
-
-/* possible error code values */
-typedef enum
-{
-    kDNSServiceDiscoveryWaiting     = 1,
-    kDNSServiceDiscoveryNoError     = 0,
-      // mDNS Error codes are in the range
-      // FFFE FF00 (-65792) to FFFE FFFF (-65537)
-    kDNSServiceDiscoveryUnknownErr        = -65537,       // 0xFFFE FFFF
-    kDNSServiceDiscoveryNoSuchNameErr     = -65538,
-    kDNSServiceDiscoveryNoMemoryErr       = -65539,
-    kDNSServiceDiscoveryBadParamErr       = -65540,
-    kDNSServiceDiscoveryBadReferenceErr   = -65541,
-    kDNSServiceDiscoveryBadStateErr       = -65542,
-    kDNSServiceDiscoveryBadFlagsErr       = -65543,
-    kDNSServiceDiscoveryUnsupportedErr    = -65544,
-    kDNSServiceDiscoveryNotInitializedErr = -65545,
-    kDNSServiceDiscoveryNoCache           = -65546,
-    kDNSServiceDiscoveryAlreadyRegistered = -65547,
-    kDNSServiceDiscoveryNameConflict      = -65548,
-    kDNSServiceDiscoveryInvalid           = -65549,
-    kDNSServiceDiscoveryMemFree           = -65792        // 0xFFFE FF00
-} DNSServiceRegistrationReplyErrorType;
-
-typedef uint32_t DNSRecordReference;
-
-
-/*!
-@function DNSServiceResolver_handleReply
- @description This function should be called with the Mach message sent
- to the port returned by the call to DNSServiceResolverResolve.
- The reply message will be interpreted and will result in a
- call to the specified callout function.
- @param replyMsg The Mach message.
- */
-void DNSServiceDiscovery_handleReply(void *replyMsg);
-
-/* Service Registration */
-
-typedef void (*DNSServiceRegistrationReply) (
-    DNSServiceRegistrationReplyErrorType               errorCode,
-    void                                                                               *context
-);
-
-/*!
-@function DNSServiceRegistrationCreate
-    @description Register a named service with DNS Service Discovery
-    @param name The name of this service instance (e.g. "Steve's Printer")
-    @param regtype The service type (e.g. "_printer._tcp." -- see
-        RFC 2782 (DNS SRV) and <http://www.iana.org/assignments/port-numbers>)
-    @param domain The domain in which to register the service (e.g. "apple.com.")
-    @param port The local port on which this service is being offered (in network byte order)
-    @param txtRecord Optional protocol-specific additional information
-    @param callBack The DNSServiceRegistrationReply function to be called
-    @param context A user specified context which will be passed to the callout function.
-    @result A dns_registration_t
-*/
-dns_service_discovery_ref DNSServiceRegistrationCreate
-(
-    const char                 *name,
-    const char                 *regtype,
-    const char                 *domain,
-    uint16_t           port,
-    const char                 *txtRecord,
-    DNSServiceRegistrationReply callBack,
-    void               *context
-) AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED;
-
-/***************************************************************************/
-/*   DNS Domain Enumeration   */
-
-typedef enum
-{
-    DNSServiceDomainEnumerationReplyAddDomain,                 // Domain found
-    DNSServiceDomainEnumerationReplyAddDomainDefault,          // Domain found (and should be selected by default)
-    DNSServiceDomainEnumerationReplyRemoveDomain,                      // Domain has been removed from network
-} DNSServiceDomainEnumerationReplyResultType;
-
-typedef enum
-{
-    DNSServiceDiscoverReplyFlagsFinished,
-    DNSServiceDiscoverReplyFlagsMoreComing,
-} DNSServiceDiscoveryReplyFlags;
-
-typedef void (*DNSServiceDomainEnumerationReply) (
-    DNSServiceDomainEnumerationReplyResultType                         resultType,             // One of DNSServiceDomainEnumerationReplyResultType
-    const char                                                 *replyDomain,
-    DNSServiceDiscoveryReplyFlags              flags,                  // DNS Service Discovery reply flags information
-    void                                                               *context                
-);
-
-/*!
-    @function DNSServiceDomainEnumerationCreate
-    @description Asynchronously create a DNS Domain Enumerator
-    @param registrationDomains A boolean indicating whether you are looking
-        for recommended registration domains
-        (e.g. equivalent to the AppleTalk zone list in the AppleTalk Control Panel)
-        or recommended browsing domains
-        (e.g. equivalent to the AppleTalk zone list in the Chooser).
-    @param callBack The function to be called when domains are found or removed
-    @param context A user specified context which will be passed to the callout function.
-    @result A dns_registration_t
-*/
-dns_service_discovery_ref DNSServiceDomainEnumerationCreate
-(
-    int                registrationDomains,
-    DNSServiceDomainEnumerationReply   callBack,
-    void               *context
-) AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED;
-
-/***************************************************************************/
-/*   DNS Service Browser   */
-
-typedef enum
-{
-    DNSServiceBrowserReplyAddInstance, // Instance of service found
-    DNSServiceBrowserReplyRemoveInstance       // Instance has been removed from network
-} DNSServiceBrowserReplyResultType;
-
-typedef void (*DNSServiceBrowserReply) (
-    DNSServiceBrowserReplyResultType                   resultType,             // One of DNSServiceBrowserReplyResultType
-    const char         *replyName,
-    const char         *replyType,
-    const char         *replyDomain,
-    DNSServiceDiscoveryReplyFlags                              flags,                  // DNS Service Discovery reply flags information
-    void                       *context
-);
-
-/*!
-    @function DNSServiceBrowserCreate
-    @description Asynchronously create a DNS Service browser
-    @param regtype The type of service
-    @param domain The domain in which to find the service
-    @param callBack The function to be called when service instances are found or removed
-    @param context A user specified context which will be passed to the callout function.
-    @result A dns_registration_t
-*/
-dns_service_discovery_ref DNSServiceBrowserCreate
-(
-    const char                 *regtype,
-    const char                 *domain,
-    DNSServiceBrowserReply     callBack,
-    void               *context
-) AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED;
-
-/***************************************************************************/
-/* Resolver requests */
-
-typedef void (*DNSServiceResolverReply) (
-    struct sockaddr    *interface,             // Needed for scoped addresses like link-local
-    struct sockaddr    *address,
-    const char                         *txtRecord,
-    DNSServiceDiscoveryReplyFlags                              flags,                  // DNS Service Discovery reply flags information
-    void                               *context
-);
-
-/*!
-@function DNSServiceResolverResolve
-    @description Resolved a named instance of a service to its address, port, and
-        (optionally) other demultiplexing information contained in the TXT record.
-    @param name The name of the service instance
-    @param regtype The type of service
-    @param domain The domain in which to find the service
-    @param callBack The DNSServiceResolverReply function to be called when the specified
-        address has been resolved.
-    @param context A user specified context which will be passed to the callout function.
-    @result A dns_registration_t
-*/
-
-dns_service_discovery_ref DNSServiceResolverResolve
-(
-    const char                 *name,
-    const char                 *regtype,
-    const char                 *domain,
-    DNSServiceResolverReply callBack,
-    void               *context
-) AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED;
-
-/***************************************************************************/
-/* Mach port accessor and deallocation */
-
-/*!
-    @function DNSServiceDiscoveryMachPort
-    @description Returns the mach port for a dns_service_discovery_ref
-    @param registration A dns_service_discovery_ref as returned from DNSServiceRegistrationCreate
-    @result A mach reply port which will be sent messages as appropriate.
-        These messages should be passed to the DNSServiceDiscovery_handleReply
-        function.  A NULL value indicates that no address was
-        specified or some other error occurred which prevented the
-        resolution from being started.
-*/
-mach_port_t DNSServiceDiscoveryMachPort(dns_service_discovery_ref dnsServiceDiscovery) AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED;
-
-/*!
-    @function DNSServiceDiscoveryDeallocate
-    @description Deallocates the DNS Service Discovery type / closes the connection to the server
-    @param dnsServiceDiscovery A dns_service_discovery_ref as returned from a creation or enumeration call
-    @result void
-*/
-void DNSServiceDiscoveryDeallocate(dns_service_discovery_ref dnsServiceDiscovery) AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED;
-
-/***************************************************************************/
-/* Registration updating */
-
-
-/*!
-    @function DNSServiceRegistrationAddRecord
-    @description Request that the mDNS Responder add the DNS Record of a specific type
-    @param dnsServiceDiscovery A dns_service_discovery_ref as returned from a DNSServiceRegistrationCreate call
-    @param rrtype A standard DNS Resource Record Type, from http://www.iana.org/assignments/dns-parameters
-    @param rdlen Length of the data
-    @param rdata Opaque binary Resource Record data, up to 64 kB.
-    @param ttl time to live for the added record.
-    @result DNSRecordReference An opaque reference that can be passed to the update and remove record calls.  If an error occurs, this value will be zero or negative
-*/
-DNSRecordReference DNSServiceRegistrationAddRecord(dns_service_discovery_ref dnsServiceDiscovery, uint16_t rrtype, uint16_t rdlen, const char *rdata, uint32_t ttl)
-AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED;
-
-/*!
-    @function DNSServiceRegistrationUpdateRecord
-    @description Request that the mDNS Responder add the DNS Record of a specific type
-    @param dnsServiceDiscovery A dns_service_discovery_ref as returned from a DNSServiceRegistrationCreate call
-    @param dnsRecordReference A dnsRecordReference as returned from a DNSServiceRegistrationAddRecord call
-    @param rdlen Length of the data
-    @param rdata Opaque binary Resource Record data, up to 64 kB.
-    @param ttl time to live for the updated record.
-    @result DNSServiceRegistrationReplyErrorType If an error occurs, this value will be non zero
-*/
-DNSServiceRegistrationReplyErrorType DNSServiceRegistrationUpdateRecord(dns_service_discovery_ref ref, DNSRecordReference reference, uint16_t rdlen, const char *rdata, uint32_t ttl)
-AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED;
-
-/*!
-    @function DNSServiceRegistrationRemoveRecord
-    @description Request that the mDNS Responder remove the DNS Record(s) of a specific type
-    @param dnsServiceDiscovery A dns_service_discovery_ref as returned from a DNSServiceRegistrationCreate call
-    @param dnsRecordReference A dnsRecordReference as returned from a DNSServiceRegistrationAddRecord call
-    @result DNSServiceRegistrationReplyErrorType If an error occurs, this value will be non zero
-*/
-DNSServiceRegistrationReplyErrorType DNSServiceRegistrationRemoveRecord(dns_service_discovery_ref ref, DNSRecordReference reference)
-AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED;
-
-
-__END_DECLS
-
-#endif /* __DNS_SERVICE_DISCOVERY_H */
diff --git a/mdns.subproj/DNSServiceDiscoveryDefines.h b/mdns.subproj/DNSServiceDiscoveryDefines.h
deleted file mode 100644 (file)
index 9f021d9..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2001 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
-                                                               * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
- *
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef __DNS_SERVICE_DISCOVERY_DEFINES_H
-#define __DNS_SERVICE_DISCOVERY_DEFINES_H
-
-#include <mach/mach_types.h>
-
-#define DNS_SERVICE_DISCOVERY_SERVER "com.apple.mDNSResponder"
-
-typedef char    DNSCString[1024];
-typedef char    sockaddr_t[128];
-
-typedef const char * record_data_t;
-typedef struct { char bytes[4]; } IPPort;
-
-#endif /* __DNS_SERVICE_DISCOVERY_DEFINES_H */
-
diff --git a/mdns.subproj/DNSServiceDiscoveryReply.defs b/mdns.subproj/DNSServiceDiscoveryReply.defs
deleted file mode 100644 (file)
index d26c20b..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (c) 2001 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
- *
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-subsystem
-       DNSServiceDiscoveryReply 7250;
-
-ServerPrefix internal_;
-
-#include <mach/std_types.defs>
-#include <mach/mach_types.defs>
-
-import "DNSServiceDiscoveryDefines.h";
-
-type DNSCString = c_string[*:1024];
-type sockaddr_t = array[128] of char;
-
-simpleroutine DNSServiceDomainEnumerationReply_rpc(
-                               reply: mach_port_t;
-                        in     resultType: int;
-                        in     replyDomain: DNSCString;
-                        in     flags: int;
-                               SendTime        to: natural_t);
-
-simpleroutine DNSServiceBrowserReply_rpc(
-                               reply: mach_port_t;
-                        in     resultType: int;
-                        in     replyName: DNSCString;
-                        in     replyType: DNSCString;
-                        in     replyDomain: DNSCString;
-                        in     flags: int;
-                               SendTime        to: natural_t);
-
-                        
-simpleroutine DNSServiceRegistrationReply_rpc(
-                               reply: mach_port_t;
-                        in     resultType: int;
-                               SendTime        to: natural_t);
-
-
-simpleroutine DNSServiceResolverReply_rpc(
-                               reply: mach_port_t;
-                        in     interface: sockaddr_t;
-                        in     address: sockaddr_t;
-                        in     txtRecord: DNSCString;
-                        in     flags: int;
-                               SendTime        to: natural_t);
-
diff --git a/mdns.subproj/DNSServiceDiscoveryRequest.defs b/mdns.subproj/DNSServiceDiscoveryRequest.defs
deleted file mode 100644 (file)
index d14917a..0000000
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (c) 2002 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
- *
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-subsystem
-       DNSServiceDiscoveryRequest 7200;
-
-ServerPrefix provide_;
-
-#include <mach/std_types.defs>
-#include <mach/mach_types.defs>
-
-import "DNSServiceDiscoveryDefines.h";
-
-type DNSCString = c_string[*:1024];
-type record_data = ^ array [] of MACH_MSG_TYPE_BYTE
-                               ctype: record_data_t;
-type IPPort = struct[4] of char ctype:IPPort;
-
-simpleroutine DNSServiceBrowserCreate_rpc(
-                               server: mach_port_t;
-                        in     client: mach_port_t;
-                                               in      regtype: DNSCString;
-                                               in      domain: DNSCString);
-                                                
-
-simpleroutine DNSServiceDomainEnumerationCreate_rpc(
-                               server: mach_port_t;
-                        in     client: mach_port_t;
-                                               in      registrationDomains: int);
-
-simpleroutine DNSServiceRegistrationCreate_rpc(
-                               server: mach_port_t;
-                        in     client: mach_port_t;
-                        in     name: DNSCString;
-                        in     regtype: DNSCString;
-                        in     domain: DNSCString;
-                        in     port: IPPort;
-                        in     txtRecord: DNSCString);
-
-                        
-simpleroutine DNSServiceResolverResolve_rpc(
-                               server: mach_port_t;
-                        in     client: mach_port_t;
-                        in     name: DNSCString;
-                        in     regtype: DNSCString;
-                        in     domain: DNSCString);
-
-routine DNSServiceRegistrationAddRecord_rpc(
-                               server: mach_port_t;
-                                               in client: mach_port_t;
-                                               in record_type: int;
-                                               in record_data: record_data;
-                                               in ttl: uint32_t;
-                                               out record_reference: natural_t);
-
-simpleroutine DNSServiceRegistrationUpdateRecord_rpc(
-                               server: mach_port_t;
-                                               in client: mach_port_t;
-                                                in record_reference: natural_t;
-                                               in record_data: record_data;
-                                               in ttl: uint32_t);
-
-simpleroutine DNSServiceRegistrationRemoveRecord_rpc(
-                               server: mach_port_t;
-                                               in client: mach_port_t;
-                                               in record_reference: natural_t);
-                        
diff --git a/mdns.subproj/Makefile b/mdns.subproj/Makefile
deleted file mode 100644 (file)
index cda015f..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#
-# Generated by the Apple 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 = mdns
-
-PROJECTVERSION = 2.8
-PROJECT_TYPE = Component
-
-HFILES = DNSServiceDiscoveryDefines.h DNSServiceDiscovery.h dns_sd.h dnssd_ipc.h
-
-CFILES = DNSServiceDiscovery.c dnssd_clientstub.c dnssd_ipc.c dnssd_clientlib.c
-
-OTHERSRCS = Makefile.preamble Makefile Makefile.postamble\
-            DNSServiceDiscoveryReply.defs DNSServiceDiscoveryRequest.defs
-
-MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
-CODE_GEN_STYLE = DYNAMIC
-MAKEFILE = subproj.make
-NEXTSTEP_INSTALLDIR = /usr/local/lib/system
-LIBS = 
-DEBUG_LIBS = $(LIBS)
-PROF_LIBS = $(LIBS)
-
-PUBLIC_HEADERS = dns_sd.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/mdns.subproj/Makefile.postamble b/mdns.subproj/Makefile.postamble
deleted file mode 100644 (file)
index 11fac3f..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-###############################################################################
-#  Makefile.postamble
-#  Copyright 1997, Apple Computer, Inc.
-#
-#  Use this makefile, which is imported after all other makefiles, to
-#  override attributes for a project's Makefile environment. This allows you  
-#  to take advantage of the environment set up by the other Makefiles. 
-#  You can also define custom rules at the end of this file.
-#
-###############################################################################
-# 
-# These variables are exported by the standard makefiles and can be 
-# used in any customizations you make.  They are *outputs* of
-# the Makefiles and should be used, not set.
-# 
-#  PRODUCTS: products to install.  All of these products will be placed in
-#       the directory $(DSTROOT)$(INSTALLDIR)
-#  GLOBAL_RESOURCE_DIR: The directory to which resources are copied.
-#  LOCAL_RESOURCE_DIR: The directory to which localized resources are copied.
-#  OFILE_DIR: Directory into which .o object files are generated.
-#  DERIVED_SRC_DIR: Directory used for all other derived files
-#
-#  ALL_CFLAGS:  flags to pass when compiling .c files
-#  ALL_MFLAGS:  flags to pass when compiling .m files
-#  ALL_CCFLAGS:  flags to pass when compiling .cc, .cxx, and .C files
-#  ALL_MMFLAGS:  flags to pass when compiling .mm, .mxx, and .M files
-#  ALL_PRECOMPFLAGS:  flags to pass when precompiling .h files
-#  ALL_LDFLAGS:  flags to pass when linking object files
-#  ALL_LIBTOOL_FLAGS:  flags to pass when libtooling object files
-#  ALL_PSWFLAGS:  flags to pass when processing .psw and .pswm (pswrap) files
-#  ALL_RPCFLAGS:  flags to pass when processing .rpc (rpcgen) files
-#  ALL_YFLAGS:  flags to pass when processing .y (yacc) files
-#  ALL_LFLAGS:  flags to pass when processing .l (lex) files
-#
-#  NAME: name of application, bundle, subproject, palette, etc.
-#  LANGUAGES: langages in which the project is written (default "English")
-#  English_RESOURCES: localized resources (e.g. nib's, images) of project
-#  GLOBAL_RESOURCES: non-localized resources of project
-#
-#  SRCROOT:  base directory in which to place the new source files
-#  SRCPATH:  relative path from SRCROOT to present subdirectory
-#
-#  INSTALLDIR: Directory the product will be installed into by 'install' target
-#  PUBLIC_HDR_INSTALLDIR: where to install public headers.  Don't forget
-#        to prefix this with DSTROOT when you use it.
-#  PRIVATE_HDR_INSTALLDIR: where to install private headers.  Don't forget
-#       to prefix this with DSTROOT when you use it.
-#
-#  EXECUTABLE_EXT: Executable extension for the platform (i.e. .exe on Windows)
-#
-###############################################################################
-
-# Some compiler flags can be overridden here for certain build situations.
-#
-#    WARNING_CFLAGS:  flag used to set warning level (defaults to -Wmost)
-#    DEBUG_SYMBOLS_CFLAGS:  debug-symbol flag passed to all builds (defaults
-#      to -g)
-#    DEBUG_BUILD_CFLAGS:  flags passed during debug builds (defaults to -DDEBUG)
-#    OPTIMIZE_BUILD_CFLAGS:  flags passed during optimized builds (defaults
-#      to -O)
-#    PROFILE_BUILD_CFLAGS:  flags passed during profile builds (defaults
-#      to -pg -DPROFILE)
-#    LOCAL_DIR_INCLUDE_DIRECTIVE:  flag used to add current directory to
-#      the include path (defaults to -I.)
-#    DEBUG_BUILD_LDFLAGS, OPTIMIZE_BUILD_LDFLAGS, PROFILE_BUILD_LDFLAGS: flags
-#      passed to ld/libtool (defaults to nothing)
-
-
-# Library and Framework projects only:
-#    INSTALL_NAME_DIRECTIVE:  This directive ensures that executables linked
-#      against the framework will run against the correct version even if
-#      the current version of the framework changes.  You may override this
-#      to "" as an alternative to using the DYLD_LIBRARY_PATH during your
-#      development cycle, but be sure to restore it before installing.
-
-
-# Ownership and permissions of files installed by 'install' target
-
-#INSTALL_AS_USER = root
-        # User/group ownership 
-#INSTALL_AS_GROUP = wheel
-        # (probably want to set both of these) 
-#INSTALL_PERMISSIONS =
-        # If set, 'install' chmod's executable to this
-
-
-# Options to strip.  Note: -S strips debugging symbols (executables can be stripped
-# down further with -x or, if they load no bundles, with no options at all).
-
-#STRIPFLAGS = -S
-
-
-#########################################################################
-# Put rules to extend the behavior of the standard Makefiles here.  Include them in
-# the dependency tree via cvariables like AFTER_INSTALL in the Makefile.preamble.
-#
-# You should avoid redefining things like "install" or "app", as they are
-# owned by the top-level Makefile API and no context has been set up for where 
-# derived files should go.
-#
-
-mdns_hdrs: $(DSTROOT)$(PRIVATE_HDR_INSTALLDIR)$(MDNS_HEADER_DIR_SUFFIX) $(DSTROOT)$(PUBLIC_HDR_INSTALLDIR)$(MDNS_HEADER_DIR_SUFFIX)
-       $(SILENT) $(FASTCP) $(INTERNAL_MDNS_HDRS) $(DSTROOT)$(PRIVATE_HDR_INSTALLDIR)$(MDNS_HEADER_DIR_SUFFIX)
-       $(SILENT) $(FASTCP) $(PUBLIC_MDNS_HEADERS) $(DSTROOT)$(PUBLIC_HDR_INSTALLDIR)$(MDNS_HEADER_DIR_SUFFIX)
-
-$(DSTROOT)$(PRIVATE_HDR_INSTALLDIR)$(MDNS_HEADER_DIR_SUFFIX):
-       $(MKDIRS) $@
-
-$(DSTROOT)$(PUBLIC_HDR_INSTALLDIR)$(MDNS_HEADER_DIR_SUFFIX):
-       $(MKDIRS) $@
diff --git a/mdns.subproj/Makefile.preamble b/mdns.subproj/Makefile.preamble
deleted file mode 100644 (file)
index c3ae97e..0000000
+++ /dev/null
@@ -1,160 +0,0 @@
-###############################################################################
-#  Makefile.preamble
-#  Copyright 1997, Apple Computer, Inc.
-#
-#  Use this makefile for configuring the standard application makefiles 
-#  associated with ProjectBuilder. It is included before the main makefile.
-#  In Makefile.preamble you set attributes for a project, so they are available
-#  to the project's makefiles.  In contrast, you typically write additional rules or 
-#  override built-in behavior in the Makefile.postamble.
-#  
-#  Each directory in a project tree (main project plus subprojects) should 
-#  have its own Makefile.preamble and Makefile.postamble.
-###############################################################################
-#
-# Before the main makefile is included for this project, you may set:
-#
-#    MAKEFILEDIR: Directory in which to find $(MAKEFILE)
-#    MAKEFILE: Top level mechanism Makefile (e.g., app.make, bundle.make)
-
-# Compiler/linker flags added to the defaults:  The OTHER_* variables will be 
-# inherited by all nested sub-projects, but the LOCAL_ versions of the same
-# variables will not.  Put your -I, -D, -U, and -L flags in ProjectBuilder's
-# Build Attributes inspector if at all possible.  To override the default flags
-# that get passed to ${CC} (e.g. change -O to -O2), see Makefile.postamble.  The
-# variables below are *inputs* to the build process and distinct from the override
-# settings done (less often) in the Makefile.postamble.
-#
-#    OTHER_CFLAGS, LOCAL_CFLAGS:  additional flags to pass to the compiler
-#      Note that $(OTHER_CFLAGS) and $(LOCAL_CFLAGS) are used for .h, ...c, .m,
-#      .cc, .cxx, .C, and .M files.  There is no need to respecify the
-#      flags in OTHER_MFLAGS, etc.
-#    OTHER_MFLAGS, LOCAL_MFLAGS:  additional flags for .m files
-#    OTHER_CCFLAGS, LOCAL_CCFLAGS:  additional flags for .cc, .cxx, and ...C files
-#    OTHER_MMFLAGS, LOCAL_MMFLAGS:  additional flags for .mm and .M files
-#    OTHER_PRECOMPFLAGS, LOCAL_PRECOMPFLAGS:  additional flags used when
-#      precompiling header files
-#    OTHER_LDFLAGS, LOCAL_LDFLAGS:  additional flags passed to ld and libtool
-#    OTHER_PSWFLAGS, LOCAL_PSWFLAGS:  additional flags passed to pswrap
-#    OTHER_RPCFLAGS, LOCAL_RPCFLAGS:  additional flags passed to rpcgen
-#    OTHER_YFLAGS, LOCAL_YFLAGS:  additional flags passed to yacc
-#    OTHER_LFLAGS, LOCAL_LFLAGS:  additional flags passed to lex
-
-# These variables provide hooks enabling you to add behavior at almost every 
-# stage of the make:
-#
-#    BEFORE_PREBUILD: targets to build before installing headers for a subproject
-#    AFTER_PREBUILD: targets to build after installing headers for a subproject
-#    BEFORE_BUILD_RECURSION: targets to make before building subprojects
-#    BEFORE_BUILD: targets to make before a build, but after subprojects
-#    AFTER_BUILD: targets to make after a build
-#
-#    BEFORE_INSTALL: targets to build before installing the product
-#    AFTER_INSTALL: targets to build after installing the product
-#    BEFORE_POSTINSTALL: targets to build before postinstalling every subproject
-#    AFTER_POSTINSTALL: targts to build after postinstalling every subproject
-#
-#    BEFORE_INSTALLHDRS: targets to build before installing headers for a 
-#         subproject
-#    AFTER_INSTALLHDRS: targets to build after installing headers for a subproject
-#    BEFORE_INSTALLSRC: targets to build before installing source for a subproject
-#    AFTER_INSTALLSRC: targets to build after installing source for a subproject
-#
-#    BEFORE_DEPEND: targets to build before building dependencies for a
-#        subproject
-#    AFTER_DEPEND: targets to build after building dependencies for a
-#        subproject
-#
-#    AUTOMATIC_DEPENDENCY_INFO: if YES, then the dependency file is
-#        updated every time the project is built.  If NO, the dependency
-#        file is only built when the depend target is invoked.
-
-# Framework-related variables:
-#    FRAMEWORK_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
-#      where to put the framework's DLL.  This variable defaults to 
-#      $(INSTALLDIR)/../Executables
-
-# Library-related variables:
-#    PUBLIC_HEADER_DIR:  Determines where public exported header files
-#      should be installed.  Do not include $(DSTROOT) in this value --
-#      it is prefixed automatically.  For library projects you should
-#       set this to something like /Developer/Headers/$(NAME).  Do not set
-#       this variable for framework projects unless you do not want the
-#       header files included in the framework.
-#    PRIVATE_HEADER_DIR:  Determines where private exported header files
-#      should be installed.  Do not include $(DSTROOT) in this value --
-#      it is prefixed automatically.
-#    LIBRARY_STYLE:  This may be either STATIC or DYNAMIC, and determines
-#      whether the libraries produced are statically linked when they
-#      are used or if they are dynamically loadable. This defaults to
-#       DYNAMIC.
-#    LIBRARY_DLL_INSTALLDIR:  On Windows platforms, this variable indicates
-#      where to put the library's DLL.  This variable defaults to 
-#      $(INSTALLDIR)/../Executables
-#
-#    INSTALL_AS_USER: owner of the intalled products (default root)
-#    INSTALL_AS_GROUP: group of the installed products (default wheel)
-#    INSTALL_PERMISSIONS: permissions of the installed product (default o+rX)
-#
-#    OTHER_RECURSIVE_VARIABLES: The names of variables which you want to be
-#      passed on the command line to recursive invocations of make.  Note that
-#      the values in OTHER_*FLAGS are inherited by subprojects automatically --
-#      you do not have to (and shouldn't) add OTHER_*FLAGS to 
-#      OTHER_RECURSIVE_VARIABLES. 
-
-# Additional headers to export beyond those in the PB.project:
-#    OTHER_PUBLIC_HEADERS
-#    OTHER_PROJECT_HEADERS
-#    OTHER_PRIVATE_HEADERS
-
-# Additional files for the project's product: <<path relative to proj?>>
-#    OTHER_RESOURCES: (non-localized) resources for this project
-#    OTHER_OFILES: relocatables to be linked into this project
-#    OTHER_LIBS: more libraries to link against
-#    OTHER_PRODUCT_DEPENDS: other dependencies of this project
-#    OTHER_SOURCEFILES: other source files maintained by .pre/postamble
-#    OTHER_GARBAGE: additional files to be removed by `make clean'
-
-# Set this to YES if you don't want a final libtool call for a library/framework.
-#    BUILD_OFILES_LIST_ONLY
-
-# To include a version string, project source must exist in a directory named 
-# $(NAME).%d[.%d][.%d] and the following line must be uncommented.
-# OTHER_GENERATED_OFILES = $(VERS_OFILE)
-
-# This definition will suppress stripping of debug symbols when an executable
-# is installed.  By default it is YES.
-# STRIP_ON_INSTALL = NO
-
-# Uncomment to suppress generation of a KeyValueCoding index when installing 
-# frameworks (This index is used by WOB and IB to determine keys available
-# for an object).  Set to YES by default.
-# PREINDEX_FRAMEWORK = NO
-
-# Change this definition to install projects somewhere other than the
-# standard locations.  NEXT_ROOT defaults to "C:/Apple" on Windows systems
-# and "" on other systems.
-DSTROOT = $(HOME)
-
-# Additional flags (MiG generated files)
-OTHER_OFILES = DNSServiceDiscoveryRequestUser.o DNSServiceDiscoveryReplyServer.o
-
-# private headers
-INTERNAL_MDNS_HDRS = DNSServiceDiscoveryRequest.defs\
-       DNSServiceDiscoveryRequest.h \
-       DNSServiceDiscoveryReply.defs\
-       DNSServiceDiscoveryReply.h \
-       DNSServiceDiscoveryDefines.h
-
-# public headers
-PUBLIC_MDNS_HEADERS = DNSServiceDiscovery.h
-
-BEFORE_INSTALLHDRS += $(SFILE_DIR) $(INTERNAL_MDNS_HDRS) 
-AFTER_INSTALLHDRS += mdns_hdrs
-PRIVATE_HEADER_DIR = /AppleInternal/Developer/Headers
-MDNS_HEADER_DIR_SUFFIX = /DNSServiceDiscovery
-
-
-# for building 64-bit
-# <rdar://problem/3819761> Libinfo need to build with gcc-3.5 and 3-way fat
-NEXTSTEP_OBJCPLUS_COMPILER = $(CCOMPILER)
diff --git a/mdns.subproj/PB.project b/mdns.subproj/PB.project
deleted file mode 100644 (file)
index ee7d0e0..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-{
-    DYNAMIC_CODE_GEN = YES; 
-    English_RESOURCES = {}; 
-    FILESTABLE = {
-        H_FILES = (DNSServiceDiscoveryDefines.h, DNSServiceDiscovery.h, dns_sd.h, dnssd_ipc.h); 
-        OTHER_LINKED = (DNSServiceDiscovery.c, dnssd_clientstub.c, dnssd_ipc.c); 
-        OTHER_RESOURCES = (); 
-        OTHER_SOURCES = (
-            Makefile.preamble, 
-            Makefile, 
-            Makefile.postamble, 
-            DNSServiceDiscoveryReply.defs, 
-            DNSServiceDiscoveryRequest.defs
-        ); 
-        PUBLIC_HEADERS = (dns_sd.h); 
-        SUBPROJECTS = (); 
-    }; 
-    LANGUAGE = English; 
-    MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
-    NEXTSTEP_BUILDTOOL = /usr/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_JAVA_COMPILER = "$(JDKBINDIR)/javac"; 
-    PDO_UNIX_OBJCPLUS_COMPILER = "$(NEXTDEV_BIN)/gcc"; 
-    PROJECTNAME = mdns; 
-    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/mdns.subproj/dns_sd.h b/mdns.subproj/dns_sd.h
deleted file mode 100644 (file)
index a7411a3..0000000
+++ /dev/null
@@ -1,1644 +0,0 @@
-/*
- * Copyright (c) 2003-2004 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef _DNS_SD_H
-#define _DNS_SD_H
-
-#ifdef  __cplusplus
-    extern "C" {
-#endif
-
-/* standard calling convention under Win32 is __stdcall */
-#if defined(_WIN32)
-#define DNSSD_API __stdcall
-#else
-#define DNSSD_API
-#endif
-
-#if defined(__FreeBSD_version) && (__FreeBSD_version < 500000)
-/* stdint.h does not exist on FreeBSD 4.x; its types are defined in sys/types.h instead */
-#include <sys/types.h>
-#elif defined(__sun__)
-#include <sys/types.h>
-#elif defined(_WIN32)
-#include <windows.h>
-#define _UNUSED
-#define bzero(a, b) memset(a, 0, b)
-typedef UINT8       uint8_t;
-typedef INT8        int8_t;
-typedef UINT16      uint16_t;
-typedef INT16       int16_t;
-typedef UINT32      uint32_t;
-typedef INT32       int32_t;
-#else
-#include <stdint.h>
-#endif
-
-/* DNSServiceRef, DNSRecordRef
- *
- * Opaque internal data types.
- * Note: client is responsible for serializing access to these structures if
- * they are shared between concurrent threads.
- */
-
-typedef struct _DNSServiceRef_t *DNSServiceRef;
-typedef struct _DNSRecordRef_t *DNSRecordRef;
-
-/* General flags used in functions defined below */
-enum
-    {
-    kDNSServiceFlagsMoreComing          = 0x1,
-    /* MoreComing indicates to a callback that at least one more result is
-     * queued and will be delivered following immediately after this one.
-     * Applications should not update their UI to display browse
-     * results when the MoreComing flag is set, because this would
-     * result in a great deal of ugly flickering on the screen.
-     * Applications should instead wait until until MoreComing is not set,
-     * and then update their UI.
-     * When MoreComing is not set, that doesn't mean there will be no more
-     * answers EVER, just that there are no more answers immediately
-     * available right now at this instant. If more answers become available
-     * in the future they will be delivered as usual.
-     */
-
-    kDNSServiceFlagsAdd                 = 0x2,
-    kDNSServiceFlagsDefault             = 0x4,
-    /* Flags for domain enumeration and browse/query reply callbacks.
-     * "Default" applies only to enumeration and is only valid in
-     * conjuction with "Add".  An enumeration callback with the "Add"
-     * flag NOT set indicates a "Remove", i.e. the domain is no longer
-     * valid.
-     */
-
-    kDNSServiceFlagsNoAutoRename        = 0x8,
-    /* Flag for specifying renaming behavior on name conflict when registering
-     * non-shared records. By default, name conflicts are automatically handled
-     * by renaming the service.  NoAutoRename overrides this behavior - with this
-     * flag set, name conflicts will result in a callback.  The NoAutorename flag
-     * is only valid if a name is explicitly specified when registering a service
-     * (ie the default name is not used.)
-     */
-
-    kDNSServiceFlagsShared              = 0x10,
-    kDNSServiceFlagsUnique              = 0x20,
-    /* Flag for registering individual records on a connected
-     * DNSServiceRef.  Shared indicates that there may be multiple records
-     * with this name on the network (e.g. PTR records).  Unique indicates that the
-     * record's name is to be unique on the network (e.g. SRV records).
-     */
-
-    kDNSServiceFlagsBrowseDomains       = 0x40,
-    kDNSServiceFlagsRegistrationDomains = 0x80,
-    /* Flags for specifying domain enumeration type in DNSServiceEnumerateDomains.
-     * BrowseDomains enumerates domains recommended for browsing, RegistrationDomains
-     * enumerates domains recommended for registration.
-     */
-
-    kDNSServiceFlagsLongLivedQuery      = 0x100,
-    /* Flag for creating a long-lived unicast query for the DNSServiceQueryRecord call. */
-
-    kDNSServiceFlagsAllowRemoteQuery    = 0x200,
-    /* Flag for creating a record for which we will answer remote queries
-     * (queries from hosts more than one hop away; hosts not directly connected to the local link).
-     */
-
-    kDNSServiceFlagsForceMulticast      = 0x400
-    /* Flag for signifying that a query or registration should be performed exclusively via multicast DNS,
-     * even for a name in a domain (e.g. foo.apple.com.) that would normally imply unicast DNS.
-     */
-    };
-
-/*
- * The values for DNS Classes and Types are listed in RFC 1035, and are available
- * on every OS in its DNS header file. Unfortunately every OS does not have the
- * same header file containing DNS Class and Type constants, and the names of
- * the constants are not consistent. For example, BIND 8 uses "T_A",
- * BIND 9 uses "ns_t_a", Windows uses "DNS_TYPE_A", etc.
- * For this reason, these constants are also listed here, so that code using
- * the DNS-SD programming APIs can use these constants, so that the same code
- * can compile on all our supported platforms.
- */
-
-enum
-    {
-    kDNSServiceClass_IN       = 1       /* Internet */
-    };
-
-enum
-    {
-    kDNSServiceType_A         = 1,      /* Host address. */
-    kDNSServiceType_NS        = 2,      /* Authoritative server. */
-    kDNSServiceType_MD        = 3,      /* Mail destination. */
-    kDNSServiceType_MF        = 4,      /* Mail forwarder. */
-    kDNSServiceType_CNAME     = 5,      /* Canonical name. */
-    kDNSServiceType_SOA       = 6,      /* Start of authority zone. */
-    kDNSServiceType_MB        = 7,      /* Mailbox domain name. */
-    kDNSServiceType_MG        = 8,      /* Mail group member. */
-    kDNSServiceType_MR        = 9,      /* Mail rename name. */
-    kDNSServiceType_NULL      = 10,     /* Null resource record. */
-    kDNSServiceType_WKS       = 11,     /* Well known service. */
-    kDNSServiceType_PTR       = 12,     /* Domain name pointer. */
-    kDNSServiceType_HINFO     = 13,     /* Host information. */
-    kDNSServiceType_MINFO     = 14,     /* Mailbox information. */
-    kDNSServiceType_MX        = 15,     /* Mail routing information. */
-    kDNSServiceType_TXT       = 16,     /* Text strings. */
-    kDNSServiceType_RP        = 17,     /* Responsible person. */
-    kDNSServiceType_AFSDB     = 18,     /* AFS cell database. */
-    kDNSServiceType_X25       = 19,     /* X_25 calling address. */
-    kDNSServiceType_ISDN      = 20,     /* ISDN calling address. */
-    kDNSServiceType_RT        = 21,     /* Router. */
-    kDNSServiceType_NSAP      = 22,     /* NSAP address. */
-    kDNSServiceType_NSAP_PTR  = 23,     /* Reverse NSAP lookup (deprecated). */
-    kDNSServiceType_SIG       = 24,     /* Security signature. */
-    kDNSServiceType_KEY       = 25,     /* Security key. */
-    kDNSServiceType_PX        = 26,     /* X.400 mail mapping. */
-    kDNSServiceType_GPOS      = 27,     /* Geographical position (withdrawn). */
-    kDNSServiceType_AAAA      = 28,     /* Ip6 Address. */
-    kDNSServiceType_LOC       = 29,     /* Location Information. */
-    kDNSServiceType_NXT       = 30,     /* Next domain (security). */
-    kDNSServiceType_EID       = 31,     /* Endpoint identifier. */
-    kDNSServiceType_NIMLOC    = 32,     /* Nimrod Locator. */
-    kDNSServiceType_SRV       = 33,     /* Server Selection. */
-    kDNSServiceType_ATMA      = 34,     /* ATM Address */
-    kDNSServiceType_NAPTR     = 35,     /* Naming Authority PoinTeR */
-    kDNSServiceType_KX        = 36,     /* Key Exchange */
-    kDNSServiceType_CERT      = 37,     /* Certification record */
-    kDNSServiceType_A6        = 38,     /* IPv6 address (deprecates AAAA) */
-    kDNSServiceType_DNAME     = 39,     /* Non-terminal DNAME (for IPv6) */
-    kDNSServiceType_SINK      = 40,     /* Kitchen sink (experimentatl) */
-    kDNSServiceType_OPT       = 41,     /* EDNS0 option (meta-RR) */
-    kDNSServiceType_TKEY      = 249,    /* Transaction key */
-    kDNSServiceType_TSIG      = 250,    /* Transaction signature. */
-    kDNSServiceType_IXFR      = 251,    /* Incremental zone transfer. */
-    kDNSServiceType_AXFR      = 252,    /* Transfer zone of authority. */
-    kDNSServiceType_MAILB     = 253,    /* Transfer mailbox records. */
-    kDNSServiceType_MAILA     = 254,    /* Transfer mail agent records. */
-    kDNSServiceType_ANY       = 255     /* Wildcard match. */
-    };
-
-
-/* possible error code values */
-enum
-    {
-    kDNSServiceErr_NoError             = 0,
-    kDNSServiceErr_Unknown             = -65537,       /* 0xFFFE FFFF */
-    kDNSServiceErr_NoSuchName          = -65538,
-    kDNSServiceErr_NoMemory            = -65539,
-    kDNSServiceErr_BadParam            = -65540,
-    kDNSServiceErr_BadReference        = -65541,
-    kDNSServiceErr_BadState            = -65542,
-    kDNSServiceErr_BadFlags            = -65543,
-    kDNSServiceErr_Unsupported         = -65544,
-    kDNSServiceErr_NotInitialized      = -65545,
-    kDNSServiceErr_AlreadyRegistered   = -65547,
-    kDNSServiceErr_NameConflict        = -65548,
-    kDNSServiceErr_Invalid             = -65549,
-    kDNSServiceErr_Firewall            = -65550,    
-    kDNSServiceErr_Incompatible        = -65551,        /* client library incompatible with daemon */
-    kDNSServiceErr_BadInterfaceIndex   = -65552,
-    kDNSServiceErr_Refused             = -65553,
-    kDNSServiceErr_NoSuchRecord        = -65554,
-    kDNSServiceErr_NoAuth              = -65555,
-    kDNSServiceErr_NoSuchKey           = -65556,
-    kDNSServiceErr_NATTraversal        = -65557,
-    kDNSServiceErr_DoubleNAT           = -65558,
-    kDNSServiceErr_BadTime             = -65559
-    /* mDNS Error codes are in the range
-     * FFFE FF00 (-65792) to FFFE FFFF (-65537) */
-    };
-
-
-/* Maximum length, in bytes, of a domain name represented as an escaped C-String */
-/* including the final trailing dot, and the C-String terminating NULL at the end */
-
-#define kDNSServiceMaxDomainName 1005
-
-/*
- * Notes on DNS Name Escaping
- *   -- or --
- * "Why is kDNSServiceMaxDomainName 1005, when the maximum legal domain name is 255 bytes?"
- *
- * All strings used in DNS-SD are UTF-8 strings.
- * With few exceptions, most are also escaped using standard DNS escaping rules:
- *
- *   '\\' represents a single literal '\' in the name
- *   '\.' represents a single literal '.' in the name
- *   '\ddd', where ddd is a three-digit decimal value from 000 to 255,
- *        represents a single literal byte with that value.
- *   A bare unescaped '.' is a label separator, marking a boundary between domain and subdomain.
- *
- * The exceptions, that do not use escaping, are the routines where the full
- * DNS name of a resource is broken, for convenience, into servicename/regtype/domain.
- * In these routines, the "servicename" is NOT escaped. It does not need to be, since
- * it is, by definition, just a single literal string. Any characters in that string
- * represent exactly what they are. The "regtype" portion is, technically speaking,
- * escaped, but since legal regtypes are only allowed to contain letters, digits,
- * and hyphens, the issue is moot. The "domain" portion is also escaped, though
- * most domains in use on the public Internet today, like regtypes, don't contain
- * any characters that need to be escaped. As DNS-SD becomes more popular, rich-text
- * domains for service discovery will become common, so software should be written
- * to cope with domains with escaping.
- *
- * For most software, these issues are transparent. When browsing, the discovered
- * servicenames should simply be displayed as-is. When resolving, the discovered
- * servicename/regtype/domain are simply passed unchanged to DNSServiceResolve().
- * When a DNSServiceResolve() succeeds, the returned fullname is already in
- * the correct format to pass to standard system DNS APIs such as res_query().
- * For converting from servicename/regtype/domain to a single properly-escaped
- * full DNS name, the helper function DNSServiceConstructFullName() is provided.
- *
- * The following (highly contrived) example illustrates the escaping process.
- * Suppose you have an service called "Dr. Smith\Dr. Johnson", of type "_ftp._tcp"
- * in subdomain "4th. Floor" of subdomain "Building 2" of domain "apple.com."
- * The full (escaped) DNS name of this service's SRV record would be:
- * Dr\.\032Smith\\Dr\.\032Johnson._ftp._tcp.4th\.\032Floor.Building\0322.apple.com.
- */
-
-
-/* 
- * Constants for specifying an interface index
- *
- * Specific interface indexes are identified via a 32-bit unsigned integer returned
- * by the if_nametoindex() family of calls.
- * 
- * If the client passes 0 for interface index, that means "do the right thing",
- * which (at present) means, "if the name is in an mDNS local multicast domain
- * (e.g. 'local.', '254.169.in-addr.arpa.', '0.8.E.F.ip6.arpa.') then multicast
- * on all applicable interfaces, otherwise send via unicast to the appropriate
- * DNS server." Normally, most clients will use 0 for interface index to
- * automatically get the default sensible behaviour.
- * 
- * If the client passes a positive interface index, then for multicast names that
- * indicates to do the operation only on that one interface. For unicast names the
- * interface index is ignored unless kDNSServiceFlagsForceMulticast is also set.
- * 
- * If the client passes kDNSServiceInterfaceIndexLocalOnly when registering
- * a service, then that service will be found *only* by other local clients
- * on the same machine that are browsing using kDNSServiceInterfaceIndexLocalOnly
- * or kDNSServiceInterfaceIndexAny.
- * If a client has a 'private' service, accessible only to other processes
- * running on the same machine, this allows the client to advertise that service
- * in a way such that it does not inadvertently appear in service lists on
- * all the other machines on the network.
- * 
- * If the client passes kDNSServiceInterfaceIndexLocalOnly when browsing
- * then it will find *all* records registered on that same local machine.
- * Clients explicitly wishing to discover *only* LocalOnly services can
- * accomplish this by inspecting the interfaceIndex of each service reported
- * to their DNSServiceBrowseReply() callback function, and discarding those
- * where the interface index is not kDNSServiceInterfaceIndexLocalOnly.
- */
-
-#define kDNSServiceInterfaceIndexAny 0
-#define kDNSServiceInterfaceIndexLocalOnly ( (uint32_t) -1 )
-
-
-typedef uint32_t DNSServiceFlags;
-typedef int32_t DNSServiceErrorType;
-
-
-/*********************************************************************************************
- *
- * Unix Domain Socket access, DNSServiceRef deallocation, and data processing functions
- *
- *********************************************************************************************/
-
-
-/* DNSServiceRefSockFD()
- *
- * Access underlying Unix domain socket for an initialized DNSServiceRef.
- * The DNS Service Discovery implmementation uses this socket to communicate between
- * the client and the mDNSResponder daemon.  The application MUST NOT directly read from
- * or write to this socket.  Access to the socket is provided so that it can be used as a
- * run loop source, or in a select() loop: when data is available for reading on the socket,
- * DNSServiceProcessResult() should be called, which will extract the daemon's reply from
- * the socket, and pass it to the appropriate application callback.  By using a run loop or
- * select(), results from the daemon can be processed asynchronously.  Without using these
- * constructs, DNSServiceProcessResult() will block until the response from the daemon arrives.
- * The client is responsible for ensuring that the data on the socket is processed in a timely
- * fashion - the daemon may terminate its connection with a client that does not clear its
- * socket buffer.
- *
- * sdRef:            A DNSServiceRef initialized by any of the DNSService calls.
- *
- * return value:    The DNSServiceRef's underlying socket descriptor, or -1 on
- *                  error.
- */
-
-int DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef);
-
-
-/* DNSServiceProcessResult()
- *
- * Read a reply from the daemon, calling the appropriate application callback.  This call will
- * block until the daemon's response is received.  Use DNSServiceRefSockFD() in
- * conjunction with a run loop or select() to determine the presence of a response from the
- * server before calling this function to process the reply without blocking.  Call this function
- * at any point if it is acceptable to block until the daemon's response arrives.  Note that the
- * client is responsible for ensuring that DNSServiceProcessResult() is called whenever there is
- * a reply from the daemon - the daemon may terminate its connection with a client that does not
- * process the daemon's responses.
- *
- * sdRef:           A DNSServiceRef initialized by any of the DNSService calls
- *                  that take a callback parameter.
- *
- * return value:    Returns kDNSServiceErr_NoError on success, otherwise returns
- *                  an error code indicating the specific failure that occurred.
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceProcessResult(DNSServiceRef sdRef);
-
-
-/* DNSServiceRefDeallocate()
- *
- * Terminate a connection with the daemon and free memory associated with the DNSServiceRef.
- * Any services or records registered with this DNSServiceRef will be deregistered. Any
- * Browse, Resolve, or Query operations called with this reference will be terminated.
- *
- * Note: If the reference's underlying socket is used in a run loop or select() call, it should
- * be removed BEFORE DNSServiceRefDeallocate() is called, as this function closes the reference's
- * socket.
- *
- * Note: If the reference was initialized with DNSServiceCreateConnection(), any DNSRecordRefs
- * created via this reference will be invalidated by this call - the resource records are
- * deregistered, and their DNSRecordRefs may not be used in subsequent functions.  Similarly,
- * if the reference was initialized with DNSServiceRegister, and an extra resource record was
- * added to the service via DNSServiceAddRecord(), the DNSRecordRef created by the Add() call
- * is invalidated when this function is called - the DNSRecordRef may not be used in subsequent
- * functions.
- *
- * Note: This call is to be used only with the DNSServiceRef defined by this API.  It is
- * not compatible with dns_service_discovery_ref objects defined in the legacy Mach-based
- * DNSServiceDiscovery.h API.
- *
- * sdRef:           A DNSServiceRef initialized by any of the DNSService calls.
- *
- */
-
-void DNSSD_API DNSServiceRefDeallocate(DNSServiceRef sdRef);
-
-
-/*********************************************************************************************
- *
- * Domain Enumeration
- *
- *********************************************************************************************/
-
-/* DNSServiceEnumerateDomains()
- *
- * Asynchronously enumerate domains available for browsing and registration.
- *
- * The enumeration MUST be cancelled via DNSServiceRefDeallocate() when no more domains
- * are to be found.
- *
- * Note that the names returned are (like all of DNS-SD) UTF-8 strings,
- * and are escaped using standard DNS escaping rules.
- * (See "Notes on DNS Name Escaping" earlier in this file for more details.)
- * A graphical browser displaying a hierarchical tree-structured view should cut
- * the names at the bare dots to yield individual labels, then de-escape each
- * label according to the escaping rules, and then display the resulting UTF-8 text.
- *
- * DNSServiceDomainEnumReply Callback Parameters:
- *
- * sdRef:           The DNSServiceRef initialized by DNSServiceEnumerateDomains().
- *
- * flags:           Possible values are:
- *                  kDNSServiceFlagsMoreComing
- *                  kDNSServiceFlagsAdd
- *                  kDNSServiceFlagsDefault
- *
- * interfaceIndex:  Specifies the interface on which the domain exists.  (The index for a given
- *                  interface is determined via the if_nametoindex() family of calls.)
- *
- * errorCode:       Will be kDNSServiceErr_NoError (0) on success, otherwise indicates
- *                  the failure that occurred (other parameters are undefined if errorCode is nonzero).
- *
- * replyDomain:     The name of the domain.
- *
- * context:         The context pointer passed to DNSServiceEnumerateDomains.
- *
- */
-
-typedef void (DNSSD_API *DNSServiceDomainEnumReply)
-    (
-    DNSServiceRef                       sdRef,
-    DNSServiceFlags                     flags,
-    uint32_t                            interfaceIndex,
-    DNSServiceErrorType                 errorCode,
-    const char                          *replyDomain,
-    void                                *context
-    );
-
-
-/* DNSServiceEnumerateDomains() Parameters:
- *
- *
- * sdRef:           A pointer to an uninitialized DNSServiceRef. If the call succeeds 
- *                  then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
- *                  and the enumeration operation will run indefinitely until the client
- *                  terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
- *
- * flags:           Possible values are:
- *                  kDNSServiceFlagsBrowseDomains to enumerate domains recommended for browsing.
- *                  kDNSServiceFlagsRegistrationDomains to enumerate domains recommended
- *                  for registration.
- *
- * interfaceIndex:  If non-zero, specifies the interface on which to look for domains.
- *                  (the index for a given interface is determined via the if_nametoindex()
- *                  family of calls.)  Most applications will pass 0 to enumerate domains on
- *                  all interfaces. See "Constants for specifying an interface index" for more details.
- *
- * callBack:        The function to be called when a domain is found or the call asynchronously
- *                  fails.
- *
- * context:         An application context pointer which is passed to the callback function
- *                  (may be NULL).
- *
- * return value:    Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- *                  errors are delivered to the callback), otherwise returns an error code indicating
- *                  the error that occurred (the callback is not invoked and the DNSServiceRef
- *                  is not initialized.)
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceEnumerateDomains
-    (
-    DNSServiceRef                       *sdRef,
-    DNSServiceFlags                     flags,
-    uint32_t                            interfaceIndex,
-    DNSServiceDomainEnumReply           callBack,
-    void                                *context  /* may be NULL */
-    );
-
-
-/*********************************************************************************************
- *
- *  Service Registration
- *
- *********************************************************************************************/
-
-/* Register a service that is discovered via Browse() and Resolve() calls.
- *
- *
- * DNSServiceRegisterReply() Callback Parameters:
- *
- * sdRef:           The DNSServiceRef initialized by DNSServiceRegister().
- *
- * flags:           Currently unused, reserved for future use.
- *
- * errorCode:       Will be kDNSServiceErr_NoError on success, otherwise will
- *                  indicate the failure that occurred (including name conflicts, if the
- *                  kDNSServiceFlagsNoAutoRename flag was passed to the
- *                  callout.)  Other parameters are undefined if errorCode is nonzero.
- *
- * name:            The service name registered (if the application did not specify a name in
- *                  DNSServiceRegister(), this indicates what name was automatically chosen).
- *
- * regtype:         The type of service registered, as it was passed to the callout.
- *
- * domain:          The domain on which the service was registered (if the application did not
- *                  specify a domain in DNSServiceRegister(), this indicates the default domain
- *                  on which the service was registered).
- *
- * context:         The context pointer that was passed to the callout.
- *
- */
-
-typedef void (DNSSD_API *DNSServiceRegisterReply)
-    (
-    DNSServiceRef                       sdRef,
-    DNSServiceFlags                     flags,
-    DNSServiceErrorType                 errorCode,
-    const char                          *name,
-    const char                          *regtype,
-    const char                          *domain,
-    void                                *context
-    );
-
-
-/* DNSServiceRegister()  Parameters:
- *
- * sdRef:           A pointer to an uninitialized DNSServiceRef. If the call succeeds 
- *                  then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
- *                  and the registration will remain active indefinitely until the client
- *                  terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
- *
- * interfaceIndex:  If non-zero, specifies the interface on which to register the service
- *                  (the index for a given interface is determined via the if_nametoindex()
- *                  family of calls.)  Most applications will pass 0 to register on all
- *                  available interfaces. See "Constants for specifying an interface index" for more details.
- *
- * flags:           Indicates the renaming behavior on name conflict (most applications
- *                  will pass 0).  See flag definitions above for details.
- *
- * name:            If non-NULL, specifies the service name to be registered.
- *                  Most applications will not specify a name, in which case the
- *                  computer name is used (this name is communicated to the client via
- *                  the callback).
- *
- * regtype:         The service type followed by the protocol, separated by a dot
- *                  (e.g. "_ftp._tcp").  The transport protocol must be "_tcp" or "_udp".
- *                  New service types should be registered at htp://www.dns-sd.org/ServiceTypes.html.
- *
- * domain:          If non-NULL, specifies the domain on which to advertise the service.
- *                  Most applications will not specify a domain, instead automatically
- *                  registering in the default domain(s).
- *
- * host:            If non-NULL, specifies the SRV target host name.  Most applications
- *                  will not specify a host, instead automatically using the machine's
- *                  default host name(s).  Note that specifying a non-NULL host does NOT
- *                  create an address record for that host - the application is responsible
- *                  for ensuring that the appropriate address record exists, or creating it
- *                  via DNSServiceRegisterRecord().
- *
- * port:            The port, in network byte order, on which the service accepts connections.
- *                  Pass 0 for a "placeholder" service (i.e. a service that will not be discovered
- *                  by browsing, but will cause a name conflict if another client tries to
- *                  register that same name).  Most clients will not use placeholder services.
- *
- * txtLen:          The length of the txtRecord, in bytes.  Must be zero if the txtRecord is NULL.
- *
- * txtRecord:       The txt record rdata.  May be NULL.  Note that a non-NULL txtRecord
- *                  MUST be a properly formatted DNS TXT record, i.e. <length byte> <data>
- *                  <length byte> <data> ...
- *
- * callBack:        The function to be called when the registration completes or asynchronously
- *                  fails.  The client MAY pass NULL for the callback -  The client will NOT be notified
- *                  of the default values picked on its behalf, and the client will NOT be notified of any
- *                  asynchronous errors (e.g. out of memory errors, etc.) that may prevent the registration
- *                  of the service.  The client may NOT pass the NoAutoRename flag if the callback is NULL.
- *                  The client may still deregister the service at any time via DNSServiceRefDeallocate().
- *
- * context:         An application context pointer which is passed to the callback function
- *                  (may be NULL).
- *
- * return value:    Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- *                  errors are delivered to the callback), otherwise returns an error code indicating
- *                  the error that occurred (the callback is never invoked and the DNSServiceRef
- *                  is not initialized.)
- *
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceRegister
-    (
-    DNSServiceRef                       *sdRef,
-    DNSServiceFlags                     flags,
-    uint32_t                            interfaceIndex,
-    const char                          *name,         /* may be NULL */
-    const char                          *regtype,
-    const char                          *domain,       /* may be NULL */
-    const char                          *host,         /* may be NULL */
-    uint16_t                            port,
-    uint16_t                            txtLen,
-    const void                          *txtRecord,    /* may be NULL */
-    DNSServiceRegisterReply             callBack,      /* may be NULL */
-    void                                *context       /* may be NULL */
-    );
-
-
-/* DNSServiceAddRecord()
- *
- * Add a record to a registered service.  The name of the record will be the same as the
- * registered service's name.
- * The record can later be updated or deregistered by passing the RecordRef initialized
- * by this function to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
- *
- *
- * Parameters;
- *
- * sdRef:           A DNSServiceRef initialized by DNSServiceRegister().
- *
- * RecordRef:       A pointer to an uninitialized DNSRecordRef.  Upon succesfull completion of this
- *                  call, this ref may be passed to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
- *                  If the above DNSServiceRef is passed to DNSServiceRefDeallocate(), RecordRef is also
- *                  invalidated and may not be used further.
- *
- * flags:           Currently ignored, reserved for future use.
- *
- * rrtype:          The type of the record (e.g. kDNSServiceType_TXT, kDNSServiceType_SRV, etc)
- *
- * rdlen:           The length, in bytes, of the rdata.
- *
- * rdata:           The raw rdata to be contained in the added resource record.
- *
- * ttl:             The time to live of the resource record, in seconds.  Pass 0 to use a default value.
- *
- * return value:    Returns kDNSServiceErr_NoError on success, otherwise returns an
- *                  error code indicating the error that occurred (the RecordRef is not initialized).
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceAddRecord
-    (
-    DNSServiceRef                       sdRef,
-    DNSRecordRef                        *RecordRef,
-    DNSServiceFlags                     flags,
-    uint16_t                            rrtype,
-    uint16_t                            rdlen,
-    const void                          *rdata,
-    uint32_t                            ttl
-    );
-
-
-/* DNSServiceUpdateRecord
- *
- * Update a registered resource record.  The record must either be:
- *   - The primary txt record of a service registered via DNSServiceRegister()
- *   - A record added to a registered service via DNSServiceAddRecord()
- *   - An individual record registered by DNSServiceRegisterRecord()
- *
- *
- * Parameters:
- *
- * sdRef:           A DNSServiceRef that was initialized by DNSServiceRegister()
- *                  or DNSServiceCreateConnection().
- *
- * RecordRef:       A DNSRecordRef initialized by DNSServiceAddRecord, or NULL to update the
- *                  service's primary txt record.
- *
- * flags:           Currently ignored, reserved for future use.
- *
- * rdlen:           The length, in bytes, of the new rdata.
- *
- * rdata:           The new rdata to be contained in the updated resource record.
- *
- * ttl:             The time to live of the updated resource record, in seconds.
- *
- * return value:    Returns kDNSServiceErr_NoError on success, otherwise returns an
- *                  error code indicating the error that occurred.
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceUpdateRecord
-    (
-    DNSServiceRef                       sdRef,
-    DNSRecordRef                        RecordRef,     /* may be NULL */
-    DNSServiceFlags                     flags,
-    uint16_t                            rdlen,
-    const void                          *rdata,
-    uint32_t                            ttl
-    );
-
-
-/* DNSServiceRemoveRecord
- *
- * Remove a record previously added to a service record set via DNSServiceAddRecord(), or deregister
- * an record registered individually via DNSServiceRegisterRecord().
- *
- * Parameters:
- *
- * sdRef:           A DNSServiceRef initialized by DNSServiceRegister() (if the
- *                  record being removed was registered via DNSServiceAddRecord()) or by
- *                  DNSServiceCreateConnection() (if the record being removed was registered via
- *                  DNSServiceRegisterRecord()).
- *
- * recordRef:       A DNSRecordRef initialized by a successful call to DNSServiceAddRecord()
- *                  or DNSServiceRegisterRecord().
- *
- * flags:           Currently ignored, reserved for future use.
- *
- * return value:    Returns kDNSServiceErr_NoError on success, otherwise returns an
- *                  error code indicating the error that occurred.
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceRemoveRecord
-    (
-    DNSServiceRef                 sdRef,
-    DNSRecordRef                  RecordRef,
-    DNSServiceFlags               flags
-    );
-
-
-/*********************************************************************************************
- *
- *  Service Discovery
- *
- *********************************************************************************************/
-
-/* Browse for instances of a service.
- *
- *
- * DNSServiceBrowseReply() Parameters:
- *
- * sdRef:           The DNSServiceRef initialized by DNSServiceBrowse().
- *
- * flags:           Possible values are kDNSServiceFlagsMoreComing and kDNSServiceFlagsAdd.
- *                  See flag definitions for details.
- *
- * interfaceIndex:  The interface on which the service is advertised.  This index should
- *                  be passed to DNSServiceResolve() when resolving the service.
- *
- * errorCode:       Will be kDNSServiceErr_NoError (0) on success, otherwise will
- *                  indicate the failure that occurred.  Other parameters are undefined if
- *                  the errorCode is nonzero.
- *
- * serviceName:     The discovered service name. This name should be displayed to the user,
- *                  and stored for subsequent use in the DNSServiceResolve() call.
- *
- * regtype:         The service type, which is usually (but not always) the same as was passed
- *                  to DNSServiceBrowse(). One case where the discovered service type may
- *                  not be the same as the requested service type is when using subtypes:
- *                  The client may want to browse for only those ftp servers that allow
- *                  anonymous connections. The client will pass the string "_ftp._tcp,_anon"
- *                  to DNSServiceBrowse(), but the type of the service that's discovered
- *                  is simply "_ftp._tcp". The regtype for each discovered service instance
- *                  should be stored along with the name, so that it can be passed to
- *                  DNSServiceResolve() when the service is later resolved.
- *
- * domain:          The domain of the discovered service instance. This may or may not be the
- *                  same as the domain that was passed to DNSServiceBrowse(). The domain for each
- *                  discovered service instance should be stored along with the name, so that
- *                  it can be passed to DNSServiceResolve() when the service is later resolved.
- *
- * context:         The context pointer that was passed to the callout.
- *
- */
-
-typedef void (DNSSD_API *DNSServiceBrowseReply)
-    (
-    DNSServiceRef                       sdRef,
-    DNSServiceFlags                     flags,
-    uint32_t                            interfaceIndex,
-    DNSServiceErrorType                 errorCode,
-    const char                          *serviceName,
-    const char                          *regtype,
-    const char                          *replyDomain,
-    void                                *context
-    );
-
-
-/* DNSServiceBrowse() Parameters:
- *
- * sdRef:           A pointer to an uninitialized DNSServiceRef. If the call succeeds 
- *                  then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
- *                  and the browse operation will run indefinitely until the client
- *                  terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
- *
- * flags:           Currently ignored, reserved for future use.
- *
- * interfaceIndex:  If non-zero, specifies the interface on which to browse for services
- *                  (the index for a given interface is determined via the if_nametoindex()
- *                  family of calls.)  Most applications will pass 0 to browse on all available
- *                  interfaces. See "Constants for specifying an interface index" for more details.
- *
- * regtype:         The service type being browsed for followed by the protocol, separated by a
- *                  dot (e.g. "_ftp._tcp").  The transport protocol must be "_tcp" or "_udp".
- *
- * domain:          If non-NULL, specifies the domain on which to browse for services.
- *                  Most applications will not specify a domain, instead browsing on the
- *                  default domain(s).
- *
- * callBack:        The function to be called when an instance of the service being browsed for
- *                  is found, or if the call asynchronously fails.
- *
- * context:         An application context pointer which is passed to the callback function
- *                  (may be NULL).
- *
- * return value:    Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- *                  errors are delivered to the callback), otherwise returns an error code indicating
- *                  the error that occurred (the callback is not invoked and the DNSServiceRef
- *                  is not initialized.)
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceBrowse
-    (
-    DNSServiceRef                       *sdRef,
-    DNSServiceFlags                     flags,
-    uint32_t                            interfaceIndex,
-    const char                          *regtype,
-    const char                          *domain,    /* may be NULL */
-    DNSServiceBrowseReply               callBack,
-    void                                *context    /* may be NULL */
-    );
-
-
-/* DNSServiceResolve()
- *
- * Resolve a service name discovered via DNSServiceBrowse() to a target host name, port number, and
- * txt record.
- *
- * Note: Applications should NOT use DNSServiceResolve() solely for txt record monitoring - use
- * DNSServiceQueryRecord() instead, as it is more efficient for this task.
- *
- * Note: When the desired results have been returned, the client MUST terminate the resolve by calling
- * DNSServiceRefDeallocate().
- *
- * Note: DNSServiceResolve() behaves correctly for typical services that have a single SRV record and
- * a single TXT record (the TXT record may be empty.)  To resolve non-standard services with multiple
- * SRV or TXT records, DNSServiceQueryRecord() should be used.
- *
- * DNSServiceResolveReply Callback Parameters:
- *
- * sdRef:           The DNSServiceRef initialized by DNSServiceResolve().
- *
- * flags:           Currently unused, reserved for future use.
- *
- * interfaceIndex:  The interface on which the service was resolved.
- *
- * errorCode:       Will be kDNSServiceErr_NoError (0) on success, otherwise will
- *                  indicate the failure that occurred.  Other parameters are undefined if
- *                  the errorCode is nonzero.
- *
- * fullname:        The full service domain name, in the form <servicename>.<protocol>.<domain>.
- *                  (This name is escaped following standard DNS rules, making it suitable for
- *                  passing to standard system DNS APIs such as res_query(), or to the
- *                  special-purpose functions included in this API that take fullname parameters.
- *                  See "Notes on DNS Name Escaping" earlier in this file for more details.)
- *
- * hosttarget:      The target hostname of the machine providing the service.  This name can
- *                  be passed to functions like gethostbyname() to identify the host's IP address.
- *
- * port:            The port, in network byte order, on which connections are accepted for this service.
- *
- * txtLen:          The length of the txt record, in bytes.
- *
- * txtRecord:       The service's primary txt record, in standard txt record format.
- *
-
- * context:         The context pointer that was passed to the callout.
- *
- */
-
-typedef void (DNSSD_API *DNSServiceResolveReply)
-    (
-    DNSServiceRef                       sdRef,
-    DNSServiceFlags                     flags,
-    uint32_t                            interfaceIndex,
-    DNSServiceErrorType                 errorCode,
-    const char                          *fullname,
-    const char                          *hosttarget,
-    uint16_t                            port,
-    uint16_t                            txtLen,
-    const char                          *txtRecord,
-    void                                *context
-    );
-
-
-/* DNSServiceResolve() Parameters
- *
- * sdRef:           A pointer to an uninitialized DNSServiceRef. If the call succeeds 
- *                  then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
- *                  and the resolve operation will run indefinitely until the client
- *                  terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
- *
- * flags:           Currently ignored, reserved for future use.
- *
- * interfaceIndex:  The interface on which to resolve the service. If this resolve call is
- *                  as a result of a currently active DNSServiceBrowse() operation, then the
- *                  interfaceIndex should be the index reported in the DNSServiceBrowseReply
- *                  callback. If this resolve call is using information previously saved
- *                  (e.g. in a preference file) for later use, then use interfaceIndex 0, because
- *                  the desired service may now be reachable via a different physical interface.
- *                  See "Constants for specifying an interface index" for more details.
- *
- * name:            The name of the service instance to be resolved, as reported to the
- *                  DNSServiceBrowseReply() callback.
- *
- * regtype:         The type of the service instance to be resolved, as reported to the
- *                  DNSServiceBrowseReply() callback.
- *
- * domain:          The domain of the service instance to be resolved, as reported to the
- *                  DNSServiceBrowseReply() callback.
- *
- * callBack:        The function to be called when a result is found, or if the call
- *                  asynchronously fails.
- *
- * context:         An application context pointer which is passed to the callback function
- *                  (may be NULL).
- *
- * return value:    Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- *                  errors are delivered to the callback), otherwise returns an error code indicating
- *                  the error that occurred (the callback is never invoked and the DNSServiceRef
- *                  is not initialized.)
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceResolve
-    (
-    DNSServiceRef                       *sdRef,
-    DNSServiceFlags                     flags,
-    uint32_t                            interfaceIndex,
-    const char                          *name,
-    const char                          *regtype,
-    const char                          *domain,
-    DNSServiceResolveReply              callBack,
-    void                                *context  /* may be NULL */
-    );
-
-
-/*********************************************************************************************
- *
- *  Special Purpose Calls (most applications will not use these)
- *
- *********************************************************************************************/
-
-/* DNSServiceCreateConnection()
- *
- * Create a connection to the daemon allowing efficient registration of
- * multiple individual records.
- *
- *
- * Parameters:
- *
- * sdRef:           A pointer to an uninitialized DNSServiceRef.  Deallocating
- *                  the reference (via DNSServiceRefDeallocate()) severs the
- *                  connection and deregisters all records registered on this connection.
- *
- * return value:    Returns kDNSServiceErr_NoError on success, otherwise returns
- *                  an error code indicating the specific failure that occurred (in which
- *                  case the DNSServiceRef is not initialized).
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceCreateConnection(DNSServiceRef *sdRef);
-
-
-/* DNSServiceRegisterRecord
- *
- * Register an individual resource record on a connected DNSServiceRef.
- *
- * Note that name conflicts occurring for records registered via this call must be handled
- * by the client in the callback.
- *
- *
- * DNSServiceRegisterRecordReply() parameters:
- *
- * sdRef:           The connected DNSServiceRef initialized by
- *                  DNSServiceDiscoveryConnect().
- *
- * RecordRef:       The DNSRecordRef initialized by DNSServiceRegisterRecord().  If the above
- *                  DNSServiceRef is passed to DNSServiceRefDeallocate(), this DNSRecordRef is
- *                  invalidated, and may not be used further.
- *
- * flags:           Currently unused, reserved for future use.
- *
- * errorCode:       Will be kDNSServiceErr_NoError on success, otherwise will
- *                  indicate the failure that occurred (including name conflicts.)
- *                  Other parameters are undefined if errorCode is nonzero.
- *
- * context:         The context pointer that was passed to the callout.
- *
- */
-
- typedef void (DNSSD_API *DNSServiceRegisterRecordReply)
-    (
-    DNSServiceRef                       sdRef,
-    DNSRecordRef                        RecordRef,
-    DNSServiceFlags                     flags,
-    DNSServiceErrorType                 errorCode,
-    void                                *context
-    );
-
-
-/* DNSServiceRegisterRecord() Parameters:
- *
- * sdRef:           A DNSServiceRef initialized by DNSServiceCreateConnection().
- *
- * RecordRef:       A pointer to an uninitialized DNSRecordRef.  Upon succesfull completion of this
- *                  call, this ref may be passed to DNSServiceUpdateRecord() or DNSServiceRemoveRecord().
- *                  (To deregister ALL records registered on a single connected DNSServiceRef
- *                  and deallocate each of their corresponding DNSServiceRecordRefs, call
- *                  DNSServiceRefDealloocate()).
- *
- * flags:           Possible values are kDNSServiceFlagsShared or kDNSServiceFlagsUnique
- *                  (see flag type definitions for details).
- *
- * interfaceIndex:  If non-zero, specifies the interface on which to register the record
- *                  (the index for a given interface is determined via the if_nametoindex()
- *                  family of calls.)  Passing 0 causes the record to be registered on all interfaces.
- *                  See "Constants for specifying an interface index" for more details.
- *
- * fullname:        The full domain name of the resource record.
- *
- * rrtype:          The numerical type of the resource record (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
- *
- * rrclass:         The class of the resource record (usually kDNSServiceClass_IN)
- *
- * rdlen:           Length, in bytes, of the rdata.
- *
- * rdata:           A pointer to the raw rdata, as it is to appear in the DNS record.
- *
- * ttl:             The time to live of the resource record, in seconds.  Pass 0 to use a default value.
- *
- * callBack:        The function to be called when a result is found, or if the call
- *                  asynchronously fails (e.g. because of a name conflict.)
- *
- * context:         An application context pointer which is passed to the callback function
- *                  (may be NULL).
- *
- * return value:    Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- *                  errors are delivered to the callback), otherwise returns an error code indicating
- *                  the error that occurred (the callback is never invoked and the DNSRecordRef is
- *                  not initialized.)
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceRegisterRecord
-    (
-    DNSServiceRef                       sdRef,
-    DNSRecordRef                        *RecordRef,
-    DNSServiceFlags                     flags,
-    uint32_t                            interfaceIndex,
-    const char                          *fullname,
-    uint16_t                            rrtype,
-    uint16_t                            rrclass,
-    uint16_t                            rdlen,
-    const void                          *rdata,
-    uint32_t                            ttl,
-    DNSServiceRegisterRecordReply       callBack,
-    void                                *context    /* may be NULL */
-    );
-
-
-/* DNSServiceQueryRecord
- *
- * Query for an arbitrary DNS record.
- *
- *
- * DNSServiceQueryRecordReply() Callback Parameters:
- *
- * sdRef:           The DNSServiceRef initialized by DNSServiceQueryRecord().
- *
- * flags:           Possible values are kDNSServiceFlagsMoreComing and
- *                  kDNSServiceFlagsAdd.  The Add flag is NOT set for PTR records
- *                  with a ttl of 0, i.e. "Remove" events.
- *
- * interfaceIndex:  The interface on which the query was resolved (the index for a given
- *                  interface is determined via the if_nametoindex() family of calls).
- *                  See "Constants for specifying an interface index" for more details.
- *
- * errorCode:       Will be kDNSServiceErr_NoError on success, otherwise will
- *                  indicate the failure that occurred.  Other parameters are undefined if
- *                  errorCode is nonzero.
- *
- * fullname:        The resource record's full domain name.
- *
- * rrtype:          The resource record's type (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
- *
- * rrclass:         The class of the resource record (usually kDNSServiceClass_IN).
- *
- * rdlen:           The length, in bytes, of the resource record rdata.
- *
- * rdata:           The raw rdata of the resource record.
- *
- * ttl:             The resource record's time to live, in seconds.
- *
- * context:         The context pointer that was passed to the callout.
- *
- */
-
-typedef void (DNSSD_API *DNSServiceQueryRecordReply)
-    (
-    DNSServiceRef                       DNSServiceRef,
-    DNSServiceFlags                     flags,
-    uint32_t                            interfaceIndex,
-    DNSServiceErrorType                 errorCode,
-    const char                          *fullname,
-    uint16_t                            rrtype,
-    uint16_t                            rrclass,
-    uint16_t                            rdlen,
-    const void                          *rdata,
-    uint32_t                            ttl,
-    void                                *context
-    );
-
-
-/* DNSServiceQueryRecord() Parameters:
- *
- * sdRef:           A pointer to an uninitialized DNSServiceRef. If the call succeeds 
- *                  then it initializes the DNSServiceRef, returns kDNSServiceErr_NoError,
- *                  and the query operation will run indefinitely until the client
- *                  terminates it by passing this DNSServiceRef to DNSServiceRefDeallocate().
- *
- * flags:           Pass kDNSServiceFlagsLongLivedQuery to create a "long-lived" unicast
- *                  query in a non-local domain.  Without setting this flag, unicast queries
- *                  will be one-shot - that is, only answers available at the time of the call
- *                  will be returned.  By setting this flag, answers (including Add and Remove
- *                  events) that become available after the initial call is made will generate
- *                  callbacks.  This flag has no effect on link-local multicast queries.
- *
- * interfaceIndex:  If non-zero, specifies the interface on which to issue the query
- *                  (the index for a given interface is determined via the if_nametoindex()
- *                  family of calls.)  Passing 0 causes the name to be queried for on all
- *                  interfaces. See "Constants for specifying an interface index" for more details.
- *
- * fullname:        The full domain name of the resource record to be queried for.
- *
- * rrtype:          The numerical type of the resource record to be queried for
- *                  (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
- *
- * rrclass:         The class of the resource record (usually kDNSServiceClass_IN).
- *
- * callBack:        The function to be called when a result is found, or if the call
- *                  asynchronously fails.
- *
- * context:         An application context pointer which is passed to the callback function
- *                  (may be NULL).
- *
- * return value:    Returns kDNSServiceErr_NoError on succeses (any subsequent, asynchronous
- *                  errors are delivered to the callback), otherwise returns an error code indicating
- *                  the error that occurred (the callback is never invoked and the DNSServiceRef
- *                  is not initialized.)
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
-    (
-    DNSServiceRef                       *sdRef,
-    DNSServiceFlags                     flags,
-    uint32_t                            interfaceIndex,
-    const char                          *fullname,
-    uint16_t                            rrtype,
-    uint16_t                            rrclass,
-    DNSServiceQueryRecordReply          callBack,
-    void                                *context  /* may be NULL */
-    );
-
-
-/* DNSServiceReconfirmRecord
- *
- * Instruct the daemon to verify the validity of a resource record that appears to
- * be out of date (e.g. because tcp connection to a service's target failed.)
- * Causes the record to be flushed from the daemon's cache (as well as all other
- * daemons' caches on the network) if the record is determined to be invalid.
- *
- * Parameters:
- *
- * flags:           Currently unused, reserved for future use.
- *
- * interfaceIndex:  If non-zero, specifies the interface of the record in question.
- *                  Passing 0 causes all instances of this record to be reconfirmed.
- *
- * fullname:        The resource record's full domain name.
- *
- * rrtype:          The resource record's type (e.g. kDNSServiceType_PTR, kDNSServiceType_SRV, etc)
- *
- * rrclass:         The class of the resource record (usually kDNSServiceClass_IN).
- *
- * rdlen:           The length, in bytes, of the resource record rdata.
- *
- * rdata:           The raw rdata of the resource record.
- *
- */
-
-void DNSSD_API DNSServiceReconfirmRecord
-    (
-    DNSServiceFlags                    flags,
-    uint32_t                           interfaceIndex,
-    const char                         *fullname,
-    uint16_t                           rrtype,
-    uint16_t                           rrclass,
-    uint16_t                           rdlen,
-    const void                         *rdata
-    );
-
-
-/*********************************************************************************************
- *
- *  General Utility Functions
- *
- *********************************************************************************************/
-
-/* DNSServiceConstructFullName()
- *
- * Concatenate a three-part domain name (as returned by the above callbacks) into a
- * properly-escaped full domain name. Note that callbacks in the above functions ALREADY ESCAPE
- * strings where necessary.
- *
- * Parameters:
- *
- * fullName:        A pointer to a buffer that where the resulting full domain name is to be written.
- *                  The buffer must be kDNSServiceMaxDomainName (1005) bytes in length to
- *                  accommodate the longest legal domain name without buffer overrun.
- *
- * service:         The service name - any dots or slashes must NOT be escaped.
- *                  May be NULL (to construct a PTR record name, e.g.
- *                  "_ftp._tcp.apple.com").
- *
- * regtype:         The service type followed by the protocol, separated by a dot
- *                  (e.g. "_ftp._tcp").
- *
- * domain:          The domain name, e.g. "apple.com.".  Literal dots or backslashes,
- *                  if any, must be escaped, e.g. "1st\. Floor.apple.com."
- *
- * return value:    Returns 0 on success, -1 on error.
- *
- */
-
-int DNSSD_API DNSServiceConstructFullName
-    (
-    char                            *fullName,
-    const char                      *service,      /* may be NULL */
-    const char                      *regtype,
-    const char                      *domain
-    );
-
-
-/*********************************************************************************************
- *
- *   TXT Record Construction Functions
- *
- *********************************************************************************************/
-
-/*
- * A typical calling sequence for TXT record construction is something like:
- *
- * Client allocates storage for TXTRecord data (e.g. declare buffer on the stack)
- * TXTRecordCreate();
- * TXTRecordSetValue();
- * TXTRecordSetValue();
- * TXTRecordSetValue();
- * ...
- * DNSServiceRegister( ... TXTRecordGetLength(), TXTRecordGetBytesPtr() ... );
- * TXTRecordDeallocate();
- * Explicitly deallocate storage for TXTRecord data (if not allocated on the stack)
- */
-
-
-/* TXTRecordRef
- *
- * Opaque internal data type.
- * Note: Represents a DNS-SD TXT record.
- */
-
-typedef struct _TXTRecordRef_t { char privatedata[16]; } TXTRecordRef;
-
-
-/* TXTRecordCreate()
- *
- * Creates a new empty TXTRecordRef referencing the specified storage.
- *
- * If the buffer parameter is NULL, or the specified storage size is not
- * large enough to hold a key subsequently added using TXTRecordSetValue(),
- * then additional memory will be added as needed using malloc().
- *
- * On some platforms, when memory is low, malloc() may fail. In this
- * case, TXTRecordSetValue() will return kDNSServiceErr_NoMemory, and this
- * error condition will need to be handled as appropriate by the caller.
- *
- * You can avoid the need to handle this error condition if you ensure
- * that the storage you initially provide is large enough to hold all
- * the key/value pairs that are to be added to the record.
- * The caller can precompute the exact length required for all of the
- * key/value pairs to be added, or simply provide a fixed-sized buffer
- * known in advance to be large enough.
- * A no-value (key-only) key requires  (1 + key length) bytes.
- * A key with empty value requires     (1 + key length + 1) bytes.
- * A key with non-empty value requires (1 + key length + 1 + value length).
- * For most applications, DNS-SD TXT records are generally
- * less than 100 bytes, so in most cases a simple fixed-sized
- * 256-byte buffer will be more than sufficient.
- * Recommended size limits for DNS-SD TXT Records are discussed in
- * <http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt>
- *
- * Note: When passing parameters to and from these TXT record APIs,
- * the key name does not include the '=' character. The '=' character
- * is the separator between the key and value in the on-the-wire
- * packet format; it is not part of either the key or the value.
- *
- * txtRecord:       A pointer to an uninitialized TXTRecordRef.
- *
- * bufferLen:       The size of the storage provided in the "buffer" parameter.
- *
- * buffer:          The storage used to hold the TXTRecord data.
- *                  This storage must remain valid for as long as
- *                  the TXTRecordRef.
- */
-
-void DNSSD_API TXTRecordCreate
-    (
-    TXTRecordRef     *txtRecord,
-    uint16_t         bufferLen,
-    void             *buffer
-    );
-
-
-/* TXTRecordDeallocate()
- *
- * Releases any resources allocated in the course of preparing a TXT Record
- * using TXTRecordCreate()/TXTRecordSetValue()/TXTRecordRemoveValue().
- * Ownership of the buffer provided in TXTRecordCreate() returns to the client.
- *
- * txtRecord:           A TXTRecordRef initialized by calling TXTRecordCreate().
- *
- */
-
-void DNSSD_API TXTRecordDeallocate
-    (
-    TXTRecordRef     *txtRecord
-    );
-
-
-/* TXTRecordSetValue()
- *
- * Adds a key (optionally with value) to a TXTRecordRef. If the "key" already
- * exists in the TXTRecordRef, then the current value will be replaced with
- * the new value.
- * Keys may exist in four states with respect to a given TXT record:
- *  - Absent (key does not appear at all)
- *  - Present with no value ("key" appears alone)
- *  - Present with empty value ("key=" appears in TXT record)
- *  - Present with non-empty value ("key=value" appears in TXT record)
- * For more details refer to "Data Syntax for DNS-SD TXT Records" in
- * <http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt>
- *
- * txtRecord:       A TXTRecordRef initialized by calling TXTRecordCreate().
- *
- * key:             A null-terminated string which only contains printable ASCII
- *                  values (0x20-0x7E), excluding '=' (0x3D). Keys should be
- *                  8 characters or less (not counting the terminating null).
- *
- * valueSize:       The size of the value.
- *
- * value:           Any binary value. For values that represent
- *                  textual data, UTF-8 is STRONGLY recommended.
- *                  For values that represent textual data, valueSize
- *                  should NOT include the terminating null (if any)
- *                  at the end of the string.
- *                  If NULL, then "key" will be added with no value.
- *                  If non-NULL but valueSize is zero, then "key=" will be
- *                  added with empty value.
- *
- * return value:    Returns kDNSServiceErr_NoError on success.
- *                  Returns kDNSServiceErr_Invalid if the "key" string contains
- *                  illegal characters.
- *                  Returns kDNSServiceErr_NoMemory if adding this key would
- *                  exceed the available storage.
- */
-
-DNSServiceErrorType DNSSD_API TXTRecordSetValue
-    (
-    TXTRecordRef     *txtRecord,
-    const char       *key,
-    uint8_t          valueSize,        /* may be zero */
-    const void       *value            /* may be NULL */
-    );
-
-
-/* TXTRecordRemoveValue()
- *
- * Removes a key from a TXTRecordRef.  The "key" must be an
- * ASCII string which exists in the TXTRecordRef.
- *
- * txtRecord:       A TXTRecordRef initialized by calling TXTRecordCreate().
- *
- * key:             A key name which exists in the TXTRecordRef.
- *
- * return value:    Returns kDNSServiceErr_NoError on success.
- *                  Returns kDNSServiceErr_NoSuchKey if the "key" does not
- *                  exist in the TXTRecordRef.
- *
- */
-
-DNSServiceErrorType DNSSD_API TXTRecordRemoveValue
-    (
-    TXTRecordRef     *txtRecord,
-    const char       *key
-    );
-
-
-/* TXTRecordGetLength()
- *
- * Allows you to determine the length of the raw bytes within a TXTRecordRef.
- *
- * txtRecord:       A TXTRecordRef initialized by calling TXTRecordCreate().
- *
- * return value:    Returns the size of the raw bytes inside a TXTRecordRef
- *                  which you can pass directly to DNSServiceRegister() or
- *                  to DNSServiceUpdateRecord().
- *                  Returns 0 if the TXTRecordRef is empty.
- *
- */
-
-uint16_t DNSSD_API TXTRecordGetLength
-    (
-    const TXTRecordRef *txtRecord
-    );
-
-
-/* TXTRecordGetBytesPtr()
- *
- * Allows you to retrieve a pointer to the raw bytes within a TXTRecordRef.
- *
- * txtRecord:       A TXTRecordRef initialized by calling TXTRecordCreate().
- *
- * return value:    Returns a pointer to the raw bytes inside the TXTRecordRef
- *                  which you can pass directly to DNSServiceRegister() or
- *                  to DNSServiceUpdateRecord().
- *
- */
-
-const void * DNSSD_API TXTRecordGetBytesPtr
-    (
-    const TXTRecordRef *txtRecord
-    );
-
-
-/*********************************************************************************************
- *
- *   TXT Record Parsing Functions
- *
- *********************************************************************************************/
-
-/*
- * A typical calling sequence for TXT record parsing is something like:
- *
- * Receive TXT record data in DNSServiceResolve() callback
- * if (TXTRecordContainsKey(txtLen, txtRecord, "key")) then do something
- * val1ptr = TXTRecordGetValuePtr(txtLen, txtRecord, "key1", &len1);
- * val2ptr = TXTRecordGetValuePtr(txtLen, txtRecord, "key2", &len2);
- * ...
- * bcopy(val1ptr, myval1, len1);
- * bcopy(val2ptr, myval2, len2);
- * ...
- * return;
- *
- * If you wish to retain the values after return from the DNSServiceResolve()
- * callback, then you need to copy the data to your own storage using bcopy()
- * or similar, as shown in the example above.
- *
- * If for some reason you need to parse a TXT record you built yourself
- * using the TXT record construction functions above, then you can do
- * that using TXTRecordGetLength and TXTRecordGetBytesPtr calls:
- * TXTRecordGetValue(TXTRecordGetLength(x), TXTRecordGetBytesPtr(x), key, &len);
- *
- * Most applications only fetch keys they know about from a TXT record and
- * ignore the rest.
- * However, some debugging tools wish to fetch and display all keys.
- * To do that, use the TXTRecordGetCount() and TXTRecordGetItemAtIndex() calls.
- */
-
-/* TXTRecordContainsKey()
- *
- * Allows you to determine if a given TXT Record contains a specified key.
- *
- * txtLen:          The size of the received TXT Record.
- *
- * txtRecord:       Pointer to the received TXT Record bytes.
- *
- * key:             A null-terminated ASCII string containing the key name.
- *
- * return value:    Returns 1 if the TXT Record contains the specified key.
- *                  Otherwise, it returns 0.
- *
- */
-
-int DNSSD_API TXTRecordContainsKey
-    (
-    uint16_t         txtLen,
-    const void       *txtRecord,
-    const char       *key
-    );
-
-
-/* TXTRecordGetValuePtr()
- *
- * Allows you to retrieve the value for a given key from a TXT Record.
- *
- * txtLen:          The size of the received TXT Record
- *
- * txtRecord:       Pointer to the received TXT Record bytes.
- *
- * key:             A null-terminated ASCII string containing the key name.
- *
- * valueLen:        On output, will be set to the size of the "value" data.
- *
- * return value:    Returns NULL if the key does not exist in this TXT record,
- *                  or exists with no value (to differentiate between
- *                  these two cases use TXTRecordContainsKey()).
- *                  Returns pointer to location within TXT Record bytes
- *                  if the key exists with empty or non-empty value.
- *                  For empty value, valueLen will be zero.
- *                  For non-empty value, valueLen will be length of value data.
- */
-
-const void * DNSSD_API TXTRecordGetValuePtr
-    (
-    uint16_t         txtLen,
-    const void       *txtRecord,
-    const char       *key,
-    uint8_t          *valueLen
-    );
-
-
-/* TXTRecordGetCount()
- *
- * Returns the number of keys stored in the TXT Record.  The count
- * can be used with TXTRecordGetItemAtIndex() to iterate through the keys.
- *
- * txtLen:          The size of the received TXT Record.
- *
- * txtRecord:       Pointer to the received TXT Record bytes.
- *
- * return value:    Returns the total number of keys in the TXT Record.
- *
- */
-
-uint16_t DNSSD_API TXTRecordGetCount
-    (
-    uint16_t         txtLen,
-    const void       *txtRecord
-    );
-
-
-/* TXTRecordGetItemAtIndex()
- *
- * Allows you to retrieve a key name and value pointer, given an index into
- * a TXT Record.  Legal index values range from zero to TXTRecordGetCount()-1.
- * It's also possible to iterate through keys in a TXT record by simply
- * calling TXTRecordGetItemAtIndex() repeatedly, beginning with index zero
- * and increasing until TXTRecordGetItemAtIndex() returns kDNSServiceErr_Invalid.
- *
- * On return:
- * For keys with no value, *value is set to NULL and *valueLen is zero.
- * For keys with empty value, *value is non-NULL and *valueLen is zero.
- * For keys with non-empty value, *value is non-NULL and *valueLen is non-zero.
- *
- * txtLen:          The size of the received TXT Record.
- *
- * txtRecord:       Pointer to the received TXT Record bytes.
- *
- * index:           An index into the TXT Record.
- *
- * keyBufLen:       The size of the string buffer being supplied.
- *
- * key:             A string buffer used to store the key name.
- *                  On return, the buffer contains a null-terminated C string
- *                  giving the key name. DNS-SD TXT keys are usually
- *                  8 characters or less. To hold the maximum possible
- *                  key name, the buffer should be 256 bytes long.
- *
- * valueLen:        On output, will be set to the size of the "value" data.
- *
- * value:           On output, *value is set to point to location within TXT
- *                  Record bytes that holds the value data.
- *
- * return value:    Returns kDNSServiceErr_NoError on success.
- *                  Returns kDNSServiceErr_NoMemory if keyBufLen is too short.
- *                  Returns kDNSServiceErr_Invalid if index is greater than
- *                  TXTRecordGetCount()-1.
- */
-
-DNSServiceErrorType DNSSD_API TXTRecordGetItemAtIndex
-    (
-    uint16_t         txtLen,
-    const void       *txtRecord,
-    uint16_t         index,
-    uint16_t         keyBufLen,
-    char             *key,
-    uint8_t          *valueLen,
-    const void       **value
-    );
-
-#ifdef __APPLE_API_PRIVATE
-
-/*
- * Mac OS X specific functionality
- * 3rd party clients of this API should not depend on future support or availability of this routine
- */
-/* DNSServiceSetDefaultDomainForUser()
- *
- * Set the default domain for the caller's UID.  Future browse and registration
- * calls by this user that do not specify an explicit domain will browse and
- * register in this wide-area domain in addition to .local.  In addition, this
- * domain will be returned as a Browse domain via domain enumeration calls.
- * 
- *
- * Parameters:
- *
- * flags:           Pass kDNSServiceFlagsAdd to add a domain for a user.  Call without
- *                  this flag set to clear a previously added domain.
- *
- * domain:          The domain to be used for the caller's UID.
- *
- * return value:    Returns kDNSServiceErr_NoError on succeses, otherwise returns
- *                  an error code indicating the error that occurred
- */
-
-DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser
-    (
-    DNSServiceFlags                    flags,
-    const char                         *domain
-    ); 
-       
-#endif //__APPLE_API_PRIVATE
-
-#ifdef  __cplusplus
-    }
-#endif
-
-#endif  /* _DNS_SD_H */
diff --git a/mdns.subproj/dnssd_clientlib.c b/mdns.subproj/dnssd_clientlib.c
deleted file mode 100755 (executable)
index d3c36ad..0000000
+++ /dev/null
@@ -1,361 +0,0 @@
-/*
- * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
-
-   Change History (most recent first):
-
-$Log: dnssd_clientlib.c,v $
-Revision 1.3  2004/09/16 23:45:23  majka
-Integrated 3775315 and 3765280.
-
-Revision 1.2.16.1  2004/09/02 19:43:41  ksekar
-<rdar://problem/3775315>: Sync dns-sd client files between Libinfo and
-mDNSResponder projects
-
-Revision 1.7  2004/06/26 03:16:34  shersche
-clean up warning messages on Win32 platform
-
-Submitted by: herscher
-
-Revision 1.6  2004/06/12 01:09:45  cheshire
-To be callable from the broadest range of clients on Windows (e.g. Visual Basic, C#, etc.)
-API routines have to be declared as "__stdcall", instead of the C default, "__cdecl"
-
-Revision 1.5  2004/05/25 18:29:33  cheshire
-Move DNSServiceConstructFullName() from dnssd_clientstub.c to dnssd_clientlib.c,
-so that it's also accessible to dnssd_clientshim.c (single address space) clients.
-
-Revision 1.4  2004/05/25 17:08:55  cheshire
-Fix compiler warning (doesn't make sense for function return type to be const)
-
-Revision 1.3  2004/05/21 21:41:35  cheshire
-Add TXT record building and parsing APIs
-
-Revision 1.2  2004/05/20 22:22:21  cheshire
-Enable code that was bracketed by "#if 0"
-
-Revision 1.1  2004/03/12 21:30:29  cheshire
-Build a System-Context Shared Library from mDNSCore, for the benefit of developers
-like Muse Research who want to be able to use mDNS/DNS-SD from GPL-licensed code.
-
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "dns_sd.h"
-
-#if MDNS_BUILDINGSHAREDLIBRARY || MDNS_BUILDINGSTUBLIBRARY
-#pragma export on
-#endif
-
-#if defined(_WIN32)
-// disable warning "conversion from <data> to uint16_t"
-#pragma warning(disable:4244)
-#endif
-
-/*********************************************************************************************
- *
- *  Supporting Functions
- *
- *********************************************************************************************/
-
-#define mdnsIsDigit(X)     ((X) >= '0' && (X) <= '9')
-
-static int DomainEndsInDot(const char *dom)
-       {
-       while (dom[0] && dom[1])
-               {
-               if (dom[0] == '\\') // advance past escaped byte sequence
-                       {
-                       if (mdnsIsDigit(dom[1]) && mdnsIsDigit(dom[2]) && mdnsIsDigit(dom[3]))
-                               dom += 4;                       // If "\ddd"    then skip four
-                       else dom += 2;                  // else if "\x" then skip two
-                       }
-               else dom++;                                     // else goto next character
-               }
-       return (dom[0] == '.');
-       }
-
-static uint8_t *InternalTXTRecordSearch
-       (
-       uint16_t         txtLen,
-       const void       *txtRecord,
-       const char       *key,
-       unsigned long    *keylen
-       )
-       {
-       uint8_t *p = (uint8_t*)txtRecord;
-       uint8_t *e = p + txtLen;
-       *keylen = (unsigned long) strlen(key);
-       while (p<e)
-               {
-               uint8_t *x = p;
-               p += 1 + p[0];
-               if (p <= e && *keylen <= x[0] && !strncmp(key, (char*)x+1, *keylen))
-                       if (*keylen == x[0] || x[1+*keylen] == '=') return(x);
-               }
-       return(NULL);
-       }
-
-/*********************************************************************************************
- *
- *  General Utility Functions
- *
- *********************************************************************************************/
-
-int DNSSD_API DNSServiceConstructFullName
-       (
-       char                      *fullName,
-       const char                *service,      /* may be NULL */
-       const char                *regtype,
-       const char                *domain
-       )
-       {
-       unsigned long len;
-       unsigned char c;
-       char *fn = fullName;
-       const char *s = service;
-       const char *r = regtype;
-       const char *d = domain;
-
-       if (service)
-               {
-               while(*s)
-                       {
-                       c = (unsigned char)*s++;
-                       if (c == '.' || (c == '\\')) *fn++ = '\\'; // escape dot and backslash literals
-                       else if (c <= ' ') // escape non-printable characters
-                               {
-                               *fn++ = '\\';
-                               *fn++ = (char) ('0' + (c / 100));
-                               *fn++ = (char) ('0' + (c / 10) % 10);
-                               c = (unsigned char)('0' + (c % 10));
-                               }
-                       *fn++ = (char)c;
-                       }
-               *fn++ = '.';
-               }
-
-       if (!regtype) return -1;
-       len = (unsigned long) strlen(regtype);
-       if (DomainEndsInDot(regtype)) len--;
-       if (len < 6) return -1; // regtype must be at least "x._udp" or "x._tcp"
-       if (strncmp((regtype + len - 4), "_tcp", 4) && strncmp((regtype + len - 4), "_udp", 4)) return -1;
-       while(*r) *fn++ = *r++;
-       if (!DomainEndsInDot(regtype)) *fn++ = '.';
-
-       if (!domain || !domain[0]) return -1;
-       while(*d) *fn++ = *d++;
-       if (!DomainEndsInDot(domain)) *fn++ = '.';
-       *fn = '\0';
-       return 0;
-       }
-
-/*********************************************************************************************
- *
- *   TXT Record Construction Functions
- *
- *********************************************************************************************/
-
-typedef struct _TXTRecordRefRealType
-       {
-       uint8_t  *buffer;               // Pointer to data
-       uint16_t buflen;                // Length of buffer
-       uint16_t datalen;               // Length currently in use
-       uint16_t malloced;      // Non-zero if buffer was allocated via malloc()
-       } TXTRecordRefRealType;
-
-#define txtRec ((TXTRecordRefRealType*)txtRecord)
-
-// The opaque storage defined in the public dns_sd.h header is 16 bytes;
-// make sure we don't exceed that.
-struct dnssd_clientlib_CompileTimeAssertionCheck
-       {
-       char assert0[(sizeof(TXTRecordRefRealType) <= 16) ? 1 : -1];
-       };
-
-void TXTRecordCreate
-       (
-       TXTRecordRef     *txtRecord,
-       uint16_t         bufferLen,
-       void             *buffer
-       )
-       {
-       txtRec->buffer   = buffer;
-       txtRec->buflen   = buffer ? bufferLen : (uint16_t)0;
-       txtRec->datalen  = 0;
-       txtRec->malloced = 0;
-       }
-
-void TXTRecordDeallocate(TXTRecordRef *txtRecord)
-       {
-       if (txtRec->malloced) free(txtRec->buffer);
-       }
-
-DNSServiceErrorType TXTRecordSetValue
-       (
-       TXTRecordRef     *txtRecord,
-       const char       *key,
-       uint8_t          valueSize,
-       const void       *value
-       )
-       {
-       uint8_t *start, *p;
-       const char *k;
-       unsigned long keysize, keyvalsize;
-
-       for (k = key; *k; k++) if (*k < 0x20 || *k > 0x7E || *k == '=') return(kDNSServiceErr_Invalid);
-       keysize = (unsigned long)(k - key);
-       keyvalsize = 1 + keysize + (value ? (1 + valueSize) : 0);
-       if (keysize < 1 || keyvalsize > 255) return(kDNSServiceErr_Invalid);
-       (void)TXTRecordRemoveValue(txtRecord, key);
-       if (txtRec->datalen + keyvalsize > txtRec->buflen)
-               {
-               unsigned char *newbuf;
-               unsigned long newlen = txtRec->datalen + keyvalsize;
-               if (newlen > 0xFFFF) return(kDNSServiceErr_Invalid);
-               newbuf = malloc((size_t)newlen);
-               if (!newbuf) return(kDNSServiceErr_NoMemory);
-               memcpy(newbuf, txtRec->buffer, txtRec->datalen);
-               if (txtRec->malloced) free(txtRec->buffer);
-               txtRec->buffer = newbuf;
-               txtRec->buflen = (uint16_t)(newlen);
-               txtRec->malloced = 1;
-               }
-       start = txtRec->buffer + txtRec->datalen;
-       p = start + 1;
-       memcpy(p, key, keysize);
-       p += keysize;
-       if (value)
-               {
-               *p++ = '=';
-               memcpy(p, value, valueSize);
-               p += valueSize;
-               }
-       *start = (uint8_t)(p - start - 1);
-       txtRec->datalen += p - start;
-       return(kDNSServiceErr_NoError);
-       }
-
-DNSServiceErrorType TXTRecordRemoveValue
-       (
-       TXTRecordRef     *txtRecord,
-       const char       *key
-       )
-       {
-       unsigned long keylen, itemlen, remainder;
-       uint8_t *item = InternalTXTRecordSearch(txtRec->datalen, txtRec->buffer, key, &keylen);
-       if (!item) return(kDNSServiceErr_NoSuchKey);
-       itemlen   = (unsigned long)(1 + item[0]);
-       remainder = (unsigned long)((txtRec->buffer + txtRec->datalen) - (item + itemlen));
-       // Use memmove because memcpy behaviour is undefined for overlapping regions
-       memmove(item, item + itemlen, remainder);
-       txtRec->datalen -= itemlen;
-       return(kDNSServiceErr_NoError);
-       }
-
-uint16_t       TXTRecordGetLength  (const TXTRecordRef *txtRecord) { return(txtRec->datalen); }
-const void *   TXTRecordGetBytesPtr(const TXTRecordRef *txtRecord) { return(txtRec->buffer); }
-
-/*********************************************************************************************
- *
- *   TXT Record Parsing Functions
- *
- *********************************************************************************************/
-
-int TXTRecordContainsKey
-       (
-       uint16_t         txtLen,
-       const void       *txtRecord,
-       const char       *key
-       )
-       {
-       unsigned long keylen;
-       return (InternalTXTRecordSearch(txtLen, txtRecord, key, &keylen) ? 1 : 0);
-       }
-
-const void * TXTRecordGetValuePtr
-       (
-       uint16_t         txtLen,
-       const void       *txtRecord,
-       const char       *key,
-       uint8_t          *valueLen
-       )
-       {
-       unsigned long keylen;
-       uint8_t *item = InternalTXTRecordSearch(txtLen, txtRecord, key, &keylen);
-       if (!item || item[0] <= keylen) return(NULL);   // If key not found, or found with no value, return NULL
-       *valueLen = (uint8_t)(item[0] - (keylen + 1));
-       return (item + 1 + keylen + 1);
-       }
-
-uint16_t TXTRecordGetCount
-       (
-       uint16_t         txtLen,
-       const void       *txtRecord
-       )
-       {
-       uint16_t count = 0;
-       uint8_t *p = (uint8_t*)txtRecord;
-       uint8_t *e = p + txtLen;
-       while (p<e) { p += 1 + p[0]; count++; }
-       return((p>e) ? (uint16_t)0 : count);
-       }
-
-DNSServiceErrorType TXTRecordGetItemAtIndex
-       (
-       uint16_t         txtLen,
-       const void       *txtRecord,
-       uint16_t         index,
-       uint16_t         keyBufLen,
-       char             *key,
-       uint8_t          *valueLen,
-       const void       **value
-       )
-       {
-       uint16_t count = 0;
-       uint8_t *p = (uint8_t*)txtRecord;
-       uint8_t *e = p + txtLen;
-       while (p<e && count<index) { p += 1 + p[0]; count++; }  // Find requested item
-       if (p<e && p + 1 + p[0] <= e)   // If valid
-               {
-               uint8_t *x = p+1;
-               unsigned long len = 0;
-               e = p + 1 + p[0];
-               while (x+len<e && x[len] != '=') len++;
-               if (len >= keyBufLen) return(kDNSServiceErr_NoMemory);
-               memcpy(key, x, len);
-               key[len] = 0;
-               if (x+len<e)            // If we found '='
-                       {
-                       *value = x + len + 1;
-                       *valueLen = (uint8_t)(p[0] - (len + 1));
-                       }
-               else
-                       {
-                       *value = NULL;
-                       *valueLen = 0;
-                       }
-               return(kDNSServiceErr_NoError);
-               }
-       return(kDNSServiceErr_Invalid);
-       }
diff --git a/mdns.subproj/dnssd_clientstub.c b/mdns.subproj/dnssd_clientstub.c
deleted file mode 100644 (file)
index e2e4fc1..0000000
+++ /dev/null
@@ -1,1176 +0,0 @@
-/* -*- Mode: C; tab-width: 4 -*-
- *
- * Copyright (c) 2003-2004, Apple Computer, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without 
- * modification, are permitted provided that the following conditions are met:
- *
- * 1.  Redistributions of source code must retain the above copyright notice, 
- *     this list of conditions and the following disclaimer. 
- * 2.  Redistributions in binary form must reproduce the above copyright notice, 
- *     this list of conditions and the following disclaimer in the documentation 
- *     and/or other materials provided with the distribution. 
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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.
-
-    Change History (most recent first):
-
-$Log: dnssd_clientstub.c,v $
-Revision 1.20.70.3  2006/05/02 16:17:04  majka
-Make NumTries unsigned.
-
-Revision 1.20.70.2  2006/05/01 21:43:09  majka
-Additional change (make NumTries static) for 4527193
-SUChardLondon Libinfo-222.4.6
-
-Revision 1.20.70.1  2006/05/01 16:10:54  majka
-Libinfo-222_4_5 is equivalent to Chardonnay Libinfo-222.0.5
-
-Revision 1.20.60.1  2006/04/27 21:33:30  majka
-Integrated 4527193
-
-Revision 1.20  2005/02/03 00:39:05  majka
-Integrated 3942900
-
-Revision 1.19.4.1  2005/02/02 00:47:40  ksekar
-<rdar://problem/3942900> dnd-sd shows the wrong port numbers
-
-Revision 1.19  2004/12/23 23:10:59  majka
-*** empty log message ***
-
-Revision 1.18.8.1  2004/12/23 17:32:56  ksekar
-<rdar://problem/3931319> Rendevzous calls leak sockets if mDNSResponder is not running
-
-Revision 1.18  2004/12/14 18:02:00  majka
-*** empty log message ***
-
-Revision 1.17.36.1  2004/12/13 17:22:39  ksekar
-<rdar://problem/3656389> Deprecate the DNSServiceDiscovery.h API in Tiger
-<rdar://problem/3873869> Add kDNSServiceInterfaceForceMulticast to header
-<rdar://problem/3526342> Remove overly-restrictive flag checks
-
-Revision 1.17  2004/09/22 20:05:38  majka
-Integrated
-3725573 - Need Error Codes for handling Lighthouse setup failure on NAT
-3805822 - Socket-based APIs aren't endian-safe
-3806739 - DNSServiceSetDefaultDomainForUser header comments incorrect
-
-Revision 1.16.2.1  2004/09/20 21:54:33  ksekar
-<rdar://problem/3805822> Socket-based APIs aren't endian-safe
-
-Revision 1.16  2004/09/17 20:19:00  majka
-Integrated 3804522
-
-Revision 1.15.2.1  2004/09/17 20:15:30  ksekar
-*** empty log message ***
-
-Revision 1.15  2004/09/16 23:45:24  majka
-Integrated 3775315 and 3765280.
-
-Revision 1.14.4.1  2004/09/02 19:43:41  ksekar
-<rdar://problem/3775315>: Sync dns-sd client files between Libinfo and
-mDNSResponder projects
-
-Revision 1.28  2004/08/11 17:10:04  cheshire
-Fix signed/unsigned warnings
-
-Revision 1.27  2004/08/11 00:54:16  cheshire
-Change "hdr->op.request_op" to just "hdr->op"
-
-Revision 1.26  2004/07/26 06:07:27  shersche
-fix bugs when using an error socket to communicate with the daemon
-
-Revision 1.25  2004/07/26 05:54:02  shersche
-DNSServiceProcessResult() returns NoError if socket read returns EWOULDBLOCK
-
-Revision 1.24  2004/07/20 06:46:21  shersche
-<rdar://problem/3730123> fix endless loop in my_read() if recv returns 0
-Bug #: 3730123
-
-Revision 1.23  2004/06/29 00:48:38  cheshire
-Don't use "MSG_WAITALL"; it returns "Invalid argument" on some Linux versions;
-use an explicit while() loop instead.
-
-Revision 1.22  2004/06/26 03:16:34  shersche
-clean up warning messages on Win32 platform
-
-Submitted by: herscher
-
-Revision 1.21  2004/06/18 04:53:56  rpantos
-Use platform layer for socket types. Introduce USE_TCP_LOOPBACK. Remove dependency on mDNSClientAPI.h.
-
-Revision 1.20  2004/06/12 00:50:22  cheshire
-Changes for Windows compatibility
-
-Revision 1.19  2004/05/25 18:29:33  cheshire
-Move DNSServiceConstructFullName() from dnssd_clientstub.c to dnssd_clientlib.c,
-so that it's also accessible to dnssd_clientshim.c (single address space) clients.
-
-Revision 1.18  2004/05/18 23:51:27  cheshire
-Tidy up all checkin comments to use consistent "<rdar://problem/xxxxxxx>" format for bug numbers
-
-Revision 1.17  2004/05/06 18:42:58  ksekar
-General dns_sd.h API cleanup, including the following radars:
-<rdar://problem/3592068>: Remove flags with zero value
-<rdar://problem/3479569>: Passing in NULL causes a crash.
-
-Revision 1.16  2004/03/12 22:00:37  cheshire
-Added: #include <sys/socket.h>
-
-Revision 1.15  2004/01/20 18:36:29  ksekar
-Propagated Libinfo fix for <rdar://problem/3483971>: SU:
-DNSServiceUpdateRecord() doesn't allow you to update the TXT record
-into TOT mDNSResponder.
-
-Revision 1.14  2004/01/19 22:39:17  cheshire
-Don't use "MSG_WAITALL"; it makes send() return "Invalid argument" on Linux;
-use an explicit while() loop instead. (In any case, this should only make a difference
-with non-blocking sockets, which we don't use on the client side right now.)
-
-Revision 1.13  2004/01/19 21:46:52  cheshire
-Fix compiler warning
-
-Revision 1.12  2003/12/23 20:46:47  ksekar
-<rdar://problem/3497428>: sync dnssd files between libinfo & mDNSResponder
-
-Revision 1.11  2003/12/08 21:11:42  rpantos
-Changes necessary to support mDNSResponder on Linux.
-
-Revision 1.10  2003/10/13 23:50:53  ksekar
-Updated dns_sd clientstub files to bring copies in synch with
-top-of-tree Libinfo:  A memory leak in dnssd_clientstub.c is fixed,
-and comments in dns_sd.h are improved.
-
-Revision 1.9  2003/08/15 21:30:39  cheshire
-Bring up to date with LibInfo version
-
-Revision 1.8  2003/08/13 23:54:52  ksekar
-Bringing dnssd_clientstub.c up to date with Libinfo, per radar 3376640
-
-Revision 1.7  2003/08/12 19:56:25  cheshire
-Update to APSL 2.0
-
- */
-
-#include <errno.h>
-#include <stdlib.h>
-#if defined(_WIN32)
-#include <winsock2.h>
-#include <windows.h>
-#define sockaddr_mdns sockaddr_in
-#define AF_MDNS AF_INET
-#else
-#include <sys/time.h>
-#include <sys/socket.h>
-#define sockaddr_mdns sockaddr_un
-#define AF_MDNS AF_LOCAL
-#endif
-
-#include "dnssd_ipc.h"
-
-#if defined(_WIN32)
-// disable warning: "'type cast' : from data pointer 'void *' to
-// function pointer"
-#pragma warning(disable:4055)
-
-// disable warning: "nonstandard extension, function/data pointer
-// conversion in expression"
-#pragma warning(disable:4152)
-
-#define sleep(X) Sleep((X) * 1000)
-
-static int g_initWinsock = 0;
-#endif
-
-
-#define CTL_PATH_PREFIX "/tmp/dnssd_clippath."
-// error socket (if needed) is named "dnssd_clipath.[pid].xxx:n" where xxx are the
-// last 3 digits of the time (in seconds) and n is the 6-digit microsecond time
-
-// general utility functions
-typedef struct _DNSServiceRef_t
-    {
-    dnssd_sock_t sockfd;  // connected socket between client and daemon
-    uint32_t op;          // request_op_t or reply_op_t
-    process_reply_callback process_reply;
-    void *app_callback;
-    void *app_context;
-    uint32_t max_index;  //largest assigned record index - 0 if no additl. recs registered
-    } _DNSServiceRef_t;
-
-typedef struct _DNSRecordRef_t
-    {
-    void *app_context;
-    DNSServiceRegisterRecordReply app_callback;
-    DNSRecordRef recref;
-    uint32_t record_index;  // index is unique to the ServiceDiscoveryRef
-    DNSServiceRef sdr;
-    } _DNSRecordRef_t;
-
-// exported functions
-
-// write len bytes.  return 0 on success, -1 on error
-static int my_write(dnssd_sock_t sd, char *buf, int len)
-    {
-    // Don't use "MSG_WAITALL"; it returns "Invalid argument" on some Linux versions; use an explicit while() loop instead.
-    //if (send(sd, buf, len, MSG_WAITALL) != len)   return -1;
-    while (len)
-       {
-       ssize_t num_written = send(sd, buf, len, 0);
-       if (num_written < 0 || num_written > len) return -1;
-       buf += num_written;
-       len -= num_written;
-       }
-    return 0;
-    }
-
-// read len bytes.  return 0 on success, -1 on error
-static int my_read(dnssd_sock_t sd, char *buf, int len)
-    {
-    // Don't use "MSG_WAITALL"; it returns "Invalid argument" on some Linux versions; use an explicit while() loop instead.
-    //if (recv(sd, buf, len, MSG_WAITALL) != len)  return -1;
-    while (len)
-       {
-       ssize_t num_read = recv(sd, buf, len, 0);
-       if ((num_read == 0) || (num_read < 0) || (num_read > len)) return -1;
-       buf += num_read;
-       len -= num_read;
-       }
-    return 0;
-    }
-
-/* create_hdr
- *
- * allocate and initialize an ipc message header.  value of len should initially be the
- * length of the data, and is set to the value of the data plus the header.  data_start
- * is set to point to the beginning of the data section.  reuse_socket should be non-zero
- * for calls that can receive an immediate error return value on their primary socket.
- * if zero, the path to a control socket is appended at the beginning of the message buffer.
- * data_start is set past this string.
- */
-
-static ipc_msg_hdr *create_hdr(uint32_t op, size_t *len, char **data_start, int reuse_socket)
-    {
-    char *msg = NULL;
-    ipc_msg_hdr *hdr;
-    int datalen;
-    char ctrl_path[256];
-
-    if (!reuse_socket)
-        {
-#if defined(USE_TCP_LOOPBACK)
-               *len += 2;      // Allocate space for two-byte port number
-#else
-               struct timeval time;
-               if (gettimeofday(&time, NULL) < 0) return NULL;
-               sprintf(ctrl_path, "%s%d-%.3lx-%.6lu", CTL_PATH_PREFIX, (int)getpid(),
-                       (unsigned long)(time.tv_sec & 0xFFF), (unsigned long)(time.tv_usec));
-        *len += strlen(ctrl_path) + 1;
-#endif
-        }
-
-    datalen = (int) *len;
-    *len += sizeof(ipc_msg_hdr);
-
-    // write message to buffer
-    msg = malloc(*len);
-    if (!msg) return NULL;
-
-    bzero(msg, *len);
-    hdr = (void *)msg;
-    hdr->datalen = datalen;
-    hdr->version = VERSION;
-    hdr->op = op;
-    if (reuse_socket) hdr->flags |= IPC_FLAGS_REUSE_SOCKET;
-    *data_start = msg + sizeof(ipc_msg_hdr);
-#if defined(USE_TCP_LOOPBACK)
-       // Put dummy data in for the port, since we don't know what
-       // it is yet.  The data will get filled in before we
-       // send the message. This happens in deliver_request().
-       if (!reuse_socket)      put_short(0, data_start);
-#else
-    if (!reuse_socket)  put_string(ctrl_path, data_start);
-#endif
-    return hdr;
-    }
-
-    // return a connected service ref (deallocate with DNSServiceRefDeallocate)
-static DNSServiceRef connect_to_server(void)
-    {
-       dnssd_sockaddr_t saddr;
-       DNSServiceRef sdr;
-       static unsigned int NumTries = 0;
-
-#if defined(_WIN32)
-       if (!g_initWinsock)
-               {
-               WSADATA wsaData;
-               DNSServiceErrorType err;
-               
-               g_initWinsock = 1;
-
-               err = WSAStartup( MAKEWORD( 2, 2 ), &wsaData );
-
-               if (err != 0) return NULL;
-               }
-#endif
-
-       sdr = malloc(sizeof(_DNSServiceRef_t));
-       if (!sdr) return(NULL);
-       sdr->sockfd = socket(AF_DNSSD, SOCK_STREAM, 0);
-       if (sdr->sockfd == dnssd_InvalidSocket) { free(sdr); return NULL; }
-#if defined(USE_TCP_LOOPBACK)
-       saddr.sin_family                =       AF_INET;
-       saddr.sin_addr.s_addr   =       inet_addr(MDNS_TCP_SERVERADDR);
-       saddr.sin_port                  =       htons(MDNS_TCP_SERVERPORT);
-#else
-       saddr.sun_family = AF_LOCAL;
-       strcpy(saddr.sun_path, MDNS_UDS_SERVERPATH);
-#endif
-       while (1)
-               {
-               int err = connect(sdr->sockfd, (struct sockaddr *) &saddr, sizeof(saddr));
-               if (!err) break;                // If we succeeded, return sdr
-               // If we failed, then it may be because the daemon is still launching.
-               // This can happen for processes that launch early in the boot process, while the
-               // daemon is still coming up. Rather than fail here, we'll wait a bit and try again.
-               // If, after ten seconds, we still can't connect to the daemon,
-               // then we give up and return a failure code.
-               if (++NumTries < 3)
-                       sleep(1);               // Sleep a bit, then try again
-               else
-                       {
-                       dnssd_close(sdr->sockfd);
-                       sdr->sockfd = dnssd_InvalidSocket;
-                       free(sdr);
-                       return NULL;
-                       }
-               }
-    return sdr;
-       }
-
-static DNSServiceErrorType deliver_request(void *msg, DNSServiceRef sdr, int reuse_sd)
-    {
-    ipc_msg_hdr *hdr = msg;
-    uint32_t datalen = hdr->datalen;
-    dnssd_sockaddr_t caddr, daddr;  // (client and daemon address structs)
-    char *data = (char *)msg + sizeof(ipc_msg_hdr);
-    dnssd_sock_t listenfd = dnssd_InvalidSocket, errsd = dnssd_InvalidSocket;
-       int ret;
-       unsigned int len = sizeof(caddr);
-    DNSServiceErrorType err = kDNSServiceErr_Unknown;
-
-    if (!hdr || sdr->sockfd < 0) return kDNSServiceErr_Unknown;
-
-       if (!reuse_sd)
-               {
-        // setup temporary error socket
-        if ((listenfd = socket(AF_DNSSD, SOCK_STREAM, 0)) < 0)
-            goto cleanup;
-        bzero(&caddr, sizeof(caddr));
-
-#if defined(USE_TCP_LOOPBACK)
-                       {
-                       union { uint16_t s; u_char b[2]; } port;
-                       caddr.sin_family      = AF_INET;
-                       caddr.sin_port        = 0;
-                       caddr.sin_addr.s_addr = inet_addr(MDNS_TCP_SERVERADDR);
-                       ret = bind(listenfd, (struct sockaddr*) &caddr, sizeof(caddr));
-                       if (ret < 0) goto cleanup;
-                       if (getsockname(listenfd, (struct sockaddr*) &caddr, &len) < 0) goto cleanup;
-                       listen(listenfd, 1);
-                       port.s = caddr.sin_port;
-                       data[0] = port.b[0];    // don't switch the byte order, as the
-                       data[1] = port.b[1];    // daemon expects it in network byte order
-                       }
-#else
-                       {
-                       mode_t mask = umask(0);
-                       caddr.sun_family = AF_LOCAL;
-#ifndef NOT_HAVE_SA_LEN                // According to Stevens (section 3.2), there is no portable way to
-                                                               // determine whether sa_len is defined on a particular platform.
-                       caddr.sun_len = sizeof(struct sockaddr_un);
-#endif
-                       strcpy(caddr.sun_path, data);
-                       ret = bind(listenfd, (struct sockaddr *)&caddr, sizeof(caddr));
-                       umask(mask);
-                       if (ret < 0) goto cleanup;
-                       listen(listenfd, 1);
-                       }
-#endif
-               }
-
-       ConvertHeaderBytes(hdr);
-    if (my_write(sdr->sockfd, msg, datalen + sizeof(ipc_msg_hdr)) < 0)
-        goto cleanup;
-    free(msg);
-    msg = NULL;
-
-    if (reuse_sd) errsd = sdr->sockfd;
-    else
-        {
-        len = sizeof(daddr);
-        errsd = accept(listenfd, (struct sockaddr *)&daddr, &len);
-        if (errsd < 0)  goto cleanup;
-        }
-
-    if (my_read(errsd, (char*)&err, (int)sizeof(err)) < 0)
-        err = kDNSServiceErr_Unknown;
-    else
-       err = ntohl(err);
-
-cleanup:
-    if (!reuse_sd && listenfd > 0) dnssd_close(listenfd);
-    if (!reuse_sd && errsd > 0) dnssd_close(errsd);
-#if !defined(USE_TCP_LOOPBACK)
-    if (!reuse_sd && data) unlink(data);
-#endif
-    if (msg) free(msg);
-    return err;
-    }
-
-int DNSSD_API DNSServiceRefSockFD(DNSServiceRef sdRef)
-    {
-    if (!sdRef) return -1;
-    return (int) sdRef->sockfd;
-    }
-
-// handle reply from server, calling application client callback.  If there is no reply
-// from the daemon on the socket contained in sdRef, the call will block.
-DNSServiceErrorType DNSSD_API DNSServiceProcessResult(DNSServiceRef sdRef)
-    {
-    ipc_msg_hdr hdr;
-    char *data;
-
-    if (!sdRef || sdRef->sockfd < 0 || !sdRef->process_reply)
-        return kDNSServiceErr_BadReference;
-
-    if (my_read(sdRef->sockfd, (void *)&hdr, sizeof(hdr)) < 0)
-               // return NoError on EWOULDBLOCK. This will handle the case
-               // where a non-blocking socket is told there is data, but
-               // it was a false positive.
-               return (dnssd_errno() == dnssd_EWOULDBLOCK) ? kDNSServiceErr_NoError : kDNSServiceErr_Unknown;
-       ConvertHeaderBytes(&hdr);
-    if (hdr.version != VERSION)
-        return kDNSServiceErr_Incompatible;
-    data = malloc(hdr.datalen);
-    if (!data) return kDNSServiceErr_NoMemory;
-    if (my_read(sdRef->sockfd, data, hdr.datalen) < 0)
-        return kDNSServiceErr_Unknown;
-    sdRef->process_reply(sdRef, &hdr, data);
-    free(data);
-    return kDNSServiceErr_NoError;
-    }
-
-void DNSSD_API DNSServiceRefDeallocate(DNSServiceRef sdRef)
-    {
-    if (!sdRef) return;
-    if (sdRef->sockfd > 0) dnssd_close(sdRef->sockfd);
-    free(sdRef);
-    }
-
-static void handle_resolve_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data)
-    {
-    DNSServiceFlags flags;
-    char fullname[kDNSServiceMaxDomainName];
-    char target[kDNSServiceMaxDomainName];
-    uint16_t txtlen;
-    union { uint16_t s; u_char b[2]; } port;
-    uint32_t ifi;
-    DNSServiceErrorType err;
-    char *txtrecord;
-    int str_error = 0;
-    (void)hdr;                 //unused
-
-    flags = get_flags(&data);
-    ifi = get_long(&data);
-    err = get_error_code(&data);
-    if (get_string(&data, fullname, kDNSServiceMaxDomainName) < 0) str_error = 1;
-    if (get_string(&data, target, kDNSServiceMaxDomainName) < 0) str_error = 1;
-    port.b[0] = *data++;
-    port.b[1] = *data++;
-    txtlen = get_short(&data);
-    txtrecord = get_rdata(&data, txtlen);
-
-       if (!err && str_error) err = kDNSServiceErr_Unknown;
-    ((DNSServiceResolveReply)sdr->app_callback)(sdr, flags, ifi, err, fullname, target, port.s, txtlen, txtrecord, sdr->app_context);
-    }
-
-DNSServiceErrorType DNSSD_API DNSServiceResolve
-    (
-    DNSServiceRef                      *sdRef,
-    DNSServiceFlags               flags,
-    uint32_t                      interfaceIndex,
-    const char                                 *name,
-    const char                                 *regtype,
-    const char                                 *domain,
-    DNSServiceResolveReply        callBack,
-    void                                       *context
-    )
-    {
-    char *msg = NULL, *ptr;
-    size_t len;
-    ipc_msg_hdr *hdr;
-    DNSServiceRef sdr;
-    DNSServiceErrorType err;
-
-    if (!sdRef) return kDNSServiceErr_BadParam;
-    *sdRef = NULL;
-
-       if (!name || !regtype || !domain || !callBack) return kDNSServiceErr_BadParam;
-
-    // calculate total message length
-    len = sizeof(flags);
-    len += sizeof(interfaceIndex);
-    len += strlen(name) + 1;
-    len += strlen(regtype) + 1;
-    len += strlen(domain) + 1;
-
-    hdr = create_hdr(resolve_request, &len, &ptr, 1);
-    if (!hdr) goto error;
-    msg = (void *)hdr;
-
-    put_flags(flags, &ptr);
-    put_long(interfaceIndex, &ptr);
-    put_string(name, &ptr);
-    put_string(regtype, &ptr);
-    put_string(domain, &ptr);
-
-    sdr = connect_to_server();
-    if (!sdr) goto error;
-    err = deliver_request(msg, sdr, 1);
-    if (err)
-        {
-        DNSServiceRefDeallocate(sdr);
-        return err;
-        }
-    sdr->op = resolve_request;
-    sdr->process_reply = handle_resolve_response;
-    sdr->app_callback = callBack;
-    sdr->app_context = context;
-    *sdRef = sdr;
-
-    return err;
-
-error:
-    if (msg) free(msg);
-    if (*sdRef) { free(*sdRef);  *sdRef = NULL; }
-    return kDNSServiceErr_Unknown;
-    }
-
-static void handle_query_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data)
-    {
-    DNSServiceFlags flags;
-    uint32_t interfaceIndex, ttl;
-    DNSServiceErrorType errorCode;
-    char name[kDNSServiceMaxDomainName];
-    uint16_t rrtype, rrclass, rdlen;
-    char *rdata;
-    int str_error = 0;
-    (void)hdr;//Unused
-
-    flags = get_flags(&data);
-    interfaceIndex = get_long(&data);
-    errorCode = get_error_code(&data);
-    if (get_string(&data, name, kDNSServiceMaxDomainName) < 0) str_error = 1;
-    rrtype = get_short(&data);
-    rrclass = get_short(&data);
-    rdlen = get_short(&data);
-    rdata = get_rdata(&data, rdlen);
-       ttl = get_long(&data);
-
-       if (!errorCode && str_error) errorCode = kDNSServiceErr_Unknown;
-       ((DNSServiceQueryRecordReply)sdr->app_callback)(sdr, flags, interfaceIndex, errorCode, name, rrtype, rrclass,
-                                                                                                       rdlen, rdata, ttl, sdr->app_context);
-    return;
-    }
-
-DNSServiceErrorType DNSSD_API DNSServiceQueryRecord
-(
- DNSServiceRef                         *sdRef,
- DNSServiceFlags                        flags,
- uint32_t                              interfaceIndex,
- const char                            *name,
- uint16_t                              rrtype,
- uint16_t                              rrclass,
- DNSServiceQueryRecordReply            callBack,
- void                                  *context
- )
-    {
-    char *msg = NULL, *ptr;
-    size_t len;
-    ipc_msg_hdr *hdr;
-    DNSServiceRef sdr;
-    DNSServiceErrorType err;
-
-    if (!sdRef) return kDNSServiceErr_BadParam;
-    *sdRef = NULL;
-
-    if (!name) name = "\0";
-
-    // calculate total message length
-    len = sizeof(flags);
-    len += sizeof(uint32_t);  //interfaceIndex
-    len += strlen(name) + 1;
-    len += 2 * sizeof(uint16_t);  // rrtype, rrclass
-
-    hdr = create_hdr(query_request, &len, &ptr, 1);
-    if (!hdr) goto error;
-    msg = (void *)hdr;
-
-    put_flags(flags, &ptr);
-    put_long(interfaceIndex, &ptr);
-    put_string(name, &ptr);
-    put_short(rrtype, &ptr);
-    put_short(rrclass, &ptr);
-
-    sdr = connect_to_server();
-    if (!sdr) goto error;
-    err = deliver_request(msg, sdr, 1);
-    if (err)
-        {
-        DNSServiceRefDeallocate(sdr);
-        return err;
-        }
-
-    sdr->op = query_request;
-    sdr->process_reply = handle_query_response;
-    sdr->app_callback = callBack;
-    sdr->app_context = context;
-    *sdRef = sdr;
-    return err;
-
-error:
-    if (msg) free(msg);
-    if (*sdRef) { free(*sdRef);  *sdRef = NULL; }
-    return kDNSServiceErr_Unknown;
-    }
-
-static void handle_browse_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data)
-    {
-    DNSServiceFlags      flags;
-    uint32_t                      interfaceIndex;
-    DNSServiceErrorType      errorCode;
-    char replyName[256], replyType[kDNSServiceMaxDomainName],
-        replyDomain[kDNSServiceMaxDomainName];
-    int str_error = 0;
-       (void)hdr;//Unused
-
-    flags = get_flags(&data);
-    interfaceIndex = get_long(&data);
-    errorCode = get_error_code(&data);
-    if (get_string(&data, replyName, 256) < 0) str_error = 1;
-    if (get_string(&data, replyType, kDNSServiceMaxDomainName) < 0) str_error = 1;
-    if (get_string(&data, replyDomain, kDNSServiceMaxDomainName) < 0) str_error = 1;
-       if (!errorCode && str_error) errorCode = kDNSServiceErr_Unknown;
-       ((DNSServiceBrowseReply)sdr->app_callback)(sdr, flags, interfaceIndex, errorCode, replyName, replyType, replyDomain, sdr->app_context);
-    }
-
-DNSServiceErrorType DNSSD_API DNSServiceBrowse
-(
- DNSServiceRef                      *sdRef,
- DNSServiceFlags              flags,
- uint32_t                     interfaceIndex,
- const char                         *regtype,
- const char                         *domain,
- DNSServiceBrowseReply        callBack,
- void                               *context
- )
-    {
-    char *msg = NULL, *ptr;
-    size_t len;
-    ipc_msg_hdr *hdr;
-    DNSServiceRef sdr;
-    DNSServiceErrorType err;
-
-    if (!sdRef) return kDNSServiceErr_BadParam;
-    *sdRef = NULL;
-
-    if (!domain) domain = "";
-
-    len = sizeof(flags);
-    len += sizeof(interfaceIndex);
-    len += strlen(regtype) + 1;
-    len += strlen(domain) + 1;
-
-    hdr = create_hdr(browse_request, &len, &ptr, 1);
-    if (!hdr) goto error;
-    msg = (char *)hdr;
-    put_flags(flags, &ptr);
-    put_long(interfaceIndex, &ptr);
-    put_string(regtype, &ptr);
-    put_string(domain, &ptr);
-
-    sdr = connect_to_server();
-    if (!sdr) goto error;
-    err = deliver_request(msg, sdr, 1);
-    if (err)
-        {
-        DNSServiceRefDeallocate(sdr);
-        return err;
-        }
-    sdr->op = browse_request;
-    sdr->process_reply = handle_browse_response;
-    sdr->app_callback = callBack;
-    sdr->app_context = context;
-    *sdRef = sdr;
-    return err;
-
-error:
-    if (msg) free(msg);
-    if (*sdRef) { free(*sdRef);  *sdRef = NULL; }
-    return kDNSServiceErr_Unknown;
-    }
-
-DNSServiceErrorType DNSSD_API DNSServiceSetDefaultDomainForUser
-(
- DNSServiceFlags                    flags,
- const char                         *domain
- )
-    {
-    DNSServiceRef sdr;
-    DNSServiceErrorType err;
-    char *ptr = NULL;
-    size_t len = sizeof(flags) + strlen(domain) + 1;
-    ipc_msg_hdr *hdr = create_hdr(setdomain_request, &len, &ptr, 1);
-
-    if (!hdr) return kDNSServiceErr_Unknown;
-    put_flags(flags, &ptr);
-    put_string(domain, &ptr);
-
-    sdr = connect_to_server();
-    if (!sdr) { free(hdr); return kDNSServiceErr_Unknown; }
-    err = deliver_request((char *)hdr, sdr, 1);                // deliver_request frees the message for us
-       DNSServiceRefDeallocate(sdr);
-       return err;
-    }
-
-
-static void handle_regservice_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data)
-    {
-    DNSServiceFlags flags;
-    uint32_t interfaceIndex;
-    DNSServiceErrorType errorCode;
-    char name[256], regtype[kDNSServiceMaxDomainName], domain[kDNSServiceMaxDomainName];
-    int str_error = 0;
-       (void)hdr;//Unused
-
-    flags = get_flags(&data);
-    interfaceIndex = get_long(&data);
-    errorCode = get_error_code(&data);
-    if (get_string(&data, name, 256) < 0) str_error = 1;
-    if (get_string(&data, regtype, kDNSServiceMaxDomainName) < 0) str_error = 1;
-    if (get_string(&data, domain, kDNSServiceMaxDomainName) < 0) str_error = 1;
-       if (!errorCode && str_error) errorCode = kDNSServiceErr_Unknown;
-    ((DNSServiceRegisterReply)sdr->app_callback)(sdr, flags, errorCode, name, regtype, domain, sdr->app_context);
-    }
-
-DNSServiceErrorType DNSSD_API DNSServiceRegister
-    (
-    DNSServiceRef                       *sdRef,
-    DNSServiceFlags                     flags,
-    uint32_t                            interfaceIndex,
-    const char                          *name,
-    const char                          *regtype,
-    const char                          *domain,
-    const char                          *host,
-    uint16_t                            PortInNetworkByteOrder,
-    uint16_t                            txtLen,
-    const void                          *txtRecord,
-    DNSServiceRegisterReply             callBack,
-    void                                *context
-    )
-    {
-    char *msg = NULL, *ptr;
-    size_t len;
-    ipc_msg_hdr *hdr;
-    DNSServiceRef sdr;
-    DNSServiceErrorType err;
-    union { uint16_t s; u_char b[2]; } port = { PortInNetworkByteOrder };
-
-    if (!sdRef) return kDNSServiceErr_BadParam;
-    *sdRef = NULL;
-
-    if (!name) name = "";
-    if (!regtype) return kDNSServiceErr_BadParam;
-    if (!domain) domain = "";
-    if (!host) host = "";
-    if (!txtRecord) txtRecord = (void*)"";
-
-    // auto-name must also have auto-rename
-    if (!name[0]  && (flags & kDNSServiceFlagsNoAutoRename))
-        return kDNSServiceErr_BadParam;
-
-    // no callback must have auto-name
-    if (!callBack && name[0]) return kDNSServiceErr_BadParam;
-
-    len = sizeof(DNSServiceFlags);
-    len += sizeof(uint32_t);  // interfaceIndex
-    len += strlen(name) + strlen(regtype) + strlen(domain) + strlen(host) + 4;
-    len += 2 * sizeof(uint16_t);  // port, txtLen
-    len += txtLen;
-
-    hdr = create_hdr(reg_service_request, &len, &ptr, 1);
-    if (!hdr) goto error;
-    if (!callBack) hdr->flags |= IPC_FLAGS_NOREPLY;
-    msg = (char *)hdr;
-    put_flags(flags, &ptr);
-    put_long(interfaceIndex, &ptr);
-    put_string(name, &ptr);
-    put_string(regtype, &ptr);
-    put_string(domain, &ptr);
-    put_string(host, &ptr);
-    *ptr++ = port.b[0];
-    *ptr++ = port.b[1];
-    put_short(txtLen, &ptr);
-    put_rdata(txtLen, txtRecord, &ptr);
-
-    sdr = connect_to_server();
-    if (!sdr) goto error;
-    err = deliver_request(msg, sdr, 1);
-    if (err)
-        {
-        DNSServiceRefDeallocate(sdr);
-        return err;
-        }
-
-    sdr->op = reg_service_request;
-    sdr->process_reply = callBack ? handle_regservice_response : NULL;
-    sdr->app_callback = callBack;
-    sdr->app_context = context;
-    *sdRef = sdr;
-
-    return err;
-
-error:
-    if (msg) free(msg);
-    if (*sdRef)        { free(*sdRef);  *sdRef = NULL; }
-    return kDNSServiceErr_Unknown;
-    }
-
-static void handle_enumeration_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data)
-    {
-    DNSServiceFlags flags;
-    uint32_t interfaceIndex;
-    DNSServiceErrorType err;
-    char domain[kDNSServiceMaxDomainName];
-    int str_error = 0;
-       (void)hdr;//Unused
-
-    flags = get_flags(&data);
-    interfaceIndex = get_long(&data);
-    err = get_error_code(&data);
-    if (get_string(&data, domain, kDNSServiceMaxDomainName) < 0) str_error = 1;
-       if (!err && str_error) err = kDNSServiceErr_Unknown;
-    ((DNSServiceDomainEnumReply)sdr->app_callback)(sdr, flags, interfaceIndex, err, domain, sdr->app_context);
-    }
-
-DNSServiceErrorType DNSSD_API DNSServiceEnumerateDomains
-(
- DNSServiceRef                    *sdRef,
- DNSServiceFlags            flags,
- uint32_t                   interfaceIndex,
- DNSServiceDomainEnumReply  callBack,
- void                             *context
- )
-    {
-    char *msg = NULL, *ptr;
-    size_t len;
-    ipc_msg_hdr *hdr;
-    DNSServiceRef sdr;
-    DNSServiceErrorType err;
-    int f1 = (flags & kDNSServiceFlagsBrowseDomains) != 0;
-    int f2 = (flags & kDNSServiceFlagsRegistrationDomains) != 0;
-    if (f1 + f2 != 1) return kDNSServiceErr_BadParam;
-
-    if (!sdRef) return kDNSServiceErr_BadParam;
-    *sdRef = NULL;
-
-       len = sizeof(DNSServiceFlags);
-    len += sizeof(uint32_t);
-
-    hdr = create_hdr(enumeration_request, &len, &ptr, 1);
-    if (!hdr) goto error;
-    msg = (void *)hdr;
-
-    put_flags(flags, &ptr);
-    put_long(interfaceIndex, &ptr);
-
-    sdr = connect_to_server();
-    if (!sdr) goto error;
-    err = deliver_request(msg, sdr, 1);
-    if (err)
-        {
-        DNSServiceRefDeallocate(sdr);
-        return err;
-        }
-
-    sdr->op = enumeration_request;
-    sdr->process_reply = handle_enumeration_response;
-    sdr->app_callback = callBack;
-    sdr->app_context = context;
-    *sdRef = sdr;
-    return err;
-
-error:
-    if (msg) free(msg);
-    if (*sdRef) { free(*sdRef);  *sdRef = NULL; }
-    return kDNSServiceErr_Unknown;
-    }
-
-static void handle_regrecord_response(DNSServiceRef sdr, ipc_msg_hdr *hdr, char *data)
-    {
-    DNSServiceFlags flags;
-    uint32_t interfaceIndex;
-    DNSServiceErrorType errorCode;
-    DNSRecordRef rref = hdr->client_context.context;
-
-    if (sdr->op != connection)
-        {
-        rref->app_callback(rref->sdr, rref, 0, kDNSServiceErr_Unknown, rref->app_context);
-        return;
-        }
-    flags = get_flags(&data);
-    interfaceIndex = get_long(&data);
-    errorCode = get_error_code(&data);
-
-    rref->app_callback(rref->sdr, rref, flags, errorCode, rref->app_context);
-    }
-
-DNSServiceErrorType DNSSD_API DNSServiceCreateConnection(DNSServiceRef *sdRef)
-    {
-    if (!sdRef) return kDNSServiceErr_BadParam;
-    *sdRef = connect_to_server();
-    if (!*sdRef)
-            return kDNSServiceErr_Unknown;
-    (*sdRef)->op = connection;
-    (*sdRef)->process_reply = handle_regrecord_response;
-    return 0;
-    }
-
-DNSServiceErrorType DNSSD_API DNSServiceRegisterRecord
-(
- DNSServiceRef                 sdRef,
- DNSRecordRef                          *RecordRef,
- DNSServiceFlags               flags,
- uint32_t                              interfaceIndex,
- const char                            *fullname,
- uint16_t                              rrtype,
- uint16_t                              rrclass,
- uint16_t                              rdlen,
- const void                            *rdata,
- uint32_t                              ttl,
- DNSServiceRegisterRecordReply         callBack,
- void                                  *context
- )
-    {
-    char *msg = NULL, *ptr;
-    size_t len;
-    ipc_msg_hdr *hdr = NULL;
-    DNSServiceRef tmp = NULL;
-    DNSRecordRef rref = NULL;
-    int f1 = (flags & kDNSServiceFlagsShared) != 0;
-    int f2 = (flags & kDNSServiceFlagsUnique) != 0;
-    if (f1 + f2 != 1) return kDNSServiceErr_BadParam;
-
-    if (!sdRef || sdRef->op != connection || sdRef->sockfd < 0)
-        return kDNSServiceErr_BadReference;
-    *RecordRef = NULL;
-
-       len = sizeof(DNSServiceFlags);
-    len += 2 * sizeof(uint32_t);  // interfaceIndex, ttl
-    len += 3 * sizeof(uint16_t);  // rrtype, rrclass, rdlen
-    len += strlen(fullname) + 1;
-    len += rdlen;
-
-    hdr = create_hdr(reg_record_request, &len, &ptr, 0);
-    if (!hdr) goto error;
-    msg = (char *)hdr;
-    put_flags(flags, &ptr);
-    put_long(interfaceIndex, &ptr);
-    put_string(fullname, &ptr);
-    put_short(rrtype, &ptr);
-    put_short(rrclass, &ptr);
-    put_short(rdlen, &ptr);
-    put_rdata(rdlen, rdata, &ptr);
-    put_long(ttl, &ptr);
-
-    rref = malloc(sizeof(_DNSRecordRef_t));
-    if (!rref) goto error;
-    rref->app_context = context;
-    rref->app_callback = callBack;
-    rref->record_index = sdRef->max_index++;
-    rref->sdr = sdRef;
-    *RecordRef = rref;
-    hdr->client_context.context = rref;
-    hdr->reg_index = rref->record_index;
-
-    return deliver_request(msg, sdRef, 0);
-
-error:
-    if (rref) free(rref);
-    if (tmp) free(tmp);
-    if (hdr) free(hdr);
-    return kDNSServiceErr_Unknown;
-    }
-
-//sdRef returned by DNSServiceRegister()
-DNSServiceErrorType DNSSD_API DNSServiceAddRecord
-    (
-    DNSServiceRef                      sdRef,
-    DNSRecordRef                       *RecordRef,
-    DNSServiceFlags               flags,
-    uint16_t                   rrtype,
-    uint16_t                   rdlen,
-    const void                         *rdata,
-    uint32_t                   ttl
-    )
-    {
-    ipc_msg_hdr *hdr;
-    size_t len = 0;
-    char *ptr;
-    DNSRecordRef rref;
-
-    if (!sdRef || (sdRef->op != reg_service_request) || !RecordRef)
-        return kDNSServiceErr_BadReference;
-    *RecordRef = NULL;
-
-    len += 2 * sizeof(uint16_t);  //rrtype, rdlen
-    len += rdlen;
-    len += sizeof(uint32_t);
-    len += sizeof(DNSServiceFlags);
-
-    hdr = create_hdr(add_record_request, &len, &ptr, 0);
-    if (!hdr) return kDNSServiceErr_Unknown;
-    put_flags(flags, &ptr);
-    put_short(rrtype, &ptr);
-    put_short(rdlen, &ptr);
-    put_rdata(rdlen, rdata, &ptr);
-    put_long(ttl, &ptr);
-
-    rref = malloc(sizeof(_DNSRecordRef_t));
-    if (!rref) goto error;
-    rref->app_context = NULL;
-    rref->app_callback = NULL;
-    rref->record_index = sdRef->max_index++;
-    rref->sdr = sdRef;
-    *RecordRef = rref;
-    hdr->client_context.context = rref;
-    hdr->reg_index = rref->record_index;
-    return deliver_request((char *)hdr, sdRef, 0);
-
-error:
-    if (hdr) free(hdr);
-    if (rref) free(rref);
-    if (*RecordRef) *RecordRef = NULL;
-    return kDNSServiceErr_Unknown;
-}
-
-//DNSRecordRef returned by DNSServiceRegisterRecord or DNSServiceAddRecord
-DNSServiceErrorType DNSSD_API DNSServiceUpdateRecord
-    (
-    DNSServiceRef              sdRef,
-    DNSRecordRef                       RecordRef,
-    DNSServiceFlags               flags,
-    uint16_t                   rdlen,
-    const void                         *rdata,
-    uint32_t                   ttl
-    )
-    {
-    ipc_msg_hdr *hdr;
-    size_t len = 0;
-    char *ptr;
-
-       if (!sdRef) return kDNSServiceErr_BadReference;
-
-    len += sizeof(uint16_t);
-    len += rdlen;
-    len += sizeof(uint32_t);
-    len += sizeof(DNSServiceFlags);
-
-    hdr = create_hdr(update_record_request, &len, &ptr, 0);
-    if (!hdr) return kDNSServiceErr_Unknown;
-    hdr->reg_index = RecordRef ? RecordRef->record_index : TXT_RECORD_INDEX;
-    put_flags(flags, &ptr);
-    put_short(rdlen, &ptr);
-    put_rdata(rdlen, rdata, &ptr);
-    put_long(ttl, &ptr);
-    return deliver_request((char *)hdr, sdRef, 0);
-    }
-
-DNSServiceErrorType DNSSD_API DNSServiceRemoveRecord
-(
- DNSServiceRef            sdRef,
- DNSRecordRef                  RecordRef,
- DNSServiceFlags          flags
- )
-    {
-    ipc_msg_hdr *hdr;
-    size_t len = 0;
-    char *ptr;
-    DNSServiceErrorType err;
-
-    if (!sdRef || !RecordRef || !sdRef->max_index)
-        return kDNSServiceErr_BadReference;
-
-    len += sizeof(flags);
-    hdr = create_hdr(remove_record_request, &len, &ptr, 0);
-    if (!hdr) return kDNSServiceErr_Unknown;
-    hdr->reg_index = RecordRef->record_index;
-    put_flags(flags, &ptr);
-    err = deliver_request((char *)hdr, sdRef, 0);
-    if (!err) free(RecordRef);
-    return err;
-    }
-
-void DNSSD_API DNSServiceReconfirmRecord
-(
- DNSServiceFlags              flags,
- uint32_t                     interfaceIndex,
- const char                         *fullname,
- uint16_t                     rrtype,
- uint16_t                     rrclass,
- uint16_t                     rdlen,
- const void                         *rdata
- )
-    {
-    char *ptr;
-    size_t len;
-    ipc_msg_hdr *hdr;
-    DNSServiceRef tmp;
-
-    len = sizeof(DNSServiceFlags);
-    len += sizeof(uint32_t);
-    len += strlen(fullname) + 1;
-    len += 3 * sizeof(uint16_t);
-    len += rdlen;
-    tmp = connect_to_server();
-    if (!tmp) return;
-    hdr = create_hdr(reconfirm_record_request, &len, &ptr, 1);
-    if (!hdr) return;
-
-    put_flags(flags, &ptr);
-    put_long(interfaceIndex, &ptr);
-    put_string(fullname, &ptr);
-    put_short(rrtype, &ptr);
-    put_short(rrclass, &ptr);
-    put_short(rdlen, &ptr);
-    put_rdata(rdlen, rdata, &ptr);
-       ConvertHeaderBytes(hdr);
-    my_write(tmp->sockfd, (char *)hdr, (int) len);
-    free(hdr);
-    DNSServiceRefDeallocate(tmp);
-    }
-
diff --git a/mdns.subproj/dnssd_ipc.c b/mdns.subproj/dnssd_ipc.c
deleted file mode 100644 (file)
index 0854ada..0000000
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
-
-       Change History (most recent first):
-
-$Log: dnssd_ipc.c,v $
-Revision 1.10  2004/09/22 20:05:38  majka
-Integrated
-3725573 - Need Error Codes for handling Lighthouse setup failure on NAT
-3805822 - Socket-based APIs aren't endian-safe
-3806739 - DNSServiceSetDefaultDomainForUser header comments incorrect
-
-Revision 1.9.4.1  2004/09/20 21:54:33  ksekar
-<rdar://problem/3805822> Socket-based APIs aren't endian-safe
-
-Revision 1.9  2004/09/16 23:45:24  majka
-Integrated 3775315 and 3765280.
-
-Revision 1.8.4.1  2004/09/02 19:43:41  ksekar
-<rdar://problem/3775315>: Sync dns-sd client files between Libinfo and
-mDNSResponder projects
-
-Revision 1.11  2004/06/18 04:56:09  rpantos
-casting goodness
-
-Revision 1.10  2004/06/12 01:08:14  cheshire
-Changes for Windows compatibility
-
-Revision 1.9  2004/05/18 23:51:27  cheshire
-Tidy up all checkin comments to use consistent "<rdar://problem/xxxxxxx>" format for bug numbers
-
-Revision 1.8  2003/11/05 22:44:57  ksekar
-<rdar://problem/3335230>: No bounds checking when reading data from client
-Reviewed by: Stuart Cheshire
-
-Revision 1.7  2003/08/12 19:56:25  cheshire
-Update to APSL 2.0
-
- */
-
-#include "dnssd_ipc.h"
-
-void put_long(const uint32_t l, char **ptr)
-       {
-       (*ptr)[0] = (char)((l >> 24) &  0xFF);
-       (*ptr)[1] = (char)((l >> 16) &  0xFF);
-       (*ptr)[2] = (char)((l >>  8) &  0xFF);
-       (*ptr)[3] = (char)((l      ) &  0xFF);
-       *ptr += sizeof(uint32_t);
-       }
-
-uint32_t get_long(char **ptr)
-       {
-       uint8_t *p = (uint8_t*) *ptr;
-       *ptr += sizeof(uint32_t);
-       return((uint32_t) ((uint32_t)p[0] << 24 | (uint32_t)p[1] << 16 | (uint32_t)p[2] << 8 | p[3]));
-       }
-
-void put_short(uint16_t s, char **ptr)
-       {
-       (*ptr)[0] = (char)((s >>  8) &  0xFF);
-       (*ptr)[1] = (char)((s      ) &  0xFF);
-       *ptr += sizeof(uint16_t);
-       }
-
-uint16_t get_short(char **ptr)
-       {
-       uint8_t *p = (uint8_t*) *ptr;
-       *ptr += sizeof(uint16_t);
-       return((uint16_t) ((uint16_t)p[0] << 8 | p[1]));
-       }
-
-int put_string(const char *str, char **ptr)
-       {
-       if (!str) str = "";
-       strcpy(*ptr, str);
-       *ptr += strlen(str) + 1;
-       return 0;
-       }
-
-int get_string(char **ptr, char *buffer, int buflen)
-       {
-       int overrun = (int)strlen(*ptr) <  buflen ? 0 : -1;
-       strncpy(buffer, *ptr,  buflen - 1);
-       buffer[buflen - 1] = '\0';
-       *ptr += strlen(buffer) + 1;
-       return overrun;
-       }
-
-void put_rdata(const int rdlen, const char *rdata, char **ptr)
-       {
-       memcpy(*ptr, rdata, rdlen);
-       *ptr += rdlen;
-       }
-
-char *get_rdata(char **ptr, int rdlen)
-       {
-       char *rd = *ptr;
-       *ptr += rdlen;
-       return rd;
-       }
-
-void ConvertHeaderBytes(ipc_msg_hdr *hdr)
-       {
-       hdr->version   = htonl(hdr->version);
-       hdr->datalen   = htonl(hdr->datalen);
-       hdr->flags     = htonl(hdr->flags);
-       hdr->op        = htonl(hdr->op );
-       hdr->reg_index = htonl(hdr->reg_index);
-       }
diff --git a/mdns.subproj/dnssd_ipc.h b/mdns.subproj/dnssd_ipc.h
deleted file mode 100644 (file)
index cecfd46..0000000
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Copyright (c) 2003 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
-
-    Change History (most recent first):
-
-$Log: dnssd_ipc.h,v $
-Revision 1.9  2004/09/22 20:05:38  majka
-Integrated
-3725573 - Need Error Codes for handling Lighthouse setup failure on NAT
-3805822 - Socket-based APIs aren't endian-safe
-3806739 - DNSServiceSetDefaultDomainForUser header comments incorrect
-
-Revision 1.8.2.1  2004/09/20 21:54:33  ksekar
-<rdar://problem/3805822> Socket-based APIs aren't endian-safe
-
-Revision 1.8  2004/09/17 20:19:01  majka
-Integrated 3804522
-
-Revision 1.7.2.1  2004/09/17 20:15:30  ksekar
-*** empty log message ***
-
-Revision 1.7  2004/09/16 23:45:24  majka
-Integrated 3775315 and 3765280.
-
-Revision 1.6.4.1  2004/09/02 19:43:41  ksekar
-<rdar://problem/3775315>: Sync dns-sd client files between Libinfo and
-mDNSResponder projects
-
-Revision 1.11  2004/08/10 06:24:56  cheshire
-Use types with precisely defined sizes for 'op' and 'reg_index', for better
-compatibility if the daemon and the client stub are built using different compilers
-
-Revision 1.10  2004/07/07 17:39:25  shersche
-Change MDNS_SERVERPORT from 5533 to 5354.
-
-Revision 1.9  2004/06/25 00:26:27  rpantos
-Changes to fix the Posix build on Solaris.
-
-Revision 1.8  2004/06/18 04:56:51  rpantos
-Add layer for platform code
-
-Revision 1.7  2004/06/12 01:08:14  cheshire
-Changes for Windows compatibility
-
-Revision 1.6  2003/08/12 19:56:25  cheshire
-Update to APSL 2.0
-
- */
-
-#ifndef DNSSD_IPC_H
-#define DNSSD_IPC_H
-
-#include "dns_sd.h"
-
-
-//
-// Common cross platform services
-//
-#if defined(WIN32)
-#      include <winsock2.h>
-#      define dnssd_InvalidSocket      INVALID_SOCKET
-#      define dnssd_EWOULDBLOCK        WSAEWOULDBLOCK
-#      define dnssd_EINTR                      WSAEINTR
-#      define MSG_WAITALL                      0
-#      define dnssd_sock_t                     SOCKET
-#      define dnssd_sockbuf_t          
-#      define dnssd_close(sock)        closesocket(sock)
-#      define dnssd_errno()            WSAGetLastError()
-#      define ssize_t                          int
-#      define getpid                           _getpid
-#else
-#      include <sys/types.h>
-#      include <unistd.h>
-#      include <sys/un.h>
-#      include <string.h>
-#      include <stdio.h>
-#      include <stdlib.h>
-#      include <sys/stat.h>
-#      include <sys/socket.h>
-#      include <netinet/in.h>
-#      define dnssd_InvalidSocket      -1
-#      define dnssd_EWOULDBLOCK        EWOULDBLOCK
-#      define dnssd_EINTR                      EINTR
-#      define dnssd_EPIPE                      EPIPE
-#      define dnssd_sock_t                     int
-#      define dnssd_close(sock)        close(sock)
-#      define dnssd_errno()            errno
-#endif
-
-#if defined(USE_TCP_LOOPBACK)
-#      define AF_DNSSD                         AF_INET
-#      define MDNS_TCP_SERVERADDR      "127.0.0.1"
-#      define MDNS_TCP_SERVERPORT      5354
-#      define LISTENQ                          5
-#      define dnssd_sockaddr_t         struct sockaddr_in
-#else
-#      define AF_DNSSD                         AF_LOCAL
-#      define MDNS_UDS_SERVERPATH      "/var/run/mDNSResponder"
-#      define LISTENQ                          100
-    // longest legal control path length
-#      define MAX_CTLPATH                      256     
-#      define dnssd_sockaddr_t         struct sockaddr_un
-#endif
-
-
-//#define UDSDEBUG  // verbose debug output
-
-// Compatibility workaround
-#ifndef AF_LOCAL
-#define        AF_LOCAL        AF_UNIX
-#endif
-
-// General UDS constants
-#define TXT_RECORD_INDEX ((uint32_t)(-1))      // record index for default text record
-
-// IPC data encoding constants and types
-#define VERSION 1
-#define IPC_FLAGS_NOREPLY 1    // set flag if no asynchronous replies are to be sent to client
-#define IPC_FLAGS_REUSE_SOCKET 2 // set flag if synchronous errors are to be sent via the primary socket
-                                // (if not set, first string in message buffer must be path to error socket
-
-typedef enum
-    {
-    connection = 1,           // connected socket via DNSServiceConnect()
-    reg_record_request,          // reg/remove record only valid for connected sockets
-    remove_record_request,
-    enumeration_request,
-    reg_service_request,
-    browse_request,
-    resolve_request,
-    query_request,
-    reconfirm_record_request,
-    add_record_request,
-    update_record_request,
-    setdomain_request
-    } request_op_t;
-
-typedef enum
-    {
-    enumeration_reply = 64,
-    reg_service_reply,
-    browse_reply,
-    resolve_reply,
-    query_reply,
-    reg_record_reply
-    } reply_op_t;
-
-typedef struct ipc_msg_hdr_struct ipc_msg_hdr;
-
-// client stub callback to process message from server and deliver results to
-// client application
-
-typedef void (*process_reply_callback)
-    (
-    DNSServiceRef sdr,
-    ipc_msg_hdr *hdr,
-    char *msg
-    );
-
-// allow 64-bit client to interoperate w/ 32-bit daemon
-typedef union
-    {
-    void *context;
-    uint32_t ptr64[2];
-    } client_context_t;
-
-typedef struct __attribute__((__packed__)) ipc_msg_hdr_struct
-    {
-    uint32_t version;
-    uint32_t datalen;
-    uint32_t flags;
-    uint32_t op;               // request_op_t or reply_op_t
-    client_context_t client_context; // context passed from client, returned by server in corresponding reply
-    uint32_t reg_index;            // identifier for a record registered via DNSServiceRegisterRecord() on a
-    // socket connected by DNSServiceConnect().  Must be unique in the scope of the connection, such that and
-    // index/socket pair uniquely identifies a record.  (Used to select records for removal by DNSServiceRemoveRecord())
-    } ipc_msg_hdr_struct;
-
-// it is advanced to point to the next field, or the end of the message
-// routines to write to and extract data from message buffers.
-// caller responsible for bounds checking.
-// ptr is the address of the pointer to the start of the field.
-// it is advanced to point to the next field, or the end of the message
-
-void put_long(const uint32_t l, char **ptr);
-uint32_t get_long(char **ptr);
-
-void put_short(uint16_t s, char **ptr);
-uint16_t get_short(char **ptr);
-
-#define put_flags put_long
-#define get_flags get_long
-
-#define put_error_code put_long
-#define get_error_code get_long
-
-int put_string(const char *str, char **ptr);
-int get_string(char **ptr, char *buffer, int buflen);
-
-void put_rdata(const int rdlen, const char *rdata, char **ptr);
-char *get_rdata(char **ptr, int rdlen);  // return value is rdata pointed to by *ptr -
-                                         // rdata is not copied from buffer.
-
-void ConvertHeaderBytes(ipc_msg_hdr *hdr);
-
-#endif // DNSSD_IPC_H
diff --git a/membership.subproj/DSmemberdMIG.defs b/membership.subproj/DSmemberdMIG.defs
new file mode 100644 (file)
index 0000000..3c5bf1a
--- /dev/null
@@ -0,0 +1 @@
+#include <../include/DSmemberdMIG.defs>
index 2544a3925636445a2ac510654acaca189ab2a8ed..9f7473cca31ef8da909930a68a2c4a4d4c2a6678 100644 (file)
@@ -12,11 +12,12 @@ NAME = membership
 PROJECTVERSION = 2.8
 PROJECT_TYPE = Component
 
-HFILES = membership.h membershipPriv.h memberd_defines.h ntsid.h
+HFILES = membership.h membershipPriv.h ntsid.h
 
 CFILES = membership.c
 
-OTHERSRCS = Makefile.preamble Makefile Makefile.postamble memberd.defs
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble DSmemberdMIG.defs \
+       mbr_check_membership.3 mbr_uid_to_uuid.3 mbr_uid_to_uuid_so.3
 
 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
 CODE_GEN_STYLE = DYNAMIC
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f20fb6f7a248b4bd0e142b47006d84c1544f7ce4 100644 (file)
@@ -0,0 +1,11 @@
+install-man-page: $(DSTROOT)/usr/share/man/man3
+       install -d $(DSTROOT)/usr/share/man/man3
+       install -c -m 644 mbr_check_membership.3 $(DSTROOT)/usr/share/man/man3
+       install -c -m 644 mbr_uid_to_uuid.3 $(DSTROOT)/usr/share/man/man3
+       install -c -m 644 mbr_uid_to_uuid_so.3 $(DSTROOT)/usr/share/man/man3/mbr_gid_to_uuid.3
+       install -c -m 644 mbr_uid_to_uuid_so.3 $(DSTROOT)/usr/share/man/man3/mbr_sid_to_uuid.3
+       install -c -m 644 mbr_uid_to_uuid_so.3 $(DSTROOT)/usr/share/man/man3/mbr_uuid_to_id.3
+       install -c -m 644 mbr_uid_to_uuid_so.3 $(DSTROOT)/usr/share/man/man3/mbr_uuid_to_sid.3
+
+$(DSTROOT)/usr/share/man/man3:
+       $(MKDIRS) $@
index 6d8c68ab9c5d6caea7c195417ccc75496fdec53d..c77ddea1a38f8d3a7bc3488d1b5f4605c322e189 100644 (file)
@@ -1,11 +1,12 @@
+AFTER_POSTINSTALL += install-man-page
 OTHER_PRIVATE_HEADERS = membershipPriv.h
 
-# Additional flags (MiG generated files)
-DEFSFILES = memberd.defs
-OTHER_OFILES = memberdUser.o
+# Enable MIG type checking
+OTHER_CFLAGS += -D__MigTypeCheck=1 -D__DARWIN_NON_CANCELABLE=1
 
-# private headers
-INTERNAL_HDRS = memberd.defs memberd.h
+# Additional flags (MiG generated files)
+DEFSFILES = DSmemberdMIG.defs
+OTHER_OFILES = DSmemberdMIGUser.o
 
 BEFORE_INSTALLHDRS += $(SFILE_DIR) $(INTERNAL_HDRS) 
 # AFTER_INSTALLHDRS += mdns_hdrs
index 9fafc152258517eb241488ac6051220746c878ce..3e5c15120f583042086b934e3e2223925fc9eb59 100644 (file)
@@ -2,9 +2,7 @@
     DYNAMIC_CODE_GEN = YES; 
     FILESTABLE = {
         H_FILES = (
-                       membership.h,
                        membershipPriv.h,
-                       memberd_defines.h,
                        ntsid.h
         ); 
         OTHER_LINKED = (membership.c); 
@@ -12,7 +10,7 @@
             Makefile.preamble, 
                        Makefile, 
                        Makefile.postamble, 
-                       memberd.defs
+                       DSmemberdMIG.defs
                ); 
         PRECOMPILED_HEADERS = (); 
         PROJECT_HEADERS = (); 
diff --git a/membership.subproj/mbr_check_membership.3 b/membership.subproj/mbr_check_membership.3
new file mode 100644 (file)
index 0000000..e268baa
--- /dev/null
@@ -0,0 +1,93 @@
+.\" Copyright (c) 2005-2007 Apple Inc
+.\" 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.
+.\" 4. Neither the name of Apple Computer 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 APPLE COMPUTER 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.
+.\"
+.\"
+.Dd February 3, 2005
+.Dt MBR_CHECK_MEMBERSHIP 3
+.Os "Mac OS X"
+.Sh NAME
+.Nm mbr_check_membership
+.Nd check whether a user is a member of a group
+.Sh SYNOPSIS
+.In membership.h
+.Ft int
+.Fn mbr_check_membership "uuid_t user" "uuid_t group" "int *ismember"
+.Sh DESCRIPTION
+.Fn mbr_check_membership
+tests if a given user is a member of a group, individually or as a member of a nested group.
+.Fa ismember
+is set to 1 if the user is a member of the group, and 0 otherwise.  
+.Pp
+Users may belong to any number of grouos.
+.Fn mbr_check_membership
+should be always be used to check group membership, rather than
+calling
+.Xr getgroups 2 ,
+and checking the returned list of gids.
+The
+.Xr setgroups 2
+and
+.Xr getgroups 2
+routines are limited to a fixed number of gids,
+and so may not include all of a user's groups.
+.Pp
+There are two special cases.
+If the two uuids are equal, then 
+.Fa ismember
+is set to 1.
+If the
+.Fa group
+uuid is equal to the reserved "everyone" uuid (ABCDEFAB-CDEF-ABCD-EFAB-CDEF0000000C), then
+.Fa ismember
+will be set to 1 for any valid user.
+.Pp
+Group membership information is managed by the
+.Xr DirectoryService 8
+daemon.
+.Sh RETURN VALUES
+.Fn mbr_check_membership
+returns 0 on success.
+It returns EIO if it is unable to communicate with the
+.Xr DirectoryService 8
+daemon.
+ENOENT is returned if
+.Fa user
+cannot be found.
+.Pp
+Note that 
+.Fn mbr_check_membership
+does not test whether
+.Fa group
+exists or not.
+Querying membership for a nonexistant group will result in
+.Fa ismember
+being to 0 and a return value of 0.
+.Sh SEE ALSO
+.Xr setgroups 2 ,
+.Xr getgroups 2 ,
+.Xr mbr_uid_to_uuid 3 ,
+.Xr DirectoryService 8
\ No newline at end of file
diff --git a/membership.subproj/mbr_uid_to_uuid.3 b/membership.subproj/mbr_uid_to_uuid.3
new file mode 100644 (file)
index 0000000..2e7aeec
--- /dev/null
@@ -0,0 +1,101 @@
+.\" Copyright (c) 2005-2007 Apple Inc
+.\" 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.
+.\" 4. Neither the name of Apple Computer 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 APPLE COMPUTER 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.
+.\"
+.\"
+.Dd February 3, 2005
+.Dt MBR_UID_TO_UUID 3
+.Os "Mac OS X"
+.Sh NAME
+.Nm mbr_uid_to_uuid,
+.Nm mbr_gid_to_uuid,
+.Nm mbr_uuid_to_id,
+.Nm mbr_sid_to_uuid,
+.Nm mbr_uuid_to_sid
+.Nd user and group identifier translation functions
+.Sh SYNOPSIS
+.In membership.h
+.Ft int
+.Fn mbr_uid_to_uuid "uid_t id" "uuid_t uu"
+.Ft int
+.Fn mbr_gid_to_uuid "gid_t id" "uuid_t uu"
+.Ft int
+.Fn mbr_uuid_to_id "const uuid_t uu" "uid_t *id" "int *id_type"
+.Ft int
+.Fn mbr_sid_to_uuid "const nt_sid_t *sid" "uuid_t uu"
+.Ft int
+.Fn mbr_uuid_to_sid "const uuid_t uu" "nt_sid_t *sid"
+.Sh DESCRIPTION
+Users and groups can be referred to in multiple ways.
+In addition to the traditional uid and gid, 
+every user or group can be referenced by a 128 bit uuid.
+Additionally, if the user or group is hosted on a PDC
+or Active Directory server, it will have a 128 bit or larger sid.
+.Pp
+These routines communicate with the
+.Xr DirectoryService 8
+daemon.
+.Pp
+.Fn mbr_uid_to_uuid
+takes a uid and looks up the associated user account.
+It provides the the uuid for that user as an output parameter.
+.Pp
+.Fn mbr_gid_to_uuid
+similarly gets the uuid associated with a group.
+.Pp
+.Fn mbr_uuid_to_id
+takes a uuid that refers to a user or group and fetches the corresponding uid or gid.
+.Fa id_type
+is set to ID_TYPE_UID or ID_TYPE_GID to indicate which type was found.
+Note that
+.Fn mbr_uuid_to_id
+always returns an id even if the uuid is not found.
+This returned id is not persistant, 
+but can be used to map back to the uuid during runtime.
+To determine if the uuid exists, the returned id can be used in a call to
+.Xr getpwuid 3
+or
+.Xr getgrgid 3 .
+.Pp
+.Fn mbr_sid_to_uuid
+takes a sid and returns the associated uuid.
+Like
+.Fn mbr_uuid_to_id ,
+.Fn mbr_sid_to_uuid
+always returns a uuid for the sid, even if the sid can not be found.
+.Pp
+.Fn mbr_uuid_to_sid
+returns a sid for the associated uuid.
+.Sh RETURN VALUES
+These functions return 0 on success, or EIO if communications with the
+.Xr DirectoryService 8
+daemon fails.
+ENOENT is returned if the mapping can not be performed.
+.Sh SEE ALSO
+.Xr getpwuid 3 ,
+.Xr getgrgid 3 ,
+.Xr mbr_check_membership 3 ,
+.Xr DirectoryService 8
\ No newline at end of file
diff --git a/membership.subproj/mbr_uid_to_uuid_so.3 b/membership.subproj/mbr_uid_to_uuid_so.3
new file mode 100644 (file)
index 0000000..af5c721
--- /dev/null
@@ -0,0 +1 @@
+.so man3/mbr_uid_to_uuid.3
diff --git a/membership.subproj/memberd.defs b/membership.subproj/memberd.defs
deleted file mode 100644 (file)
index 34c65b3..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2004-2007 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
- *
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-
-subsystem memberd 8000;
-
-serverprefix Server;
-
-#include <mach/std_types.defs>
-#include <mach/mach_types.defs>
-import "memberd_defines.h";
-
-type kauth_identity_extlookup = struct [200] of uint8_t;
-type guid_t = struct [16] of uint8_t;
-
-type StatBlock = struct [16] of uint32_t;
-
-type GIDArray = array [16] of uint32_t;
-
-type string = c_string[*:256];
-
-routine _mbr_DoMembershipCall
-(
-       server: mach_port_t;
-       inout request: kauth_identity_extlookup;
-       UserSecToken token : security_token_t
-);
-
-routine _mbr_GetStats
-(
-       server: mach_port_t;
-       out stats: StatBlock;
-       UserSecToken token : security_token_t
-);
-
-routine _mbr_ClearStats
-(
-       server: mach_port_t;
-       UserSecToken token : security_token_t
-);
-
-routine _mbr_MapName
-(
-       server: mach_port_t;
-       in isUser: uint8_t;
-       in name: string;
-       out guid: guid_t;
-       UserSecToken token : security_token_t
-);
-
-routine _mbr_GetGroups
-(
-       server: mach_port_t;
-       in uid: uint32_t;
-       out numGroups: uint32_t;
-       out gids: GIDArray;
-       UserSecToken token : security_token_t
-);
-routine _mbr_ClearCache
-(
-       server: mach_port_t;
-       UserSecToken token : security_token_t
-);
-
-routine _mbr_DumpState
-(
-       server: mach_port_t;
-       in logOnly: uint8_t;
-       UserSecToken token : security_token_t
-);
diff --git a/membership.subproj/memberd_defines.h b/membership.subproj/memberd_defines.h
deleted file mode 100644 (file)
index 6fbb468..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (c) 2004 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License").  You may not use this file except in compliance with the
- * License.  Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
- *
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef USER_API_DEFINES
-#define USER_API_DEFINES
-#import <sys/types.h>
-#import <sys/kauth.h>
-
-typedef struct kauth_identity_extlookup kauth_identity_extlookup;
-typedef char* string;
-
-typedef struct StatBlock
-{
-       uint32_t fTotalUpTime;
-       uint32_t fTotalCallsHandled;
-       uint32_t fAverageuSecPerCall;
-       uint32_t fCacheHits;
-       uint32_t fCacheMisses;
-       uint32_t fTotalRecordLookups;
-       uint32_t fNumFailedRecordLookups;
-       uint32_t fAverageuSecPerRecordLookup;
-       uint32_t fTotalMembershipSearches;
-       uint32_t fAverageuSecPerMembershipSearch;
-       uint32_t fTotalLegacySearches;
-       uint32_t fAverageuSecPerLegacySearch;
-       uint32_t fTotalGUIDMemberSearches;
-       uint32_t fAverageuSecPerGUIDMemberSearch;
-       uint32_t fTotalNestedMemberSearches;
-       uint32_t fAverageuSecPerNestedMemberSearch;
-} StatBlock;
-
-typedef uint32_t GIDArray[16];
-
-#endif
\ No newline at end of file
index 30014af3ede7b5c8ffe7f4f4ecca81be956e3fad..a650f90c9244cbc879d97444652214eeb089f9c8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004-2007 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2004-2007 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 
 #include "membership.h"
 #include "membershipPriv.h"
-#include "memberd.h"
-
+#include "DSmemberdMIG.h"
+#include "DSmemberdMIG_types.h"
 #include <sys/errno.h>
-#include <servers/bootstrap.h>
 #include <mach/mach.h>
+#include <servers/bootstrap.h>
 #include <stdlib.h>
 #include <libkern/OSByteOrder.h>
 
-static mach_port_t GetServerPort()
+
+extern mach_port_t _ds_port;
+extern int _ds_running(void);
+
+static const uint8_t _mbr_root_uuid[] = {0xff, 0xff, 0xee, 0xee, 0xdd, 0xdd, 0xcc, 0xcc, 0xbb, 0xbb, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x00};
+
+#define MAX_LOOKUP_ATTEMPTS 10
+
+__private_extern__ uid_t
+audit_token_uid(audit_token_t a)
 {
-       kern_return_t result;
-       static mach_port_t bsPort = 0;
-       static mach_port_t fServerPort = 0;
+       /*
+        * This should really call audit_token_to_au32,
+        * but that's in libbsm, not in a Libsystem library.
+        */
+       return (uid_t)a.val[1];
+}
 
-       if (bsPort == 0)
+static int
+_mbr_MembershipCall(struct kauth_identity_extlookup *req)
+{
+       audit_token_t token;
+       kern_return_t status;
+       uint32_t i;
+
+       if (_ds_running() == 0) return EIO;
+       if (_ds_port == MACH_PORT_NULL) return EIO;
+
+       memset(&token, 0, sizeof(audit_token_t));
+
+       status = MIG_SERVER_DIED;
+       for (i = 0; (_ds_port != MACH_PORT_NULL) && (status == MIG_SERVER_DIED) && (i < MAX_LOOKUP_ATTEMPTS); i++)
        {
-               result = task_get_bootstrap_port(mach_task_self(), &bsPort);
-               result = bootstrap_look_up(bsPort, "com.apple.memberd", &fServerPort);
+               status = memberdDSmig_MembershipCall(_ds_port, req, &token);
+               if (status == MACH_SEND_INVALID_DEST)
+               {
+                       mach_port_mod_refs(mach_task_self(), _ds_port, MACH_PORT_RIGHT_SEND, -1);
+                       _ds_port = MACH_PORT_NULL;
+                       _ds_running();
+                       status = MIG_SERVER_DIED;
+               }
        }
 
-       return fServerPort;
+       if (status != KERN_SUCCESS) return EIO;
+       if (audit_token_uid(token) != 0) return EAUTH;
+
+       return 0;
+}
+
+static int
+_mbr_MapName(char *name, int type, guid_t *uu)
+{
+       kern_return_t status;
+       audit_token_t token;
+       uint32_t i;
+
+       if (name == NULL) return EINVAL;
+       if (strlen(name) > 255) return EINVAL;
+
+       if (_ds_running() == 0) return EIO;
+       if (_ds_port == MACH_PORT_NULL) return EIO;
+
+       memset(&token, 0, sizeof(audit_token_t));
+
+       status = MIG_SERVER_DIED;
+       for (i = 0; (_ds_port != MACH_PORT_NULL) && (status == MIG_SERVER_DIED) && (i < MAX_LOOKUP_ATTEMPTS); i++)
+       {
+               status = memberdDSmig_MapName(_ds_port, type, name, uu, &token);
+               if (status == KERN_FAILURE) return ENOENT;
+
+               if (status == MACH_SEND_INVALID_DEST)
+               {
+                       mach_port_mod_refs(mach_task_self(), _ds_port, MACH_PORT_RIGHT_SEND, -1);
+                       _ds_port = MACH_PORT_NULL;
+                       _ds_running();
+                       status = MIG_SERVER_DIED;
+               }
+       }
+
+       if (status != KERN_SUCCESS) return EIO;
+       if (audit_token_uid(token) != 0) return EAUTH;
+
+       return 0;
+}
+
+static int
+_mbr_ClearCache()
+{
+       kern_return_t status;
+       uint32_t i;
+
+       if (_ds_running() == 0) return EIO;
+       if (_ds_port == MACH_PORT_NULL) return EIO;
+
+       status = MIG_SERVER_DIED;
+       for (i = 0; (_ds_port != MACH_PORT_NULL) && (status == MIG_SERVER_DIED) && (i < MAX_LOOKUP_ATTEMPTS); i++)
+       {
+               status = memberdDSmig_ClearCache(_ds_port);
+               if (status == MACH_SEND_INVALID_DEST)
+               {
+                       mach_port_mod_refs(mach_task_self(), _ds_port, MACH_PORT_RIGHT_SEND, -1);
+                       _ds_port = MACH_PORT_NULL;
+                       _ds_running();
+                       status = MIG_SERVER_DIED;
+               }
+       }
+
+       if (status != KERN_SUCCESS) return EIO;
+
+       return 0;
 }
 
 int mbr_uid_to_uuid(uid_t id, uuid_t uu)
 {
        struct kauth_identity_extlookup request;
-       security_token_t token;
-       int result = 0;
+       int status;
 
-       token.val[0] = -1;
-       token.val[1] = -1;
+       if (id == 0)
+       {
+               memcpy(uu, _mbr_root_uuid, sizeof(uuid_t));
+               return 0;
+       }
 
-       request.el_seqno = 1;  /* used as byte order field */
+       /* used as a byte order field */
+       request.el_seqno = 1;
        request.el_flags = KAUTH_EXTLOOKUP_VALID_UID | KAUTH_EXTLOOKUP_WANT_UGUID;
        request.el_uid = id;
-       result = _mbr_DoMembershipCall(GetServerPort(), &request, &token);
-       if (result != KERN_SUCCESS) return EIO;
-       if (token.val[0] != 0) return EAUTH;
 
-       if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_UGUID) != 0)
-               memcpy(uu, &request.el_uguid, sizeof(guid_t));
-       else
-               result = ENOENT;
+       status = _mbr_MembershipCall(&request);
+       if (status != 0) return status;
+       if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_UGUID) == 0) return ENOENT;
 
-       return result;
+       memcpy(uu, &request.el_uguid, sizeof(guid_t));
+       return 0;
 }
 
 int mbr_gid_to_uuid(gid_t id, uuid_t uu)
 {
        struct kauth_identity_extlookup request;
-       security_token_t token;
-       kern_return_t result;
-       int error = 0;
-
-       token.val[0] = -1;
-       token.val[1] = -1;
+       int status;
 
-       request.el_seqno = 1;  /* used as byte order field */
+       request.el_seqno = 1;
        request.el_flags = KAUTH_EXTLOOKUP_VALID_GID | KAUTH_EXTLOOKUP_WANT_GGUID;
        request.el_gid = id;
-       result = _mbr_DoMembershipCall(GetServerPort(), &request, &token);
-       if (result != KERN_SUCCESS) return EIO;
-       if (token.val[0] != 0) return EAUTH;
 
-       if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_GGUID) != 0)
-               memcpy(uu, &request.el_gguid, sizeof(guid_t));
-       else
-               error = ENOENT;
+       status = _mbr_MembershipCall(&request);
+       if (status != 0) return status;
+       if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_GGUID) == 0) return ENOENT;
 
-       return error;
+       memcpy(uu, &request.el_gguid, sizeof(guid_t));
+       return 0;
 }
 
 int mbr_uuid_to_id(const uuid_t uu, uid_t *id, int *id_type)
 {
        struct kauth_identity_extlookup request;
-       security_token_t token;
-       kern_return_t result;
-       int error = 0;
+       int status;
 
-       token.val[0] = -1;
-       token.val[1] = -1;
+       if (id == NULL) return EIO;
+       if (id_type == NULL) return EIO;
 
-       request.el_seqno = 1;  /* used as byte order field */
+       if (!memcmp(uu, _mbr_root_uuid, sizeof(uuid_t)))
+       {
+               *id = 0;
+               *id_type = ID_TYPE_UID;
+               return 0;
+       }
+
+       request.el_seqno = 1;
        request.el_flags = KAUTH_EXTLOOKUP_VALID_UGUID | KAUTH_EXTLOOKUP_VALID_GGUID | KAUTH_EXTLOOKUP_WANT_UID | KAUTH_EXTLOOKUP_WANT_GID;
        memcpy(&request.el_uguid, uu, sizeof(guid_t));
        memcpy(&request.el_gguid, uu, sizeof(guid_t));
-       result = _mbr_DoMembershipCall(GetServerPort(), &request, &token);
-       if (result != KERN_SUCCESS) return EIO;
-       if (token.val[0] != 0) return EAUTH;
+
+       status = _mbr_MembershipCall(&request);
+       if (status != 0) return status;
 
        if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_UID) != 0)
        {
@@ -124,194 +218,140 @@ int mbr_uuid_to_id(const uuid_t uu, uid_t *id, int *id_type)
        }
        else
        {
-               error = ENOENT;
+               return ENOENT;
        }
 
-       return error;
+       return 0;
 }
 
 int mbr_sid_to_uuid(const nt_sid_t *sid, uuid_t uu)
 {
        struct kauth_identity_extlookup request;
-       security_token_t token;
-       kern_return_t result;
-       int error = 0;
+       int status;
 
-       token.val[0] = -1;
-       token.val[1] = -1;
-
-       request.el_seqno = 1;  /* used as byte order field */
+       request.el_seqno = 1;
        request.el_flags = KAUTH_EXTLOOKUP_VALID_GSID | KAUTH_EXTLOOKUP_WANT_GGUID;
        memset(&request.el_gsid, 0, sizeof(ntsid_t));
        memcpy(&request.el_gsid, sid, KAUTH_NTSID_SIZE(sid));
-       result = _mbr_DoMembershipCall(GetServerPort(), &request, &token);
-       if (result != KERN_SUCCESS) return EIO;
-       if (token.val[0] != 0) return EAUTH;
 
-       if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_GGUID) != 0)
-               memcpy(uu, &request.el_gguid, sizeof(guid_t));
-       else
-               error = ENOENT;
+       status = _mbr_MembershipCall(&request);
+       if (status != 0) return status;
+       if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_GGUID) == 0) return ENOENT;
 
-       return error;
+       memcpy(uu, &request.el_gguid, sizeof(guid_t));
+       return 0;
 }
 
-int mbr_uuid_to_sid(const uuid_t uu, nt_sid_t *sid)
+int mbr_uuid_to_sid_type(const uuid_t uu, nt_sid_t *sid, int *id_type)
 {
        struct kauth_identity_extlookup request;
-       security_token_t token;
-       kern_return_t result;
-       int error = 0;
+       int status;
 
-       token.val[0] = -1;
-       token.val[1] = -1;
-
-       request.el_seqno = 1;  /* used as byte order field */
-       request.el_flags = KAUTH_EXTLOOKUP_VALID_GGUID | KAUTH_EXTLOOKUP_WANT_GSID;
+       request.el_seqno = 1;
+       request.el_flags = KAUTH_EXTLOOKUP_VALID_UGUID | KAUTH_EXTLOOKUP_VALID_GGUID | KAUTH_EXTLOOKUP_WANT_USID | KAUTH_EXTLOOKUP_WANT_GSID;
+       memcpy(&request.el_uguid, uu, sizeof(guid_t));
        memcpy(&request.el_gguid, uu, sizeof(guid_t));
-       result = _mbr_DoMembershipCall(GetServerPort(), &request, &token);
-       if (result != KERN_SUCCESS) return EIO;
-       if (token.val[0] != 0) return EAUTH;
 
-       if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_GSID) != 0)
+       status = _mbr_MembershipCall(&request);
+       if (status != 0) return status;
+
+       if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_USID) != 0)
+       {
+               *id_type = SID_TYPE_USER;
+               memcpy(sid, &request.el_usid, sizeof(nt_sid_t));
+       }
+       else if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_GSID) != 0)
+       {
+               *id_type = SID_TYPE_GROUP;
                memcpy(sid, &request.el_gsid, sizeof(nt_sid_t));
+       }
        else
-               error = ENOENT;
+       {
+               return ENOENT;
+       }
+
+       return 0;
+}
+
+int mbr_uuid_to_sid(const uuid_t uu, nt_sid_t *sid)
+{
+       int type, status;
 
-       return error;
+       type = 0;
+
+       status = mbr_uuid_to_sid_type(uu, sid, &type);
+       if (status != 0) return status;
+
+       return 0;
 }
 
 int mbr_check_membership(uuid_t user, uuid_t group, int *ismember)
 {
        struct kauth_identity_extlookup request;
-       security_token_t token;
-       kern_return_t result;
-       int error = 0;
-
-       token.val[0] = -1;
-       token.val[1] = -1;
+       int status;
 
-       request.el_seqno = 1;  /* used as byte order field */
+       request.el_seqno = 1;
        request.el_flags = KAUTH_EXTLOOKUP_VALID_UGUID | KAUTH_EXTLOOKUP_VALID_GGUID | KAUTH_EXTLOOKUP_WANT_MEMBERSHIP;
        memcpy(&request.el_uguid, user, sizeof(guid_t));
        memcpy(&request.el_gguid, group, sizeof(guid_t));
-       result = _mbr_DoMembershipCall(GetServerPort(), &request, &token);
-       if (result != KERN_SUCCESS) return EIO;
-       if (token.val[0] != 0) return EAUTH;
 
-       if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_MEMBERSHIP) != 0)
-               *ismember = ((request.el_flags & KAUTH_EXTLOOKUP_ISMEMBER) != 0);
-       else
-               error = ENOENT;
+       status = _mbr_MembershipCall(&request);
+       if (status != 0) return status;
+       if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_MEMBERSHIP) == 0) return ENOENT;
 
-       return error;
+       *ismember = ((request.el_flags & KAUTH_EXTLOOKUP_ISMEMBER) != 0);
+       return 0;
 }
 
-int mbr_check_membership_refresh(uuid_t user, uuid_t group, int *ismember)
+int mbr_check_membership_refresh(const uuid_t user, uuid_t group, int *ismember)
 {
        struct kauth_identity_extlookup request;
-       security_token_t token;
-       kern_return_t result;
-       int error = 0;
+       int status;
 
-       token.val[0] = -1;
-       token.val[1] = -1;
-
-       request.el_seqno = 1;  /* used as byte order field */
-       request.el_flags = KAUTH_EXTLOOKUP_VALID_UGUID | KAUTH_EXTLOOKUP_VALID_GGUID | KAUTH_EXTLOOKUP_WANT_MEMBERSHIP | (1 << 15);
+       request.el_seqno = 1;
+       request.el_flags = KAUTH_EXTLOOKUP_VALID_UGUID | KAUTH_EXTLOOKUP_VALID_GGUID | KAUTH_EXTLOOKUP_WANT_MEMBERSHIP | (1<<15);
        memcpy(&request.el_uguid, user, sizeof(guid_t));
        memcpy(&request.el_gguid, group, sizeof(guid_t));
-       result = _mbr_DoMembershipCall(GetServerPort(), &request, &token);
-       if (result != KERN_SUCCESS) return EIO;
-       if (token.val[0] != 0) return EAUTH;
 
-       if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_MEMBERSHIP) != 0)
-               *ismember = ((request.el_flags & KAUTH_EXTLOOKUP_ISMEMBER) != 0);
-       else
-               error = ENOENT;
+       status = _mbr_MembershipCall(&request);
+       if (status != 0) return status;
+       if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_MEMBERSHIP) == 0) return ENOENT;
 
-       return error;
+       *ismember = ((request.el_flags & KAUTH_EXTLOOKUP_ISMEMBER) != 0);
+       return 0;
 }
 
 int mbr_check_membership_by_id(uuid_t user, gid_t group, int *ismember)
 {
        struct kauth_identity_extlookup request;
-       security_token_t token;
-       kern_return_t result;
-       int error = 0;
-
-       token.val[0] = -1;
-       token.val[1] = -1;
+       int status;
 
-       request.el_seqno = 1;  /* used as byte order field */
+       request.el_seqno = 1;
        request.el_flags = KAUTH_EXTLOOKUP_VALID_UGUID | KAUTH_EXTLOOKUP_VALID_GID | KAUTH_EXTLOOKUP_WANT_MEMBERSHIP;
        memcpy(&request.el_uguid, user, sizeof(guid_t));
        request.el_gid = group;
-       result = _mbr_DoMembershipCall(GetServerPort(), &request, &token);
-       if (result != KERN_SUCCESS) return EIO;
-       if (token.val[0] != 0) return EAUTH;
 
-       if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_MEMBERSHIP) != 0)
-               *ismember = ((request.el_flags & KAUTH_EXTLOOKUP_ISMEMBER) != 0);
-       else
-               error = ENOENT;
+       status = _mbr_MembershipCall(&request);
+       if (status != 0) return status;
+       if ((request.el_flags & KAUTH_EXTLOOKUP_VALID_MEMBERSHIP) == 0) return ENOENT;
 
-       return error;
+       *ismember = ((request.el_flags & KAUTH_EXTLOOKUP_ISMEMBER) != 0);
+       return 0;
 }
 
 int mbr_reset_cache()
 {
-       security_token_t token;
-       kern_return_t result;
-
-       token.val[0] = -1;
-       token.val[1] = -1;
-
-       result = _mbr_ClearCache(GetServerPort(), &token);
-       if (result != KERN_SUCCESS) return EIO;
-       if (token.val[0] != 0) return EAUTH;
-
-       return 0;
+       return _mbr_ClearCache();
 }
 
 int mbr_user_name_to_uuid(const char *name, uuid_t uu)
 {
-       security_token_t token;
-       kern_return_t result;
-
-       if (name == NULL) return EINVAL;
-       if (strlen(name) > 255) return EINVAL;
-
-       token.val[0] = -1;
-       token.val[1] = -1;
-
-       result = _mbr_MapName(GetServerPort(), 1, (char *)name, (guid_t *)uu, &token);
-       if (result == KERN_FAILURE) return ENOENT;
-       else if (result != KERN_SUCCESS) return EIO;
-
-       if (token.val[0] != 0) return EAUTH;
-
-       return 0;
+       return _mbr_MapName((char *)name, 1, (guid_t *)uu);
 }
 
 int mbr_group_name_to_uuid(const char *name, uuid_t uu)
 {
-       security_token_t token;
-       kern_return_t result;
-
-       if (name == NULL) return EINVAL;
-       if (strlen(name) > 255) return EINVAL;
-
-       token.val[0] = -1;
-       token.val[1] = -1;
-
-       result = _mbr_MapName(GetServerPort(), 0, (char *)name, (guid_t *)uu, &token);
-       if (result == KERN_FAILURE) return ENOENT;
-       else if (result != KERN_SUCCESS) return EIO;
-
-       if (token.val[0] != 0) return EAUTH;
-
-       return 0;
+       return _mbr_MapName((char *)name, 0, (guid_t *)uu);
 }
 
 int mbr_check_service_membership(const uuid_t user, const char *servicename, int *ismember)
@@ -323,7 +363,7 @@ int mbr_check_service_membership(const uuid_t user, const char *servicename, int
        int result, dummy;
 
        if (servicename == NULL) return EINVAL;
-       if (strlen(servicename) > (255 - strlen(prefix))) return EINVAL;
+       if (strlen(servicename) > 255 - strlen(prefix)) return EINVAL;
 
        /* start by checking "all services" */
        result = mbr_group_name_to_uuid(all_services, group_uu);
@@ -362,7 +402,8 @@ static char *ConvertBytesToDecimal(char *buffer, unsigned long long value)
        buffer[24] = '\0';
        buffer[23] = '0';
 
-       if (value == 0) return &buffer[23];
+       if (value == 0)
+               return &buffer[23];
 
        temp = &buffer[24];
        while (value != 0)
@@ -396,7 +437,7 @@ int mbr_sid_to_string(const nt_sid_t *sid, char *string)
        current++;
        strcpy(current, ConvertBytesToDecimal(tempBuffer, temp));
 
-       for (i = 0; i < sid->sid_authcount; i++)
+       for(i=0; i < sid->sid_authcount; i++)
        {
                current = current + strlen(current);
                *current = '-';
@@ -409,12 +450,14 @@ int mbr_sid_to_string(const nt_sid_t *sid, char *string)
 
 int mbr_string_to_sid(const char *string, nt_sid_t *sid)
 {
-       char *current = string+2;
+       char *current = (char *)string+2;
        int count = 0;
        long long temp;
 
+       if (string == NULL) return EINVAL;
+
        memset(sid, 0, sizeof(nt_sid_t));
-       if ((string[0] != 'S') || (string[1] != '-')) return EINVAL;
+       if (string[0] != 'S' || string[1] != '-') return EINVAL;
 
        sid->sid_kind = strtol(current, &current, 10);
        if (*current == '\0') return EINVAL;
@@ -424,7 +467,7 @@ int mbr_string_to_sid(const char *string, nt_sid_t *sid)
        /* convert to BigEndian before copying */
        temp = OSSwapHostToBigInt64(temp);
        memcpy(sid->sid_authority, ((char*)&temp)+2, 6);
-       while ((*current != '\0') && (count < NTSID_MAX_AUTHORITIES))
+       while (*current != '\0' && count < NTSID_MAX_AUTHORITIES)
        {
                current++;
                sid->sid_authorities[count] = strtol(current, &current, 10);
@@ -442,7 +485,7 @@ static void ConvertBytesToHex(char **string, char **data, int numBytes)
 {
        int i;
 
-       for (i = 0; i < numBytes; i++)
+       for (i=0; i < numBytes; i++)
        {
                unsigned char hi = ((**data) >> 4) & 0xf;
                unsigned char low = (**data) & 0xf;
@@ -465,7 +508,7 @@ static void ConvertBytesToHex(char **string, char **data, int numBytes)
 
 int mbr_uuid_to_string(const uuid_t uu, char *string)
 {
-       char *guid = (char *)uu;
+       char *guid = (char*)uu;
        char *strPtr = string;
        ConvertBytesToHex(&strPtr, &guid, 4);
        *strPtr = '-'; strPtr++;
@@ -486,28 +529,23 @@ int mbr_string_to_uuid(const char *string, uuid_t uu)
        short dataIndex = 0;
        int isFirstNibble = 1;
 
-       if (strlen(string) > MBR_UU_STRING_SIZE)
-               return EINVAL;
+       if (string == NULL) return EINVAL;
+       if (strlen(string) > MBR_UU_STRING_SIZE) return EINVAL;
 
        while (*string != '\0' && dataIndex < 16)
        {
                char nibble;
 
-               if ((*string >= '0') && (*string <= '9'))
-               {
+               if (*string >= '0' && *string <= '9')
                        nibble = *string - '0';
-               }
-               else if ((*string >= 'A') && (*string <= 'F'))
-               {
+               else if (*string >= 'A' && *string <= 'F')
                        nibble = *string - 'A' + 10;
-               }
-               else if ((*string >= 'a') && (*string <= 'f'))
-               {
+               else if (*string >= 'a' && *string <= 'f')
                        nibble = *string - 'a' + 10;
-               }
                else
                {
-                       if (*string != '-') return EINVAL;
+                       if (*string != '-')
+                               return EINVAL;
                        string++;
                        continue;
                }
@@ -531,3 +569,4 @@ int mbr_string_to_uuid(const char *string, uuid_t uu)
 
        return 0;
 }
+
index 580b8db901c053199166dddc4b7b4704481c3c7e..35a6fe375beba2deeeff8e47485e0facfcf74995 100644 (file)
 #include <uuid/uuid.h>
 #include <ntsid.h>
 
-int mbr_reset_cache();
-int mbr_user_name_to_uuid(const char* name, uuid_t uu);
-int mbr_group_name_to_uuid(const char* name, uuid_t uu);
-int mbr_check_membership_by_id(uuid_t user, gid_t group, int* ismember);
-int mbr_check_service_membership(const uuid_t user, const char* servicename, int* ismember);
-
 #define MBR_UU_STRING_SIZE 37
 #define MBR_MAX_SID_STRING_SIZE 200
 
-int mbr_uuid_to_string(const uuid_t uu, char* string);
-int mbr_string_to_uuid(const char* string, uuid_t uu);
-int mbr_sid_to_string(const nt_sid_t* sid, char* string);
-int mbr_string_to_sid(const char* string, nt_sid_t* sid);
+#define SID_TYPE_USER 0
+#define SID_TYPE_GROUP 1
+
+__BEGIN_DECLS
+
+int mbr_reset_cache();
+int mbr_user_name_to_uuid(const char *name, uuid_t uu);
+int mbr_group_name_to_uuid(const char *name, uuid_t uu);
+int mbr_check_membership_by_id(uuid_t user, gid_t group, int *ismember);
+int mbr_check_service_membership(const uuid_t user, const char *servicename, int *ismember);
+int mbr_check_membership_refresh(const uuid_t user, uuid_t group, int *ismember);
+int mbr_uuid_to_string(const uuid_t uu, char *string);
+int mbr_string_to_uuid(const char *string, uuid_t uu);
+int mbr_sid_to_string(const nt_sid_t *sid, char *string);
+int mbr_string_to_sid(const char *string, nt_sid_t *sid);
+int mbr_uuid_to_sid_type(const uuid_t uu, nt_sid_t *sid, int *id_type);
+
+__END_DECLS
 
 #endif /* !_MEMBERSHIPPRIV_H_ */
index 015435bd661a78e1093956b68c1234f4c30f6d49..1be3deab37f96dd0744de9aa67d66bce8c069492 100644 (file)
@@ -12,14 +12,10 @@ NAME = netinfo
 PROJECTVERSION = 2.8
 PROJECT_TYPE = Component
 
-HFILES = clib.h mm.h ni.h ni_util.h sys_interfaces.h
-
-CFILES = multi_call.c ni_error.c ni_glue.c ni_pwdomain.c ni_useful.c\
-         ni_util.c sys_interfaces.c
-
-OTHERSRCS = Makefile.preamble Makefile Makefile.postamble nibind_prot.x\
-            ni_prot.x netinfo.3 netinfo.5
+HFILES = 
+CFILES = ni_stub.c
 
+OTHERSRCS = Makefile Makefile.preamble
 
 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
 CODE_GEN_STYLE = DYNAMIC
@@ -28,12 +24,9 @@ LIBS =
 DEBUG_LIBS = $(LIBS)
 PROF_LIBS = $(LIBS)
 
-
-PRIVATE_HEADERS = ni.h ni_util.h nibind_prot.x ni_prot.x
-
-
-
-NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+PRIVATE_HEADERS = 
+# NEXTSTEP_OBJCPLUS_COMPILER = /usr/bin/cc
+NEXTSTEP_OBJCPLUS_COMPILER = $(CCOMPILER)
 WINDOWS_OBJCPLUS_COMPILER = $(DEVDIR)/gcc
 PDO_UNIX_OBJCPLUS_COMPILER = $(NEXTDEV_BIN)/gcc
 NEXTSTEP_JAVA_COMPILER = /usr/bin/javac
diff --git a/netinfo.subproj/Makefile.postamble b/netinfo.subproj/Makefile.postamble
deleted file mode 100644 (file)
index 0c5d83e..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-MAN3DIR=/usr/share/man/man3
-MAN5DIR=/usr/share/man/man5
-
-install-netinfo-man:
-       install -m 755 -o root -g wheel -d $(DSTROOT)$(MAN5DIR)
-       install -m 644 -o root -g wheel -c netinfo.5 "$(DSTROOT)$(MAN5DIR)"
-
-%_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
index 8637aaba05f2ab4efbbc6218c2862590f834b8aa..004b71b7c6c685d2c58690d81366f1ebcafaf87f 100644 (file)
@@ -1,10 +1,4 @@
-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)
-AFTER_POSTINSTALL += install-netinfo-man
-OTHER_PRIVATE_HEADERS = $(NETINFO_HEADERS)
-BEFORE_INSTALLHEADERS += $(NETINFO_HEADERS)
-PRIVATE_HEADER_DIR = /usr/local/include/netinfo
+OTHER_CFLAGS += -D__DARWIN_NON_CANCELABLE=1
 
 # for building 64-bit
 # <rdar://problem/3819761> Libinfo need to build with gcc-3.5 and 3-way fat
index a527e8929a2549328671cbed8c6ec6c2236592d1..0d879af119571a95b46058cea62820d20dd59b41 100644 (file)
@@ -1,18 +1,10 @@
 {
     DYNAMIC_CODE_GEN = YES; 
     FILESTABLE = {
-        H_FILES = (clib.h, mm.h, ni.h, ni_util.h, sys_interfaces.h); 
-        OTHER_LINKED = (multi_call.c, ni_error.c, ni_glue.c, ni_pwdomain.c, ni_useful.c, ni_util.c, sys_interfaces.c); 
-        OTHER_SOURCES = (
-            Makefile.preamble, 
-            Makefile, 
-            Makefile.postamble, 
-            nibind_prot.x, 
-            ni_prot.x, 
-            netinfo.3, 
-            netinfo.5
-        ); 
-        PRIVATE_HEADERS = (ni.h, ni_util.h, ni_prot.x, nibind_prot.x); 
+        H_FILES = (); 
+        OTHER_LINKED = (ni_stub.c); 
+        OTHER_SOURCES = (Makefile.preamble, Makefile); 
+        PRIVATE_HEADERS = (); 
     }; 
     LANGUAGE = English; 
     MAKEFILEDIR = "$(MAKEFILEPATH)/pb_makefiles"; 
diff --git a/netinfo.subproj/clib.h b/netinfo.subproj/clib.h
deleted file mode 100644 (file)
index c9db33b..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A 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 *, unsigned long, unsigned long, unsigned 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
deleted file mode 100644 (file)
index 7c32dee..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A 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
deleted file mode 100644 (file)
index 2d12086..0000000
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A 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 = (long *)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/netinfo.3 b/netinfo.subproj/netinfo.3
deleted file mode 100644 (file)
index 50486b7..0000000
+++ /dev/null
@@ -1,425 +0,0 @@
-.TH NETINFO 3 "August 29, 1989" "Apple Computer, Inc."
-.SH NAME
-netinfo \- library routines for NetInfo calls
-.SH SYNOPSIS
-\fB#include <netinfo/ni.h>\fR
-.SH DESCRIPTION
-These calls are the programming interface to NetInfo.  Typically, 
-a handle (of type "void *") is allocated through a call to
-.I ni_new,
-.I ni_open,
-or
-.I ni_connect.
-This handle opens a connection to the given NetInfo domain.  Read calls
-may go to either the master or the clone servers, while writes will
-always go to the master server.  If the master is unavailable,
-no writes can be performed.
-The handle is then passed to one of several NetInfo routines for database
-operations and then freed using
-.I ni_free.
-Several utility routines are also supplied which operate on NetInfo data
-structures.  These routines don't require NetInfo handles.
-.LP
-.SH MACROS
-.PP
-.B NI_INDEX_NULL
-.IP
-A constant which evaluates to the highest unsigned integer.  It is useful
-for indicating something which should go at the end of a list, as opposed
-to a smaller value which indicates the precise position at which the insert
-should occur.
-.PP
-\fBNI_INIT\fR(\fIptr\fR)
-.IP
-Initializes a NetInfo data structure.  It effectively zeros out the structure
-referred to by
-.I ptr.
-This macro is useful for indicating an empty list or NULL value with one
-of the many NetInfo data structures.
-.SH "DATATYPES AND ASSOCIATED UTILITY ROUTINES"
-.PP
-.B ni_status
-.IP
-The result code of most NetInfo routines.
-.PP
-const char *\fBni_error\fR(ni_status \fIstatus\fR)
-.IP
-Returns the error string associated with the given NetInfo status.
-.PP
-.B ni_index
-.IP
-An index into a NetInfo list.
-.PP
-.B ni_id
-.IP
-NetInfo directories are identified through the
-.I ni_id
-data structure.  It records the ID of the directory in the
-.I nii_object
-field and the instance of the directory in the
-.I nii_instance
-field.  The instance indicates which version of the directory is being
-operated on and is only relevant for writes.  Each time a write is
-performed, the instance is incremented to reflect the new version.  If
-the instance given does not match the current instance of the directory,
-the error NI_STALE is returned, indicating a stale ID.  All NetInfo
-routines which operate on directories will return the latest value of
-the instance.
-.PP
-.B ni_name
-.IP
-A NetInfo name.  It is equivalent to a C string.
-.PP 
-ni_name \fBni_name_dup\fR(const ni_name \fIname\fR)
-.IP
-Returns a mallocated copy of a NetInfo name.
-.PP
-void \fBni_name_free\fR(ni_name *\fInamep\fR)
-.IP
-Frees a NetInfo name.  The pointer is converted to NULL.  A NULL pointer
-will not be freed.
-.PP
-int \fBni_name_match\fR(const ni_name \fIname1\fR, const ni_name \fIname2\fR)
-.IP
-Compares two NetInfo names for equality.  Returns non-zero for success,
-zero for failure.
-.PP
-.B ni_namelist
-.IP
-A list of NetInfo names.
-.PP
-ni_namelist \fBni_namelist_dup\fR(const ni_namelist \fInl\fR)
-.IP
-Returns a mallocated duplicate of a NetInfo namelist.
-.PP
-void \fBni_namelist_free\fR(ni_namelist *\fInl\fR)
-.IP
-Frees a NetInfo namelist.  The namelist structure is zeroed.  Zeroed
-namelists will not be freed.
-.PP
-void \fBni_namelist_insert\fR(ni_namelist *\fInl\fR, const ni_name \fIname\fR, ni_index \fIwhere\fR)
-.IP
-Duplicates and inserts the given name at the given location into the namelist.
-.PP
-void \fBni_namelist_delete\fR(ni_namelist *\fInl\fR, ni_index \fIwhere\fR)
-.IP
-Deletes and frees the name at the given location in the namelist.
-.PP
-ni_index \fBni_namelist_match\fR(const ni_namelist \fInl\fR, const ni_name \fIname\fR)
-.IP
-If the name is in the given namelist, the first index of its occurrence
-is returned.  Otherwise, NI_INDEX_NULL is returned indicating failure.
-.PP
-.B ni_property
-.IP
-A NetInfo property.  It contains a name and a namelist of associated values.
-.PP 
-ni_property \fBni_prop_dup\fR(const ni_property \fIprop\fR)
-.IP
-Returns a mallocated duplicate of the given NetInfo property.
-.PP
-void \fBni_prop_free\fR(ni_property *\fIprop\fR)
-.IP
-Frees and zeros the NetInfo property.  Zeroed properties will not be freed
-again.
-.PP
-.B ni_proplist
-.IP
-A list of NetInfo properties.
-.PP
-void \fBni_proplist_insert\fR(ni_proplist *\fIpl\fR, const ni_property \fIprop\fR, ni_index \fIwhere\fR)
-.IP
-Duplicates and inserts the given property at the given location into the given property
-list.
-.PP
-void \fBni_proplist_delete\fR(ni_proplist *\fIpl\fR, ni_index \fIwhere\fR)
-.IP
-Frees and deletes the property at the given location in the property list.
-.PP
-ni_index \fBni_proplist_match\fR(const ni_proplist \fIpl\fR, const ni_name \fIname\fR, const ni_name \fIval\fR)
-.IP
-Returns the location in the property list of the first property with a name
-of 
-.I name
-and having value
-.I val.
-NI_INDEX_NULL is returned on failure.
-If NULL is the \fIvalue\fR argument,
-\fBni_proplist_match\fR will match on only the \fIname\fR argument.
-.PP
-ni_proplist \fBni_proplist_dup\fR(const ni_proplist \fIpl\fR)
-.IP
-Returns a mallocated duplicate property list.
-.PP
-void \fBni_proplist_free\fR(ni_proplist *\fIpl\fR)
-.IP
-Frees and zeroes the property list.  A zeroed property will not be freed again.
-.PP
-.B ni_idlist
-.IP
-A list of NetInfo indices (usually directory ID's).
-.PP
-void \fBni_idlist_free\fR(ni_idlist *\fIidl\fR)
-.IP
-Frees and zeroes the given ID list.  A zeroed ID list will not be freed again.
-.PP
-.B ni_entry
-.IP
-An entry in a NetInfo directory.  It contains the ID of the directory and
-a list of values assocated with whatever property was requested in the
-.I ni_list
-routine.  The list may be NULL, indicating that there is not associated
-property for this directory.
-.PP
-.B ni_entrylist
-.IP
-A list of NetInfo entries.
-.PP
-void \fBni_entrylist_free\fR(ni_entrylist *\fIentries\fR)
-.IP
-Frees and zeros the given entry list.  A zeroed entry list will not be
-freed again.
-.LP
-.SH "ROUTINES"
-.PP
-ni_status \fBni_addrtag\fR(void *\fIhandle\fR, struct sockaddr_in *\fIaddr\fR, ni_name *\fItag\fR)
-.IP
-Returns the address and domain tag associated with the connected
-NetInfo handle.
-.PP
-ni_status \fBni_children\fR(void *\fIhandle\fR, ni_id *\fIdir\fR, ni_idlist *\fIidlist\fR)
-.IP
-Lists the children ID's (subdirectories) of the given directory.
-.PP
-void *\fBni_connect\fR(struct sockaddr_in *\fIaddr\fR, ni_name \fItag\fR)
-.IP
-Returns a NetInfo handle to the NetInfo domain at the given address
-and domain tag.  Returns NULL on failure.
-.PP
-ni_status \fBni_create\fR(void *\fIhandle\fR, ni_id *\fIparent\fR, ni_proplist \fIprops\fR, ni_id *\fIchild\fR, ni_index \fIwhere\fR)
-.IP
-Creates a new directory at the given index initialized with the given 
-properties.
-.PP
-ni_status \fBni_createname\fR(void *\fIhandle\fR, ni_id *\fIdir\fR, ni_index \fIprop_index\fR, ni_name \fIname\fR, ni_index \fIval_index\fR)
-.IP
-Inserts the name into the value list of the given directory at the property
-indexed by prop_index and value list location val_index.
-.PP
-ni_status \fBni_createprop\fR(void *\fIhandle\fR, ni_id *\fIdir\fR, ni_property \fIprop\fR, ni_index \fIwhere\fR)
-.IP
-Creates a new property at the given index in the given directory.
-.PP
-ni_status \fBni_destroy\fR(void *\fIhandle\fR, ni_id *\fIparent\fR, ni_id \fIchild\fR)
-.IP
-Destroys the directory child in the given parent directory.  Both instance
-must be the latest values or the error NI_STALE is returned.
-.PP
-ni_status \fBni_destroyname\fR(void *\fIhandle\fR, ni_id *\fIdir\fR, ni_index \fIprop_index\fR, ni_index \fIval_index\fR)
-.IP
-Destroys a property value in the given directory at the given prop_index and
-value-list val_index.
-.PP
-ni_status \fBni_destroyprop\fR(void *\fIhandle\fR, ni_id *\fIdir\fR, ni_index \fIwhere\fR)
-.IP
-Destroys the property at property index
-.I where
-in the given directory.
-.PP
-ni_status \fBni_fancyopen\fR(void *\fIhandle\fR, ni_name \fIdomain\fR, void **\fIrethandle\fR, ni_fancyopenargs *\fIargs\fR)
-.PP
-.nf
-typedef struct ni_fancyopenargs {
-       int rtimeout; 
-       int wtimeout; 
-       int abort;    
-       int needwrite;
-} ni_fancyopenargs;
-.fi
-.IP
-A fancier version of ni_open which allows one to set
-various attributes on the the returned handle. See 
-.I ni_setreadtimeout(), 
-.I ni_setwritetimeout(), 
-.I ni_setabort()
-and 
-.I ni_needwrite()
-for descriptions of the fields 
-in the ni_fancyopenargs structure. A 0 in the 
-rtimeout or wtimeout field indicates the 
-default timeout should be used.
-.PP
-void \fBni_free\fR(void *\fIhandle\fR)
-.IP
-Frees a NetInfo handle and closes any associated connections.
-.PP
-ni_status \fBni_list\fR(void *\fIhandle\fR, ni_id *\fIdir\fR , ni_name \fIname\fR, ni_entrylist *\fIentries\fR)
-.IP
-Lists all the subdirectories of the given directory along with any associated
-values they may have for the property 
-.I name.
-If a subdirectory doesn't have the property \fIname\fR,
-the entry is still returned but with a NULL property list.
-.PP
-ni_status \fBni_listprops\fR(void *\fIhandle\fR, ni_id *\fIdir\fR, ni_namelist *\fInl\fR)
-.IP
-Returns the list of property names associated with the given directory.
-.PP
-ni_status \fBni_lookup\fR(void *\fIhandle\fR, ni_id *\fIdir\fR, ni_name \fIname\fR, ni_name \fIval\fR, ni_idlist *\fIfound\fR)
-.IP
-Returns a list of subdirectories which satisfy the relation 
-.I name
-equals
-.I val.
-.PP
-ni_status \fBni_lookupprop\fR(void *\fIhandle\fR, ni_id *\fIdir\fR, ni_name \fIname\fR, ni_namelist *\fIval\fR)
-.IP
-Returns the values associated with the property named 
-.I name
-in the given directory.
-.PP
-ni_status \fBni_lookupread\fR(void *\fIhandle\fR, ni_id *\fIdirid\fR, ni_name \fIpropname\fR, ni_name \fIpropval\fR, ni_proplist *\fIprops\fR)
-.IP
-Looks up the subdirectory given the 
-.I (propname, propval\) 
-pair
-and returns the subdirectory's properties. This call is equivalent to 
-an 
-.I ni_lookup() 
-followed by an 
-.I ni_read().
-.PP
-void \fBni_needwrite\fR(void *\fIhandle\fR, int \fIneedwrite\fR)
-.IP
-Indicates whether subsequent calls will need to write to a 
-netinfo server. By default, the flag is off and the netinfo 
-library will automatically switch to a server capable of 
-writing whenever a write call occurs. However, since writes
-may take some time to reach the clone server, one could read
-stale information from a clone server and then attempt to 
-write the master based upon the stale information. Setting 
-.I needwrite
-will lock the handle onto the master netinfo server even for 
-reads to prevent this from happening.
-.PP
-ni_status \fBni_open\fR(void *\fIrelativeto\fR, ni_name \fIdomain\fR, void **\fIresult\fR)
-.IP
-Opens a connection to the NetInfo domain 
-.I domain.
-The returned handle is opened relative to the domain specified in the
-.I relativeto.
-This handle may be passed as NULL, indicating relative to the local
-NetInfo domain.  The path may contain "/"s to indicate a multilevel 
-search and may also be "." or ".." to indicate the current domain or
-parent domain, respectively.
-.PP
-ni_status \fBni_parent\fR(void *\fIhandle\fR, ni_id *\fIdir\fR, ni_index *\fIparent_id\fR)
-.IP
-Returns the parent ID of the given directory.
-.PP
-ni_status \fBni_pathsearch\fR(void *\fIhandle\fR, ni_id *\fIdir\fR, ni_name \fIpath\fR)
-.IP
-Does a multilevel lookup on a directory, relative to the given directory
-ID.  The path may contain "/"s to separative directory components.  "="s
-are used to specify relations and both may be escaped using "\\"s.  For
-example, to find the directory associated with the superuser, you may
-specify (relative to the root directory) "/name=users/uid=0".  Note that
-the equal signs are not mandatory and will default to "name=" if none
-are specified.  In the previous example, "/users/uid=0" would accomplish
-the same result.
-.PP
-ni_status \fBni_read\fR(void *\fIhandle\fR, ni_id *\fIdir\fR, ni_proplist *\fIprops\fR)
-.IP
-Reads all of the properties of the given directory.
-.PP
-ni_status \fBni_readname\fR(void *\fIhandle\fR, ni_id *\fIdir\fR, ni_index \fIprop_index\fR, ni_index \fIval_index\fR, ni_name *\fIvalue\fR)
-.IP
-Reads a value from a property in the given directory.  The value is indexed
-by property index 
-.I prop_index
-and value index
-.I val_index.
-.PP
-ni_status \fBni_readprop\fR(void *\fIhandle\fR, ni_id *\fIdir\fR, ni_index \fIprop_index\fr, ni_namelist *\fInl\fR)
-.IP
-Reads the value-list associated with the given property, indexed by
-.I prop_index.
-.PP
-ni_status \fBni_renameprop\fR(void *\fIhandle\fR, ni_id *\fIdir\fR, ni_index \fIprop_index\fR, ni_name \fInewname\fR)
-.IP
-Renames the property indexed by
-.I prop_index
-to the new name
-.I newname.
-.PP
-ni_status \fBni_resync\fR(void *\fIhandle\fR)
-.IP
-Attempts to resynchronize the clone servers with the master copy of
-the database.
-.PP
-ni_status \fBni_root\fR(void *\fIhandle\fR, ni_id *\fIdir\fR)
-.IP
-Returns the directory ID of the root of the directory tree.
-.PP
-ni_status \fBni_self\fR(void *\fIhandle\fR, ni_id *\fIdir\fR)
-.IP
-Returns the directory ID of the given directory.  Simply refreshes the
-instance field to the latest value.
-.PP
-void \fBni_setabort\fR(void *\fIhandle\fR, int \fIshouldabort\fR)
-.IP
-By default, netinfo calls will try forever until an answer 
-is returned from a server. 
-.I ni_setabort
- allows one to have 
-netinfo return failure upon the first timeout or other failure.
-.PP
-ni_status \fBni_setpassword\fR(void *\fIhandle\fR, ni_name \fIpassword\fR)
-.IP
-Sets the password for the session to
-.I password.  
-By default, no password is sent.
-.PP
-void \fBni_setreadtimeout\fR(void *\fIhandle\fR, int \fIseconds\fR)
-.IP
-Sets the timeout associated with reads on netinfo. The timeout
-is only a hint and the effective timeout may be longer. Note
-that calls will not abort even if a timeout is set unless the
-abort flag has been set (see 
-.I ni_setabort()).
-.PP
-ni_status \fBni_setuser\fr(void *\fIhandle\fR, ni_name \fIusername\fR)
-.IP
-Changes the username associated with the session.  By default, the username
-is the one associated with the user-ID that was used during the UNIX login
-process.
-.PP
-void \fBni_setwritetimeout\fR(void *\fIhandle\fR, int \fIseconds\fR)
-.IP
-Sets the timeout associated with writes on netinfo. The timeout
-is only a hint and the effective timeout may be a longer. Note
-that calls will not abort even if a timeout is set unless the
-abort flag has been set (see 
-.I ni_setabort()).
-.PP
-ni_status \fBni_statistics\fR(void *\fIhandle\fR, ni_proplist *\fIstatistics\fR)
-.IP
-Returns various statistics from the server.
-.PP
-ni_status \fBni_write\fR(void *\fIhandle\fR, ni_id *\fIdir\fR, ni_proplist \fIprops\fR)
-.IP
-Writes a new property list to the directory.
-.PP
-ni_status \fBni_writename\fr(void *\fIhandle\fR, ni_id *\fIdir\fR, ni_index \fIprop_index\fr, ni_index \fIname_index\fR, ni_name \fIval\fR)
-.IP
-Writes a new property value to the property indexed by
-.I prop_index
-and value indexed by
-.I val_index.
-.PP
-ni_status \fBni_writeprop\fr(void *\fIhandle\fR, ni_id *\fIdir\fR, ni_index \fIprop_index\fR, ni_namelist \fIvalues\fR) 
-.IP
-Writes a new value list to the property indexed by
-.I prop_index.
-It is allowable to have more than one property with the same name.
-.IP
diff --git a/netinfo.subproj/netinfo.5 b/netinfo.subproj/netinfo.5
deleted file mode 100644 (file)
index aea5803..0000000
+++ /dev/null
@@ -1,278 +0,0 @@
-.TH NETINFO 5 "October 8, 1990" "Apple Computer, Inc."
-.SH NAME
-netinfo \- network administrative information
-.SH DESCRIPTION
-NetInfo stores its administration information in a hierarchical database.
-The hierarchy is composed of nodes called NetInfo
-.I directories.
-Each directory may have zero or more NetInfo
-.I properties
-associated with it.
-Each property has a 
-.I name
-and zero or more
-.I values.
-.PP
-This man page describes those directories and properties which have
-meaning in the system distributed by Apple. Users and 3rd-parties may
-create other directories and properties, which of course cannot be
-described here.
-.PP
-.I Search Policy
-.PP
-Virtually everything that utilizes NetInfo for lookups adheres to the
-following convention. Search the local domain first. If found, return
-the answer. Otherwise, try the next level up and so on until the top
-of the domain hierarchy is reached. For compatibility with Yellow Pages
-and BIND, see 
-.I lookupd(8).
-.PP
-.I Database Format
-.PP
-At the top level, the root directory contains a single property called
-.I master.
-This properties indicates who is the master of this database, i.e., which
-server contains the master copy of the database. The singular value of master
-contains two fields, a hostname and a domain tag separated by a '/' which 
-uniquely identifies the machine and process serving as master of this data.
-For example, the entry 
-.I clothier/network
-says that the 
-.I netinfod(8) 
-process serving domain tag
-.I network
-on the machine 
-.I clothier 
-controls the master copy of the database.
-.PP
-For added security, a second property can be installed in the root directory
-to limit who can connect to the domain. By default, anybody can connect to
-the domain, which would allow them to read anything that is there (writes are
-protected however). If this default is undesirable, a property called
-.I trusted_networks
-should be enabled in the root directory. Its values should be the network 
-(or subnet) addresses which are assumed to contain trusted machines which
-are allowed to connect to the domain. Any other clients are assumed to be
-untrustworthy. A name may be used instead of an address. If a name is given,
-then that name should be listed as a subdirectory of "/networks" within the
-same domain and resolve to the appropriate network address. 
-.PP
-At the second level, the following directories exist which have the
-following names (property named "name" has these values):
-.PP
-.RS
-.I aliases
-.LP
-.I groups
-.LP
-.I machines
-.LP
-.I mounts
-.LP
-.I networks
-.LP
-.I printers
-.LP
-.I protocols
-.LP
-.I rpcs
-.LP
-.I services
-.LP
-.I users
-.RE
-.PP
-These directories contain, for the most part, only the single property
-named "name". The exception is the "machines" directory which  contains
-other properties having to do with automatic host installation. These 
-properties are the following:
-.PP
-.RS
-"promiscuous" - if it exists, the bootpd(8) daemon is 
-promiscuous. Has no value.
-.LP
-"assignable_ipaddr" - a range of IP addresses to automatically assigned,
-specified with two values as endpoints.
-.LP
-"configuration_ipaddr" - the temporary IP address given to unknown machines in the process of booting.
-.LP
-"default_bootfile" - the default bootfile to assign to a new machine.
-.LP
-"net_passwd" - optional property. If it exists, it's the encrypted password
-for protecting automatic host installations.
-.RE
-.PP
-The directory "/aliases" contains directories which refer to individual
-mailing aliases. The relevant properties are:
-.PP
-.RS
-"name" - the name of the alias
-.LP
-"members" - a list of values, each of which is a member of this alias.
-.RE
-.PP
-The directory "/groups" contains directories which refer to individual
-system groups. The relevant properties are:
-.PP
-.RS
-"name" - the name of the system group
-.LP
-"passwd" - the associated password
-.LP
-"gid" - the associated group id
-.LP
-"users" - a list of values, each of which is a user who is a member
-of this system group.
-.RE
-.PP
-The directory "/machines" contains directories which refer to individual
-machines. The relevant properties are:
-.PP
-.RS
-"name" - the name of this machine. This property can have multiple values 
-if the machine name has aliases.
-.LP
-"ip_address" - the Internet Protocol address of the machine. This property
-can have multiple values if the machine has multiple IP addresses. Note
-that the address MUST be stored in decimal-dot notation with no leading
-zeroes.
-.LP
-"en_address" - the Ethernet address of the machine. Note that the address
-MUST be stored in standard 6 field hex Ethernet notation, with no leading
-zeros. For example, "0:0:f:0:7:5a" is a valid Ethernet address, 
-"00:00:0f:00:07:5a" is not.
-.LP
-"serves" - a list of values, each of which is information about which
-NetInfo domains this machine serves. Each value has the format
-.I domain-name/domain-tag.
-The domain name is the external name of the domain served by this machine as 
-seen from this level of hierarchy. The domain tag is the internal
-name associated with the actual process on the machine that serves this
-information.
-.LP
-"bootfile" - the name of the kernel that this machine will use by 
-default when NetBooting.
-.LP
-"bootparams" - a list of values, each of which is a Bootparams protocol
-key-value pair. For example, "root=parrish:/" has the Bootparams key
-"root" and Bootparams value "parrish:/".
-.LP
-"netgroups" - a list of values, each of which is the name of a netgroup
-of which this machine is a member.
-.RE
-.PP
-The directory "/mounts" contains directories which refer to filesystems.
-The relevant properties are:
-.PP
-.RS
-"name" - the name of the filesytem. For example, "/dev/od0a" or
-"papazian:/".
-.LP
-"dir" - the directory upon which this filesystem is mounted.
-.LP
-"type" - the filesystem type of the mount
-.LP
-"opts" - a list of values, each of which is a
-.I mount(8)
-option associated with the mounting of this filesystem.
-.LP
-"passno" - pass number on parallel 
-.I fsck(8)
-.LP
-"freq" - dump frequency, in days.
-.RE
-.PP
-The directory "/networks" contains directories which refer to Internet
-networks. The relevant properties are:
-.PP
-.RS
-"name" - the name of the network. If the network has aliases, there
-may be more than one value for this property.
-.LP
-"address" - the network number of this network. The value MUST be
-in decimal-dot notation with no leading zeroes.
-.RE
-.PP
-The directory "/printers" contains directories which refer to
-printer entries. The relevant properties are:
-.PP
-.RS
-"name" - the name of the printer. If the printer has alias, this
-property will have multiple values.
-.LP
-"lp", "sd", etc. - the names of 
-.I printcap(5)
-properties associated with this printer. If the value associated with
-the property name is numeric, the number has a leading "#" prepended
-to it.
-.RE
-.PP
-The directory "/protocols" contains directories which refer to 
-transport protocols. The relevant properties are:
-.PP
-.RS
-"name" - the name of the protocol. If the protocol has aliases, the
-property will have multiple values.
-.LP
-"number" - the associated protocol number.
-.RE
-.PP
-The directory "/services" contains directories which refer to
-ARPA services. The relevant properties are:
-.PP
-.RS
-"name" - the name of the service. If the service has aliases, the
-property will have multiple values.
-.LP
-"protocol" - the name of the protocol upon which the service runs.
-If the service runs on multiple protocols, this property will have
-multiple values.
-.LP
-"port" - the associated port number of the service.
-.RE
-.PP
-The directory "/users" contains information which refer to users.
-The relevant properties are:
-.PP
-.RS
-"name" - the login name of the user.
-.LP
-"passwd" - the encrypted password of the user.
-.LP
-"uid" - the user id of the user.
-.LP
-"gid" - the default group id of the user.
-.LP
-"realname" - the real name of the user.
-.LP
-"home" - the home directory of the user.
-.LP
-"shell" - the login shell of the user.
-.SH "SEE ALSO"
-.I aliases(5)
-.LP
-.I bootparams(5)
-.LP
-.I bootptab(5)
-.LP
-.I fstab(5)
-.LP
-.I group(5)
-.LP
-.I hosts(5)
-.LP
-.I lookupd(8)
-.LP
-.I netinfod(8)
-.LP
-.I netgroup(5)
-.LP
-.I networks(5)
-.LP
-.I passwd(5)
-.LP
-.I printcap(5)
-.LP
-.I protocols(5)
-.LP
-.I services(5)
diff --git a/netinfo.subproj/ni.h b/netinfo.subproj/ni.h
deleted file mode 100644 (file)
index 8f364e6..0000000
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A 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
-
-#ifdef __cplusplus
-extern "C" {
-#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);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif __NI_HEADER__
-
diff --git a/netinfo.subproj/ni_error.c b/netinfo.subproj/ni_error.c
deleted file mode 100644 (file)
index 63aaff8..0000000
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A 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
deleted file mode 100644 (file)
index 43c146d..0000000
+++ /dev/null
@@ -1,2325 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
- * Reserved. This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
- * except in compliance with the License. Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A 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 <string.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 <errno.h>
-#include "clib.h"
-#include "sys_interfaces.h"
-
-#define LOCAL_PORT 1033
-
-#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 16     /* 16 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))
-
-#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 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";
-
-static const ni_name NAME_DOMAIN_SERVERS = "domain_servers";
-
-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);
-extern int bindresvport(int, struct sockaddr_in *);
-
-/*
- * 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(struct sockaddr_in);
-       if (getsockname(sock, (struct sockaddr *)&sin, &sinlen) != 0) return -1;
-
-       if (sin.sin_port == 0)
-       {
-               if (bind(sock, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)) != 0) return -1;
-
-               sinlen = sizeof(struct sockaddr_in);
-               if (getsockname(sock, (struct sockaddr *)&sin, &sinlen) != 0) return -1;
-       }
-
-       return ntohs(sin.sin_port);
-}
-
-
-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, (char *)&tv);
-}
-
-
-/*
- * Connect to a given address/tag
- */
-static int
-connectit(ni_private *ni)
-{
-       struct sockaddr_in sin;
-       int sock, islocal;
-       CLIENT *cl;
-       struct timeval tv;
-       enum clnt_stat stat;
-       nibind_getregister_res res;
-       interface_list_t *ilist;
-
-       sock = -1;
-       bzero(&sin, sizeof(sin));
-       sin.sin_port = 0;
-       sin.sin_family = AF_INET;
-
-       tv.tv_sec = ni->rtv_sec == 0 ? NI_TIMEOUT_SHORT : ni->rtv_sec;
-       tv.tv_usec = 0;
-
-       ni_settimeout(ni, tv.tv_sec);
-       fixtimeout(&tv, ni->tv_sec, NI_TRIES);
-
-       /*
-        * If connecting to local domain, try using the "well-known" port first.
-        */
-       islocal = 0;
-
-       if (!strcmp(ni->tags[0], "local"))
-       {
-               if (ni->addrs[0].s_addr == htonl(INADDR_LOOPBACK))
-               {
-                       islocal = 1;
-               }
-               else
-               {
-                       ilist = _libinfo_ni_sys_interfaces();
-                       if (_libinfo_ni_sys_is_my_address(ilist, &ni->addrs[0])) islocal = 1;
-                       _libinfo_ni_sys_interfaces_release(ilist);
-               }
-
-               if (islocal != 0)
-               {
-                       sin.sin_port = htons(LOCAL_PORT);
-                       sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-                       sock = socket_open(&sin, NI_PROG, NI_VERS, ni->tv_sec, NI_TRIES, IPPROTO_TCP);
-               }
-       }
-
-       /*
-        * If connecting to a domain other than the local domain, * or if connection to local didn't work with local's well-known port, * then go through portmap & nibindd to find the port and connect.
-        */
-       if (sock < 0)
-       {
-               sin.sin_port = 0;
-               sin.sin_addr = ni->addrs[0];
-
-               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, (xdrproc_t)xdr_ni_name, (char *)&ni->tags[0], (xdrproc_t)xdr_nibind_getregister_res, (char *)&res, tv);
-               clnt_destroy(cl);
-               close(sock);
-               if (stat != RPC_SUCCESS || res.status != NI_OK) return 0;
-
-               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, (char *)&tv);
-       ni->tc = cl;
-       ni->tsock = sock;
-       ni->tport = getmyport(sock);
-       createauth(ni);
-       fcntl(ni->tsock, F_SETFD, 1);
-       return 1;
-}
-
-
-void
-ni_setabort(void *ni, int abort)
-{
-       if (ni == NULL) return;
-
-       ((ni_private *)ni)->abort = abort;
-}
-
-
-void
-ni_setwritetimeout(void *ni, int timeout)
-{
-       if (ni == NULL) return;
-
-       ((ni_private *)ni)->wtv_sec = timeout;
-}
-
-
-void
-ni_setreadtimeout(void *ni, int timeout)
-{
-       if (ni == NULL) return;
-
-       ((ni_private *)ni)->rtv_sec = timeout;
-}
-
-
-void
-ni_needwrite(void *ni, int needwrite)
-{
-       if (ni == NULL) return;
-
-       ((ni_private *)ni)->needwrite = needwrite;
-}
-
-
-/*
- * Returns a client handle to the NetInfo server, if it's running
- */
-static int
-connectlocal(ni_private *ni)
-{
-       int printed = 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) == 0)
-       {
-               if (printed == 0)
-               {
-                       syslog(LOG_ERR, "NetInfo timeout connecting to local domain, sleeping");
-                       printed = 1;
-               }
-
-               sleep(NI_SLEEPTIME);
-               /* wait forever */
-       }
-
-       if (printed != 0) syslog(LOG_INFO, "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;
-       int p;
-
-       p = getmyport(sock);
-
-       if ((sock >= 0) && (p != -1) && (p != port))
-       {
-               /* Somebody has the reused the socket. */
-               save = 1;
-       }
-
-       if (cl != NULL)
-       {
-               if (cl->cl_auth != NULL) auth_destroy(cl->cl_auth);
-               clnt_destroy(cl);
-       }
-
-       if (save == 0) close(sock);
-}
-
-
-/*
- * Reinitialize everything
- */
-static void
-reinit(ni_private *ni)
-{
-       if (ni == NULL) return;
-
-       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 (ni == NULL) return;
-       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;
-
-       if (a == b) return;
-
-       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;
-}
-
-static ni_status
-ni_ping(unsigned short port, struct in_addr addr)
-{
-       struct sockaddr_in sin;
-       int sock;
-       CLIENT *cl;
- struct timeval timeout, retry;
-       enum clnt_stat stat;
- memset(&sin, 0, sizeof(struct sockaddr_in));
- sin.sin_family = AF_INET;
- sin.sin_port = port;
- sin.sin_addr = addr;
- timeout.tv_sec = NI_TIMEOUT_SHORT;
- timeout.tv_usec = 0;
- retry.tv_sec = 1;
- retry.tv_usec = 0;
-       sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (sock < 0) return NI_FAILED;
- cl = clntudp_create(&sin, NI_PROG, NI_VERS, timeout, &sock);
- if (cl == NULL)
- {
- close(sock);
- return NI_FAILED;
- }
- clnt_control(cl, CLSET_RETRY_TIMEOUT, (char *)&retry);
- stat = clnt_call(cl, _NI_PING, (xdrproc_t)xdr_void, (char *)NULL, (xdrproc_t)xdr_void, (char *)NULL, timeout);
- clnt_destroy(cl);
- close(sock);
- if (stat != RPC_SUCCESS) return NI_FAILED;
- return NI_OK;
-}
-
-/*
- * Callback routine for multi_call
- * XXX: should save returned port numbers
- */
-static bool_t
-eachresult(void *vstuff, struct sockaddr_in *sin, int which)
-{
-       ni_status status;
-       getreg_stuff *stuff = (getreg_stuff *)vstuff;
-
-       if (stuff->res.status != NI_OK) return FALSE;
-
- /*
- * Actually talk to server (netinfod) to make sure it is alive
- * before switching. If we got this far, nibindd gave us a
- * port number for an address and tag. We connect to that
- * port and do a ni_root() query before accepting the server.
- */
-       status = ni_ping(htons(stuff->res.nibind_getregister_res_u.addrs.udp_port), stuff->ni->addrs[which]);
- if (status != NI_OK) return FALSE;
-
-       ni_switch(stuff->ni, which);
-       return TRUE;
-}
-
-
-/*
- * shuffle addresses
- */
-static void
-shuffle(ni_private *ni)
-{
-       int *shuffle;
-       int i, j, rfd, rv, te;
-       unsigned int re;
-       static int initialized = 0;
-
-       if (ni == NULL) return;
-       if (ni->naddrs <= 1) return;
-
-       rfd = open("/dev/random", O_RDONLY, 0);
-       shuffle = (int *)malloc(ni->naddrs * sizeof(int));
-       for (i = 0; i < ni->naddrs; i++) shuffle[i] = i;
-       for (i = 0, j = ni->naddrs; j > 0; i++, j--)
-       {
-               /* get a random number */
-               if ((rfd < 0) || (read(rfd, &rv, sizeof(rv)) != sizeof(rv)))
-               {
-                       /* if we could not read from /dev/random */
-                       if (initialized == 0)
-                       {
-                               srandom(gethostid() ^ time(NULL));
-                               initialized = 1;
-                       }
-                       rv = random();
-               }
-
-               re = (unsigned int)rv % j;      /* pick one of the remaining entries */
-               te = shuffle[re];               /* grab the random entry */
-               shuffle[re] = shuffle[j-1];     /* the last entry moves to the random slot */ 
-               shuffle[j-1] = te;              /* the last slot gets the random entry */
-               ni_swap(ni, re, j-1);           /* and swap the actual NI addresses */
-       }
-
-       free(shuffle);
-       if (rfd > 0) close(rfd);
-       return;
-}
-
-
-static int
-rebind(ni_private *ni)
-{
-       enum clnt_stat stat;
-       getreg_stuff stuff;
-       int sleeptime = NI_SLEEPTIME;
-       int printed = 0;
-       int nlocal;
-       int nnetwork;
-       interface_list_t *ilist;
-       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
-        */
-
-       ilist = _libinfo_ni_sys_interfaces();
-
-       /*
-        * shuffle addresses
-        */
-       shuffle(ni);
-
-       /*
-        * move local servers to the head of the list
-        */
-       nlocal = 0;
-       for (i = nlocal; i < ni->naddrs; i++)
-       {
-               if (_libinfo_ni_sys_is_my_address(ilist, &ni->addrs[i]))
-               {
-                       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 (_libinfo_ni_sys_is_my_network(ilist, &ni->addrs[i]) || IS_BROADCASTADDR(ni->addrs[i].s_addr))
-               {
-                       ni_swap(ni, nnetwork, i);
-                       nnetwork++;
-               }
-       }
-
-       _libinfo_ni_sys_interfaces_release(ilist);
-
-       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, (xdrproc_t)xdr_ni_name, (void *)ni->tags, sizeof(ni_name), (xdrproc_t)xdr_nibind_getregister_res, (void *)&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, (xdrproc_t)xdr_ni_name, (void *)ni->tags, sizeof(ni_name), (xdrproc_t)xdr_nibind_getregister_res, (void *)&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, (xdrproc_t)xdr_ni_name, (void *)ni->tags, sizeof(ni_name), (xdrproc_t)xdr_nibind_getregister_res, (void *)&stuff, eachresult, (ni->rtv_sec == 0) ? NI_TIMEOUT_SHORT : ni->rtv_sec);
-               if (stat == RPC_SUCCESS) break;
-
-               if (ni->abort) return 0;
-
-               if (printed == 0)
-               {
-                       if (ni->whichwrite >= 0)
-                       {
-                               syslog(LOG_WARNING, 
-                                       "NetInfo connect timeout (domain with master %s/%s), sleeping", inet_ntoa(ni->addrs[ni->whichwrite]), ni->tags[ni->whichwrite]);
-                       }
-                       else
-                       {
-                               syslog(LOG_WARNING, "NetInfo connect timeout (domain with server %s/%s), sleeping", inet_ntoa(ni->addrs[0]), ni->tags[0]);
-                       }
-
-                       printed = 1;
-               }
-
-               sleep(sleeptime);
-               if (sleeptime < NI_MAXSLEEPTIME)
-               {
-                       /* backoff */
-                       sleeptime *= 2; 
-               }
-       }
-
-       syslog(LOG_INFO, "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)
-{
-       int p;
-
-       if (ni->tsock != -1)
-       {
-               p = getmyport(ni->tsock);
-               if ((p != -1) && (p == ni->tport))
-               {
-                       /* All is well */
-                       return 1;
-               }
-
-               if (p == -1)
-               {
-                       /* Socket has died. Close it so it doesn't become a zombie. */
-                       close(ni->tsock);
-               }
-
-               /*
-                * Somebody has reused our socket.
-                */
-               if (ni->tc != NULL)
-               {
-                       if (ni->tc->cl_auth != NULL) auth_destroy(ni->tc->cl_auth);
-                       clnt_destroy(ni->tc);
-                       ni->tc = NULL;
-               }
-       }
-
-       if ((needwrite == 0) && (rebind(ni) == 0) && (ni->abort != 0)) 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;
-       }
-
-       NI_INIT(&nl);
-       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];
-
-       NI_INIT(&idl);
-       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);
-
-       NI_INIT(&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);
-       NI_INIT(&nl);
-       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) == 0) return NULL;
-                       ni_switch(ni, ni->whichwrite);
-               }
-
-               if (needwrite == 0)
-               {
-                       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 != 0) syslog(LOG_INFO, "NetInfo connected to %s/%s", inet_ntoa(ni->addrs[0]), ni->tags[0]);
-                               return resp;
-                       }
-
-                       if (ni->tc != NULL)
-                       {
-                               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 != 0)
-               {
-                       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 = 1;
-                               }
-                               else
-                               {
-                                       /* first attempt failed */
-                                       syslog(LOG_NOTICE, "%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 = 1;
-                       }
-               }
-
-               if (sleeptime > 0)
-               {
-                       sleep(sleeptime);
-                        /* backoff */
-                       if (sleeptime < NI_MAXSLEEPTIME) sleeptime *= 2;
-               }
-               else
-               {
-                       /*
-                        * Do not sleep on the first timeout.
-                        * It is likely we will find another server quickly.
-                        */
-                       sleeptime = NI_SLEEPTIME;
-               }
-
-               reinit(ni);
-               rebind(ni);
-       }
-}
-
-
-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;
-
-       if (ni == NULL) return NULL;
-
-       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 void
-add_addr_tag(ni_private *ni, ni_name addrtag)
-{
-       struct in_addr addr;
-       ni_name tag;
-       char *slash;
-
-       slash = strchr(addrtag, '/');
-       if (slash == NULL) return;
-
-       tag = slash + 1;
-       if (tag[0] == '\0') return;
-
-       *slash = '\0';
-
-       if (inet_aton(addrtag, &addr) == 0) return;
-
-       if (ni->naddrs == 0)
-       {
-               ni->addrs = (struct in_addr *)calloc(1, sizeof(struct in_addr));
-               if (ni->addrs == NULL) return;
-
-               ni->tags = (ni_name *)calloc(1, sizeof(ni_name));
-               if (ni->tags == NULL) return;
-       }
-       else
-       {
-               ni->addrs = (struct in_addr *)realloc(ni->addrs, ((ni->naddrs + 1) * sizeof(struct in_addr)));
-               if (ni->addrs == NULL) return;
-
-               ni->tags = (ni_name *)realloc(ni->tags, ((ni->naddrs + 1) * sizeof(ni_name)));
-               if (ni->tags == NULL) return;
-       }
-
-       ni->addrs[ni->naddrs] = addr;
-       ni->tags[ni->naddrs] = ni_name_dup(tag);
-       ni->naddrs++;
-}
-
-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;
-       ni_status status;
-
-       if (ni == NULL) return 0;
-       if (tag == NULL) return 0;
-       if (target_ni == NULL) return 0;
-
-       id.nii_object = ido;
-       NI_INIT(&nl);
-
-       status = ni_lookupprop(ni, &id, NAME_IP_ADDRESS, &nl);
-       if (status != NI_OK) return 0;
-
-       if (nl.ni_namelist_len == 0) return 0;
-
-       if (target_ni->naddrs == 0) 
-       {
-               target_ni->addrs = (struct in_addr *)malloc(nl.ni_namelist_len * sizeof(struct in_addr));
-               target_ni->tags = (ni_name *)malloc(nl.ni_namelist_len * sizeof(ni_name));
-       }
-       else
-       {
-               target_ni->addrs = (struct in_addr *)realloc(target_ni->addrs, ((target_ni->naddrs + nl.ni_namelist_len) * sizeof(struct in_addr)));
-               target_ni->tags = (ni_name *)realloc(target_ni->tags, ((target_ni->naddrs + nl.ni_namelist_len) * sizeof(ni_name)));
-       }
-
-       for (i = 0; i < nl.ni_namelist_len; i++)
-       {
-               addr.s_addr = inet_addr(nl.ni_namelist_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 nid;
-       ni_idlist ids;
-       ni_entrylist entries;
-       ni_proplist pl;
-       ni_index i;
-       ni_index j;
-       ni_name tag;
-
-       if (ni == NULL) return 0;
-       if (dom == NULL) return 0;
-       if (target_ni == NULL) return 0;
-
-       if (!strcmp(dom, "."))
-       {
-               /* check for server list */
-               NI_INIT(&pl);
-               if (ni_statistics(ni, &pl) == NI_OK)
-               {
-                       i = ni_proplist_match(pl, NAME_DOMAIN_SERVERS, NULL);
-                       if (i != NI_INDEX_NULL)
-                       {
-                               if (pl.ni_proplist_val[i].nip_val.ni_namelist_len > 0)
-                               {
-                                       for (j = 0; j < pl.ni_proplist_val[i].nip_val.ni_namelist_len; j++)
-                                       {
-                                               add_addr_tag(target_ni, pl.ni_proplist_val[i].nip_val.ni_namelist_val[j]);
-                                       }
-
-                                       ni_proplist_free(&pl);
-                                       return 1;
-                               }
-                       }
-
-                       ni_proplist_free(&pl);
-               }
-       }
-
-       if (ni_root(ni, &nid) != NI_OK) return 0;
-
-       NI_INIT(&ids);
-       if (ni_lookup(ni, &nid, NAME_NAME, NAME_MACHINES, &ids) != NI_OK) return 0;
-
-       nid.nii_object = ids.niil_val[0];
-       ni_idlist_free(&ids);
-
-       NI_INIT(&entries);
-       if (ni_list(ni, &nid, NAME_SERVES, &entries) != NI_OK) return 0;
-
-       for (i = 0; i < entries.niel_len; i++)
-       {
-               if (entries.niel_val[i].names == NULL) continue;
-
-               for (j = 0; j < entries.niel_val[i].names->ni_namelist_len; j++)
-               {
-                       if (match(dom, entries.niel_val[i].names->ni_namelist_val[j], &tag))
-                       {
-                               addaddr(ni, entries.niel_val[i].id, tag, target_ni);
-                               ni_name_free(&tag);
-                       }
-               }
-       }
-
-       ni_entrylist_free(&entries);
-       return (target_ni->naddrs > 0);
-}
-
-static ni_status
-getparent(ni_private *oldni, ni_private **newni)
-{
-       ni_rparent_res *resp;
-       ni_private *ni = NULL;
-       ni_private *dupni;
-       int found = 0;
-       ni_index i;
-       struct in_addr raddr;
-       int printed = 0;
-       int inlist = 0;
-
-       if (oldni == NULL) return 0;
-       if (newni == NULL) return 0;
-
-       while (found == 0)
-       {
-               /*
-                * 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 != 0)
-                       {
-                               syslog(LOG_WARNING, "NetInfo timeout finding server for parent of %s/%s, sleeping",                             inet_ntoa(oldni->addrs[0]), oldni->tags[0]);
-                               printed = 1;
-                       }
-
-                       sleep(NI_SLEEPTIME);
-               }
-
-               if (printed)
-               {
-                       raddr.s_addr = htonl(resp->ni_rparent_res_u.binding.addr);
-
-                       syslog(LOG_INFO, "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((xdrproc_t)xdr_ni_rparent_res, (void *)resp);
-
-               dupni = ni;
-               ni = ni_alloc();
-               *ni = *dupni;
-               ni_clear(ni);
-               if (get_daddr(dupni, ".", ni) == 0) 
-               {
-                       if (oldni->abort == 1)
-                       {
-                               ni_free(dupni);
-                               break;
-                       }
-               }
-               else
-               {
-                       /*
-                        * 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 = 1;
-
-                       /*
-                        * 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;
-       }
-
-       if (ni != NULL) ni_free(ni);
-       return NI_FAILED;
-}
-
-
-void *
-ni_connect(struct sockaddr_in *sin, const char *tag)
-{
-       void *ni;
-
-       if (sin == NULL) return NULL;
-       if (tag == NULL) return NULL;
-
-       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 (ni == NULL) return NI_FAILED;
-       if (addr == NULL) return NI_FAILED;
-       if (tag == NULL) return NI_FAILED;
-
-       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 (domain == NULL) return NULL;
-
-       sep = index(domain, '@');
-       if (sep != NULL)
-       {
-               tag = strncpy((char *)malloc(sep - domain + 1), domain, sep - domain);
-               tag[sep - domain] = '\0';
-
-               addr = NULL;
-               asprintf(&addr, "%s", 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);
-
-               return (void *)ni;
-       }
-
-       ni = NULL;
-
-       if (oldni == NULL)
-       {
-               ni = ni_alloc();
-               if (connectlocal(ni) == 0)
-               {
-                       free(ni);
-                       return NULL;
-               }
-
-               if (strcmp(domain, ".") == 0) return (void *)ni;
-
-               if (strcmp(domain, "..") == 0)
-               {
-                       oldni = ni;
-                       status = getparent((ni_private *)oldni, &ni);
-                       ni_free(oldni);
-                       if (status != NI_OK) return NULL;
-                       return (void *)ni;
-               }
-
-               ni_free(ni);
-               return NULL;
-       }
-
-       if (strcmp(domain, "..") == 0)
-       {
-               status = getparent((ni_private *)oldni, &ni);
-               if (status != NI_OK) return NULL;
-               return (void *)ni;
-       }
-
-       ni = ni_alloc();
-       *ni = *NIP(oldni);
-       ni_clear(ni);
-       if (get_daddr(oldni, (ni_name)domain, ni) == 0)
-       {
-               ni_free(ni);
-               return NULL;
-       }
-
-       return (void *)ni;
-}
-
-
-void
-ni_free(void *ni)
-{
-       ni_index i;
-
-       if (ni == NULL) return;
-
-       if (NIP(ni)->tc != NULL) clnt_kill(NIP(ni)->tc, NIP(ni)->tsock, NIP(ni)->tport);
-
-       if (NIP(ni)->naddrs > 0)
-       {
-               for (i = 0; i < NIP(ni)->naddrs; i++) ni_name_free(&NIP(ni)->tags[i]);
-               free(NIP(ni)->tags);
-               free(NIP(ni)->addrs);
-       }
-
-       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 (ni == NULL) return NI_FAILED;
-       if (pl == NULL) return NI_FAILED;
-
-       resp = (ni_proplist *)RCALLIT(ni, _ni_statistics_2, NULL);
-       if (resp == NULL)
-       {
-               clnt_debug(ni, "_ni_statistics");
-               return NI_FAILED;
-       }
-
-       *pl = *resp;
-       return NI_OK;
-}
-
-
-ni_status
-ni_root(void *ni, ni_id *id)
-{
-       ni_id_res *resp;
-
-       if (ni == NULL) return NI_FAILED;
-       if (id == NULL) return NI_FAILED;
-
-       resp = RCALLIT(ni, _ni_root_2, id);
-       if (resp == 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 (ni == NULL) return NI_FAILED;
-       if (id == NULL) return NI_FAILED;
-
-       resp = RCALLIT(ni, _ni_self_2, id);
-       if (resp == 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 (ni == NULL) return NI_FAILED;
-       if (id == NULL) return NI_FAILED;
-       if (parent_id_p == NULL) return NI_FAILED;
-
-       resp = RCALLIT(ni, _ni_parent_2, id);
-       if (resp == 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 (ni == NULL) return NI_FAILED;
-       if (id == NULL) return NI_FAILED;
-       if (children == NULL) return NI_FAILED;
-
-       resp = RCALLIT(ni, _ni_children_2, id);
-       if (resp == 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;
-
-       if (ni == NULL) return NI_FAILED;
-       if (parent_id == NULL) return NI_FAILED;
-       if (child_id_p == NULL) return NI_FAILED;
-
-       args.id = *parent_id;
-       args.props = pl;
-       args.where = where;
-       args.target_id = NULL;
-
-       resp = WCALLIT(ni, _ni_create_2, &args);
-       if (resp == 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;
-
-       if (ni == NULL) return NI_FAILED;
-       if (parent_id == NULL) return NI_FAILED;
-
-       args.parent_id = *parent_id;
-       args.self_id = self_id;
-
-       resp = WCALLIT(ni, _ni_destroy_2, &args);
-       if (resp == 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;
-
-       if (ni == NULL) return NI_FAILED;
-       if (self_id == NULL) return NI_FAILED;
-
-       args.id = *self_id;
-       args.props = pl;
-
-       resp = WCALLIT(ni, _ni_write_2, &args);
-       if (resp == 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 (ni == NULL) return NI_FAILED;
-       if (self_id == NULL) return NI_FAILED;
-       if (pl == NULL) return NI_FAILED;
-
-       resp = RCALLIT(ni, _ni_read_2, self_id);
-       if (resp == 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;
-
-       if (ni == NULL) return NI_FAILED;
-       if (id == NULL) return NI_FAILED;
-       if (pname == NULL) return NI_FAILED;
-       /* pval may be NULL */
-       if (hits == NULL) return NI_FAILED;
-
-       args.id = *id;
-       args.key = (ni_name)pname;
-       args.value = (ni_name)pval;
-
-       resp = RCALLIT(ni, _ni_lookup_2, &args);
-       if (resp == 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;
-
-       if (ni == NULL) return NI_FAILED;
-       if (id == NULL) return NI_FAILED;
-       if (pname == NULL) return NI_FAILED;
-       /* pval may be NULL*/
-       if (props == NULL) return NI_FAILED;
-
-       args.id = *id;
-       args.key = (ni_name)pname;
-       args.value = (ni_name)pval;
-
-       resp = RCALLIT(ni, _ni_lookupread_2, &args);
-       if (resp == 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;
-
-       if (ni == NULL) return NI_FAILED;
-       if (id == NULL) return NI_FAILED;
-       if (pname == NULL) return NI_FAILED;
-       if (entries == NULL) return NI_FAILED;
-
-       args.id = *id;
-       args.name = (ni_name)pname;
-
-       resp = RCALLIT(ni, _ni_list_2, &args);
-       if (resp == 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 (ni == NULL) return NI_FAILED;
-       if (id == NULL) return NI_FAILED;
-       if (entries == NULL) return NI_FAILED;
-
-       resp = RCALLIT(ni, _ni_listall_2, id);
-       if (resp == 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;
-
-       if (ni == NULL) return NI_FAILED;
-       if (id == NULL) return NI_FAILED;
-       if (propval_p == NULL) return NI_FAILED;
-
-       args.id = *id;
-       args.prop_index = which;
-
-       resp = RCALLIT(ni, _ni_readprop_2, &args);
-       if (resp == 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;
-
-       if (ni == NULL) return NI_FAILED;
-       if (id == NULL) return NI_FAILED;
-
-       args.id = *id;
-       args.prop_index = which;
-       args.values = propval;
-
-       resp = WCALLIT(ni, _ni_writeprop_2, &args);
-       if (resp == 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 (ni == NULL) return NI_FAILED;
-       if (id == NULL) return NI_FAILED;
-       if (propnames == NULL) return NI_FAILED;
-
-       resp = RCALLIT(ni, _ni_listprops_2, id);
-       if (resp == 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;
-
-       if (ni == NULL) return NI_FAILED;
-       if (id == NULL) return NI_FAILED;
-
-       args.id = *id;
-       args.prop = prop;
-       args.where = where;
-
-       resp = WCALLIT(ni, _ni_createprop_2, &args);
-       if (resp == 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;
-
-       if (ni == NULL) return NI_FAILED;
-       if (id == NULL) return NI_FAILED;
-
-       args.id = *id;
-       args.prop_index = which;
-
-       resp = WCALLIT(ni, _ni_destroyprop_2, &args);
-       if (resp == 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;
-
-       if (ni == NULL) return NI_FAILED;
-       if (id == NULL) return NI_FAILED;
-       if (name == NULL) return NI_FAILED;
-
-       args.id = *id;
-       args.prop_index = prop_index;
-       args.name = (ni_name)name;
-
-       resp = WCALLIT(ni, _ni_renameprop_2, &args);
-       if (resp == 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;
-
-       if (ni == NULL) return NI_FAILED;
-       if (id == NULL) return NI_FAILED;
-       if (name == NULL) return NI_FAILED;
-
-       args.id = *id;
-       args.prop_index = prop_index;
-       args.name = (ni_name)name;
-       args.where = where;
-
-       resp = WCALLIT(ni, _ni_createname_2, &args);
-       if (resp == 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;
-
-       if (ni == NULL) return NI_FAILED;
-       if (id == NULL) return NI_FAILED;
-
-       args.id = *id;
-       args.prop_index = prop_index;
-       args.name_index = name_index;
-
-       resp = WCALLIT(ni, _ni_destroyname_2, &args);
-       if (resp == 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;
-
-       if (ni == NULL) return NI_FAILED;
-       if (id == NULL) return NI_FAILED;
-       if (name == NULL) return NI_FAILED;
-
-       args.id = *id;
-       args.prop_index = prop_index;
-       args.name_index = name_index;
-       args.name = (ni_name)name;
-
-       resp = WCALLIT(ni, _ni_writename_2, &args);
-       if (resp == 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;
-
-       if (ni == NULL) return NI_FAILED;
-       if (id == NULL) return NI_FAILED;
-       if (name == NULL) return NI_FAILED;
-
-       args.id = *id;
-       args.prop_index = prop_index;
-       args.name_index = name_index;
-
-       resp = RCALLIT(ni, _ni_readname_2, &args);
-       if (resp == 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 (ni == NULL) return NI_FAILED;
-
-       resp = (ni_status *)RCALLIT(ni, _ni_resync_2, NULL);
-       if (resp == NULL)
-       {
-               clnt_debug(ni, "_ni_resync");
-               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;
-       ni_status status;
-
-       if (ni == NULL) return NI_FAILED;
-
-       if (user == NULL)
-       {
-               NIP(ni)->uid = getuid();
-               return ni_setpassword(ni, NULL);
-       }
-
-       status = ni_root(ni, &id);
-       if (status != NI_OK) return NI_NOUSER;
-
-       NI_INIT(&ids);
-       status = ni_lookup(ni, &id, NAME_NAME, NAME_USERS, &ids);
-       if (status != NI_OK) return NI_NOUSER;
-
-       id.nii_object = ids.niil_val[0];
-       ni_idlist_free(&ids);
-
-       NI_INIT(&ids);
-       status = ni_lookup(ni, &id, NAME_NAME, user, &ids);
-       if (status != NI_OK) return NI_NOUSER;
-
-       id.nii_object = ids.niil_val[0];
-       ni_idlist_free(&ids);
-
-       NI_INIT(&nl);
-       status = ni_lookupprop(ni, &id, NAME_UID, &nl);
-       if (status != NI_OK) return NI_NOUSER;
-
-       if (nl.ninl_len == 0) return NI_NOUSER;
-
-       for (p = nl.ninl_val[0]; *p; p++)
-       {
-               if (isdigit(*p) == 0)
-               {
-                       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 (ni == NULL) return NI_FAILED;
-
-       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;
-}
-
-
-/*
- *     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 != 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, (xdrproc_t)xdr_pmap, (char *)&parms, (xdrproc_t)xdr_u_short, (char *)&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);
-
-       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)
-{
-       struct sockaddr_in bindsin;
-       int sock;
-       int reuse = 1;
-       u_short port;
-
-       memset(&bindsin, 0, sizeof(bindsin));
-
-       /*
-        * If no port number given ask the pmap for one
-        */
-       if (raddr->sin_port == 0)
-       {
-               port = pmap_getport_to(raddr, prog, vers, IPPROTO_UDP, timeout, ntries);
-               if (port == 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;
-
-       if ((bindresvport(sock, NULL) < 0) && (errno == EADDRNOTAVAIL))
-       {
-               /* XXX - we're hitting this case way too often under load */
-               /* fail gracefully: some address is better than none most of the time */
-               syslog(LOG_DEBUG, "Libinfo[%s():%d] bindresvport(): %m", __func__, __LINE__);
-               if (bind(sock, (struct sockaddr *)&bindsin, sizeof(bindsin)) < 0)
-               {
-                       /* The system is really sad now if it can't give me any address... */
-                       syslog(LOG_DEBUG, "Libinfo[%s():%d] bind(): %m", __func__, __LINE__);
-                       close(sock);
-                       return -1;
-               }
-       }
-
-       setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof(int));
-       setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(int));
-
-       if (proto == IPPROTO_TCP)
-       {
-               if (connect(sock, (struct sockaddr *)raddr, sizeof(*raddr)) < 0)
-               {
-                       syslog(LOG_DEBUG, "Libinfo[%s():%d] connect(): %m", __func__, __LINE__);
-                       close(sock);
-                       return -1;
-               }
-       }
-
-       return sock;
-}
diff --git a/netinfo.subproj/ni_prot.x b/netinfo.subproj/ni_prot.x
deleted file mode 100644 (file)
index a83e0fe..0000000
+++ /dev/null
@@ -1,502 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A 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
deleted file mode 100644 (file)
index e6e1a23..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A 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>
-#include "sys_interfaces.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###";
-
-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 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;
-       }
-
-       ilist = _libinfo_ni_sys_interfaces();
-       if (ilist == NULL) return ni_name_dup(NAME_UNKNOWN);
-       if (_libinfo_ni_sys_is_my_address(ilist, &(addr.sin_addr)))
-       {
-               /* Try all my non-loopback interfaces */
-               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);
-                               _libinfo_ni_sys_interfaces_release(ilist);
-                               return dom;
-                       }
-               }
-       }
-       _libinfo_ni_sys_interfaces_release(ilist);
-
-       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_stub.c b/netinfo.subproj/ni_stub.c
new file mode 100644 (file)
index 0000000..183d72d
--- /dev/null
@@ -0,0 +1,171 @@
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+
+#define NI_FAILED 9999
+#define RPC_FAILED 16
+
+typedef struct 
+{
+       int a;
+       int b;
+} stub_type_0;
+
+typedef struct
+{
+       int a;
+       void *b;
+} stub_type_1;
+
+typedef struct
+{
+       void *a;
+       stub_type_1 b;
+} stub_type_2;
+
+static stub_type_1 empty_stub_type_1()
+{
+       stub_type_1 a;
+       
+       memset(&a, 0, sizeof(stub_type_1));
+       return a;
+}
+
+static stub_type_2 empty_stub_type_2()
+{
+       stub_type_2 a;
+       
+       memset(&a, 0, sizeof(stub_type_2));
+       return a;
+}
+
+static int debug_log(const char *func)
+{
+       syslog(LOG_ERR, "NetInfo stub: %s", func);
+       return NI_FAILED;
+}
+
+const char *ni_error(int a) { return "Communication failure"; }
+int multi_call(int a, void *b, int c, int d, int e, void *f, void *g, int h, void *i, void *j, int (*k)(void *, void *, int), int l) { return RPC_FAILED; }
+stub_type_2 ni_prop_dup(stub_type_2 a) { return empty_stub_type_2(); }
+int ni_name_match(void *a, void *b) { return 0; }
+void *ni_name_dup(void *a) { return NULL; }
+
+stub_type_1 ni_idlist_dup(stub_type_1 a)   { return empty_stub_type_1(); }
+stub_type_1 ni_proplist_dup(stub_type_1 a) { return empty_stub_type_1(); }
+stub_type_1 ni_namelist_dup(stub_type_1 a) { return empty_stub_type_1(); }
+
+int ni_idlist_delete(void *a, int b)                   { return -1; }
+int ni_proplist_match(stub_type_1 a, void *b, void *c) { return -1; }
+int ni_namelist_match(stub_type_1 a, void *b)          { return -1; }
+
+void ni_idlist_insert(void *a, int b, int c)                            {}
+void ni_idlist_free(void *a)                                            {}
+void ni_proplist_insert(void *a, stub_type_2 b, int c)                  {}
+void ni_proplist_delete(void *a, int b)                                 {}
+void ni_proplist_free(void *a)                                          {}
+void ni_proplist_list_free(void *a)                                     {}
+void ni_prop_free(void *a)                                              {}
+void ni_name_free(void *a)                                              {}
+void ni_namelist_free(void *a)                                          {}
+void ni_namelist_insert(void *a, void *b, int c)                        {}
+void ni_namelist_delete(void *a, int b)                                 {}
+void ni_entrylist_insert(void *a, stub_type_1 b)                        {}
+void ni_entrylist_delete(void *a, int b)                                {}
+void ni_entrylist_free(void *a)                                         {}
+void ni_parse_url(void *a, void *b, void *c, void *d, void *e, void *f) {}
+void ni_setabort(void *a, int b)                                        {}
+void ni_setwritetimeout(void *a, int b)                                 {}
+void ni_setreadtimeout(void *a, int b)                                  {}
+void ni_needwrite(void *a, int b)                                       {}
+void ni_free(void *a)                                                   {}
+
+int ni_find(void *a, void *b, void *c, int d)                     { return debug_log(__FUNCTION__); }
+int ni_open(void *a, void *b, void *c)                            { return debug_log(__FUNCTION__); }
+int ni_fancyopen(void *a, void *b, void *c, void *d)              { return debug_log(__FUNCTION__); }
+int ni_host_domain(void *a, void *b, void *c)                     { return debug_log(__FUNCTION__); }
+int ni_url(void *a, void *b, void *c)                             { return debug_log(__FUNCTION__); }
+
+void *_ni_dup(void *a)                                            { debug_log(__FUNCTION__); return NULL; }
+void *ni_connect(void *a, void *b)                                { debug_log(__FUNCTION__); return NULL; }
+void *ni_new(void *a, void *b)                                    { debug_log(__FUNCTION__); return NULL; }
+
+int ni_lookupprop(void *a, void *b, void *c, void *d)             { return NI_FAILED; }
+int ni_search(void *a, void *b, void *c, void *d, int e, void *f) { return NI_FAILED; }
+int ni_pathsearch(void *a, void *b, void *c)                      { return NI_FAILED; }
+int ni_pwdomain(void *a, void *b)                                 { return NI_FAILED; }
+int ni_addrtag(void *a, void *b, void *c)                         { return NI_FAILED; }
+int ni_statistics(void *q, void *b)                               { return NI_FAILED; }
+int ni_root(void *a, void *b)                                     { return NI_FAILED; }
+int ni_self(void *a, void *b)                                     { return NI_FAILED; }
+int ni_parent(void *q, void *b, void *c)                          { return NI_FAILED; }
+int ni_children(void *q, void *b, void *c)                        { return NI_FAILED; }
+int ni_create(void *a, void *b, stub_type_1 c, void *d, int e)    { return NI_FAILED; }
+int ni_destroy(void *a, void *b, stub_type_0 c)                   { return NI_FAILED; }
+int ni_write(void *a, void *b, stub_type_1 c)                     { return NI_FAILED; }
+int ni_read(void *a, void *b, void *c)                            { return NI_FAILED; }
+int ni_lookup(void *a, void *b, void *c, void *d, void *e)        { return NI_FAILED; }
+int ni_lookupread(void *a, void *b, void *c, void *d, void *e)    { return NI_FAILED; }
+int ni_list(void *a, void *b, void *c, void *d)                   { return NI_FAILED; }
+int ni_listall(void *a, void *b, void *c)                         { return NI_FAILED; }
+int ni_readprop(void *a, void *b, int c, void *d)                 { return NI_FAILED; }
+int ni_writeprop(void *a, void *b, int c, stub_type_1 d)          { return NI_FAILED; }
+int ni_listprops(void *a, void *b, void *c)                       { return NI_FAILED; }
+int ni_createprop(void *a, void *b, stub_type_2 c, int d)         { return NI_FAILED; }
+int ni_destroyprop(void *a, void *b, int c)                       { return NI_FAILED; }
+int ni_renameprop(void *a, void *b, int c, void *d)               { return NI_FAILED; }
+int ni_createname(void *a, void *b, int c, void *d, int e)        { return NI_FAILED; }
+int ni_destroyname(void *a, void *b, int c, int d)                { return NI_FAILED; }
+int ni_writename(void *a, void *b, int c, int d, void *e)         { return NI_FAILED; }
+int ni_readname(void *a, void *b, int c, int d, void *e)          { return NI_FAILED; }
+int ni_resync(void *a)                                            { return NI_FAILED; }
+int ni_setuser(void *a, void *b)                                  { return NI_FAILED; }
+int ni_setpassword(void *a, void *b)                              { return NI_FAILED; }
+
+int xdr_ni_id(void *a, void *b)              { return 0; }
+int xdr_ni_name(void *a, void *b)            { return 0; }
+int xdr_ni_namelist(void *a, void *b)        { return 0; }
+int xdr_ni_property(void *a, void *b)        { return 0; }
+int xdr_ni_proplist(void *a, void *b)        { return 0; }
+int xdr_ni_idlist(void *a, void *b)          { return 0; }
+int xdr_ni_object(void *a, void *b)          { return 0; }
+int xdr_ni_status(void *a, void *b)          { return 0; }
+int xdr_ni_id_res(void *a, void *b)          { return 0; }
+int xdr_ni_parent_stuff(void *a, void *b)    { return 0; }
+int xdr_ni_parent_res(void *a, void *b)      { return 0; }
+int xdr_ni_children_stuff(void *a, void *b)  { return 0; }
+int xdr_ni_children_res(void *a, void *b)    { return 0; }
+int xdr_ni_entry(void *a, void *b)           { return 0; }
+int xdr_ni_entrylist(void *a, void *b)       { return 0; }
+int xdr_ni_list_stuff(void *a, void *b)      { return 0; }
+int xdr_ni_list_res(void *a, void *b)        { return 0; }
+int xdr_ni_proplist_stuff(void *a, void *b)  { return 0; }
+int xdr_ni_create_args(void *a, void *b)     { return 0; }
+int xdr_ni_proplist_res(void *a, void *b)    { return 0; }
+int xdr_ni_create_stuff(void *a, void *b)    { return 0; }
+int xdr_ni_create_res(void *a, void *b)      { return 0; }
+int xdr_ni_destroy_args(void *a, void *b)    { return 0; }
+int xdr_ni_lookup_args(void *a, void *b)     { return 0; }
+int xdr_ni_lookup_stuff(void *a, void *b)    { return 0; }
+int xdr_ni_lookup_res(void *a, void *b)      { return 0; }
+int xdr_ni_name_args(void *a, void *b)       { return 0; }
+int xdr_ni_createprop_args(void *a, void *b) { return 0; }
+int xdr_ni_writeprop_args(void *a, void *b)  { return 0; }
+int xdr_ni_prop_args(void *a, void *b)       { return 0; }
+int xdr_ni_namelist_stuff(void *a, void *b)  { return 0; }
+int xdr_ni_namelist_res(void *a, void *b)    { return 0; }
+int xdr_ni_propname_args(void *a, void *b)   { return 0; }
+int xdr_ni_createname_args(void *a, void *b) { return 0; }
+int xdr_ni_nameindex_args(void *a, void *b)  { return 0; }
+int xdr_ni_writename_args(void *a, void *b)  { return 0; }
+int xdr_ni_readname_stuff(void *a, void *b)  { return 0; }
+int xdr_ni_readname_res(void *a, void *b)    { return 0; }
+int xdr_ni_binding(void *a, void *b)         { return 0; }
+int xdr_ni_rparent_res(void *a, void *b)     { return 0; }
+int xdr_ni_object_list(void *a, void *b)     { return 0; }
+int xdr_ni_object_node(void *a, void *b)     { return 0; }
+int xdr_ni_readall_stuff(void *a, void *b)   { return 0; }
+int xdr_ni_readall_res(void *a, void *b)     { return 0; }
+int xdr_ni_proplist_list(void *a, void *b)   { return 0; }
+int xdr_ni_listall_stuff(void *a, void *b)   { return 0; }
+int xdr_ni_listall_res(void *a, void *b)     { return 0; }
diff --git a/netinfo.subproj/ni_useful.c b/netinfo.subproj/ni_useful.c
deleted file mode 100644 (file)
index 9364584..0000000
+++ /dev/null
@@ -1,746 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A 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 = (char *)domain;
-       while ((slash = (char *)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);
-       NI_INIT(&idl);
-       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
deleted file mode 100644 (file)
index e99f78c..0000000
+++ /dev/null
@@ -1,541 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A 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;
-       struct sockaddr_in addr;
-
-       *dom = NULL;
-       nid->nii_object = NI_INDEX_NULL;
-       nid->nii_instance = NI_INDEX_NULL;
-       
-       memset(&addr, 0, sizeof(struct sockaddr_in));
-       addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-
-       d = ni_connect(&addr, "local");
-       if (d == NULL) return NI_FAILED;
-
-       while (d != NULL)
-       {
-               if (timeout > 0)
-               {
-                       ni_setreadtimeout(d, timeout);
-                       ni_setabort(d, 1);
-               }
-
-               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;
-
-       /* compile the regular expression */
-       cexp = (regex_t *)malloc(sizeof(regex_t));
-       memset(cexp, 0, sizeof(regex_t));
-       i = regcomp(cexp, expr, flags);
-       if (i != 0)
-       {
-               free(cexp);
-               return NI_FAILED;
-       }
-
-       /* get subdirectory list */
-       NI_INIT(&el);
-       status = ni_list(handle, dir, name, &el);
-       if (status != NI_OK)
-       {
-               regfree(cexp);
-               free(cexp);
-               return status;
-       }
-
-       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;
-
-               found = 0;
-               for (j = 0; j < nl->ni_namelist_len; j++)
-               {
-                       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);
-       regfree(cexp);
-       free(cexp);
-
-       return NI_OK;
-}
diff --git a/netinfo.subproj/ni_util.h b/netinfo.subproj/ni_util.h
deleted file mode 100644 (file)
index f0d599d..0000000
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A 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>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#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 *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif !_NI_UTIL_H_
-
diff --git a/netinfo.subproj/nibind_prot.x b/netinfo.subproj/nibind_prot.x
deleted file mode 100644 (file)
index 19ef737..0000000
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A 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/netinfo.subproj/sys_interfaces.c b/netinfo.subproj/sys_interfaces.c
deleted file mode 100644 (file)
index ff78452..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * Copyright (c) 2001 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A 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 <unistd.h>
-#include <ifaddrs.h>
-#include "sys_interfaces.h"
-
-__private_extern__ interface_list_t *
-_libinfo_ni_sys_interfaces(void)
-{
-       interface_list_t *my_interfaces = NULL;
-       interface_t *iface;
-       struct ifaddrs *ifa, *p;
-
-       if (getifaddrs(&ifa) < 0) return NULL;
-
-       my_interfaces = (interface_list_t *)malloc(sizeof(interface_list_t));
-       my_interfaces->count = 0;
-       my_interfaces->interface = NULL;
-
-       for (p = ifa; p != NULL; p = p->ifa_next)
-       {
-               if (p->ifa_addr == NULL) continue;
-               if ((p->ifa_flags & IFF_UP) == 0) continue;
-               if (p->ifa_addr->sa_family != AF_INET) 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));
-               iface->name = strdup(p->ifa_name);
-               iface->flags = p->ifa_flags;
-               iface->addr.s_addr = ((struct sockaddr_in *)(p->ifa_addr))->sin_addr.s_addr;
-               iface->mask.s_addr = ((struct sockaddr_in *)(p->ifa_netmask))->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);
-       }
-
-       freeifaddrs(ifa);
-
-       return my_interfaces;
-}
-
-__private_extern__  void
-_libinfo_ni_sys_interfaces_release(interface_list_t *l)
-{
-       int i;
-
-       if (l == NULL) return;
-
-       for (i = 0; i < l->count; i++)
-       {
-               if (l->interface[i].name != NULL) free(l->interface[i].name);
-       }
-
-       free(l->interface);
-       free(l);
-}
-
-__private_extern__ int
-_libinfo_ni_sys_is_my_address(interface_list_t *l, struct in_addr *a)
-{
-       int i;
-
-       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;
-}
-
-__private_extern__ int
-_libinfo_ni_sys_is_my_network(interface_list_t *l, struct in_addr *a)
-{
-       int i;
-
-       if (l == NULL) return 0;
-       
-       for (i = 0; i < l->count; i++)
-       {
-               if ((a->s_addr & l->interface[i].mask.s_addr) ==
-                       l->interface[i].netaddr.s_addr) return 1;
-
-       }
-       return 0;
-}
diff --git a/netinfo.subproj/sys_interfaces.h b/netinfo.subproj/sys_interfaces.h
deleted file mode 100644 (file)
index 8064075..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (c) 2001 Apple Computer, Inc. All rights reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License").  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
- * 
- * The Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License.
- * 
- * @APPLE_LICENSE_HEADER_END@
- */
-
-#ifndef __SYS_INTERFACES__
-#define __SYS_INTERFACES__
-
-#include <sys/types.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-#include <net/if.h>
-
-typedef struct
-{
-       char *name;
-       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;
-
-interface_list_t *_libinfo_ni_sys_interfaces(void);
-void _libinfo_ni_sys_interfaces_release(interface_list_t *l);
-int _libinfo_ni_sys_is_my_address(interface_list_t *l, struct in_addr *a);
-int _libinfo_ni_sys_is_my_network(interface_list_t *l, struct in_addr *a);
-
-#endif /* __SYS_INTERFACES__ */
index 8792e4bb8b4357d8d679d04fcd31b29748adc5bc..542d83551cd9b229c3028954ec4dd16d52145e01 100644 (file)
@@ -28,7 +28,7 @@ CFILES = getdomainname.c getnetgrent.c innetgr.c setdomainname.c\
 OTHERSRCS = Makefile.preamble Makefile yp_all.3 yp_bind.3 yp_first.3\
             yp_get_default_domain.3 yp_master.3 yp_match.3 yp_next.3\
             yp_order.3 yp_unbind.3 ypclnt.3 yperr_string.3 ypprot_err.3\
-            Makefile.postamble
+            yp.8 Makefile.postamble
 
 
 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
index e8f240ca82ae170fa0fc0422afa8e4857e960623..019c45f6bed0ea47e63dd07b97b80c623b959c61 100644 (file)
 
 MAN3DIR=/usr/share/man/man3
 MAN5DIR=/usr/share/man/man5
+MAN8DIR=/usr/share/man/man8
 
 install-nis-man:
        install -m 755 -o root -g wheel -d $(DSTROOT)$(MAN3DIR)
+       install -m 755 -o root -g wheel -d $(DSTROOT)$(MAN8DIR)
        install -m 644 -o root -g wheel -c yp_all.3                "$(DSTROOT)$(MAN3DIR)"
        install -m 644 -o root -g wheel -c yp_bind.3               "$(DSTROOT)$(MAN3DIR)"
        install -m 644 -o root -g wheel -c yp_first.3              "$(DSTROOT)$(MAN3DIR)"
@@ -127,3 +129,5 @@ install-nis-man:
        install -m 644 -o root -g wheel -c ypclnt.3                "$(DSTROOT)$(MAN3DIR)"
        install -m 644 -o root -g wheel -c yperr_string.3          "$(DSTROOT)$(MAN3DIR)"
        install -m 644 -o root -g wheel -c ypprot_err.3            "$(DSTROOT)$(MAN3DIR)"
+       install -m 644 -o root -g wheel -c yp.8                    "$(DSTROOT)$(MAN8DIR)"
+
index a5e57b42f449efe53e4f5dfdbe52f5fb025dd2f7..a0abefb92aea9e81347a1cd2acfd006c101db2e0 100644 (file)
@@ -1,6 +1,8 @@
 AFTER_POSTINSTALL += install-nis-man
 PUBLIC_HEADER_DIR_SUFFIX = /rpcsvc
 
+OTHER_CFLAGS += -D__DARWIN_NON_CANCELABLE=1
+
 # for building 64-bit
 # <rdar://problem/3819761> Libinfo need to build with gcc-3.5 and 3-way fat
 NEXTSTEP_OBJCPLUS_COMPILER = $(CCOMPILER)
index 137ea49eb86c731c9e0df8cfafbc39069b23845a..14a354463f8444754d699da5b0b6beb2dbb6e187 100644 (file)
@@ -77,5 +77,5 @@ struct ypmaplist *objp;
                return FALSE;
        }
        return xdr_pointer(xdrs, (caddr_t *)&objp->next,
-           sizeof(struct ypmaplist), xdr_ypmaplist);
+           sizeof(struct ypmaplist), (xdrproc_t)xdr_ypmaplist);
 }
index cce1529289273db3cd7ea674dec108bf42ad04a4..db238de6b6861b653a5bc66cb47ac37b05f0b281 100644 (file)
@@ -77,5 +77,5 @@ struct ypresp_maplist *objp;
                return FALSE;
        }
        return xdr_pointer(xdrs, (caddr_t *)&objp->maps,
-           sizeof(struct ypmaplist), xdr_ypmaplist);
+           sizeof(struct ypmaplist), (xdrproc_t)xdr_ypmaplist);
 }
diff --git a/nis.subproj/yp.8 b/nis.subproj/yp.8
new file mode 100644 (file)
index 0000000..b903753
--- /dev/null
@@ -0,0 +1,566 @@
+.\" Copyright (c) 1992/3 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. 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.
+.\"
+.\"     from: @(#)yp.8 1.0 (deraadt) 4/26/93
+.\" $FreeBSD: src/share/man/man8/yp.8,v 1.36 2005/01/21 08:36:40 ru Exp $
+.\"
+.Dd April 5, 1993
+.Dt YP 8
+.Os
+.Sh NAME
+.Nm yp
+.Nd description of the YP/NIS system
+.Sh SYNOPSIS
+.Nm
+.Sh DESCRIPTION
+The
+.Nm YP
+subsystem allows network management of passwd, group, netgroup, hosts,
+services, rpc, bootparams and ethers file
+entries through the functions
+.Xr getpwent 3 ,
+.Xr getgrent 3 ,
+.Xr getnetgrent 3 ,
+.Xr gethostent 3 ,
+.Xr getnetent 3 ,
+.Xr getrpcent 3 ,
+and
+.Xr ethers 3 .
+The
+.Xr bootparamd 8
+daemon makes direct
+.Tn NIS
+library calls since there are no
+functions in the standard C library for reading bootparams.
+.Tn NIS
+support is enabled in
+.Xr nsswitch.conf 5 .
+.Pp
+The
+.Nm YP
+subsystem is started automatically in
+.Pa /etc/rc
+if it has been initialized in
+.Pa /etc/rc.conf
+and if the directory
+.Pa /var/yp
+exists (which it does in the default distribution).
+The default
+.Tn NIS
+domain must also be set with the
+.Xr domainname 1
+command, which will happen automatically at system startup if it is
+specified in
+.Pa /etc/rc.conf .
+.Pp
+.Tn NIS
+is an
+.Tn RPC Ns -based
+client/server system that allows a group of
+machines within an
+.Tn NIS
+domain to share a common set of configuration files.
+This permits a system
+administrator to set up
+.Tn NIS
+client systems with only minimal configuration
+data and add, remove or modify configuration data from a single location.
+.Pp
+The canonical copies of all
+.Tn NIS
+information are stored on a single machine
+called the
+.Tn NIS
+.Em "master server" .
+The databases used to store the information are called
+.Tn NIS
+.Em maps .
+In
+.Fx ,
+these maps are stored in
+.Pa /var/yp/ Ns Aq Ar domainname
+where
+.Aq Ar domainname
+is the name of the
+.Tn NIS
+domain being served.
+A single
+.Tn NIS
+server can
+support several domains at once, therefore it is possible to have several
+such directories, one for each supported domain.
+Each domain will have
+its own independent set of maps.
+.Pp
+In
+.Fx ,
+the
+.Tn NIS
+maps are Berkeley DB hashed database files (the
+same format used for the
+.Xr passwd 5
+database files).
+Other operating systems that support
+.Tn NIS
+use old-style
+.Nm ndbm
+databases instead (largely because Sun Microsystems originally based
+their
+.Tn NIS
+implementation on
+.Nm ndbm ,
+and other vendors have simply licensed
+Sun's code rather than design their own implementation with a different
+database format).
+On these systems, the databases are generally split
+into
+.Pa .dir
+and
+.Pa .pag
+files which the
+.Nm ndbm
+code uses to hold separate parts of the hash
+database.
+The Berkeley DB hash method instead uses a single file for
+both pieces of information.
+This means that while you may have
+.Pa passwd.byname.dir
+and
+.Pa passwd.byname.pag
+files on other operating systems (both of which are really parts of the
+same map),
+.Fx
+will have only one file called
+.Pa passwd.byname .
+The difference in format is not significant: only the
+.Tn NIS
+server,
+.Xr ypserv 8 ,
+and related tools need to know the database format of the
+.Tn NIS
+maps.
+Client
+.Tn NIS
+systems receive all
+.Tn NIS
+data in
+.Tn ASCII
+form.
+.Pp
+There are three main types of
+.Tn NIS
+systems:
+.Bl -enum
+.It
+.Tn NIS
+clients,
+which query
+.Tn NIS
+servers for information.
+.It
+.Tn NIS
+master servers,
+which maintain the canonical copies of all
+.Tn NIS
+maps.
+.It
+.Tn NIS
+slave servers,
+which maintain backup copies of
+.Tn NIS
+maps that are periodically
+updated by the master.
+.El
+.Pp
+A
+.Tn NIS
+client establishes what is called a
+.Em binding
+to a particular
+.Tn NIS
+server using the
+.Xr ypbind 8
+daemon.
+The
+.Xr ypbind 8
+utility checks the system's default domain (as set by the
+.Xr domainname 1
+command) and begins broadcasting
+.Tn RPC
+requests on the local network.
+These requests specify the name of the domain for which
+.Xr ypbind 8
+is attempting to establish a binding.
+If a server that has been
+configured to serve the requested domain receives one of the broadcasts,
+it will respond to
+.Xr ypbind 8 ,
+which will record the server's address.
+If there are several servers
+available (a master and several slaves, for example),
+.Xr ypbind 8
+will use the address of the first one to respond.
+From that point
+on, the client system will direct all of its
+.Tn NIS
+requests to that server.
+The
+.Xr ypbind 8
+utility will occasionally
+.Dq ping
+the server to make sure it is still up
+and running.
+If it fails to receive a reply to one of its pings
+within a reasonable amount of time,
+.Xr ypbind 8
+will mark the domain as unbound and begin broadcasting again in the
+hopes of locating another server.
+.Pp
+.Tn NIS
+master and slave servers handle all
+.Tn NIS
+requests with the
+.Xr ypserv 8
+daemon.
+The
+.Xr ypserv 8
+utility is responsible for receiving incoming requests from
+.Tn NIS
+clients,
+translating the requested domain and map name to a path to the
+corresponding database file and transmitting data from the database
+back to the client.
+There is a specific set of requests that
+.Xr ypserv 8
+is designed to handle, most of which are implemented as functions
+within the standard C library:
+.Bl -tag -width ".Fn yp_master"
+.It Fn yp_order
+check the creation date of a particular map
+.It Fn yp_master
+obtain the name of the
+.Tn NIS
+master server for a given
+map/domain
+.It Fn yp_match
+lookup the data corresponding to a given in key in a particular
+map/domain
+.It Fn yp_first
+obtain the first key/data pair in a particular map/domain
+.It Fn yp_next
+pass
+.Xr ypserv 8
+a key in a particular map/domain and have it return the
+key/data pair immediately following it (the functions
+.Fn yp_first
+and
+.Fn yp_next
+can be used to do a sequential search of an
+.Tn NIS
+map)
+.It Fn yp_all
+retrieve the entire contents of a map
+.El
+.Pp
+There are a few other requests which
+.Xr ypserv 8
+is capable of handling (i.e., acknowledge whether or not you can handle
+a particular domain
+.Pq Dv YPPROC_DOMAIN ,
+or acknowledge only if you can handle the domain and be silent otherwise
+.Pq Dv YPPROC_DOMAIN_NONACK )
+but
+these requests are usually generated only by
+.Xr ypbind 8
+and are not meant to be used by standard utilities.
+.Pp
+On networks with a large number of hosts, it is often a good idea to
+use a master server and several slaves rather than just a single master
+server.
+A slave server provides the exact same information as a master
+server: whenever the maps on the master server are updated, the new
+data should be propagated to the slave systems using the
+.Xr yppush 8
+command.
+The
+.Tn NIS
+.Pa Makefile
+.Pq Pa /var/yp/Makefile
+will do this automatically if the administrator comments out the
+line which says
+.Dq Li NOPUSH=true
+.Va ( NOPUSH
+is set to true by default because the default configuration is
+for a small network with only one
+.Tn NIS
+server).
+The
+.Xr yppush 8
+command will initiate a transaction between the master and slave
+during which the slave will transfer the specified maps from the
+master server using
+.Xr ypxfr 8 .
+(The slave server calls
+.Xr ypxfr 8
+automatically from within
+.Xr ypserv 8 ;
+therefore it is not usually necessary for the administrator
+to use it directly.
+It can be run manually if
+desired, however.)
+Maintaining
+slave servers helps improve
+.Tn NIS
+performance on large
+networks by:
+.Bl -bullet
+.It
+Providing backup services in the event that the
+.Tn NIS
+master crashes
+or becomes unreachable
+.It
+Spreading the client load out over several machines instead of
+causing the master to become overloaded
+.It
+Allowing a single
+.Tn NIS
+domain to extend beyond
+a local network (the
+.Xr ypbind 8
+daemon might not be able to locate a server automatically if it resides on
+a network outside the reach of its broadcasts.
+It is possible to force
+.Xr ypbind 8
+to bind to a particular server with
+.Xr ypset 8
+but this is sometimes inconvenient.
+This problem can be avoided simply by
+placing a slave server on the local network.)
+.El
+.Pp
+The
+.Fx
+.Xr ypserv 8
+is specially designed to provide enhanced security (compared to
+other
+.Tn NIS
+implementations) when used exclusively with
+.Fx
+client
+systems.
+The
+.Fx
+password database system (which is derived directly
+from
+.Bx 4.4 )
+includes support for
+.Em "shadow passwords" .
+The standard password database does not contain users' encrypted
+passwords: these are instead stored (along with other information)
+in a separate database which is accessible only by the super-user.
+If the encrypted password database were made available as an
+.Tn NIS
+map, this security feature would be totally disabled, since any user
+is allowed to retrieve
+.Tn NIS
+data.
+.Pp
+To help prevent this,
+.Fx Ns 's
+.Tn NIS
+server handles the shadow password maps
+.Pa ( master.passwd.byname
+and
+.Pa master.passwd.byuid )
+in a special way: the server will only provide access to these
+maps in response to requests that originate on privileged ports.
+Since only the super-user is allowed to bind to a privileged port,
+the server assumes that all such requests come from privileged
+users.
+All other requests are denied: requests from non-privileged
+ports will receive only an error code from the server.
+Additionally,
+.Fx Ns 's
+.Xr ypserv 8
+includes support for
+.An Wietse Venema Ns 's
+tcp wrapper package; with tcp
+wrapper support enabled, the administrator can configure
+.Xr ypserv 8
+to respond only to selected client machines.
+.Pp
+While these enhancements provide better security than stock
+.Tn NIS ,
+they are by no means 100% effective.
+It is still possible for
+someone with access to your network to spoof the server into disclosing
+the shadow password maps.
+.Pp
+On the client side,
+.Fx Ns 's
+.Xr getpwent 3
+functions will automatically search for the
+.Pa master.passwd
+maps and use them if they exist.
+If they do, they will be used, and
+all fields in these special maps (class, password age and account
+expiration) will be decoded.
+If they are not found, the standard
+.Pa passwd
+maps will be used instead.
+.Sh COMPATIBILITY
+When using a
+.No non- Ns Fx
+.Tn NIS
+server for
+.Xr passwd 5
+files, it is unlikely that the default MD5-based format that
+.Fx
+uses for passwords will be accepted by it.
+If this is the case, the value of the
+.Va passwd_format
+setting in
+.Xr login.conf 5
+should be changed to
+.Qq Li des
+for compatibility.
+.Pp
+Some systems, such as
+.Tn SunOS
+4.x, need
+.Tn NIS
+to be running in order
+for their hostname resolution functions
+.Fn ( gethostbyname ,
+.Fn gethostbyaddr ,
+etc.) to work properly.
+On these systems,
+.Xr ypserv 8
+performs
+.Tn DNS
+lookups when asked to return information about
+a host that does not exist in its
+.Pa hosts.byname
+or
+.Pa hosts.byaddr
+maps.
+.Fx Ns 's
+resolver uses
+.Tn DNS
+by default (it can be made to use
+.Tn NIS ,
+if desired), therefore its
+.Tn NIS
+server does not do
+.Tn DNS
+lookups
+by default.
+However,
+.Xr ypserv 8
+can be made to perform
+.Tn DNS
+lookups if it is started with a special
+flag.
+It can also be made to register itself as an
+.Tn NIS
+v1 server
+in order to placate certain systems that insist on the presence of
+a v1 server
+.No ( Fx
+uses only
+.Tn NIS
+v2, but many other systems,
+including
+.Tn SunOS
+4.x, search for both a v1 and v2 server when binding).
+.Fx Ns 's
+.Xr ypserv 8
+does not actually handle
+.Tn NIS
+v1 requests, but this
+.Dq "kludge mode"
+is useful for silencing stubborn systems that search for both
+a v1 and v2 server.
+.Pp
+(Please see the
+.Xr ypserv 8
+manual page for a detailed description of these special features
+and flags.)
+.Sh HISTORY
+The
+.Nm YP
+subsystem was written from the ground up by
+.An Theo de Raadt
+to be compatible to Sun's implementation.
+Bug fixes, improvements
+and
+.Tn NIS
+server support were later added by
+.An Bill Paul .
+The server-side code was originally written by
+.An Peter Eriksson
+and
+.An Tobias Reber
+and is subject to the GNU Public License.
+No Sun code was
+referenced.
+.Sh BUGS
+While
+.Fx
+now has both
+.Tn NIS
+client and server capabilities, it does not yet have support for
+.Xr ypupdated 8
+or the
+.Fn yp_update
+function.
+Both of these require secure
+.Tn RPC ,
+which
+.Fx
+does not
+support yet either.
+.Pp
+The
+.Xr getservent 3
+and
+.Xr getprotoent 3
+functions do not yet have
+.Tn NIS
+support.
+Fortunately, these files
+do not need to be updated that often.
+.Pp
+Many more manual pages should be written, especially
+.Xr ypclnt 3 .
+For the time being, seek out a local Sun machine and read the
+manuals for there.
+.Pp
+Neither Sun nor this author have found a clean way to handle
+the problems that occur when ypbind cannot find its server
+upon bootup.
index 55778c8a07031b3baeb3c44109c7ad5fa874ae1f..e08a981c4738494fcdc52852e3e33fbc6151cfec 100644 (file)
@@ -89,12 +89,12 @@ u_long *objp;
        memset(&out, 0, sizeof out);
        while(1) {
                if( !xdr_ypresp_all(xdrs, &out)) {
-                       xdr_free(xdr_ypresp_all, (char *)&out);
+                       xdr_free((xdrproc_t)xdr_ypresp_all, (char *)&out);
                        *objp = (u_long)YP_YPERR;
                        return FALSE;
                }
                if(out.more == 0) {
-                       xdr_free(xdr_ypresp_all, (char *)&out);
+                       xdr_free((xdrproc_t)xdr_ypresp_all, (char *)&out);
                        return FALSE;
                }
                status = out.ypresp_all_u.val.stat;
@@ -118,7 +118,7 @@ u_long *objp;
                                free(key);
                                key = NULL;
                        }
-                       xdr_free(xdr_ypresp_all, (char *)&out);
+                       xdr_free((xdrproc_t)xdr_ypresp_all, (char *)&out);
 
                        if (key == NULL || val == NULL)
                                return FALSE;
@@ -133,10 +133,10 @@ u_long *objp;
                                return TRUE;
                        break;
                case YP_NOMORE:
-                       xdr_free(xdr_ypresp_all, (char *)&out);
+                       xdr_free((xdrproc_t)xdr_ypresp_all, (char *)&out);
                        return TRUE;
                default:
-                       xdr_free(xdr_ypresp_all, (char *)&out);
+                       xdr_free((xdrproc_t)xdr_ypresp_all, (char *)&out);
                        *objp = status;
                        return TRUE;
                }
@@ -183,7 +183,7 @@ yp_all(indomain, inmap, incallback)
        ypresp_data = (void *) incallback->data;
 
        (void) clnt_call(clnt, YPPROC_ALL,
-           xdr_ypreq_nokey, &yprnk, xdr_ypresp_all_seq, &status, tv);
+           (xdrproc_t)xdr_ypreq_nokey, &yprnk, (xdrproc_t)xdr_ypresp_all_seq, &status, tv);
        clnt_destroy(clnt);
        if(status != YP_FALSE)
                r = ypprot_err(status);
index a8b9c9d91e9f9fe9f700675e0f27a83eb38ee4d6..14b20bbb8bd10ebf7d5650c123ae5a9ff6b1f3dc 100644 (file)
@@ -71,8 +71,12 @@ static char *rcsid = "$OpenBSD: yp_bind.c,v 1.9 1997/04/29 21:25:20 deraadt Exp
 #include <rpc/xdr.h>
 #include <rpcsvc/yp.h>
 #include <rpcsvc/ypclnt.h>
+#include <notify.h>
+#include <pthread.h>
 #include "ypinternal.h"
 
+extern int notify_register_plain(char *, int *);
+
 struct dom_binding *_ypbindlist = NULL;
 char _yp_domain[MAXHOSTNAMELEN] = { '\0' };
 
@@ -84,7 +88,6 @@ _yp_dobind(dom, ypdb)
        struct dom_binding **ypdb;
 {
        static int      pid = -1;
-       char            path[MAXPATHLEN];
        struct dom_binding *ysd, *ysd2;
        struct ypbind_resp ypbr;
        struct timeval  tv;
@@ -92,141 +95,141 @@ _yp_dobind(dom, ypdb)
        struct ypbind_binding *bn;
        int             clnt_sock, fd, gpid;
        CLIENT         *client;
-       int             new = 0, r;
+       int             new = 0, r, proto;
        int             count = 0;
        u_short         port;
+       int status, notify_token;
+       uint64_t abort;
+       char *notify_name;
 
        /*
         * 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);
+       if ((fd = open(YPBINDLOCK, O_RDONLY)) == -1) return YPERR_YPBIND;
+
+       if (!((flock(fd, LOCK_EX | LOCK_NB) == -1) && (errno == EWOULDBLOCK)))
+       {
+               close(fd);
                return YPERR_YPBIND;
        }
-       (void)close(fd);
+
+       close(fd);
 
        gpid = getpid();
-       if (!(pid == -1 || pid == gpid)) {
+       if (!((pid == -1) || (pid == gpid)))
+       {
                ysd = _ypbindlist;
-               while (ysd) {
-                       if (ysd->dom_client)
-                               clnt_destroy(ysd->dom_client);
+               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 (ypdb != NULL) *ypdb = NULL;
 
-       if (dom == NULL || strlen(dom) == 0)
-               return YPERR_BADARGS;
+       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);
+       {
+               if (strcmp(dom, ysd->dom_domain) == 0) break;
+       }
+
+       if (ysd == NULL)
+       {
+               ysd = calloc(1, sizeof(struct dom_binding));
+               if (ysd == NULL) return YPERR_YPERR;
                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);
+       /*
+        * Get notification token
+        * we use a self-notification token to allow a caller
+        * to signal the thread doing this bind call to quit.
+        */
+       notify_name = NULL;
+       notify_token = -1;
+
+       asprintf(&notify_name, "self.thread.%lu", (unsigned long)pthread_self());
+       if (notify_name != NULL) 
+       {
+               status = notify_register_plain(notify_name, &notify_token);
+               free(notify_name);
+       }
+
+again:
+       if (notify_token != -1)
+       {
+               abort = 0;
+               status = notify_get_state(notify_token, &abort);
+               if (abort == ThreadStateExitRequested)
+               {
+                       if (new) free(ysd);
+                       notify_cancel(notify_token);
                        return YPERR_YPBIND;
                }
        }
-trynet:
-       if (ysd->dom_vers == -1 || ysd->dom_vers == 0) {
-               (void)memset(&clnt_sin, 0, sizeof clnt_sin);
+
+       proto = YP_BIND_UDP;
+       if (ysd->dom_vers == YP_BIND_TCP) proto = YP_BIND_TCP;
+
+       if ((ysd->dom_vers == 0) || (ysd->dom_vers == YP_BIND_UDP) || (ysd->dom_vers == YP_BIND_TCP))
+       {
+               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) {
+               client = clnttcp_create(&clnt_sin, YPBINDPROG, YPBINDVERS, &clnt_sock, 0, 0);
+               if (client == NULL)
+               {
                        clnt_pcreateerror("clnttcp_create");
-                       if (new)
-                               free(ysd);
+                       if (new) free(ysd);
+                       if (notify_token != -1) notify_cancel(notify_token);
                        return YPERR_YPBIND;
                }
-               if (ntohs(clnt_sin.sin_port) >= IPPORT_RESERVED ||
-                   ntohs(clnt_sin.sin_port) == 20) {
+
+               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);
+                       if (new) free(ysd);
+                       if (notify_token != -1) notify_cancel(notify_token);
                        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);
+
+               r = clnt_call(client, YPBINDPROC_DOMAIN, (xdrproc_t)xdr_domainname, &dom, (xdrproc_t)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;
+                       ysd->dom_vers = proto;
                        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) {
+               if ((ntohs(port) >= IPPORT_RESERVED) || (ntohs(port) == 20))
+               {
                        /*
                         * This is bogus -- the ypbind wants me to
                         * communicate to an insecure ypserv.  We are
@@ -234,46 +237,51 @@ gotdata:
                         * but for now we'll simply ignore it; real YP
                         * is obviously not running.
                         */
-                       if (new)
-                               free(ysd);
+                       if (new) free(ysd);
+                       if (notify_token != -1) notify_cancel(notify_token);
                        return YPERR_YPBIND;
                }
-               (void)memset(&ysd->dom_server_addr, 0, 
-                   sizeof ysd->dom_server_addr);
+
+               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));
+               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);
+               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);
+
+       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;
+
+       if (proto == YP_BIND_UDP) ysd->dom_client = clntudp_create(&ysd->dom_server_addr, YPPROG, YPVERS, tv, &ysd->dom_socket);
+       else ysd->dom_client = clnttcp_create(&ysd->dom_server_addr, YPPROG, YPVERS, &ysd->dom_socket, 0, 0);
+
+       if (ysd->dom_client == NULL)
+       {
+               if (proto == YP_BIND_UDP) clnt_pcreateerror("clntudp_create");
+               else clnt_pcreateerror("clnttcp_create");
+               ysd->dom_vers = proto;
                goto again;
        }
+
+       if (notify_token != -1) notify_cancel(notify_token);
+
        if (fcntl(ysd->dom_socket, F_SETFD, 1) == -1)
                perror("fcntl: F_SETFD");
 
-       if (new) {
+       if (new != 0)
+       {
                ysd->dom_pnext = _ypbindlist;
                _ypbindlist = ysd;
        }
-       if (ypdb != NULL)
-               *ypdb = ysd;
+
+       if (ypdb != NULL) *ypdb = ysd;
        return 0;
 }
 
index 5bdcf11f3cd819520ff1d549543d3f469526f4f7..446d4b6b8e0afc35cf57fbb38c511a9bca6a37fd 100644 (file)
@@ -86,6 +86,7 @@ yp_first(indomain, inmap, outkey, outkeylen, outval, outvallen)
        struct dom_binding *ysd;
        struct timeval  tv;
        int tries = 0, r;
+       static int proto = YP_BIND_UDP;
 
        if (indomain == NULL || *indomain == '\0' ||
            strlen(indomain) > YPMAXDOMAIN || inmap == NULL ||
@@ -106,14 +107,18 @@ again:
        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;
+       r = clnt_call(ysd->dom_client, YPPROC_FIRST, (xdrproc_t)xdr_ypreq_nokey, &yprnk, (xdrproc_t)xdr_ypresp_key_val, &yprkv, tv);
+       if (r != RPC_SUCCESS)
+       {
+               if (tries++) clnt_perror(ysd->dom_client, "yp_first: clnt_call");
+
+               if (proto == YP_BIND_UDP) proto = YP_BIND_TCP;
+               else proto = YP_BIND_UDP;
+               ysd->dom_vers = proto;
+
                goto again;
        }
+
        if (!(r = ypprot_err(yprkv.stat))) {
                *outkeylen = yprkv.key.keydat_len;
                if ((*outkey = malloc(*outkeylen + 1)) == NULL)
@@ -130,7 +135,7 @@ again:
                        (*outval)[*outvallen] = '\0';
                }
        }
-       xdr_free(xdr_ypresp_key_val, (char *) &yprkv);
+       xdr_free((xdrproc_t)xdr_ypresp_key_val, (char *) &yprkv);
        _yp_unbind(ysd);
        return r;
 }
index e795ad2fc857fdf94820114240177e30a84dd017..ef7894becd4603fce16c169c8d561124223c277d 100644 (file)
@@ -81,6 +81,7 @@ yp_maplist(indomain, outmaplist)
        struct ypresp_maplist ypml;
        struct timeval  tv;
        int tries = 0, r;
+       static int proto = YP_BIND_UDP;
 
 again:
        if (_yp_dobind(indomain, &ysd) != 0)
@@ -91,14 +92,18 @@ again:
 
        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;
+       r = clnt_call(ysd->dom_client, YPPROC_MAPLIST, (xdrproc_t)xdr_domainname, &indomain, (xdrproc_t)xdr_ypresp_maplist, &ypml, tv);
+       if (r != RPC_SUCCESS)
+       {
+               if (tries++) clnt_perror(ysd->dom_client, "yp_maplist: clnt_call");
+
+               if (proto == YP_BIND_UDP) proto = YP_BIND_TCP;
+               else proto = YP_BIND_UDP;
+               ysd->dom_vers = proto;
+
                goto again;
        }
+
        *outmaplist = ypml.maps;
        /* NO: xdr_free(xdr_ypresp_maplist, &ypml); */
        _yp_unbind(ysd);
index b3a0795c700c326f8632246d3ad172bd6e30571e..1e13be359b561c5406a26c2b407ae0ae46f77cf2 100644 (file)
@@ -83,6 +83,7 @@ yp_master(indomain, inmap, outname)
        struct ypreq_nokey yprnk;
        struct timeval  tv;
        int tries = 0, r;
+       static int proto = YP_BIND_UDP;
 
        if (indomain == NULL || *indomain == '\0' ||
            strlen(indomain) > YPMAXDOMAIN || inmap == NULL ||
@@ -101,19 +102,23 @@ again:
 
        (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;
+       r = clnt_call(ysd->dom_client, YPPROC_MASTER, (xdrproc_t)xdr_ypreq_nokey, &yprnk, (xdrproc_t)xdr_ypresp_master, &yprm, tv);
+       if (r != RPC_SUCCESS)
+       {
+               if (tries++) clnt_perror(ysd->dom_client, "yp_master: clnt_call");
+
+               if (proto == YP_BIND_UDP) proto = YP_BIND_TCP;
+               else proto = YP_BIND_UDP;
+               ysd->dom_vers = proto;
+
                goto again;
        }
+
        if (!(r = ypprot_err(yprm.stat))) {
                if ((*outname = strdup(yprm.peer)) == NULL)
                        r = YPERR_RESRC;
        }
-       xdr_free(xdr_ypresp_master, (char *) &yprm);
+       xdr_free((xdrproc_t)xdr_ypresp_master, (char *) &yprm);
        _yp_unbind(ysd);
        return r;
 }
index 44b7a7c0b85bbc1aca3ceadfb73acce34750826c..72946d7936a0b6180177f8f5a4d802133a0ffe8c 100644 (file)
@@ -82,7 +82,8 @@ yp_order(indomain, inmap, outorder)
        struct ypresp_order ypro;
        struct ypreq_nokey yprnk;
        struct timeval  tv;
-       int             r = 0;
+       int tries = 0, r = 0;
+       static int proto = YP_BIND_UDP;
 
        if (indomain == NULL || *indomain == '\0' ||
            strlen(indomain) > YPMAXDOMAIN || inmap == NULL ||
@@ -102,7 +103,7 @@ again:
        (void)memset(&ypro, 0, sizeof ypro);
 
        r = clnt_call(ysd->dom_client, YPPROC_ORDER,
-           xdr_ypreq_nokey, &yprnk, xdr_ypresp_order, &ypro, tv);
+           (xdrproc_t)xdr_ypreq_nokey, &yprnk, (xdrproc_t)xdr_ypresp_order, &ypro, tv);
        /*
         * XXX
         * NIS+ YP emulation package does not impliment YPPROC_ORDER
@@ -111,13 +112,21 @@ again:
                r = YPERR_YPERR;
                goto bail;
        }
-       if (r != RPC_SUCCESS) {
-               clnt_perror(ysd->dom_client, "yp_order: clnt_call");
-               ysd->dom_vers = -1;
+
+       if (r != RPC_SUCCESS)
+       {
+               /* call failed - switch protocols and try again */
+               if (tries++) clnt_perror(ysd->dom_client, "yp_order: clnt_call");
+
+               if (proto == YP_BIND_UDP) proto = YP_BIND_TCP;
+               else proto = YP_BIND_UDP;
+               ysd->dom_vers = proto;
+
                goto again;
        }
+
        *outorder = ypro.ordernum;
-       xdr_free(xdr_ypresp_order, (char *) &ypro);
+       xdr_free((xdrproc_t)xdr_ypresp_order, (char *) &ypro);
        r = ypprot_err(ypro.stat);
 bail:
        _yp_unbind(ysd);
index 0d8951eb9cc8b55f71259f1c0be713162ca2efae..669104a4c1be9ab1b837221806aaa879476d173a 100644 (file)
@@ -51,7 +51,7 @@
 .Nm ypprot_err
 .Nd Interface to the YP subsystem
 .Sh SYNOPSIS
-.Fd #include <sys/types.h>
+.Fd #include <rpc/rpc.h>
 .Fd #include <rpcsvc/ypclnt.h>
 .Fd #include <rpcsvc/yp_prot.h>
 .Ft int
@@ -339,4 +339,4 @@ The client cannot communicate with the YP server process.
 .Xr ypbind 8 ,
 .Xr ypserv 8
 .Sh AUTHOR
-Theo De Raadt
+Theo De Raadt
\ No newline at end of file
index 848c572abb858a27864822adb58c04efbbc360e6..b40fbee38d794d32d42f2551e9441df6acc11198 100644 (file)
@@ -79,6 +79,14 @@ extern int _yplib_timeout;
 void _yp_unbind __P((struct dom_binding *));
 int _yp_check __P((char **));
 
+/* allows callers to cancel yp_bind */
+#define ThreadStateExitRequested 4
+
+/* used to tell _yp_dobind to use UDP or TCP */
+#define YP_BIND_UDP -1
+#define YP_BIND_TCP -2
+
+
 #ifdef YPMATCHCACHE
 
 static bool_t ypmatch_add __P((const char *, const char *,
index e689913090bcafabb820d37bcc9fb4d90dfa62ea..19ae14967f1d02432aab61ba66d2ae1d6534056b 100644 (file)
@@ -188,6 +188,7 @@ yp_match(indomain, inmap, inkey, inkeylen, outval, outvallen)
        struct timeval  tv;
        struct ypreq_key yprk;
        int tries = 0, r;
+       static int proto = YP_BIND_UDP;
 
        if (indomain == NULL || *indomain == '\0' || 
            strlen(indomain) > YPMAXDOMAIN || inmap == NULL ||
@@ -227,14 +228,19 @@ again:
 
        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;
+       r = clnt_call(ysd->dom_client, YPPROC_MATCH, (xdrproc_t)xdr_ypreq_key, &yprk, (xdrproc_t)xdr_ypresp_val, &yprv, tv);
+       if (r != RPC_SUCCESS)
+       {
+               /* call failed - switch protocols and try again */
+               if (tries++) clnt_perror(ysd->dom_client, "yp_match: clnt_call");
+
+               if (proto == YP_BIND_UDP) proto = YP_BIND_TCP;
+               else proto = YP_BIND_UDP;
+               ysd->dom_vers = proto;
+
                goto again;
        }
+
        if (!(r = ypprot_err(yprv.stat))) {
                *outvallen = yprv.val.valdat_len;
                if ((*outval = malloc(*outvallen + 1)) == NULL) {
@@ -251,7 +257,7 @@ again:
 #endif
        }
 out:
-       xdr_free(xdr_ypresp_val, (char *) &yprv);
+       xdr_free((xdrproc_t)xdr_ypresp_val, (char *) &yprv);
        _yp_unbind(ysd);
        return r;
 }
@@ -272,6 +278,7 @@ yp_next(indomain, inmap, inkey, inkeylen, outkey, outkeylen, outval, outvallen)
        struct dom_binding *ysd;
        struct timeval  tv;
        int tries = 0, r;
+       static int proto = YP_BIND_UDP;
 
        if (indomain == NULL || *indomain == '\0' ||
            strlen(indomain) > YPMAXDOMAIN || inmap == NULL ||
@@ -294,14 +301,19 @@ again:
        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;
+       r = clnt_call(ysd->dom_client, YPPROC_NEXT, (xdrproc_t)xdr_ypreq_key, &yprk, (xdrproc_t)xdr_ypresp_key_val, &yprkv, tv);
+       if (r != RPC_SUCCESS)
+       {
+               /* call failed - switch protocols and try again */
+               if (tries++) clnt_perror(ysd->dom_client, "yp_next: clnt_call");
+
+               if (proto == YP_BIND_UDP) proto = YP_BIND_TCP;
+               else proto = YP_BIND_UDP;
+               ysd->dom_vers = proto;
+
                goto again;
        }
+
        if (!(r = ypprot_err(yprkv.stat))) {
                *outkeylen = yprkv.key.keydat_len;
                if ((*outkey = malloc(*outkeylen + 1)) == NULL)
@@ -318,7 +330,7 @@ again:
                        (*outval)[*outvallen] = '\0';
                }
        }
-       xdr_free(xdr_ypresp_key_val, (char *) &yprkv);
+       xdr_free((xdrproc_t)xdr_ypresp_key_val, (char *) &yprkv);
        _yp_unbind(ysd);
        return r;
 }
index 1139cb34cc50c90d52d1f7dab9ffa2830ab62863..f74a5256cd02badf397f27de489bbcf44eb58d42 100644 (file)
@@ -25,7 +25,8 @@ CFILES = auth_none.c auth_unix.c authunix_prot.c bindresvport.c\
          xdr_array.c xdr_float.c xdr_mem.c xdr_rec.c xdr_reference.c\
          xdr_sizeof.c xdr_stdio.c getrpcport.c pmap_wakeup.c
 
-OTHERSRCS = Makefile.preamble Makefile
+OTHERSRCS = Makefile.preamble Makefile Makefile.postamble \
+           bindresvport.3 getrpcent.3 getrpcport.3 rpc.3 xdr.3
 
 
 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
diff --git a/rpc.subproj/Makefile.postamble b/rpc.subproj/Makefile.postamble
new file mode 100644 (file)
index 0000000..b851b91
--- /dev/null
@@ -0,0 +1,224 @@
+###############################################################################
+#  NeXT Makefile.postamble Template
+#  Copyright 1993, NeXT Computer, Inc.
+#
+#  This Makefile is used for configuring the standard app makefiles associated
+#  with ProjectBuilder.  
+#  
+#  Use this template to set attributes for a project, sub-project, bundle, or
+#  palette.  Each node in the project's tree of sub-projects and bundles 
+#  should have it's own Makefile.preamble and Makefile.postamble.  Additional
+#  rules (e.g., after_install) that are defined by the developer should be
+#  defined in this file.
+#
+###############################################################################
+# 
+# Here are the variables exported by the common "app" makefiles that can be 
+# used in any customizations you make to the template below:
+# 
+#      PRODUCT_ROOT - Name of the directory to which resources are copied.
+#      OFILE_DIR - Directory into which .o object files are generated.
+#                  (Note that this name is calculated based on the target 
+#                   architectures specified in Project Builder).
+#      DERIVED_SRC_DIR - Directory used for all other derived files
+#      ALL_CFLAGS - All the flags passed to the cc(1) driver for compilations
+#
+#      NAME - name of application, bundle, subproject, palette, etc.
+#      LANGUAGE - langage in which the project is written (default "English")
+#      LOCAL_RESOURCES - localized resources (e.g. nib's, images) of project
+#      GLOBAL_RESOURCES - non-localized resources of project
+#      PROJECTVERSION - version of ProjectBuilder project (NS3.X = 1.1, NS4.0 = 2.0)
+#      ICONSECTIONS - Specifies icon sections when linking executable 
+#
+#      CLASSES - Class implementation files in project.
+#      HFILES - Header files in project.
+#      MFILES - Other Objective-C source files in project. 
+#      CFILES - Other C source files in project. 
+#      PSWFILES - .psw files in the project
+#      PSWMFILES - .pswm files in the project
+#      SUBPROJECTS - Subprojects of this project
+#      BUNDLES - Bundle subprojects of this project
+#      OTHERSRCS - Other miscellaneous sources of this project
+#      OTHERLINKED - Source files not matching a standard source extention
+#
+#      LIBS - Libraries to link with when making app target
+#      DEBUG_LIBS - Libraries to link with when making debug target
+#      PROF_LIBS - Libraries to link with when making profile target
+#      OTHERLINKEDOFILES - Other relocatable files to (always) link in.
+#
+#      APP_MAKEFILE_DIR - Directory in which to find generic set of Makefiles
+#      MAKEFILEDIR - Directory in which to find $(MAKEFILE)
+#      MAKEFILE - Top level mechanism Makefile (e.g., app.make, bundle.make)
+#      INSTALLDIR - Directory app will be installed into by 'install' target
+#
+###############################################################################
+
+
+# Change defaults assumed by the standard makefiles here.  Edit the 
+# following default values as appropriate. (Note that if no Makefile.postamble 
+# exists, these values will have defaults set in common.make).
+
+# Versioning of frameworks, libraries, bundles, and palettes:
+#CURRENTLY_ACTIVE_VERSION = YES    # Set to "NO" to produce a compatibility binary
+#DEPLOY_WITH_VERSION_NAME = A
+#COMPATIBILITY_PROJECT_VERSION = 1
+
+# Some compiler flags can be easily overridden here, but onlytake effect at 
+# the top-level:
+#OPTIMIZATION_CFLAG = -O
+#DEBUG_SYMBOLS_CFLAG = -g
+#WARNING_CFLAGS = -Wall
+#DEBUG_BUILD_CFLAGS = -DDEBUG
+#PROFILE_BUILD_CFLAGS = -pg -DPROFILE
+
+# Flags passed to yacc
+#YFLAGS = -d
+
+# Library and Framework projects only:
+# 1. If you want something other than the default .dylib name, override it here
+#DYLIB_INSTALL_NAME = lib$(NAME).dylib
+
+# 2. If you want to change the -install_name flag from the absolute path to the development area, change it here.  One good choice is the installation directory.  Another one might be none at all.
+#DYLIB_INSTALL_DIR = $(INSTALLDIR)
+
+# Ownership and permissions of files installed by 'install' target
+#INSTALL_AS_USER = root        # User/group ownership 
+#INSTALL_AS_GROUP = wheel      # (probably want to set both of these) 
+#INSTALL_PERMISSIONS =         # If set, 'install' chmod's executable to this
+
+# Options to strip for various project types. Note: -S strips debugging symbols
+#    (executables can be stripped down further with -x or, if they load no bundles, with no
+#     options at all).
+#APP_STRIP_OPTS = -S
+#TOOL_STRIP_OPTS = -S
+#LIBRARY_STRIP_OPTS = -S   # for .a archives
+#DYNAMIC_STRIP_OPTS = -S   # for bundles and shared libraries
+
+#########################################################################
+# Put rules to extend the behavior of the standard Makefiles here.  "Official" 
+# user-defined rules are:
+#   * before_install
+#   * after_install
+#   * after_installhdrs
+# You should avoid redefining things like "install" or "app", as they are
+# owned by the top-level Makefile API and no context has been set up for where 
+# derived files should go.
+
+
+#install::
+#      @(if [ "$(CODE_GEN_STYLE)" != "STATIC" ]; then\
+#              $(MAKE) install "CODE_GEN_STYLE=STATIC"\
+#                      "DSTROOT=$(DSTROOT)"\
+#                      "OBJROOT=$(OBJROOT)"\
+#                      "SYMROOT=$(SYMROOT)"\
+#                      "RC_CFLAGS = $(RC_CFLAGS)"\
+#                      "RC_ARCHS = $(RC_ARCHS)" ;\
+#      fi )
+
+install-man-page:
+       mkdir -p "$(DSTROOT)/usr/share/man/man3"
+       install -c -m 644 bindresvport.3 "$(DSTROOT)/usr/share/man/man3"
+       install -c -m 644 getrpcent.3 "$(DSTROOT)/usr/share/man/man3"
+       install -c -m 644 getrpcport.3 "$(DSTROOT)/usr/share/man/man3"
+       install -c -m 644 rpc.3 "$(DSTROOT)/usr/share/man/man3"
+       install -c -m 644 xdr.3 "$(DSTROOT)/usr/share/man/man3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getrpcent.3" "$(DSTROOT)/usr/share/man/man3/getrpcbyname.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getrpcent.3" "$(DSTROOT)/usr/share/man/man3/getrpcbynumber.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getrpcent.3" "$(DSTROOT)/usr/share/man/man3/endrpcent.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/getrpcent.3" "$(DSTROOT)/usr/share/man/man3/setrpcent.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/auth_destroy.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/authnone_create.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/authunix_create.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/authunix_create_default.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/callrpc.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/clnt_broadcast.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/clnt_call.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/clnt_control.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/clnt_create.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/clnt_destroy.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/clnt_freeres.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/clnt_geterr.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/clnt_pcreateerror.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/clnt_perrno.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/clnt_perror.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/clnt_spcreateerror.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/clnt_sperrno.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/clnt_sperror.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/clntraw_create.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/clnttcp_create.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/clntudp_bufcreate.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/clntudp_create.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/get_myaddress.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/pmap_getmaps.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/pmap_getport.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/pmap_rmtcall.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/pmap_set.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/pmap_unset.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/regsterrpc.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/rpc_createerr.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svc_destroy.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svc_fds.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svc_fdset.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svc_getargs.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svc_getcaller.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svc_getreg.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svc_getregset.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svc_register.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svc_run.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svc_sendreply.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svc_unregister.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svcerr_auth.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svcerr_decode.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svcerr_noproc.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svcerr_noprog.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svcerr_progvers.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svcerr_systemerr.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svcerr_weakauth.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svcfd_create.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svcraw_create.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svctcp_create.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/svcudp_bufcreate.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/xdr_accepted_reply.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/xdr_authunix_parms.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/xdr_callhdr.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/xdr_callmsg.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/xdr_opaque_auth.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/xdr_pmap.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/xdr_pmaplist.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/xdr_rejected_reply.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/xdr_replymsg.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/xprt_register.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/rpc.3" "$(DSTROOT)/usr/share/man/man3/xprt_unregister.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_array.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_bool.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_bytes.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_char.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_destroy.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_double.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_enum.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_float.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_free.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_getpos.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_inline.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_int.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_long.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdrmem_create.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_opaque.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_pointer.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdrrec_create.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdrrec_endofrecord.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdrrec_eof.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdrrec_skiprecord.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_reference.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_setpos.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_short.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdrstdio_create.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_string.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_u_char.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_u_long.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_u_short.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_union.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_vector.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_void.3"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man3/xdr.3" "$(DSTROOT)/usr/share/man/man3/xdr_wrapstring.3"
+
index 83c6f72c29db17591e46666cf5c344667e92d517..e827b3c9336c87026e7c38fb14ed2b5c95dfb235 100644 (file)
@@ -1,4 +1,5 @@
 OTHER_CFLAGS = \
+       -D__DARWIN_NON_CANCELABLE=1 \
        -Dsetrpcent=_old_setrpcent \
        -Dgetrpcent=_old_getrpcent \
        -Dendrpcent=_old_endrpcent \
@@ -10,3 +11,5 @@ PUBLIC_HEADER_DIR_SUFFIX = /rpc
 # for building 64-bit
 # <rdar://problem/3819761> Libinfo need to build with gcc-3.5 and 3-way fat
 NEXTSTEP_OBJCPLUS_COMPILER = $(CCOMPILER)
+
+AFTER_POSTINSTALL += install-man-page
index 4c3b5289cd3aef26bac6f951d52d687426960b54..1f9394efe08c92b97835b6489aece3dc18fa5586 100644 (file)
@@ -91,7 +91,12 @@ enum auth_stat {
        AUTH_FAILED=7                   /* some unknown reason */
 };
 
-typedef unsigned long u_int32; /* 32-bit unsigned integers */
+/* 32-bit unsigned integers */
+#ifdef __LP64__
+typedef unsigned int u_int32;
+#else
+typedef unsigned long u_int32;
+#endif
 
 union des_block {
        struct {
index f2902c1f7757a6a801263a4b817ccf0cfd576e33..9bfe58060cf5771abcb81c1ff778012750867056 100644 (file)
@@ -220,7 +220,7 @@ authunix_create_default()
        char machname[MAX_MACHINE_NAME + 1];
        register int uid;
        register int gid;
-       int gids[NGROUPS];
+       gid_t gids[NGROUPS];
 
        if (gethostname(machname, MAX_MACHINE_NAME) == -1)
                abort();
@@ -232,7 +232,7 @@ authunix_create_default()
         if (len > maxgrplist) {
             len = maxgrplist;
         }
-       return (authunix_create(machname, uid, gid, len, gids));
+       return (authunix_create(machname, uid, gid, len, (int *)gids));
 }
 
 /*
index 88705448e1b6eed4e9cf06464ba22c1db1cad59a..496defb79a9f22c6e3a79aba6a6e3c7e23e9b0bc 100644 (file)
  * Unix style credentials.
  */
 struct authunix_parms {
+#ifdef __LP64__
+       unsigned int     aup_time;
+#else
        unsigned long    aup_time;
+#endif
        char    *aup_machname;
        int      aup_uid;
        int      aup_gid;
index 38864f24661b36aefbca1e661f046b50eed88369..52ca1a8a1dad54757940956a7bdfbe7bfeeb5da7 100644 (file)
@@ -86,7 +86,7 @@ xdr_authunix_parms(xdrs, p)
            && 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) ) {
+                   &(p->aup_len), NGROUPS, sizeof(int), (xdrproc_t)xdr_int) ) {
                return (TRUE);
        }
        return (FALSE);
diff --git a/rpc.subproj/bindresvport.3 b/rpc.subproj/bindresvport.3
new file mode 100644 (file)
index 0000000..0ec6ffb
--- /dev/null
@@ -0,0 +1,27 @@
+.\"    from: @(#)bindresvport.3n       2.2 88/08/02 4.0 RPCSRC; from 1.7 88/03/14 SMI
+.\"    $Id: bindresvport.3,v 1.1 1999/04/13 23:15:36 wsanchez Exp $
+.\"
+.Dd November 22, 1987
+.Dt BINDRESVPORT 3
+.Os
+.Sh NAME
+.Nm bindresvport
+.Nd bind a socket to a privileged IP port
+.Sh SYNOPSIS
+.Fd #include <sys/types.h>
+.Fd include <netinet/in.h>
+.Ft int
+.Fn bindresvport "int sd" "struct sockaddr_in **sin"
+.Sh DESCRIPTION
+.Fn bindresvport
+is used to bind a socket descriptor to a privileged
+.Tn IP
+port, that is, a
+port number in the range 0-1023.
+The routine returns 0 if it is successful,
+otherwise -1 is returned and
+.Va errno
+set to reflect the cause of the error.
+.Pp
+Only root can bind to a privileged port; this call will fail for any
+other users.
index 2e47ff0b7a412a04dfa6f4217c9d5a4f33aea9c1..29d82d4623044f008551279c36f1284e39a10504 100644 (file)
@@ -84,7 +84,7 @@ bindresvport_sa(sd, sa)
        struct sockaddr_in6 *sin6;
        int proto, portrange, portlow;
        u_int16_t port;
-       int salen;
+       u_int32_t salen;
 
        if (sa == NULL) {
                salen = sizeof(myaddr);
@@ -120,7 +120,7 @@ bindresvport_sa(sd, sa)
        sa->sa_len = salen;
 
        if (port == 0) {
-               int oldlen = sizeof(old);
+               u_int32_t oldlen = sizeof(old);
 
                error = getsockopt(sd, proto, portrange, &old, &oldlen);
                if (error < 0)
index 4aeca14a9f3eb8d72bf5258a8b8f94bf8abf4e59..4ed9b51bf3361953565035d5547f8e061a4364a7 100644 (file)
@@ -123,12 +123,22 @@ struct rpc_err {
                int RE_errno;           /* realated system error */
                enum auth_stat RE_why;  /* why the auth error occurred */
                struct {
+#ifdef __LP64__
+                       unsigned int low;       /* lowest verion supported */
+                       unsigned int high;      /* highest verion supported */
+#else
                        unsigned long low;      /* lowest verion supported */
                        unsigned long high;     /* highest verion supported */
+#endif
                } RE_vers;
                struct {                /* maybe meaningful if RPC_FAILED */
+#ifdef __LP64__
+                       int s1;
+                       int s2;
+#else
                        long s1;
                        long s2;
+#endif
                } RE_lb;                /* life boot & debugging only */
        } ru;
 #define        re_errno        ru.RE_errno
@@ -148,7 +158,11 @@ struct CLIENT
 {
        AUTH    *cl_auth;       /* authenticator */
        struct clnt_ops {
+#ifdef __LP64__
+               enum clnt_stat (*cl_call)(CLIENT *, unsigned int, xdrproc_t, void *, xdrproc_t, void *, struct timeval);        /* call remote procedure */
+#else
                enum clnt_stat (*cl_call)(CLIENT *, unsigned long, xdrproc_t, void *, xdrproc_t, void *, struct timeval);       /* call remote procedure */
+#endif
                void (*cl_abort)(void);         /* abort a call */
                void (*cl_geterr)(CLIENT *, struct rpc_err *);  /* get specific error code */
                bool_t (*cl_freeres)(CLIENT *, xdrproc_t, void *);      /* frees results */
@@ -169,7 +183,7 @@ struct CLIENT
  * enum clnt_stat
  * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout)
  *     CLIENT *rh;
- *     unsigned long proc;
+ *     u_long proc;
  *     xdrproc_t xargs;
  *     caddr_t argsp;
  *     xdrproc_t xres;
@@ -245,16 +259,27 @@ struct CLIENT
  * and network administration.
  */
 
+#ifdef __LP64__
+#define RPCTEST_PROGRAM                ((unsigned int)1)
+#define RPCTEST_VERSION                ((unsigned int)1)
+#define RPCTEST_NULL_PROC      ((unsigned int)2)
+#define RPCTEST_NULL_BATCH_PROC        ((unsigned int)3)
+#else
 #define RPCTEST_PROGRAM                ((unsigned long)1)
 #define RPCTEST_VERSION                ((unsigned long)1)
 #define RPCTEST_NULL_PROC      ((unsigned long)2)
 #define RPCTEST_NULL_BATCH_PROC        ((unsigned long)3)
+#endif
 
 /*
  * By convention, procedure 0 takes null arguments and returns them
  */
 
+#ifdef __LP64__
+#define NULLPROC ((unsigned int)0)
+#else
 #define NULLPROC ((unsigned long)0)
+#endif
 
 /*
  * Below are the client handle creation routines for the various
@@ -266,11 +291,15 @@ struct CLIENT
  * Memory based rpc (for speed check and testing)
  * CLIENT *
  * clntraw_create(prog, vers)
- *     unsigned long prog;
- *     unsigned long vers;
+ *     u_long prog;
+ *     u_long vers;
  */
 __BEGIN_DECLS
+#ifdef __LP64__
+extern CLIENT *clntraw_create  __P((unsigned int, unsigned int));
+#else
 extern CLIENT *clntraw_create  __P((unsigned long, unsigned long));
+#endif
 __END_DECLS
 
 
@@ -279,12 +308,16 @@ __END_DECLS
  * CLIENT *
  * clnt_create(host, prog, vers, prot);
  *     char *host;     -- hostname
- *     unsigned long prog;     -- program number
- *     unsigned long vers;     -- version number
+ *     u_long prog;    -- program number
+ *     u_long vers;    -- version number
  *     char *prot;     -- protocol
  */
 __BEGIN_DECLS
+#ifdef __LP64__
+extern CLIENT *clnt_create     __P((char *, unsigned int, unsigned int, char *));
+#else
 extern CLIENT *clnt_create     __P((char *, unsigned long, unsigned long, char *));
+#endif
 __END_DECLS
 
 
@@ -293,19 +326,28 @@ __END_DECLS
  * CLIENT *
  * clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
  *     struct sockaddr_in *raddr;
- *     unsigned long prog;
- *     unsigned long version;
+ *     u_long prog;
+ *     u_long version;
  *     register int *sockp;
  *     unsigned int sendsz;
  *     unsigned int recvsz;
  */
 __BEGIN_DECLS
+#ifdef __LP64__
+extern CLIENT *clnttcp_create  __P((struct sockaddr_in *,
+                                                                        unsigned int,
+                                                                        unsigned int,
+                                                                        int *,
+                                                                        unsigned int,
+                                                                        unsigned int));
+#else
 extern CLIENT *clnttcp_create  __P((struct sockaddr_in *,
-                                    unsigned long,
-                                    unsigned long,
-                                    int *,
-                                    unsigned int,
-                                    unsigned int));
+                                                                        unsigned long,
+                                                                        unsigned long,
+                                                                        int *,
+                                                                        unsigned int,
+                                                                        unsigned int));
+#endif
 __END_DECLS
 
 
@@ -314,8 +356,8 @@ __END_DECLS
  * CLIENT *
  * clntudp_create(raddr, program, version, wait, sockp)
  *     struct sockaddr_in *raddr;
- *     unsigned long program;
- *     unsigned long version;
+ *     u_long program;
+ *     u_long version;
  *     struct timeval wait;
  *     int *sockp;
  *
@@ -323,26 +365,41 @@ __END_DECLS
  * CLIENT *
  * clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
  *     struct sockaddr_in *raddr;
- *     unsigned long program;
- *     unsigned long version;
+ *     u_long program;
+ *     u_long version;
  *     struct timeval wait;
  *     int *sockp;
  *     unsigned int sendsz;
  *     unsigned int recvsz;
  */
 __BEGIN_DECLS
+#ifdef __LP64__
 extern CLIENT *clntudp_create  __P((struct sockaddr_in *,
-                                    unsigned long,
-                                    unsigned long,
-                                    struct timeval,
-                                    int *));
+                                                                        unsigned int,
+                                                                        unsigned int,
+                                                                        struct timeval,
+                                                                        int *));
 extern CLIENT *clntudp_bufcreate __P((struct sockaddr_in *,
-                                    unsigned long,
-                                    unsigned long,
-                                    struct timeval,
-                                    int *,
-                                    unsigned int,
-                                    unsigned int));
+                                                                         unsigned int,
+                                                                         unsigned int,
+                                                                         struct timeval,
+                                                                         int *,
+                                                                         unsigned int,
+                                                                         unsigned int));
+#else
+extern CLIENT *clntudp_create  __P((struct sockaddr_in *,
+                                                                        unsigned long,
+                                                                        unsigned long,
+                                                                        struct timeval,
+                                                                        int *));
+extern CLIENT *clntudp_bufcreate __P((struct sockaddr_in *,
+                                                                         unsigned long,
+                                                                         unsigned long,
+                                                                         struct timeval,
+                                                                         int *,
+                                                                         unsigned int,
+                                                                         unsigned int));
+#endif
 __END_DECLS
 
 
index 3901b6037301116592f85ca533736537aa5d4c6a..231dd670c768bc9e465f33950bc0dc1275e68cd6 100644 (file)
@@ -72,10 +72,17 @@ static char *rcsid = "$Id: clnt_generic.c,v 1.3 2002/02/19 20:36:22 epeyton Exp
  */
 CLIENT *
 clnt_create(hostname, prog, vers, proto)
+#ifdef __LP64__
+       char *hostname;
+       uint32_t prog;
+       uint32_t vers;
+       char *proto;
+#else
        char *hostname;
        u_long prog;
        u_long vers;
        char *proto;
+#endif
 {
        struct hostent *h;
        struct protoent *p;
index 84db7359dc3dc686ad14d03c51cc08c3479f42da..a48c79a73a6d8a7ca6f16c600707d4d7edf0d3b9 100644 (file)
@@ -131,9 +131,11 @@ clnt_sperror(rpch, s)
                break;
 
        case RPC_VERSMISMATCH:
-               (void) sprintf(str,
-                       "; low version = %lu, high version = %lu", 
-                       e.re_vers.low, e.re_vers.high);
+#ifdef __LP64__
+               (void) sprintf(str, "; low version = %u, high version = %u", e.re_vers.low, e.re_vers.high);
+#else
+               (void) sprintf(str, "; low version = %lu, high version = %lu", e.re_vers.low, e.re_vers.high);
+#endif
                str += strlen(str);
                break;
 
@@ -152,16 +154,20 @@ clnt_sperror(rpch, s)
                break;
 
        case RPC_PROGVERSMISMATCH:
-               (void) sprintf(str, 
-                       "; low version = %lu, high version = %lu", 
-                       e.re_vers.low, e.re_vers.high);
+#ifdef __LP64__
+               (void) sprintf(str, "; low version = %u, high version = %u",  e.re_vers.low, e.re_vers.high);
+#else
+               (void) sprintf(str, "; low version = %lu, high version = %lu",  e.re_vers.low, e.re_vers.high);
+#endif
                str += strlen(str);
                break;
 
        default:        /* unknown */
-               (void) sprintf(str, 
-                       "; s1 = %lu, s2 = %lu", 
-                       e.re_lb.s1, e.re_lb.s2);
+#ifdef __LP64__
+               (void) sprintf(str, "; s1 = %u, s2 = %u", e.re_lb.s1, e.re_lb.s2);
+#else
+               (void) sprintf(str, "; s1 = %lu, s2 = %lu", e.re_lb.s1, e.re_lb.s2);
+#endif
                str += strlen(str);
                break;
        }
index 0fccf080cbc0431d6a052c0829fa264e7f75e04b..75a44aa4dd2595ae344d56763dc11d9094910b85 100644 (file)
@@ -109,13 +109,18 @@ void      svc_getreq();
  */
 CLIENT *
 clntraw_create(prog, vers)
+#ifdef __LP64__
+       uint32_t prog;
+       uint32_t vers;
+#else
        u_long prog;
        u_long vers;
+#endif
 {
        register struct clntraw_private *clp = clntraw_private;
        struct rpc_msg call_msg;
        XDR *xdrs = &clp->xdr_stream;
-       CLIENT  *client = &clp->client_object;
+       CLIENT *client = &clp->client_object;
 
        if (clp == 0) {
                clp = (struct clntraw_private *)calloc(1, sizeof (*clp));
@@ -153,7 +158,7 @@ clntraw_create(prog, vers)
 static enum clnt_stat 
 clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout)
        CLIENT *h;
-       u_long proc;
+       rpc_uint proc;
        xdrproc_t xargs;
        caddr_t argsp;
        xdrproc_t xresults;
@@ -175,12 +180,17 @@ call_again:
        xdrs->x_op = XDR_ENCODE;
        XDR_SETPOS(xdrs, 0);
        ((struct rpc_msg *)clp->mashl_callmsg)->rm_xid ++ ;
+#ifdef __LP64__
        if ((! XDR_PUTBYTES(xdrs, clp->mashl_callmsg, clp->mcnt)) ||
-           (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
+           (! XDR_PUTLONG(xdrs, (int *)&proc)) ||
            (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
-           (! (*xargs)(xdrs, argsp))) {
-               return (RPC_CANTENCODEARGS);
-       }
+           (! (*xargs)(xdrs, argsp))) return (RPC_CANTENCODEARGS);
+#else
+       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);
+#endif
        (void)XDR_GETPOS(xdrs);  /* called just to cause overhead */
 
        /*
index 71afd9d16fe09e0645a3f5fbf28e23cbf6f49043..106d4be4861f9d9d9b74d10dafe158ed081e59c3 100644 (file)
@@ -63,7 +63,7 @@ static char *rcsid = "$Id: clnt_tcp.c,v 1.4 2002/03/15 22:07:48 majka Exp $";
  *
  * 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
+ * returns 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).
  *
@@ -93,6 +93,8 @@ extern int errno;
 extern int     bindresvport();
 extern bool_t  xdr_opaque_auth();
 
+__private_extern__ u_short pmap_getport_timeout(struct sockaddr_in *address, uint32_t program, uint32_t version, uint32_t protocol, struct timeval *timeout, struct timeval *totaltimeout);
+
 static int     readtcp();
 static int     writetcp();
 
@@ -115,8 +117,8 @@ static struct clnt_ops tcp_ops = {
 struct ct_data {
        int             ct_sock;
        bool_t          ct_closeit;
-       struct timeval  ct_wait;
-       bool_t          ct_waitset;       /* wait set by clnt_control? */
+       struct timeval  ct_timeout;
+       bool_t          ct_timeout_set;       /* timeout set by clnt_control? */
        struct sockaddr_in ct_addr; 
        struct rpc_err  ct_error;
        char            ct_mcall[MCALL_MSG_SIZE];       /* marshalled callmsg */
@@ -139,30 +141,26 @@ struct ct_data {
  * 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;
+clnttcp_create_timeout(struct sockaddr_in *raddr, uint32_t prog, uint32_t vers, int *sockp, uint32_t sendsz, uint32_t recvsz, struct timeval *retry_timeout, struct timeval *total_timeout)
 {
        CLIENT *h;
        register struct ct_data *ct = NULL;
        struct timeval now;
        struct rpc_msg call_msg;
        int rfd;
+       u_short port;
 
-       h  = (CLIENT *)mem_alloc(sizeof(*h));
-       if (h == NULL) {
-               (void)fprintf(stderr, "clnttcp_create: out of memory\n");
+       h = (CLIENT *)mem_alloc(sizeof(*h));
+       if (h == NULL)
+       {
                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");
+       if (ct == NULL)
+       {
                rpc_createerr.cf_stat = RPC_SYSTEMERROR;
                rpc_createerr.cf_error.re_errno = errno;
                goto fooy;
@@ -171,32 +169,38 @@ clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
        /*
         * 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) {
+       if (raddr->sin_port == 0)
+       {
+               port = pmap_getport_timeout(raddr, prog, vers, IPPROTO_TCP, retry_timeout, total_timeout);
+               if (port == 0)
+               {
                        mem_free((caddr_t)ct, sizeof(struct ct_data));
                        mem_free((caddr_t)h, sizeof(CLIENT));
-                       return ((CLIENT *)NULL);
+                       return NULL;
                }
+
                raddr->sin_port = htons(port);
        }
 
        /*
         * If no socket given, open one
         */
-       if (*sockp < 0) {
+       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)) {
+               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);
+                       close(*sockp);
                        goto fooy;
                }
+
                ct->ct_closeit = TRUE;
-       } else {
+       }
+       else
+       {
                ct->ct_closeit = FALSE;
        }
 
@@ -204,8 +208,14 @@ clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
         * Set up private data struct
         */
        ct->ct_sock = *sockp;
-       ct->ct_wait.tv_usec = 0;
-       ct->ct_waitset = FALSE;
+       ct->ct_timeout.tv_sec = 60;
+       ct->ct_timeout.tv_usec = 0;
+       ct->ct_timeout_set = FALSE;
+       if (total_timeout != NULL)
+       {
+               ct->ct_timeout = *total_timeout;
+               ct->ct_timeout_set = TRUE;
+       }
        ct->ct_addr = *raddr;
 
        /*
@@ -217,6 +227,7 @@ clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
                gettimeofday(&now, (struct timezone *)0);
                call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec;
        }
+
        if (rfd > 0) close(rfd);
 
        call_msg.rm_direction = CALL;
@@ -227,14 +238,13 @@ clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
        /*
         * 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);
-               }
+       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) close(*sockp);
                goto fooy;
        }
+
        ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
        XDR_DESTROY(&(ct->ct_xdrs));
 
@@ -242,20 +252,37 @@ clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
         * 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);
+       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_private = (caddr_t)ct;
        h->cl_auth = authnone_create();
-       return (h);
+       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);
+       return NULL;
+}
+
+CLIENT *
+clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
+#ifdef __LP64__
+struct sockaddr_in *raddr;
+uint32_t prog;
+uint32_t vers;
+int *sockp;
+uint32_t sendsz;
+uint32_t recvsz;
+#else
+struct sockaddr_in *raddr;
+u_long prog;
+u_long vers;
+register int *sockp;
+u_int sendsz;
+u_int recvsz;
+#endif
+{
+       return clnttcp_create_timeout(raddr, (uint32_t)prog, (uint32_t)vers, sockp, (uint32_t)sendsz, (uint32_t)recvsz, NULL, NULL);
 }
 
 static enum clnt_stat
@@ -276,8 +303,8 @@ clnttcp_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout)
        register bool_t shipnow;
        int refreshes = 2;
 
-       if (!ct->ct_waitset) {
-               ct->ct_wait = timeout;
+       if (!ct->ct_timeout_set) {
+               ct->ct_timeout = timeout;
        }
 
        shipnow =
@@ -288,10 +315,18 @@ call_again:
        xdrs->x_op = XDR_ENCODE;
        ct->ct_error.re_status = RPC_SUCCESS;
        x_id = ntohl(--(*msg_x_id));
+#ifdef __LP64__
        if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) ||
-           (! XDR_PUTLONG(xdrs, (long *)&proc)) ||
+           (! XDR_PUTLONG(xdrs, (int *)&proc)) ||
            (! AUTH_MARSHALL(h->cl_auth, xdrs)) ||
-           (! (*xdr_args)(xdrs, args_ptr))) {
+           (! (*xdr_args)(xdrs, args_ptr)))
+#else
+       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)))
+#endif                 
+       {
                if (ct->ct_error.re_status == RPC_SUCCESS)
                        ct->ct_error.re_status = RPC_CANTENCODEARGS;
                (void)xdrrec_endofrecord(xdrs, TRUE);
@@ -316,7 +351,7 @@ call_again:
        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;
+               reply_msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
                if (! xdrrec_skiprecord(xdrs))
                        return (ct->ct_error.re_status);
                /* now decode and validate the response header */
@@ -394,11 +429,11 @@ clnttcp_control(cl, request, info)
 
        switch (request) {
        case CLSET_TIMEOUT:
-               ct->ct_wait = *(struct timeval *)info;
-               ct->ct_waitset = TRUE;
+               ct->ct_timeout = *(struct timeval *)info;
+               ct->ct_timeout_set = TRUE;
                break;
        case CLGET_TIMEOUT:
-               *(struct timeval *)info = ct->ct_wait;
+               *(struct timeval *)info = ct->ct_timeout;
                break;
        case CLGET_SERVER_ADDR:
                *(struct sockaddr_in *)info = ct->ct_addr;
@@ -445,8 +480,7 @@ readtcp(ct, buf, len)
        FD_SET(ct->ct_sock, &mask);
        while (TRUE) {
                readfds = mask;
-               switch (select(ct->ct_sock+1, &readfds, NULL, NULL,
-                              &(ct->ct_wait))) {
+               switch (select(ct->ct_sock+1, &readfds, NULL, NULL, &(ct->ct_timeout))) {
                case 0:
                        ct->ct_error.re_status = RPC_TIMEDOUT;
                        return (-1);
index 446603a9dfba002415dfd3f5c64aae9dccf5064f..53c618b4d77328b18ff79992c20292e47a2a33ae 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1999-2007 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -77,6 +77,8 @@ static char *rcsid = "$Id: clnt_udp.c,v 1.4 2002/03/15 22:07:49 majka Exp $";
 extern int     bindresvport();
 extern bool_t  xdr_opaque_auth();
 
+__private_extern__ u_short pmap_getport_timeout(struct sockaddr_in *address, uint32_t program, uint32_t version, uint32_t protocol, struct timeval *timeout, struct timeval *totaltimeout);
+
 extern int errno;
 
 /*
@@ -106,8 +108,8 @@ struct cu_data {
        bool_t             cu_closeit;
        struct sockaddr_in cu_raddr;
        int                cu_rlen;
-       struct timeval     cu_wait;
-       struct timeval     cu_total;
+       struct timeval     cu_retry_timeout;
+       struct timeval     cu_total_timeout;
        struct rpc_err     cu_error;
        XDR                cu_outxdrs;
        u_int              cu_xdrpos;
@@ -133,57 +135,60 @@ struct cu_data {
  * 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;
+__private_extern__ CLIENT *
+clntudp_bufcreate_timeout(struct sockaddr_in *raddr, uint32_t program, uint32_t version, int *sockp, uint32_t sendsz, uint32_t recvsz, struct timeval *retry_timeout, struct timeval *total_timeout)
 {
        CLIENT *cl;
-       register struct cu_data *cu = NULL;
+       struct cu_data *cu = NULL;
        struct timeval now;
        struct rpc_msg call_msg;
        int rfd;
+       u_short port;
+       socklen_t len;
+       unsigned int rsize;
 
        cl = (CLIENT *)mem_alloc(sizeof(CLIENT));
-       if (cl == NULL) {
-               (void) fprintf(stderr, "clntudp_create: out of memory\n");
+       if (cl == NULL)
+       {
                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");
+       if (cu == NULL)
+       {
                rpc_createerr.cf_stat = RPC_SYSTEMERROR;
                rpc_createerr.cf_error.re_errno = errno;
                goto fooy;
        }
+
        cu->cu_outbuf = &cu->cu_inbuf[recvsz];
 
-       if (raddr->sin_port == 0) {
-               u_short port;
-               if ((port =
-                   pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) {
-                       goto fooy;
-               }
+       if (raddr->sin_port == 0)
+       {
+               port = pmap_getport_timeout(raddr, program, version, IPPROTO_UDP, retry_timeout, total_timeout);
+               if (port == 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;
+
+       cu->cu_retry_timeout.tv_sec = 1;
+       cu->cu_retry_timeout.tv_usec = 0;
+       if (retry_timeout != NULL) cu->cu_retry_timeout = *retry_timeout;
+       
+       cu->cu_total_timeout.tv_sec = -1;
+       cu->cu_total_timeout.tv_usec = -1;
+       if (total_timeout != NULL) cu->cu_total_timeout = *retry_timeout;
        
        rfd = open("/dev/random", O_RDONLY, 0);
        if ((rfd < 0) || (read(rfd, &call_msg.rm_xid, sizeof(call_msg.rm_xid)) != sizeof(call_msg.rm_xid)))
@@ -191,57 +196,110 @@ clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
                gettimeofday(&now, (struct timezone *)0);
                call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec;
        }
+
        if (rfd > 0) close(rfd);
 
        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;
-       }
+       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) {
+       if (*sockp < 0)
+       {
                int dontblock = 1;
 
                *sockp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-               if (*sockp < 0) {
+               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 */
+
+               /* the socket's rpc controls are non-blocking */
                (void)ioctl(*sockp, FIONBIO, (char *) &dontblock);
                cu->cu_closeit = TRUE;
-       } else {
+
+               /* set receive size */
+               rsize = 0;
+               len = sizeof(rsize);
+               if (getsockopt(*sockp, SOL_SOCKET, SO_RCVBUF, (char *)&rsize, &len) != 0)
+               {
+                       close(*sockp);
+                       *sockp = -1;
+                       goto fooy;
+               }
+
+               len = sizeof(recvsz);
+               if ((recvsz > rsize) && (setsockopt(*sockp, SOL_SOCKET, SO_RCVBUF, (char *)&recvsz, len)))
+               {
+                       close(*sockp);
+                       *sockp = -1;
+                       goto fooy;
+               }
+       }
+       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);
+       if (cu) mem_free((caddr_t)cu, sizeof(*cu) + sendsz + recvsz);
+       if (cl) mem_free((caddr_t)cl, sizeof(CLIENT));
+       return NULL;
+}
+
+CLIENT *
+clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz)
+#ifdef __LP64__
+struct sockaddr_in *raddr;
+uint32_t program;
+uint32_t version;
+struct timeval wait;
+int *sockp;
+uint32_t sendsz;
+uint32_t recvsz;
+#else
+struct sockaddr_in *raddr;
+u_long program;
+u_long version;
+struct timeval wait;
+register int *sockp;
+u_int sendsz;
+u_int recvsz;
+#endif
+{
+       return clntudp_bufcreate_timeout(raddr, (uint32_t)program, (uint32_t)version, sockp, (uint32_t)sendsz, (uint32_t)recvsz, &wait, NULL);
 }
 
 CLIENT *
 clntudp_create(raddr, program, version, wait, sockp)
+#ifdef __LP64__
+       struct sockaddr_in *raddr;
+       uint32_t program;
+       uint32_t version;
+       struct timeval wait;
+       int *sockp;
+#else
        struct sockaddr_in *raddr;
        u_long program;
        u_long version;
        struct timeval wait;
        register int *sockp;
+#endif
 {
 
-       return(clntudp_bufcreate(raddr, program, version, wait, sockp,
-           UDPMSGSIZE, UDPMSGSIZE));
+       return clntudp_bufcreate(raddr, program, version, wait, sockp, UDPMSGSIZE, UDPMSGSIZE);
 }
 
 static enum clnt_stat 
@@ -258,7 +316,7 @@ clntudp_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
        register XDR *xdrs;
        register int outlen;
        register int inlen;
-       int fromlen;
+       u_int32_t fromlen;
        fd_set readfds;
        fd_set mask;
        struct sockaddr_in from;
@@ -269,32 +327,45 @@ clntudp_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout)
        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 */
+       if (cu->cu_total_timeout.tv_sec == -1)
+       {
+               /* use supplied total timeout */
+               timeout = utimeout;
+       }
+       else
+       {
+               /* use client's total timeout */
+               timeout = cu->cu_total_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))++;
+#ifdef __LP64__
+       if ((! XDR_PUTLONG(xdrs, (int *)&proc)) ||
+           (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
+           (! (*xargs)(xdrs, argsp)))
+               return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
+#else
        if ((! XDR_PUTLONG(xdrs, (long *)&proc)) ||
            (! AUTH_MARSHALL(cl->cl_auth, xdrs)) ||
            (! (*xargs)(xdrs, argsp)))
                return (cu->cu_error.re_status = RPC_CANTENCODEARGS);
+#endif
        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) {
+       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);
        }
@@ -302,9 +373,11 @@ send_again:
        /*
         * Hack to provide rpc-based message passing
         */
-       if (timeout.tv_sec == 0 && timeout.tv_usec == 0) {
+       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.
@@ -315,14 +388,13 @@ send_again:
        reply_msg.acpted_rply.ar_results.proc = xresults;
        FD_ZERO(&mask);
        FD_SET(cu->cu_sock, &mask);
-       for (;;) {
+       for (;;)
+       {
                readfds = mask;
-               switch (select(cu->cu_sock+1, &readfds, NULL, 
-                              NULL, &(cu->cu_wait))) {
-
+               switch (select(cu->cu_sock+1, &readfds, NULL, NULL, &(cu->cu_retry_timeout))) {
                case 0:
-                       time_waited.tv_sec += cu->cu_wait.tv_sec;
-                       time_waited.tv_usec += cu->cu_wait.tv_usec;
+                       time_waited.tv_sec += cu->cu_retry_timeout.tv_sec;
+                       time_waited.tv_usec += cu->cu_retry_timeout.tv_usec;
                        while (time_waited.tv_usec >= 1000000) {
                                time_waited.tv_sec++;
                                time_waited.tv_usec -= 1000000;
@@ -438,16 +510,16 @@ clntudp_control(cl, request, info)
 
        switch (request) {
        case CLSET_TIMEOUT:
-               cu->cu_total = *(struct timeval *)info;
+               cu->cu_total_timeout = *(struct timeval *)info;
                break;
        case CLGET_TIMEOUT:
-               *(struct timeval *)info = cu->cu_total;
+               *(struct timeval *)info = cu->cu_total_timeout;
                break;
        case CLSET_RETRY_TIMEOUT:
-               cu->cu_wait = *(struct timeval *)info;
+               cu->cu_retry_timeout = *(struct timeval *)info;
                break;
        case CLGET_RETRY_TIMEOUT:
-               *(struct timeval *)info = cu->cu_wait;
+               *(struct timeval *)info = cu->cu_retry_timeout;
                break;
        case CLGET_SERVER_ADDR:
                *(struct sockaddr_in *)info = cu->cu_raddr;
diff --git a/rpc.subproj/getrpcent.3 b/rpc.subproj/getrpcent.3
new file mode 100644 (file)
index 0000000..dc4826d
--- /dev/null
@@ -0,0 +1,93 @@
+.\"    from: @(#)getrpcent.3n  2.2 88/08/02 4.0 RPCSRC; from 1.11 88/03/14 SMI
+.\"    $Id: getrpcent.3,v 1.1 1999/04/13 23:15:37 wsanchez Exp $
+.\"
+.Dd December 14, 1987
+.Dt GETRPCENT 3
+.Os
+.Sh NAME
+.Nm getrpcent ,
+.Nm getrpcbyname ,
+.Nm getrpcbynumber ,
+.Nm endrpcent ,
+.Nm setrpcent
+.Nd get RPC entry
+.Sh SYNOPSIS
+.Fd #include <netdb.h>
+.Ft struct rpcent *
+.Fn getrpcent void
+.Ft struct rpcent *
+.Fn getrpcbyname "char *name"
+.Ft struct rpcent *
+.Fn getrpcbynumber "int number"
+.Ft void
+.Fn setrpcent "int stayopen"
+.Ft void 
+.Fn endrpcent void
+.Sh DESCRIPTION
+.Fn getrpcent ,
+.Fn getrpcbyname ,
+and
+.Fn getrpcbynumber ,
+each return a pointer to an object with the
+following structure
+containing the broken-out
+fields of a line in the rpc program number data base,
+.Pa /etc/rpc :
+.Bd -literal -offset indent
+struct rpcent {
+       char    *r_name;        /* name of server for this rpc program */
+       char    **r_aliases;    /* alias list */
+       long    r_number;       /* rpc program number */
+};
+.Ed
+.Pp
+The members of this structure are:
+.Bl -tag -width r_aliases -offset indent
+.It r_name
+The name of the server for this rpc program.
+.It r_aliases
+A zero terminated list of alternate names for the rpc program.
+.It r_number
+The rpc program number for this service.
+.El
+.Pp
+.Fn getrpcent
+reads the next line of the file, opening the file if necessary.
+.Pp
+.Fn setrpcent
+opens and rewinds the file.  If the
+.Fa stayopen
+flag is non-zero,
+the net data base will not be closed after each call to
+.Fn getrpcent 
+(either directly, or indirectly through one of
+the other 
+.Dq getrpc
+calls).
+.Pp
+.Fn endrpcent
+closes the file.
+.Pp
+.Fn getrpcbyname
+and
+.Fn getrpcbynumber
+sequentially search from the beginning
+of the file until a matching rpc program name or
+program number is found, or until end-of-file is encountered.
+.Sh FILES
+.Pa /etc/rpc
+.Sh SEE ALSO
+.Xr rpc 5 ,
+.Xr rpcinfo 8 ,
+.Xr ypserv 8
+.Sh DIAGNOSTICS
+A
+.Dv NULL
+pointer is returned on 
+.Dv EOF
+or error.
+.Sh BUGS
+All information
+is contained in a static area
+so it must be copied if it is
+to be saved.
index 74fc04386f494bb4273de2c22c5222ceb821a3d5..6e53c28a07eca0a69cadc7c04839d6f122d96533 100644 (file)
@@ -98,17 +98,30 @@ _rpcdata()
 
 struct rpcent *
 getrpcbynumber(number)
+#ifdef __LP64__
+       int32_t number;
+#else
        register long number;
+#endif
 {
        register struct rpcdata *d = _rpcdata();
        register struct rpcent *p;
+#ifdef __LP64__
+       int x;
+       
+       x = number;
+#endif
 
        if (d == 0)
                return (0);
        setrpcent(0);
-       while ((p = getrpcent())) {
-               if (p->r_number == number)
-                       break;
+       while ((p = getrpcent()))
+       {
+#ifdef __LP64__
+               if (p->r_number == x) break;
+#else
+               if (p->r_number == number) break;
+#endif
        }
        endrpcent();
        return (p);
diff --git a/rpc.subproj/getrpcport.3 b/rpc.subproj/getrpcport.3
new file mode 100644 (file)
index 0000000..16ab68c
--- /dev/null
@@ -0,0 +1,32 @@
+.\"    from: @(#)getrpcport.3r 2.2 88/08/02 4.0 RPCSRC; from 1.12 88/02/26 SMI
+.\"    $Id: getrpcport.3,v 1.1 1999/04/13 23:15:37 wsanchez Exp $
+.\"
+.Dd October 6, 1987
+.Dt GETRPCPORT 3
+.Os
+.Sh NAME
+.Nm getrpcport
+.Nd get RPC port number
+.Sh SYNOPSIS
+.Fd #include <rpc/rpc.h>
+.Ft int
+.Fn getrpcport "char *host" "int prognum" "int versnum" "int proto"
+.Sh DESCRIPTION
+.Fn getrpcport
+returns the port number for version
+.Fa versnum
+of the RPC program
+.Fa prognum
+running on
+.Fa host
+and using protocol
+.Fa proto .
+It returns 0 if it cannot contact the portmapper, or if
+.Fa prognum
+is not registered.  If
+.Fa prognum
+is registered but not with version
+.Fa versnum ,
+it will still return a port number (for some version of the program)
+indicating that the program is indeed registered.
+The version mismatch will be detected upon the first call to the service.
index 0a8923256bf4945bd488bfebba342cf0d39829fd..9cb337b37a8f84b82fd9fcd37f29780dd626aa2c 100644 (file)
@@ -76,11 +76,15 @@ static char *rcsid = "$Id: pmap_clnt.c,v 1.5 2004/12/19 22:45:44 zarzycki Exp $"
 
 #include "pmap_wakeup.h"
 
-static struct timeval timeout = { 5, 0 };
-static struct timeval tottimeout = { 60, 0 };
+__private_extern__ CLIENT *clntudp_bufcreate_timeout(struct sockaddr_in *raddr, uint32_t program, uint32_t version, int *sockp, uint32_t sendsz, uint32_t recvsz, struct timeval *timeout, struct timeval *totaltimeout);
 
-void clnt_perror();
+static struct timeval set_retry_timeout = { 5, 0 };
+static struct timeval set_total_timeout = { 60, 0 };
+
+static struct timeval unset_retry_timeout = { 1, 0 };
+static struct timeval unset_total_timeout = { 5, 0 };
 
+void clnt_perror();
 
 /*
  * Set a mapping between program,version and port.
@@ -88,10 +92,17 @@ void clnt_perror();
  */
 bool_t
 pmap_set(program, version, protocol, port)
+#ifdef __LP64__
+       uint32_t program;
+       uint32_t version;
+       int32_t protocol;
+       uint16_t port;
+#else
        u_long program;
        u_long version;
        int protocol;
        u_short port;
+#endif
 {
        struct sockaddr_in myaddress;
        int socket = -1;
@@ -99,28 +110,24 @@ pmap_set(program, version, protocol, port)
        struct pmap parms;
        bool_t rslt;
 
-       pmap_wakeup();
+       if (pmap_wakeup() != 0) return FALSE;
 
        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);
+       client = clntudp_bufcreate_timeout(&myaddress, PMAPPROG, PMAPVERS, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE, &set_retry_timeout, &set_total_timeout);
+       if (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);
-       }
+       if (CLNT_CALL(client, PMAPPROC_SET, (xdrproc_t)xdr_pmap, &parms, (xdrproc_t)xdr_bool, &rslt, set_total_timeout) != RPC_SUCCESS) return FALSE;
+
        CLNT_DESTROY(client);
-       (void)close(socket);
-       return (rslt);
+       close(socket);
+       return rslt;
 }
 
 /*
@@ -129,8 +136,13 @@ pmap_set(program, version, protocol, port)
  */
 bool_t
 pmap_unset(program, version)
+#ifdef __LP64__
+       uint32_t program;
+       uint32_t version;
+#else
        u_long program;
        u_long version;
+#endif
 {
        struct sockaddr_in myaddress;
        int socket = -1;
@@ -138,22 +150,23 @@ pmap_unset(program, version)
        struct pmap parms;
        bool_t rslt;
 
-       pmap_wakeup();
+       if (pmap_wakeup() != 0) return FALSE;
 
        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);
+       client = clntudp_bufcreate_timeout(&myaddress, PMAPPROG, PMAPVERS, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE, &unset_retry_timeout, &unset_total_timeout);
+       if (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);
+       parms.pm_port = 0;
+       parms.pm_prot = 0;
+
+       CLNT_CALL(client, PMAPPROC_UNSET, (xdrproc_t)xdr_pmap, &parms, (xdrproc_t)xdr_bool, &rslt, unset_total_timeout);
+
        CLNT_DESTROY(client);
-       (void)close(socket);
-       return (rslt);
+       close(socket);
+       return rslt;
 }
index f89b81e4653ec42202eb9d264e1b09cab81c4c03..c07a81902bd3f6eacdd30800d4a0c24bbd4ed68b 100644 (file)
 #include <sys/cdefs.h>
 
 __BEGIN_DECLS
+#ifdef __LP64__
+extern bool_t          pmap_set        __P((unsigned int, unsigned int, int, int));
+extern bool_t          pmap_unset      __P((unsigned int, unsigned int));
+extern enum clnt_stat  pmap_rmtcall    __P((struct sockaddr_in *,
+                                                                                        unsigned int, unsigned int, unsigned int,
+                                                                                        xdrproc_t, caddr_t,
+                                                                                        xdrproc_t, caddr_t,
+                                                                                        struct timeval, unsigned int *));
+extern enum clnt_stat  clnt_broadcast  __P((unsigned int, unsigned int, unsigned int,
+                                                                                        xdrproc_t, char *,
+                                                                                        xdrproc_t, char *,
+                                                                                        bool_t (*)()));
+extern unsigned short          pmap_getport    __P((struct sockaddr_in *,
+                                                                                                unsigned int, unsigned int, unsigned int));
+#else
 extern bool_t          pmap_set        __P((unsigned long, unsigned long, int, int));
 extern bool_t          pmap_unset      __P((unsigned long, unsigned long));
-extern struct pmaplist *pmap_getmaps   __P((struct sockaddr_in *));
 extern enum clnt_stat  pmap_rmtcall    __P((struct sockaddr_in *,
-                                            unsigned long, unsigned long, unsigned long,
-                                            xdrproc_t, caddr_t,
-                                            xdrproc_t, caddr_t,
-                                            struct timeval, unsigned long *));
+                                                                                        unsigned long, unsigned long, unsigned long,
+                                                                                        xdrproc_t, caddr_t,
+                                                                                        xdrproc_t, caddr_t,
+                                                                                        struct timeval, unsigned long *));
 extern enum clnt_stat  clnt_broadcast  __P((unsigned long, unsigned long, unsigned long,
-                                            xdrproc_t, char *,
-                                            xdrproc_t, char *,
-                                            bool_t (*)()));
+                                                                                        xdrproc_t, char *,
+                                                                                        xdrproc_t, char *,
+                                                                                        bool_t (*)()));
 extern unsigned short          pmap_getport    __P((struct sockaddr_in *,
-                                            unsigned long, unsigned long, unsigned int));
+                                                                                                unsigned long, unsigned long, unsigned int));
+#endif
+extern struct pmaplist *pmap_getmaps   __P((struct sockaddr_in *));
+extern int             getrpcport      __P((char *, int, int, int));
 __END_DECLS
 
 #endif /* !_RPC_PMAPCLNT_H */
index 98eeedd460eca9a918a84d6a138917e29bb2a40b..b359b9c0b1b6d723d8333f22b9c2b84beed57fc4 100644 (file)
@@ -77,8 +77,6 @@ static char *rcsid = "$Id: pmap_getmaps.c,v 1.4 2004/12/19 22:45:44 zarzycki Exp
 #define NAMELEN 255
 #define MAX_BROADCAST_SIZE 1400
 
-#include "pmap_wakeup.h"
-
 extern int errno;
 
 /*
@@ -94,16 +92,13 @@ pmap_getmaps(address)
        struct timeval minutetimeout;
        register CLIENT *client;
 
-       pmap_wakeup();
-
        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) {
+               if (CLNT_CALL(client, PMAPPROC_DUMP, (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_pmaplist, &head, minutetimeout) != RPC_SUCCESS) {
                        clnt_perror(client, "pmap_getmaps rpc problem");
                }
                CLNT_DESTROY(client);
index 2c33f722be37ee7522f5cdb1f54d6fe8948010d8..2a0949226f5211e051a082b3d04a05262f8525cd 100644 (file)
@@ -70,48 +70,75 @@ static char *rcsid = "$Id: pmap_getport.c,v 1.4 2004/12/19 22:45:44 zarzycki Exp
 #include <sys/socket.h>
 #include <net/if.h>
 
-#include "pmap_wakeup.h"
-
-static struct timeval timeout = { 5, 0 };
-static struct timeval tottimeout = { 60, 0 };
+static struct timeval default_timeout = { 5, 0 };
+static struct timeval default_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;
+__private_extern__ u_short
+pmap_getport_timeout(struct sockaddr_in *address, uint32_t program, uint32_t version, uint32_t protocol, struct timeval *timeout, struct timeval *totaltimeout)
 {
-       u_short port = 0;
-       int socket = -1;
+       u_short port;
+       int socket;
        register CLIENT *client;
        struct pmap parms;
+       enum clnt_stat status;
+       struct timeval real_t, real_tt;
+
+       real_t = default_timeout;
+       if (timeout != NULL) real_t = *timeout;
 
-       pmap_wakeup();
+       real_tt = default_timeout;
+       if (totaltimeout != NULL) real_tt = *totaltimeout;
 
+       port = 0;
+       socket = -1;
        address->sin_port = htons(PMAPPORT);
-       client = clntudp_bufcreate(address, PMAPPROG,
-           PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
-       if (client != (CLIENT *)NULL) {
+       client = clntudp_bufcreate(address, PMAPPROG, PMAPVERS, real_t, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+       if (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){
+               /* not needed or used */
+               parms.pm_port = 0;
+
+               status = CLNT_CALL(client, PMAPPROC_GETPORT, (xdrproc_t)xdr_pmap, &parms, (xdrproc_t)xdr_u_short, &port, real_tt);
+               if (status != RPC_SUCCESS)
+               {
                        rpc_createerr.cf_stat = RPC_PMAPFAILURE;
                        clnt_geterr(client, &rpc_createerr.cf_error);
-               } else if (port == 0) {
+               }
+               else if (port == 0)
+               {
                        rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
                }
+
                CLNT_DESTROY(client);
        }
-       (void)close(socket);
+
+       close(socket);
        address->sin_port = 0;
-       return (port);
+       return port;
 }
+
+u_short
+pmap_getport(address, program, version, protocol)
+#ifdef __LP64__
+struct sockaddr_in *address;
+uint32_t program;
+uint32_t version;
+uint32_t protocol;
+#else
+struct sockaddr_in *address;
+u_long program;
+u_long version;
+u_int protocol;
+#endif
+{
+       return pmap_getport_timeout(address, (uint32_t)program, (uint32_t)version, (uint32_t)protocol, NULL, NULL);
+}
+
index a51ce234d552211d9ad31497e0edf4a6d4b74910..c5dc139e41487333466c11e62195663c1f6e0d15 100644 (file)
 #include <sys/cdefs.h>
 
 #define PMAPPORT               ((unsigned short)111)
+#ifdef __LP64__
+#define PMAPPROG               ((unsigned int)100000)
+#define PMAPVERS               ((unsigned int)2)
+#define PMAPVERS_PROTO         ((unsigned int)2)
+#define PMAPVERS_ORIG          ((unsigned int)1)
+#define PMAPPROC_NULL          ((unsigned int)0)
+#define PMAPPROC_SET           ((unsigned int)1)
+#define PMAPPROC_UNSET         ((unsigned int)2)
+#define PMAPPROC_GETPORT       ((unsigned int)3)
+#define PMAPPROC_DUMP          ((unsigned int)4)
+#define PMAPPROC_CALLIT                ((unsigned int)5)
+#else
 #define PMAPPROG               ((unsigned long)100000)
 #define PMAPVERS               ((unsigned long)2)
 #define PMAPVERS_PROTO         ((unsigned long)2)
 #define PMAPPROC_GETPORT       ((unsigned long)3)
 #define PMAPPROC_DUMP          ((unsigned long)4)
 #define PMAPPROC_CALLIT                ((unsigned long)5)
+#endif
 
 struct pmap {
+#ifdef __LP64__
+       unsigned int pm_prog;
+       unsigned int pm_vers;
+       unsigned int pm_prot;
+       unsigned int pm_port;
+#else
        long unsigned pm_prog;
        long unsigned pm_vers;
        long unsigned pm_prot;
        long unsigned pm_port;
+#endif
 };
 
 struct pmaplist {
index a5bd77d0a464bd9404afbecc5e72e6c660a821b9..6c286c7d6652f4ce8a229f90b668e0d16aa834f7 100644 (file)
@@ -133,8 +133,7 @@ xdr_pmaplist(xdrs, rp)
                 */
                if (freeing)
                        next = &((*rp)->pml_next); 
-               if (! xdr_reference(xdrs, (caddr_t *)rp,
-                   (u_int)sizeof(struct pmaplist), xdr_pmap))
+               if (! xdr_reference(xdrs, (caddr_t *)rp, (u_int)sizeof(struct pmaplist), (xdrproc_t)xdr_pmap))
                        return (FALSE);
                rp = (freeing) ? next : &((*rp)->pml_next);
        }
index a91b2a27e0f59c8e3577958052f95c9604e0335c..c9813ba92ddc613f144dc90d8c5bd996f94676df 100644 (file)
@@ -79,8 +79,6 @@ static char *rcsid = "$Id: pmap_rmt.c,v 1.6 2004/12/19 22:45:44 zarzycki Exp $";
 #include <arpa/inet.h>
 #define MAX_BROADCAST_SIZE 1400
 
-#include "pmap_wakeup.h"
-
 static struct timeval timeout = { 3, 0 };
 
 
@@ -93,12 +91,21 @@ static struct timeval timeout = { 3, 0 };
 */
 enum clnt_stat
 pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_ptr)
+#ifdef __LP64__
+       struct sockaddr_in *addr;
+       uint32_t prog, vers, proc;
+       xdrproc_t xdrargs, xdrres;
+       caddr_t argsp, resp;
+       struct timeval tout;
+       uint32_t *port_ptr;
+#else
        struct sockaddr_in *addr;
        u_long prog, vers, proc;
        xdrproc_t xdrargs, xdrres;
        caddr_t argsp, resp;
        struct timeval tout;
        u_long *port_ptr;
+#endif
 {
        int socket = -1;
        register CLIENT *client;
@@ -106,8 +113,6 @@ pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_pt
        struct rmtcallres r;
        enum clnt_stat stat;
 
-       pmap_wakeup();
-
        addr->sin_port = htons(PMAPPORT);
        client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &socket);
        if (client != (CLIENT *)NULL) {
@@ -119,8 +124,7 @@ pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_pt
                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);
+               stat = CLNT_CALL(client, PMAPPROC_CALLIT, (xdrproc_t)xdr_rmtcall_args, &a, (xdrproc_t)xdr_rmtcallres, &r, tout);
                CLNT_DESTROY(client);
        } else {
                stat = RPC_FAILED;
@@ -174,9 +178,12 @@ xdr_rmtcallres(xdrs, 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;
+       if (xdr_reference(xdrs, &port_ptr, sizeof (u_long), (xdrproc_t)xdr_u_long) && xdr_u_long(xdrs, &crp->resultslen)) {
+#ifdef __LP64__
+               crp->port_ptr = (unsigned int *)port_ptr;
+#else
+               crp->port_ptr = (unsigned long *)port_ptr;
+#endif
                return ((*(crp->xdr_results))(xdrs, crp->results_ptr));
        }
        return (FALSE);
@@ -245,6 +252,16 @@ typedef bool_t (*resultproc_t)();
 
 enum clnt_stat 
 clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
+#ifdef __LP64__
+       uint32_t prog;          /* program number */
+       uint32_t vers;          /* version number */
+       uint32_t 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 */
+#else
        u_long          prog;           /* program number */
        u_long          vers;           /* version number */
        u_long          proc;           /* procedure number */
@@ -253,20 +270,26 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
        xdrproc_t       xresults;       /* xdr routine for results */
        caddr_t         resultsp;       /* pointer to results */
        resultproc_t    eachresult;     /* call with each result obtained */
+#endif
 {
        enum clnt_stat stat;
        AUTH *unix_auth = authunix_create_default();
        XDR xdr_stream;
        register XDR *xdrs = &xdr_stream;
-       int outlen, inlen, fromlen, nets;
+       int outlen, inlen, nets;
+       unsigned int fromlen;
        register int sock;
        int on = 1;
        fd_set mask;
        fd_set readfds;
        register int i;
        bool_t done = FALSE;
-       u_long xid;
-       u_long port;
+       uint32_t xid;
+#ifdef __LP64__
+       unsigned int port;
+#else
+       unsigned long port;
+#endif
        struct in_addr addrs[20];
        struct sockaddr_in baddr, raddr; /* broadcast and response addresses */
        struct rmtcallargs a;
@@ -276,6 +299,8 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
        char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE];
        int rfd;
 
+       stat = RPC_SUCCESS;
+
        /*
         * initialization: create a socket, a broadcast address, and
         * preserialize the arguments into a send buffer.
@@ -355,7 +380,7 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
        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;
+               msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_rmtcallres;
                readfds = mask;
                switch (select(sock+1, &readfds, NULL, NULL, &t)) {
 
@@ -373,8 +398,7 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
                }  /* end of select results switch */
        try_again:
                fromlen = sizeof(struct sockaddr);
-               inlen = recvfrom(sock, inbuf, UDPMSGSIZE, 0,
-                       (struct sockaddr *)&raddr, &fromlen);
+               inlen = recvfrom(sock, inbuf, UDPMSGSIZE, 0, (struct sockaddr *)&raddr, &fromlen);
                if (inlen < 0) {
                        if (errno == EINTR)
                                goto try_again;
@@ -406,7 +430,7 @@ clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult)
 #endif
                }
                xdrs->x_op = XDR_FREE;
-               msg.acpted_rply.ar_results.proc = xdr_void;
+               msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void;
                (void)xdr_replymsg(xdrs, &msg);
                (void)(*xresults)(xdrs, resultsp);
                xdr_destroy(xdrs);
index a768d462cb5d84da598190e3261139377299800a..9ffbd1cb458c7dfc8a738128722c9693d6876844 100644 (file)
 #include <sys/cdefs.h>
 
 struct rmtcallargs {
+#ifdef __LP64__
+       unsigned int prog, vers, proc, arglen;
+#else
        unsigned long prog, vers, proc, arglen;
+#endif
        caddr_t args_ptr;
        xdrproc_t xdr_args;
 };
 
 struct rmtcallres {
+#ifdef __LP64__
+       unsigned int *port_ptr;
+       unsigned int resultslen;
+#else
        unsigned long *port_ptr;
        unsigned long resultslen;
+#endif
        caddr_t results_ptr;
        xdrproc_t xdr_results;
 };
index 4d302e6087497f01143d18141ee0fe0129ddf3c3..920ae867baf069e4d4c6119a7fd8c17f1e2ae0de 100644 (file)
@@ -6,7 +6,7 @@
 
 #include "pmap_wakeup.h"
 
-void pmap_wakeup(void)
+int pmap_wakeup(void)
 {
        struct sockaddr_un sun;
        int fd;
@@ -19,13 +19,14 @@ void pmap_wakeup(void)
 
        fd = socket(AF_UNIX, SOCK_STREAM, 0);
        if (fd == -1)
-               return;
+               return -1;
 
        if (connect(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
                close(fd);
-               return;
+               return -1;
        }
 
        read(fd, &b, sizeof(b));
        close(fd);
+       return 0;
 }
index b5dda38aa8f0fbc1f9f7f857db9164426f00b10e..4cab42bdb86e6b099fb0c886d5734c3919089e53 100644 (file)
@@ -1,6 +1,6 @@
 #ifndef __PMAP_WAKEUP_H__
 #define __PMAP_WAKEUP_H__
 
-void pmap_wakeup(void);
+int pmap_wakeup(void);
 
 #endif
diff --git a/rpc.subproj/rpc.3 b/rpc.subproj/rpc.3
new file mode 100644 (file)
index 0000000..767fe74
--- /dev/null
@@ -0,0 +1,1731 @@
+.\"    from: @(#)rpc.3n        2.4 88/08/08 4.0 RPCSRC; from 1.19 88/06/24 SMI
+.\"    $Id: rpc.3,v 1.1 1999/04/13 23:15:37 wsanchez Exp $
+.\"
+.TH RPC 3N "16 February 1988"
+.SH NAME
+rpc \- library routines for remote procedure calls
+.SH SYNOPSIS AND DESCRIPTION
+These routines allow C programs to make procedure
+calls on other machines across the network.
+First, the client calls a procedure to send a
+data packet to the server.
+Upon receipt of the packet, the server calls a dispatch routine
+to perform the requested service, and then sends back a
+reply.
+Finally, the procedure call returns to the client.
+.LP
+Routines that are used for Secure RPC (DES authentication) are described in
+.BR rpc_secure (3N).
+Secure RPC can be used only if DES encryption is available.
+.LP
+.ft B
+.nf
+.sp .5
+#include <rpc/rpc.h>
+.fi
+.ft R
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+auth_destroy(auth)
+\s-1AUTH\s0 *auth;
+.fi
+.ft R
+.IP
+A macro that destroys the authentication information associated with
+.IR auth .
+Destruction usually involves deallocation of private data
+structures. The use of
+.I auth
+is undefined after calling
+.BR auth_destroy(\|) .
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+\s-1AUTH\s0 *
+authnone_create(\|)
+.fi
+.ft R
+.IP
+Create and returns an
+.SM RPC
+authentication handle that passes nonusable authentication
+information with each remote procedure call. This is the
+default authentication used by
+.SM RPC.
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+\s-1AUTH\s0 *
+authunix_create(host, uid, gid, len, aup_gids)
+char *host;
+int uid, gid, len, *aup.gids;
+.fi
+.ft R
+.IP
+Create and return an
+.SM RPC
+authentication handle that contains
+.UX
+authentication information.
+The parameter
+.I host
+is the name of the machine on which the information was
+created;
+.I uid
+is the user's user
+.SM ID ;
+.I gid
+is the user's current group
+.SM ID ;
+.I len
+and
+.I aup_gids
+refer to a counted array of groups to which the user belongs.
+It is easy to impersonate a user.
+.br
+.if t .ne 5
+.LP
+.ft B
+.nf
+.sp .5
+\s-1AUTH\s0 *
+authunix_create_default(\|)
+.fi
+.ft R
+.IP
+Calls
+.B authunix_create(\|)
+with the appropriate parameters.
+.br
+.if t .ne 13
+.LP
+.ft B
+.nf
+.sp .5
+callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
+char *host;
+u_long prognum, versnum, procnum;
+char *in, *out;
+xdrproc_t inproc, outproc;
+.fi
+.ft R
+.IP
+Call the remote procedure associated with
+.IR prognum ,
+.IR versnum ,
+and
+.I procnum
+on the machine,
+.IR host .
+The parameter
+.I in
+is the address of the procedure's argument(s), and
+.I out
+is the address of where to place the result(s);
+.I inproc
+is used to encode the procedure's parameters, and
+.I outproc
+is used to decode the procedure's results.
+This routine returns zero if it succeeds, or the value of
+.B "enum clnt_stat"
+cast to an integer if it fails.
+The routine
+.B clnt_perrno(\|)
+is handy for translating failure statuses into messages.
+.IP
+Warning: calling remote procedures with this routine
+uses
+.SM UDP/IP
+as a transport; see
+.B clntudp_create(\|)
+for restrictions.
+You do not have control of timeouts or authentication using
+this routine.
+.br
+.if t .ne 16
+.LP
+.ft B
+.nf
+.sp .5
+enum clnt_stat
+clnt_broadcast(prognum, versnum, procnum, inproc, in, outproc, out, eachresult)
+u_long prognum, versnum, procnum;
+char *in, *out;
+xdrproc_t inproc, outproc;
+resultproc_t eachresult;
+.fi
+.ft R
+.IP
+Like
+.BR callrpc(\|) ,
+except the call message is broadcast to all locally
+connected broadcast nets. Each time it receives a
+response, this routine calls
+.BR eachresult(\|) ,
+whose form is:
+.IP
+.RS 1i
+.ft B
+.nf
+eachresult(out, addr)
+char *out;
+struct sockaddr_in *addr;
+.ft R
+.fi
+.RE
+.IP
+where
+.I out
+is the same as
+.I out
+passed to
+.BR clnt_broadcast(\|) ,
+except that the remote procedure's output is decoded there;
+.I addr
+points to the address of the machine that sent the results.
+If
+.B eachresult(\|)
+returns zero,
+.B clnt_broadcast(\|)
+waits for more replies; otherwise it returns with appropriate
+status.
+.IP
+Warning: broadcast sockets are limited in size to the
+maximum transfer unit of the data link. For ethernet,
+this value is 1500 bytes.
+.br
+.if t .ne 13
+.LP
+.ft B
+.nf
+.sp .5
+enum clnt_stat
+clnt_call(clnt, procnum, inproc, in, outproc, out, tout)
+\s-1CLIENT\s0 *clnt;
+u_long
+procnum;
+xdrproc_t inproc, outproc;
+char *in, *out;
+struct timeval tout;
+.fi
+.ft R
+.IP
+A macro that calls the remote procedure
+.I procnum
+associated with the client handle,
+.IR clnt ,
+which is obtained with an
+.SM RPC
+client creation routine such as
+.BR clnt_create(\|) .
+The parameter
+.I in
+is the address of the procedure's argument(s), and
+.I out
+is the address of where to place the result(s);
+.I inproc
+is used to encode the procedure's parameters, and
+.I outproc
+is used to decode the procedure's results;
+.I tout
+is the time allowed for results to come back.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+clnt_destroy(clnt)
+\s-1CLIENT\s0 *clnt;
+.fi
+.ft R
+.IP
+A macro that destroys the client's
+.SM RPC
+handle. Destruction usually involves deallocation
+of private data structures, including
+.I clnt
+itself.  Use of
+.I clnt
+is undefined after calling
+.BR clnt_destroy(\|) .
+If the
+.SM RPC
+library opened the associated socket, it will close it also.
+Otherwise, the socket remains open.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+\s-1CLIENT\s0 *
+clnt_create(host, prog, vers, proto)
+char *host;
+u_long prog, vers;
+char *proto;
+.fi
+.ft R
+.IP
+Generic client creation routine.
+.I host
+identifies the name of the remote host where the server
+is located.
+.I proto
+indicates which kind of transport protocol to use. The
+currently supported values for this field are \(lqudp\(rq
+and \(lqtcp\(rq.
+Default timeouts are set, but can be modified using
+.BR clnt_control(\|) .
+.IP
+Warning: Using
+.SM UDP
+has its shortcomings.  Since
+.SM UDP\s0-based
+.SM RPC
+messages can only hold up to 8 Kbytes of encoded data,
+this transport cannot be used for procedures that take
+large arguments or return huge results.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+bool_t
+clnt_control(cl, req, info)
+\s-1CLIENT\s0 *cl;
+char *info;
+.fi
+.ft R
+.IP
+A macro used to change or retrieve various information
+about a client object.
+.I req
+indicates the type of operation, and
+.I info
+is a pointer to the information. For both
+.SM UDP
+and
+.SM TCP\s0,
+the supported values of
+.I req
+and their argument types and what they do are:
+.IP
+.nf
+.ta +2.0i +2.0i +2.0i
+.SM CLSET_TIMEOUT\s0   struct timeval  set total timeout
+.SM CLGET_TIMEOUT\s0   struct timeval  get total timeout
+.fi
+.IP
+Note: if you set the timeout using
+.BR clnt_control(\|) ,
+the timeout parameter passed to
+.B clnt_call(\|)
+will be ignored in all future calls.
+.IP
+.nf
+.SM CLGET_SERVER_ADDR\s0       struct sockaddr_in      get server's address
+.fi
+.br
+.IP
+The following operations are valid for
+.SM UDP
+only:
+.IP
+.nf
+.ta +2.0i +2.0i +2.0i
+.SM CLSET_RETRY_TIMEOUT\s0             struct timeval  set the retry timeout
+.SM CLGET_RETRY_TIMEOUT\s0             struct timeval  get the retry timeout
+.fi
+.br
+.IP
+The retry timeout is the time that
+.SM "UDP RPC"
+waits for the server to reply before
+retransmitting the request.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+clnt_freeres(clnt, outproc, out)
+\s-1CLIENT\s0 *clnt;
+xdrproc_t outproc;
+char *out;
+.fi
+.ft R
+.IP
+A macro that frees any data allocated by the
+.SM RPC/XDR
+system when it decoded the results of an
+.SM RPC
+call.  The
+parameter
+.I out
+is the address of the results, and
+.I outproc
+is the
+.SM XDR
+routine describing the results.
+This routine returns one if the results were successfully
+freed,
+and zero otherwise.
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+void
+clnt_geterr(clnt, errp)
+\s-1CLIENT\s0 *clnt;
+struct rpc_err *errp;
+.fi
+.ft R
+.IP
+A macro that copies the error structure out of the client
+handle
+to the structure at address
+.IR errp .
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+clnt_pcreateerror(s)
+char *s;
+.fi
+.ft R
+.IP
+Print a message to standard error indicating
+why a client
+.SM RPC
+handle could not be created.
+The message is prepended with string
+.I s
+and a colon.
+Used when a
+.BR clnt_create(\|) ,
+.BR clntraw_create(\|) ,
+.BR clnttcp_create(\|) ,
+or
+.B clntudp_create(\|)
+call fails.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+clnt_perrno(stat)
+enum clnt_stat stat;
+.fi
+.ft R
+.IP
+Print a message to standard error corresponding
+to the condition indicated by
+.IR stat .
+Used after
+.BR callrpc(\|) .
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+clnt_perror(clnt, s)
+\s-1CLIENT\s0 *clnt;
+char *s;
+.fi
+.ft R
+.IP
+Print a message to standard error indicating why an
+.SM RPC
+call failed;
+.I clnt
+is the handle used to do the call.
+The message is prepended with string
+.I s
+and a colon.
+Used after
+.BR clnt_call(\|) .
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+char *
+clnt_spcreateerror
+char *s;
+.fi
+.ft R
+.IP
+Like
+.BR clnt_pcreateerror(\|) ,
+except that it returns a string
+instead of printing to the standard error.
+.IP
+Bugs: returns pointer to static data that is overwritten
+on each call.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+char *
+clnt_sperrno(stat)
+enum clnt_stat stat;
+.fi
+.ft R
+.IP
+Take the same arguments as
+.BR clnt_perrno(\|) ,
+but instead of sending a message to the standard error
+indicating why an
+.SM RPC
+call failed, return a pointer to a string which contains
+the message.  The string ends with a
+.SM NEWLINE\s0.
+.IP
+.B clnt_sperrno(\|)
+is used instead of
+.B clnt_perrno(\|)
+if the program does not have a standard error (as a program
+running as a server quite likely does not), or if the
+programmer
+does not want the message to be output with
+.BR printf ,
+or if a message format different than that supported by
+.B clnt_perrno(\|)
+is to be used.
+Note: unlike
+.B clnt_sperror(\|)
+and
+.BR clnt_spcreaterror(\|) ,
+.B clnt_sperrno(\|)
+returns pointer to static data, but the
+result will not get overwritten on each call.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+char *
+clnt_sperror(rpch, s)
+\s-1CLIENT\s0 *rpch;
+char *s;
+.fi
+.ft R
+.IP
+Like
+.BR clnt_perror(\|) ,
+except that (like
+.BR clnt_sperrno(\|) )
+it returns a string instead of printing to standard error.
+.IP
+Bugs: returns pointer to static data that is overwritten
+on each call.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+\s-1CLIENT\s0 *
+clntraw_create(prognum, versnum)
+u_long prognum, versnum;
+.fi
+.ft R
+.IP
+This routine creates a toy
+.SM RPC
+client for the remote program
+.IR prognum ,
+version
+.IR versnum .
+The transport used to pass messages to the service is
+actually a buffer within the process's address space, so the
+corresponding
+.SM RPC
+server should live in the same address space; see
+.BR svcraw_create(\|) .
+This allows simulation of
+.SM RPC
+and acquisition of
+.SM RPC
+overheads, such as round trip times, without any
+kernel interference. This routine returns
+.SM NULL
+if it fails.
+.br
+.if t .ne 15
+.LP
+.ft B
+.nf
+.sp .5
+\s-1CLIENT\s0 *
+clnttcp_create(addr, prognum, versnum, sockp, sendsz, recvsz)
+struct sockaddr_in *addr;
+u_long prognum, versnum;
+int *sockp;
+u_int sendsz, recvsz;
+.fi
+.ft R
+.IP
+This routine creates an
+.SM RPC
+client for the remote program
+.IR prognum ,
+version
+.IR versnum ;
+the client uses
+.SM TCP/IP
+as a transport. The remote program is located at Internet
+address
+.IR *addr .
+If
+.\"The following in-line font conversion is necessary for the hyphen indicator
+\fB\%addr\->sin_port\fR
+is zero, then it is set to the actual port that the remote
+program is listening on (the remote
+.B portmap
+service is consulted for this information). The parameter
+.I sockp
+is a socket; if it is
+.BR \s-1RPC_ANYSOCK\s0 ,
+then this routine opens a new one and sets
+.IR sockp .
+Since
+.SM TCP\s0-based
+.SM RPC
+uses buffered
+.SM I/O ,
+the user may specify the size of the send and receive buffers
+with the parameters
+.I sendsz
+and
+.IR recvsz ;
+values of zero choose suitable defaults.
+This routine returns
+.SM NULL
+if it fails.
+.br
+.if t .ne 15
+.LP
+.ft B
+.nf
+.sp .5
+\s-1CLIENT\s0 *
+clntudp_create(addr, prognum, versnum, wait, sockp)
+struct sockaddr_in *addr;
+u_long prognum, versnum;
+struct timeval wait;
+int *sockp;
+.fi
+.ft R
+.IP
+This routine creates an
+.SM RPC
+client for the remote program
+.IR prognum ,
+version
+.IR versnum ;
+the client uses use
+.SM UDP/IP
+as a transport. The remote program is located at Internet
+address
+.IR addr .
+If
+\fB\%addr\->sin_port\fR
+is zero, then it is set to actual port that the remote
+program is listening on (the remote
+.B portmap
+service is consulted for this information). The parameter
+.I sockp
+is a socket; if it is
+.BR \s-1RPC_ANYSOCK\s0 ,
+then this routine opens a new one and sets
+.IR sockp .
+The
+.SM UDP
+transport resends the call message in intervals of
+.B wait
+time until a response is received or until the call times
+out.
+The total time for the call to time out is specified by
+.BR clnt_call(\|) .
+.IP
+Warning: since
+.SM UDP\s0-based
+.SM RPC
+messages can only hold up to 8 Kbytes
+of encoded data, this transport cannot be used for procedures
+that take large arguments or return huge results.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+\s-1CLIENT\s0 *
+clntudp_bufcreate(addr, prognum, versnum, wait, sockp, sendsize, recosize)
+struct sockaddr_in *addr;
+u_long prognum, versnum;
+struct timeval wait;
+int *sockp;
+unsigned int sendsize;
+unsigned int recosize;
+.fi
+.ft R
+.IP
+This routine creates an
+.SM RPC
+client for the remote program
+.IR prognum ,
+on
+.IR versnum ;
+the client uses use
+.SM UDP/IP
+as a transport. The remote program is located at Internet
+address
+.IR addr .
+If
+\fB\%addr\->sin_port\fR
+is zero, then it is set to actual port that the remote
+program is listening on (the remote
+.B portmap
+service is consulted for this information). The parameter
+.I sockp
+is a socket; if it is
+.BR \s-1RPC_ANYSOCK\s0 ,
+then this routine opens a new one and sets
+.BR sockp .
+The
+.SM UDP
+transport resends the call message in intervals of
+.B wait
+time until a response is received or until the call times
+out.
+The total time for the call to time out is specified by
+.BR clnt_call(\|) .
+.IP
+This allows the user to specify the maximun packet size for sending and receiving 
+.SM UDP\s0-based
+.SM RPC
+messages.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+get_myaddress(addr)
+struct sockaddr_in *addr;
+.fi
+.ft R
+.IP
+Stuff the machine's
+.SM IP
+address into
+.IR *addr ,
+without consulting the library routines that deal with
+.BR /etc/hosts .
+The port number is always set to
+.BR htons(\s-1PMAPPORT\s0) .
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+struct pmaplist *
+pmap_getmaps(addr)
+struct sockaddr_in *addr;
+.fi
+.ft R
+.IP
+A user interface to the
+.B portmap
+service, which returns a list of the current
+.SM RPC
+program-to-port mappings
+on the host located at
+.SM IP
+address
+.IR *addr .
+This routine can return
+.SM NULL .
+The command
+.RB ` "rpcinfo \-p" '
+uses this routine.
+.br
+.if t .ne 12
+.LP
+.ft B
+.nf
+.sp .5
+u_short
+pmap_getport(addr, prognum, versnum, protocol)
+struct sockaddr_in *addr;
+u_long prognum, versnum, protocol;
+.fi
+.ft R
+.IP
+A user interface to the
+.B portmap
+service, which returns the port number
+on which waits a service that supports program number
+.IR prognum ,
+version
+.IR versnum ,
+and speaks the transport protocol associated with
+.IR protocol .
+The value of
+.I protocol
+is most likely
+.B
+.SM IPPROTO_UDP
+or 
+.BR \s-1IPPROTO_TCP\s0 .
+A return value of zero means that the mapping does not exist
+or that
+the
+.SM RPC
+system failured to contact the remote
+.B portmap
+service.  In the latter case, the global variable
+.B rpc_createerr(\|)
+contains the
+.SM RPC
+status.
+.br
+.if t .ne 15
+.LP
+.ft B
+.nf
+.sp .5
+enum clnt_stat
+pmap_rmtcall(addr, prognum, versnum, procnum, inproc, in, outproc, out, tout, portp)
+struct sockaddr_in *addr;
+u_long prognum, versnum, procnum;
+char *in, *out;
+xdrproc_t inproc, outproc;
+struct timeval tout;
+u_long *portp;
+.fi
+.ft R
+.IP
+A user interface to the
+.B portmap
+service, which instructs
+.B portmap
+on the host at
+.SM IP
+address
+.I *addr
+to make an
+.SM RPC
+call on your behalf to a procedure on that host.
+The parameter
+.I *portp
+will be modified to the program's port number if the
+procedure
+succeeds. The definitions of other parameters are discussed
+in
+.B callrpc(\|)
+and
+.BR clnt_call(\|) .
+This procedure should be used for a \(lqping\(rq and nothing
+else.
+See also
+.BR clnt_broadcast(\|) .
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+pmap_set(prognum, versnum, protocol, port)
+u_long prognum, versnum, protocol;
+u_short port;
+.fi
+.ft R
+.IP
+A user interface to the
+.B portmap
+service, which establishes a mapping between the triple
+.RI [ prognum , versnum , protocol\fR]
+and
+.I port
+on the machine's
+.B portmap
+service. The value of
+.I protocol
+is most likely
+.B
+.SM IPPROTO_UDP
+or 
+.BR \s-1IPPROTO_TCP\s0 .
+This routine returns one if it succeeds, zero otherwise.
+Automatically done by
+.BR svc_register(\|) .
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+pmap_unset(prognum, versnum)
+u_long prognum, versnum;
+.fi
+.ft R
+.IP
+A user interface to the
+.B portmap
+service, which destroys all mapping between the triple
+.RI [ prognum , versnum , *\fR]
+and
+.B ports
+on the machine's
+.B portmap
+service. This routine returns one if it succeeds, zero
+otherwise.
+.br
+.if t .ne 15
+.LP
+.ft B
+.nf
+.sp .5
+registerrpc(prognum, versnum, procnum, procname, inproc, outproc)
+u_long prognum, versnum, procnum;
+char *(*procname) (\|) ;
+xdrproc_t inproc, outproc;
+.fi
+.ft R
+.IP
+Register procedure
+.I procname
+with the
+.SM RPC
+service package.  If a request arrives for program
+.IR prognum ,
+version
+.IR versnum ,
+and procedure
+.IR procnum ,
+.I procname
+is called with a pointer to its parameter(s);
+.I progname
+should return a pointer to its static result(s);
+.I inproc
+is used to decode the parameters while
+.I outproc
+is used to encode the results.
+This routine returns zero if the registration succeeded, \-1
+otherwise.
+.IP
+Warning: remote procedures registered in this form
+are accessed using the
+.SM UDP/IP
+transport; see
+.B svcudp_create(\|)
+for restrictions.
+.br
+.if t .ne 5
+.LP
+.ft B
+.nf
+.sp .5
+struct rpc_createerr     rpc_createerr;
+.fi
+.ft R
+.IP
+A global variable whose value is set by any
+.SM RPC
+client creation routine
+that does not succeed.  Use the routine
+.B clnt_pcreateerror(\|)
+to print the reason why.
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+svc_destroy(xprt)
+\s-1SVCXPRT\s0 *
+xprt;
+.fi
+.ft R
+.IP
+A macro that destroys the
+.SM RPC
+service transport handle,
+.IR xprt .
+Destruction usually involves deallocation
+of private data structures, including
+.I xprt
+itself.  Use of
+.I xprt
+is undefined after calling this routine.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+fd_set svc_fdset;
+.fi
+.ft R
+.IP
+A global variable reflecting the
+.SM RPC
+service side's
+read file descriptor bit mask; it is suitable as a parameter
+to the
+.B select
+system call. This is only of interest
+if a service implementor does not call
+.BR svc_run(\|) ,
+but rather does his own asynchronous event processing.
+This variable is read-only (do not pass its address to
+.BR select !),
+yet it may change after calls to
+.B svc_getreqset(\|)
+or any creation routines.
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+int svc_fds;
+.fi
+.ft R
+.IP
+Similar to
+.BR svc_fedset(\|) ,
+but limited to 32 descriptors. This
+interface is obsoleted by
+.BR svc_fdset(\|) .
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+svc_freeargs(xprt, inproc, in)
+\s-1SVCXPRT\s0 *xprt;
+xdrproc_t inproc;
+char *in;
+.fi
+.ft R
+.IP
+A macro that frees any data allocated by the
+.SM RPC/XDR
+system when it decoded the arguments to a service procedure
+using
+.BR svc_getargs(\|) .
+This routine returns 1 if the results were successfully
+freed,
+and zero otherwise.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+svc_getargs(xprt, inproc, in)
+\s-1SVCXPRT\s0 *xprt;
+xdrproc_t inproc;
+char *in;
+.fi
+.ft R
+.IP
+A macro that decodes the arguments of an
+.SM RPC
+request
+associated with the
+.SM RPC
+service transport handle,
+.IR xprt .
+The parameter
+.I in
+is the address where the arguments will be placed;
+.I inproc
+is the
+.SM XDR
+routine used to decode the arguments.
+This routine returns one if decoding succeeds, and zero
+otherwise.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+struct sockaddr_in *
+svc_getcaller(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+The approved way of getting the network address of the caller
+of a procedure associated with the
+.SM RPC
+service transport handle,
+.IR xprt .
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+svc_getreqset(rdfds)
+fd_set *rdfds;
+.fi
+.ft R
+.IP
+This routine is only of interest if a service implementor
+does not call
+.BR svc_run(\|) ,
+but instead implements custom asynchronous event processing.
+It is called when the
+.B select
+system call has determined that an
+.SM RPC
+request has arrived on some
+.SM RPC
+.B socket(s) ;
+.I rdfds
+is the resultant read file descriptor bit mask.
+The routine returns when all sockets associated with the
+value of
+.I rdfds
+have been serviced.
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+svc_getreq(rdfds)
+int rdfds;
+.fi
+.ft R
+.IP
+Similar to
+.BR svc_getreqset(\|) ,
+but limited to 32 descriptors. This interface is obsoleted by
+.BR svc_getreqset(\|) .
+.br
+.if t .ne 17
+.LP
+.ft B
+.nf
+.sp .5
+svc_register(xprt, prognum, versnum, dispatch, protocol)
+\s-1SVCXPRT\s0 *xprt;
+u_long prognum, versnum;
+void (*dispatch) (\|);
+u_long protocol;
+.fi
+.ft R
+.IP
+Associates
+.I prognum
+and
+.I versnum
+with the service dispatch procedure,
+.IR dispatch .
+If
+.I protocol
+is zero, the service is not registered with the
+.B portmap
+service.  If
+.I protocol
+is non-zero, then a mapping of the triple
+.RI [ prognum , versnum , protocol\fR]
+to
+\fB\%xprt\->xp_port\fR
+is established with the local
+.B portmap
+service (generally
+.I protocol
+is zero,
+.B
+.SM IPPROTO_UDP
+or 
+.B
+.SM IPPROTO_TCP
+).
+The procedure
+.I dispatch
+has the following form:
+.RS 1i
+.ft B
+.nf
+dispatch(request, xprt)
+struct svc_req *request;
+\s-1SVCXPRT\s0 *xprt;
+.ft R
+.fi
+.RE
+.IP
+The
+.B svc_register(\|)
+routine returns one if it succeeds, and zero otherwise.
+.br
+.if t .ne 6
+.LP
+.ft B
+.nf
+.sp .5
+svc_run(\|)
+.fi
+.ft R
+.IP
+This routine never returns. It waits for
+.SM RPC
+requests to arrive, and calls the appropriate service
+procedure using
+.B svc_getreq(\|)
+when one arrives. This procedure is usually waiting for a
+.B select(\|)
+system call to return.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+svc_sendreply(xprt, outproc, out)
+\s-1SVCXPRT\s0 *xprt;
+xdrproc_t outproc;
+char *out;
+.fi
+.ft R
+.IP
+Called by an
+.SM RPC
+service's dispatch routine to send the results of a
+remote procedure call.  The parameter
+.I xprt
+is the request's associated transport handle;
+.I outproc
+is the
+.SM XDR
+routine which is used to encode the results; and
+.I out
+is the address of the results.
+This routine returns one if it succeeds, zero otherwise.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svc_unregister(prognum, versnum)
+u_long prognum, versnum;
+.fi
+.ft R
+.IP
+Remove all mapping of the double
+.RI [ prognum , versnum ]
+to dispatch routines, and of the triple
+.RI [ prognum , versnum , *\fR]
+to port number.
+.br
+.if t .ne 9
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_auth(xprt, why)
+\s-1SVCXPRT\s0 *xprt;
+enum auth_stat why;
+.fi
+.ft R
+.IP
+Called by a service dispatch routine that refuses to perform
+a remote procedure call due to an authentication error.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_decode(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called by a service dispatch routine that cannot successfully
+decode its parameters. See also
+.BR svc_getargs(\|) .
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_noproc(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called by a service dispatch routine that does not implement
+the procedure number that the caller requests.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_noprog(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called when the desired program is not registered with the
+.SM RPC
+package. Service implementors usually do not need this routine.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_progvers(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called when the desired version of a program is not registered
+with the
+.SM RPC
+package. Service implementors usually do not need this routine.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_systemerr(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called by a service dispatch routine when it detects a system
+error
+not covered by any particular protocol.
+For example, if a service can no longer allocate storage,
+it may call this routine.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+svcerr_weakauth(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Called by a service dispatch routine that refuses to perform
+a remote procedure call due to insufficient
+authentication parameters.  The routine calls
+.BR "svcerr_auth(xprt, \s-1AUTH_TOOWEAK\s0)" .
+.br
+.if t .ne 11
+.LP
+.ft B
+.nf
+.sp .5
+\s-1SVCXPRT\s0 *
+svcraw_create(\|)
+.fi
+.ft R
+.IP
+This routine creates a toy
+.SM RPC
+service transport, to which it returns a pointer.  The
+transport
+is really a buffer within the process's address space,
+so the corresponding
+.SM RPC
+client should live in the same
+address space;
+see
+.BR clntraw_create(\|) .
+This routine allows simulation of
+.SM RPC
+and acquisition of
+.SM RPC
+overheads (such as round trip times), without any kernel
+interference.
+This routine returns
+.SM NULL
+if it fails.
+.br
+.if t .ne 11
+.LP
+.ft B
+.nf
+.sp .5
+\s-1SVCXPRT\s0 *
+svctcp_create(sock, send_buf_size, recv_buf_size)
+int sock;
+u_int send_buf_size, recv_buf_size;
+.fi
+.ft R
+.IP
+This routine creates a
+.SM TCP/IP\s0-based
+.SM RPC
+service transport, to which it returns a pointer.
+The transport is associated with the socket
+.IR sock ,
+which may be
+.BR \s-1RPC_ANYSOCK\s0 ,
+in which case a new socket is created.
+If the socket is not bound to a local
+.SM TCP
+port, then this routine binds it to an arbitrary port.  Upon
+completion,
+\fB\%xprt\->xp_sock\fR
+is the transport's socket descriptor, and
+\fB\%xprt\->xp_port\fR
+is the transport's port number.
+This routine returns
+.SM NULL
+if it fails. Since
+.SM TCP\s0-based
+.SM RPC
+uses buffered
+.SM I/O ,
+users may specify the size of buffers; values of zero
+choose suitable defaults.
+.br
+.if t .ne 11
+.LP
+.ft B
+.nf
+.sp .5
+\s-1SVCXPRT\s0 *
+svcfd_create(fd, sendsize, recvsize)
+int fd;
+u_int sendsize;
+u_int recvsize;
+.fi
+.ft R
+.IP
+Create a service on top of any open descriptor. Typically,
+this
+descriptor is a connected socket for a stream protocol such
+as
+.SM TCP\s0.
+.I sendsize
+and
+.I recvsize
+indicate sizes for the send and receive buffers.  If they are
+zero, a reasonable default is chosen.
+.br
+.if t .ne 10
+.LP
+.ft B
+.nf
+.sp .5
+\s-1SVCXPRT\s0 *
+svcudp_bufcreate(sock, sendsize, recosize)
+int sock;
+.fi
+.ft R
+.IP
+This routine creates a
+.SM UDP/IP\s0-based
+.SM RPC
+service transport, to which it returns a pointer.
+The transport is associated with the socket
+.IR sock ,
+which may be
+.B \s-1RPC_ANYSOCK\s0 ,
+in which case a new socket is created.
+If the socket is not bound to a local
+.SM UDP
+port, then this routine binds it to an arbitrary port. Upon
+completion,
+\fB\%xprt\->xp_sock\fR
+is the transport's socket descriptor, and
+\fB\%xprt\->xp_port\fR
+is the transport's port number.
+This routine returns
+.SM NULL
+if it fails.
+.IP
+This allows the user to specify the maximun packet size for sending and 
+receiving
+.SM UDP\s0-based
+.SM RPC messages.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_accepted_reply(xdrs, ar)
+\s-1XDR\s0 *xdrs;
+struct accepted_reply *ar;
+.fi
+.ft R
+.IP
+Used for encoding
+.SM RPC
+reply messages. This routine is useful for users who
+wish to generate
+\s-1RPC\s0-style
+messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_authunix_parms(xdrs, aupp)
+\s-1XDR\s0 *xdrs;
+struct authunix_parms *aupp;
+.fi
+.ft R
+.IP
+Used for describing
+.SM UNIX
+credentials. This routine is useful for users
+who wish to generate these credentials without using the
+.SM RPC
+authentication package.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+void
+xdr_callhdr(xdrs, chdr)
+\s-1XDR\s0 *xdrs;
+struct rpc_msg *chdr;
+.fi
+.ft R
+.IP
+Used for describing
+.SM RPC
+call header messages.
+This routine is useful for users who wish to generate
+.SM RPC\s0-style
+messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_callmsg(xdrs, cmsg)
+\s-1XDR\s0 *xdrs;
+struct rpc_msg *cmsg;
+.fi
+.ft R
+.IP
+Used for describing
+.SM RPC
+call messages.
+This routine is useful for users who wish to generate
+.SM RPC\s0-style
+messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_opaque_auth(xdrs, ap)
+\s-1XDR\s0 *xdrs;
+struct opaque_auth *ap;
+.fi
+.ft R
+.IP
+Used for describing
+.SM RPC
+authentication information messages.
+This routine is useful for users who wish to generate
+.SM RPC\s0-style
+messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_pmap(xdrs, regs)
+\s-1XDR\s0 *xdrs;
+struct pmap *regs;
+.fi
+.ft R
+.IP
+Used for describing parameters to various
+.B portmap
+procedures, externally.
+This routine is useful for users who wish to generate
+these parameters without using the
+.B pmap
+interface.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_pmaplist(xdrs, rp)
+\s-1XDR\s0 *xdrs;
+struct pmaplist **rp;
+.fi
+.ft R
+.IP
+Used for describing a list of port mappings, externally.
+This routine is useful for users who wish to generate
+these parameters without using the
+.B pmap
+interface.
+.br
+.if t .ne 7
+.LP
+.ft B
+.nf
+.sp .5
+xdr_rejected_reply(xdrs, rr)
+\s-1XDR\s0 *xdrs;
+struct rejected_reply *rr;
+.fi
+.ft R
+.IP
+Used for describing
+.SM RPC
+reply messages.
+This routine is useful for users who wish to generate
+.SM RPC\s0-style
+messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+xdr_replymsg(xdrs, rmsg)
+\s-1XDR\s0 *xdrs;
+struct rpc_msg *rmsg;
+.fi
+.ft R
+.IP
+Used for describing
+.SM RPC
+reply messages.
+This routine is useful for users who wish to generate
+.SM RPC
+style messages without using the
+.SM RPC
+package.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+xprt_register(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+After
+.SM RPC
+service transport handles are created,
+they should register themselves with the
+.SM RPC
+service package.
+This routine modifies the global variable
+.BR svc_fds(\|) .
+Service implementors usually do not need this routine.
+.br
+.if t .ne 8
+.LP
+.ft B
+.nf
+.sp .5
+void
+xprt_unregister(xprt)
+\s-1SVCXPRT\s0 *xprt;
+.fi
+.ft R
+.IP
+Before an
+.SM RPC
+service transport handle is destroyed,
+it should unregister itself with the
+.SM RPC
+service package.
+This routine modifies the global variable
+.BR svc_fds(\|) .
+Service implementors usually do not need this routine.
+.SH SEE ALSO
+.BR rpc_secure (3N),
+.BR xdr (3N)
+.br
+The following manuals:
+.RS
+.ft I
+Remote Procedure Calls: Protocol Specification
+.br
+Remote Procedure Call Programming Guide
+.br
+rpcgen Programming Guide
+.br
+.ft R
+.RE
+.IR "\s-1RPC\s0: Remote Procedure Call Protocol Specification" ,
+.SM RFC1050, Sun Microsystems, Inc.,
+.SM USC-ISI\s0.
+
index 69a65ed4c2e2381d8059d18106931d366ccc596e..789fd00740f25d63d154e13d3c5de8fcb777e134 100644 (file)
@@ -79,7 +79,11 @@ xdr_callmsg(xdrs, cmsg)
        register XDR *xdrs;
        register struct rpc_msg *cmsg;
 {
+#ifdef __LP64__
+       int *buf;
+#else
        register long *buf;
+#endif
        register struct opaque_auth *oa;
 
        if (xdrs->x_op == XDR_ENCODE) {
@@ -89,10 +93,17 @@ xdr_callmsg(xdrs, cmsg)
                if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) {
                        return (FALSE);
                }
+#ifdef __LP64__
+               buf = (int *)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));
+#else
                buf = (long *)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));
+                                                                + RNDUP(cmsg->rm_call.cb_cred.oa_length)
+                                                                + 2 * BYTES_PER_XDR_UNIT
+                                                                + RNDUP(cmsg->rm_call.cb_verf.oa_length));
+#endif
                if (buf != NULL) {
                        IXDR_PUT_LONG(buf, cmsg->rm_xid);
                        IXDR_PUT_ENUM(buf, cmsg->rm_direction);
@@ -111,7 +122,11 @@ xdr_callmsg(xdrs, cmsg)
                        IXDR_PUT_LONG(buf, oa->oa_length);
                        if (oa->oa_length) {
                                bcopy(oa->oa_base, (caddr_t)buf, oa->oa_length);
+#ifdef __LP64__
+                               buf += RNDUP(oa->oa_length) / sizeof (int);
+#else
                                buf += RNDUP(oa->oa_length) / sizeof (long);
+#endif
                        }
                        oa = &cmsg->rm_call.cb_verf;
                        IXDR_PUT_ENUM(buf, oa->oa_flavor);
@@ -119,6 +134,7 @@ xdr_callmsg(xdrs, cmsg)
                        if (oa->oa_length) {
                                bcopy(oa->oa_base, (caddr_t)buf, oa->oa_length);
                                /* no real need....
+                               * N.B. Fix this for __LP64__ if it is uncommented *
                                buf += RNDUP(oa->oa_length) / sizeof (long);
                                */
                        }
@@ -126,7 +142,11 @@ xdr_callmsg(xdrs, cmsg)
                }
        }
        if (xdrs->x_op == XDR_DECODE) {
+#ifdef __LP64__
+               buf = (int *)XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT);
+#else
                buf = (long *)XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT);
+#endif
                if (buf != NULL) {
                        cmsg->rm_xid = IXDR_GET_LONG(buf);
                        cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type);
@@ -151,7 +171,11 @@ xdr_callmsg(xdrs, cmsg)
                                        oa->oa_base = (caddr_t)
                                                mem_alloc(oa->oa_length);
                                }
+#ifdef __LP64__
+                               buf = (int *)XDR_INLINE(xdrs, RNDUP(oa->oa_length));
+#else
                                buf = (long *)XDR_INLINE(xdrs, RNDUP(oa->oa_length));
+#endif
                                if (buf == NULL) {
                                        if (xdr_opaque(xdrs, oa->oa_base,
                                            oa->oa_length) == FALSE) {
@@ -161,13 +185,17 @@ xdr_callmsg(xdrs, cmsg)
                                        bcopy((caddr_t)buf, oa->oa_base,
                                            oa->oa_length);
                                        /* no real need....
-                                       buf += RNDUP(oa->oa_length) /
-                                               sizeof (long);
+                                       * N.B. Fix this for __LP64__ if it is uncommented *
+                                       buf += RNDUP(oa->oa_length) / sizeof (long);
                                        */
                                }
                        }
                        oa = &cmsg->rm_call.cb_verf;
+#ifdef __LP64__
+                       buf = (int *)XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
+#else
                        buf = (long *)XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
+#endif
                        if (buf == NULL) {
                                if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE ||
                                    xdr_u_int(xdrs, &oa->oa_length) == FALSE) {
@@ -185,7 +213,11 @@ xdr_callmsg(xdrs, cmsg)
                                        oa->oa_base = (caddr_t)
                                                mem_alloc(oa->oa_length);
                                }
+#ifdef __LP64__
+                               buf = (int *)XDR_INLINE(xdrs, RNDUP(oa->oa_length));
+#else
                                buf = (long *)XDR_INLINE(xdrs, RNDUP(oa->oa_length));
+#endif
                                if (buf == NULL) {
                                        if (xdr_opaque(xdrs, oa->oa_base,
                                            oa->oa_length) == FALSE) {
@@ -195,8 +227,8 @@ xdr_callmsg(xdrs, cmsg)
                                        bcopy((caddr_t)buf, oa->oa_base,
                                            oa->oa_length);
                                        /* no real need...
-                                       buf += RNDUP(oa->oa_length) /
-                                               sizeof (long);
+                                       * N.B. Fix this for __LP64__ if it is uncommented *
+                                       buf += RNDUP(oa->oa_length) / sizeof (long);
                                        */
                                }
                        }
index 6f5611bc1c004c0cfe37bb0bcfccf1d610b13948..ec2d929c61f6eeef135315737484f4861c814f0f 100644 (file)
 #ifndef _RPC_RPCMSG_H
 #define _RPC_RPCMSG_H
 
+#ifdef __LP64__
+#define RPC_MSG_VERSION                ((unsigned int) 2)
+#else
 #define RPC_MSG_VERSION                ((unsigned long) 2)
+#endif
 #define RPC_SERVICE_PORT       ((unsigned short) 2048)
 
 /*
@@ -111,8 +115,13 @@ struct accepted_reply {
        enum accept_stat        ar_stat;
        union {
                struct {
-                       unsigned long   low;
-                       unsigned long   high;
+#ifdef __LP64__
+                       unsigned int low;
+                       unsigned int high;
+#else
+                       unsigned long low;
+                       unsigned long high;
+#endif
                } AR_versions;
                struct {
                        caddr_t where;
@@ -131,8 +140,13 @@ struct rejected_reply {
        enum reject_stat rj_stat;
        union {
                struct {
+#ifdef __LP64__
+                       unsigned int low;
+                       unsigned int high;
+#else
                        unsigned long low;
                        unsigned long high;
+#endif
                } RJ_versions;
                enum auth_stat RJ_why;  /* why authentication did not work */
        } ru;
@@ -157,10 +171,17 @@ struct reply_body {
  * Body of an rpc request call.
  */
 struct call_body {
+#ifdef __LP64__
+       unsigned int cb_rpcvers;        /* must be equal to two */
+       unsigned int cb_prog;
+       unsigned int cb_vers;
+       unsigned int cb_proc;
+#else
        unsigned long cb_rpcvers;       /* must be equal to two */
        unsigned long cb_prog;
        unsigned long cb_vers;
        unsigned long cb_proc;
+#endif
        struct opaque_auth cb_cred;
        struct opaque_auth cb_verf; /* protocol specific - provided by client */
 };
@@ -169,7 +190,11 @@ struct call_body {
  * The rpc message
  */
 struct rpc_msg {
+#ifdef __LP64__
+       unsigned int                    rm_xid;
+#else
        unsigned long                   rm_xid;
+#endif
        enum msg_type           rm_direction;
        union {
                struct call_body RM_cmb;
index 101bdcba20e4f8b1feec26da7c87285c5e778a28..0299d1d2772d90fee097d1fcacfce9ec1aaf0b9c 100644 (file)
@@ -162,8 +162,8 @@ xdr_rejected_reply(xdrs, rr)
 }
 
 static struct xdr_discrim reply_dscrm[3] = {
-       { (int)MSG_ACCEPTED, xdr_accepted_reply },
-       { (int)MSG_DENIED, xdr_rejected_reply },
+       { (int)MSG_ACCEPTED, (xdrproc_t)xdr_accepted_reply },
+       { (int)MSG_DENIED, (xdrproc_t)xdr_rejected_reply },
        { __dontcare__, NULL_xdrproc_t } };
 
 /*
@@ -243,8 +243,13 @@ accepted(acpt_stat, error)
        }
        /* something's wrong, but we don't know what ... */
        error->re_status = RPC_FAILED;
+#ifdef __LP64__
+       error->re_lb.s1 = (int)MSG_ACCEPTED;
+       error->re_lb.s2 = (int)acpt_stat;
+#else
        error->re_lb.s1 = (long)MSG_ACCEPTED;
        error->re_lb.s2 = (long)acpt_stat;
+#endif
 }
 
 static void 
@@ -266,8 +271,13 @@ rejected(rjct_stat, error)
        }
        /* something's wrong, but we don't know what ... */
        error->re_status = RPC_FAILED;
+#ifdef __LP64__
+       error->re_lb.s1 = (int)MSG_DENIED;
+       error->re_lb.s2 = (int)rjct_stat;
+#else
        error->re_lb.s1 = (long)MSG_DENIED;
        error->re_lb.s2 = (long)rjct_stat;
+#endif
 }
 
 /*
@@ -296,7 +306,11 @@ _seterr_reply(msg, error)
 
        default:
                error->re_status = RPC_FAILED;
+#ifdef __LP64__
+               error->re_lb.s1 = (int)(msg->rm_reply.rp_stat);
+#else
                error->re_lb.s1 = (long)(msg->rm_reply.rp_stat);
+#endif
                break;
        }
        switch (error->re_status) {
index b0a6a9ae6969277cc086c5434c7bf1d4250ed94a..b17fe4e63b479a5b00b0fe063c80ea7756b22943 100644 (file)
@@ -150,11 +150,19 @@ xprt_unregister(xprt)
  */
 bool_t
 svc_register(xprt, prog, vers, dispatch, protocol)
+#ifdef __LP64__
+       SVCXPRT *xprt;
+       uint32_t prog;
+       uint32_t vers;
+       void (*dispatch)();
+       int32_t protocol;
+#else
        SVCXPRT *xprt;
        u_long prog;
        u_long vers;
        void (*dispatch)();
        int protocol;
+#endif
 {
        struct svc_callout *prev;
        register struct svc_callout *s;
@@ -186,8 +194,13 @@ pmap_it:
  */
 void
 svc_unregister(prog, vers)
+#ifdef __LP64__
+       uint32_t prog;
+       uint32_t vers;
+#else
        u_long prog;
        u_long vers;
+#endif
 {
        struct svc_callout *prev;
        register struct svc_callout *s;
@@ -347,9 +360,15 @@ svcerr_noprog(xprt)
  */
 void  
 svcerr_progvers(xprt, low_vers, high_vers)
+#ifdef __LP64__
+       register SVCXPRT *xprt; 
+       uint32_t low_vers;
+       uint32_t high_vers;
+#else
        register SVCXPRT *xprt; 
        u_long low_vers;
        u_long high_vers;
+#endif
 {
        struct rpc_msg rply;
 
index 55df0fdafb27f680e891a9f9fb7da321d5041456..ca1270db2a75f584a56cae515a2936869dc74a61 100644 (file)
@@ -171,9 +171,15 @@ typedef struct {
  * Service request
  */
 struct svc_req {
+#ifdef __LP64__
+       unsigned int            rq_prog;        /* service program number */
+       unsigned int            rq_vers;        /* service protocol version */
+       unsigned int            rq_proc;        /* the desired procedure */
+#else
        unsigned long           rq_prog;        /* service program number */
        unsigned long           rq_vers;        /* service protocol version */
        unsigned long           rq_proc;        /* the desired procedure */
+#endif
        struct opaque_auth rq_cred;     /* raw creds from the wire */
        caddr_t         rq_clntcred;    /* read only cooked cred */
        SVCXPRT *rq_xprt;               /* associated transport */
@@ -185,24 +191,32 @@ struct svc_req {
  *
  * svc_register(xprt, prog, vers, dispatch, protocol)
  *     SVCXPRT *xprt;
- *     unsigned long prog;
- *     unsigned long vers;
+ *     u_long prog;
+ *     u_long vers;
  *     void (*dispatch)(...); // fixincludes needs the ..., even in a comment
  *     int protocol;  like TCP or UDP, zero means do not register 
  */
 __BEGIN_DECLS
+#ifdef __LP64__
+extern bool_t  svc_register __P((SVCXPRT *, unsigned int, unsigned int, void (*)(), int));
+#else
 extern bool_t  svc_register __P((SVCXPRT *, unsigned long, unsigned long, void (*)(), int));
+#endif
 __END_DECLS
 
 /*
  * Service un-registration
  *
  * svc_unregister(prog, vers)
- *     unsigned long prog;
- *     unsigned long vers;
+ *     u_long prog;
+ *     u_long vers;
  */
 __BEGIN_DECLS
+#ifdef __LP64__
+extern void    svc_unregister __P((unsigned int, unsigned int));
+#else
 extern void    svc_unregister __P((unsigned long, unsigned long));
+#endif
 __END_DECLS
 
 /*
@@ -259,7 +273,11 @@ 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 *));
+#ifdef __LP64__
+extern void    svcerr_progvers __P((SVCXPRT *, unsigned int, unsigned int));
+#else
 extern void    svcerr_progvers __P((SVCXPRT *, unsigned long, unsigned long));
+#endif
 extern void    svcerr_auth     __P((SVCXPRT *, enum auth_stat));
 extern void    svcerr_noprog   __P((SVCXPRT *));
 extern void    svcerr_systemerr __P((SVCXPRT *));
index e96e505b91e794af6ed4ed9ae9101d2aae0d343d..3412d81df6ae0b9f2484cddb3667fd9d5a06287e 100644 (file)
@@ -83,7 +83,11 @@ _svcauth_unix(rqst, msg)
        register enum auth_stat stat;
        XDR xdrs;
        register struct authunix_parms *aup;
+#ifdef __LP64__
+       int *buf;
+#else
        register long *buf;
+#endif
        struct area {
                struct authunix_parms area_aup;
                char area_machname[MAX_MACHINE_NAME+1];
@@ -98,7 +102,11 @@ _svcauth_unix(rqst, msg)
        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);
+#ifdef __LP64__
+       buf = (int *)XDR_INLINE(&xdrs, auth_len);
+#else
        buf = (long *)XDR_INLINE(&xdrs, auth_len);
+#endif
        if (buf != NULL) {
                aup->aup_time = IXDR_GET_LONG(buf);
                str_len = IXDR_GET_U_LONG(buf);
@@ -109,7 +117,11 @@ _svcauth_unix(rqst, msg)
                bcopy((caddr_t)buf, aup->aup_machname, str_len);
                aup->aup_machname[str_len] = 0;
                str_len = RNDUP(str_len);
+#ifdef __LP64__
+               buf += str_len / sizeof (int);
+#else
                buf += str_len / sizeof (long);
+#endif
                aup->aup_uid = IXDR_GET_LONG(buf);
                aup->aup_gid = IXDR_GET_LONG(buf);
                gid_len = IXDR_GET_U_LONG(buf);
@@ -127,7 +139,8 @@ _svcauth_unix(rqst, msg)
                 */
                if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len) {
                        /* LIBRARY CODE SHOULD NOT PRINT
-                       (void) printf("bad auth_len gid %d str %d auth %d\n", gid_len, 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;
index 22687327ddc149c4163fed9b2efc1e1670ff99bf..3796844273ee89d9d3d2aea2ac50422a3c7054d7 100644 (file)
@@ -89,8 +89,11 @@ registerrpc(prognum, versnum, procnum, progname, inproc, outproc)
 {
        
        if (procnum == NULLPROC) {
-               (void) fprintf(stderr,
-                   "can't reassign procedure number %ld\n", NULLPROC);
+#ifdef __LP64__
+               (void) fprintf(stderr, "can't reassign procedure number %d\n", NULLPROC);
+#else
+               (void) fprintf(stderr, "can't reassign procedure number %ld\n", NULLPROC);
+#endif
                return (-1);
        }
        if (transp == 0) {
@@ -136,7 +139,7 @@ universal(rqstp, transp)
         * enforce "procnum 0 is echo" convention
         */
        if (rqstp->rq_proc == NULLPROC) {
-               if (svc_sendreply(transp, xdr_void, (char *)NULL) == FALSE) {
+               if (svc_sendreply(transp, (xdrproc_t)xdr_void, (char *)NULL) == FALSE) {
                        (void) fprintf(stderr, "xxx\n");
                        exit(1);
                }
@@ -153,7 +156,7 @@ universal(rqstp, transp)
                                return;
                        }
                        outdata = (*(pl->p_progname))(xdrbuf);
-                       if (outdata == NULL && pl->p_outproc != xdr_void)
+                       if (outdata == NULL && pl->p_outproc != (xdrproc_t)xdr_void)
                                /* there was an error */
                                return;
                        if (!svc_sendreply(transp, pl->p_outproc, outdata)) {
index 59303fe07717af8f1df51acebac10277fc4168d4..23c6f65f3b3ab5c2c339c2ad881c10c9bff52970 100644 (file)
@@ -158,7 +158,7 @@ svctcp_create(sock, sendsize, recvsize)
        register SVCXPRT *xprt;
        register struct tcp_rendezvous *r;
        struct sockaddr_in addr;
-       int len = sizeof(struct sockaddr_in);
+       unsigned int len = sizeof(struct sockaddr_in);
 
        if (sock == RPC_ANYSOCK) {
                if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
@@ -266,13 +266,12 @@ rendezvous_request(xprt)
        int sock;
        struct tcp_rendezvous *r;
        struct sockaddr_in addr;
-       int len;
+       unsigned 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 ((sock = accept(xprt->xp_sock, (struct sockaddr *)&addr, &len)) < 0) {
                if (errno == EINTR)
                        goto again;
               return (FALSE);
index 5f836b49be6cff0bded57793bd9062d7b819ef12..3cbd9f4cf2f5f0a37cab0cb6be640f05ecf95190 100644 (file)
@@ -129,7 +129,7 @@ svcudp_bufcreate(sock, sendsz, recvsz)
        register SVCXPRT *xprt;
        register struct svcudp_data *su;
        struct sockaddr_in addr;
-       int len = sizeof(struct sockaddr_in);
+       unsigned int len = sizeof(struct sockaddr_in);
 
        if (sock == RPC_ANYSOCK) {
                if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
@@ -209,8 +209,7 @@ svcudp_recv(xprt, msg)
 
     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));
+       rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), (int) su->su_iosz, 0, (struct sockaddr *)&(xprt->xp_raddr), (unsigned int *)&(xprt->xp_addrlen));
        if (rlen == -1 && errno == EINTR)
                goto again;
        if (rlen < 4*sizeof(u_long))
index 33ae11ca47fa49a6dc0a33ddb9099bdbf21e1827..0fe5adc1c01341898991cc5f4fe8650d9102f0ae 100644 (file)
 #endif
 #include <sys/time.h>
 
+#ifdef __LP64__
+typedef int rpc_int;
+typedef unsigned int rpc_uint;
+#else
+typedef long rpc_int;
+typedef unsigned long rpc_uint;
+#endif
+
 #endif /* !_RPC_TYPES_H */
diff --git a/rpc.subproj/xdr.3 b/rpc.subproj/xdr.3
new file mode 100644 (file)
index 0000000..029eb4f
--- /dev/null
@@ -0,0 +1,829 @@
+.\" @(#)xdr.3n 2.2 88/08/03 4.0 RPCSRC; from 1.16 88/03/14 SMI
+.\" $FreeBSD: src/lib/libc/xdr/xdr.3,v 1.16 2002/12/19 09:40:28 ru Exp $
+.\"
+.Dd February 16, 1988
+.Dt XDR 3
+.Os
+.Sh NAME
+.Nm xdr ,
+.Nm xdr_array ,
+.Nm xdr_bool ,
+.Nm xdr_bytes ,
+.Nm xdr_char ,
+.Nm xdr_destroy ,
+.Nm xdr_double ,
+.Nm xdr_enum ,
+.Nm xdr_float ,
+.Nm xdr_free ,
+.Nm xdr_getpos ,
+.Nm xdr_hyper ,
+.Nm xdr_inline ,
+.Nm xdr_int ,
+.Nm xdr_long ,
+.Nm xdr_longlong_t ,
+.Nm xdrmem_create ,
+.Nm xdr_opaque ,
+.Nm xdr_pointer ,
+.Nm xdrrec_create ,
+.Nm xdrrec_endofrecord ,
+.Nm xdrrec_eof ,
+.Nm xdrrec_skiprecord ,
+.Nm xdr_reference ,
+.Nm xdr_setpos ,
+.Nm xdr_short ,
+.Nm xdrstdio_create ,
+.Nm xdr_string ,
+.Nm xdr_u_char ,
+.Nm xdr_u_hyper ,
+.Nm xdr_u_int ,
+.Nm xdr_u_long ,
+.Nm xdr_u_longlong_t ,
+.Nm xdr_u_short ,
+.Nm xdr_union ,
+.Nm xdr_vector ,
+.Nm xdr_void ,
+.Nm xdr_wrapstring
+.Nd "library routines for external data representation"
+.Sh LIBRARY
+.Lb libc
+.Sh SYNOPSIS
+.In rpc/types.h
+.In rpc/xdr.h
+.Pp
+See
+.Sx DESCRIPTION
+for function declarations.
+.Sh DESCRIPTION
+These routines allow C programmers to describe
+arbitrary data structures in a machine-independent fashion.
+Data for remote procedure calls are transmitted using these
+routines.
+.Pp
+.Bl -tag -width indent -compact
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fo xdr_array
+.Fa "XDR *xdrs"
+.Fa "char **arrp"
+.Fa "u_int *sizep"
+.Fa "u_int maxsize"
+.Fa "u_int elsize"
+.Fa "xdrproc_t elproc"
+.Fc
+.Xc
+.Pp
+A filter primitive that translates between variable-length
+arrays
+and their corresponding external representations.
+The
+.Fa arrp
+argument
+is the address of the pointer to the array, while
+.Fa sizep
+is the address of the element count of the array;
+this element count cannot exceed
+.Fa maxsize .
+The
+.Fa elsize
+argument
+is the
+.Ic sizeof
+each of the array's elements, and
+.Fa elproc
+is an
+.Tn XDR
+filter that translates between
+the array elements' C form, and their external
+representation.
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_bool "XDR *xdrs" "bool_t *bp"
+.Xc
+.Pp
+A filter primitive that translates between booleans (C
+integers)
+and their external representations.
+When encoding data, this
+filter produces values of either one or zero.
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_bytes "XDR *xdrs" "char **sp" "u_int *sizep" "u_int maxsize"
+.Xc
+.Pp
+A filter primitive that translates between counted byte
+strings and their external representations.
+The
+.Fa sp
+argument
+is the address of the string pointer.
+The length of the
+string is located at address
+.Fa sizep ;
+strings cannot be longer than
+.Fa maxsize .
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_char "XDR *xdrs" "char *cp"
+.Xc
+.Pp
+A filter primitive that translates between C characters
+and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+Note: encoded characters are not packed, and occupy 4 bytes
+each.
+For arrays of characters, it is worthwhile to
+consider
+.Fn xdr_bytes ,
+.Fn xdr_opaque
+or
+.Fn xdr_string .
+.Pp
+.It Xo
+.Ft void
+.Xc
+.It Xo
+.Fn xdr_destroy "XDR *xdrs"
+.Xc
+.Pp
+A macro that invokes the destroy routine associated with the
+.Tn XDR
+stream,
+.Fa xdrs .
+Destruction usually involves freeing private data structures
+associated with the stream.
+Using
+.Fa xdrs
+after invoking
+.Fn xdr_destroy
+is undefined.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_double "XDR *xdrs" "double *dp"
+.Xc
+.Pp
+A filter primitive that translates between C
+.Vt double
+precision numbers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_enum "XDR *xdrs" "enum_t *ep"
+.Xc
+.Pp
+A filter primitive that translates between C
+.Vt enum Ns s
+(actually integers) and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_float "XDR *xdrs" "float *fp"
+.Xc
+.Pp
+A filter primitive that translates between C
+.Vt float Ns s
+and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+.It Xo
+.Ft void
+.Xc
+.It Xo
+.Fn xdr_free "xdrproc_t proc" "char *objp"
+.Xc
+.Pp
+Generic freeing routine.
+The first argument is the
+.Tn XDR
+routine for the object being freed.
+The second argument
+is a pointer to the object itself.
+Note: the pointer passed
+to this routine is
+.Em not
+freed, but what it points to
+.Em is
+freed (recursively).
+.Pp
+.It Xo
+.Ft u_int
+.Xc
+.It Xo
+.Fn xdr_getpos "XDR *xdrs"
+.Xc
+.Pp
+A macro that invokes the get\-position routine
+associated with the
+.Tn XDR
+stream,
+.Fa xdrs .
+The routine returns an unsigned integer,
+which indicates the position of the
+.Tn XDR
+byte stream.
+A desirable feature of
+.Tn XDR
+streams is that simple arithmetic works with this number,
+although the
+.Tn XDR
+stream instances need not guarantee this.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_hyper "XDR *xdrs" "quad_t *llp"
+.Xc
+A filter primitive that translates between ANSI C
+.Vt "long long"
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+.It Xo
+.Ft "long *"
+.Xc
+.It Xo
+.Fn xdr_inline "XDR *xdrs" "int len"
+.Xc
+.Pp
+A macro that invokes the in-line routine associated with the
+.Tn XDR
+stream,
+.Fa xdrs .
+The routine returns a pointer
+to a contiguous piece of the stream's buffer;
+.Fa len
+is the byte length of the desired buffer.
+Note: pointer is cast to
+.Vt "long *" .
+.Pp
+Warning:
+.Fn xdr_inline
+may return
+.Dv NULL
+(0)
+if it cannot allocate a contiguous piece of a buffer.
+Therefore the behavior may vary among stream instances;
+it exists for the sake of efficiency.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_int "XDR *xdrs" "int *ip"
+.Xc
+.Pp
+A filter primitive that translates between C integers
+and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_long "XDR *xdrs" "long *lp"
+.Xc
+.Pp
+A filter primitive that translates between C
+.Vt long
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_longlong_t "XDR *xdrs" "quad_t *llp"
+.Xc
+A filter primitive that translates between ANSI C
+.Vt "long long"
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+.It Xo
+.Ft void
+.Xc
+.It Xo
+.Fn xdrmem_create "XDR *xdrs" "char *addr" "u_int size" "enum xdr_op op"
+.Xc
+.Pp
+This routine initializes the
+.Tn XDR
+stream object pointed to by
+.Fa xdrs .
+The stream's data is written to, or read from,
+a chunk of memory at location
+.Fa addr
+whose length is no more than
+.Fa size
+bytes long.
+The
+.Fa op
+argument
+determines the direction of the
+.Tn XDR
+stream
+(either
+.Dv XDR_ENCODE ,
+.Dv XDR_DECODE ,
+or
+.Dv XDR_FREE ) .
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_opaque "XDR *xdrs" "char *cp" "u_int cnt"
+.Xc
+.Pp
+A filter primitive that translates between fixed size opaque
+data
+and its external representation.
+The
+.Fa cp
+argument
+is the address of the opaque object, and
+.Fa cnt
+is its size in bytes.
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_pointer "XDR *xdrs" "char **objpp" "u_int objsize" "xdrproc_t xdrobj"
+.Xc
+.Pp
+Like
+.Fn xdr_reference
+except that it serializes
+.Dv NULL
+pointers, whereas
+.Fn xdr_reference
+does not.
+Thus,
+.Fn xdr_pointer
+can represent
+recursive data structures, such as binary trees or
+linked lists.
+.Pp
+.It Xo
+.Ft void
+.Xc
+.It Xo
+.Fo xdrrec_create
+.Fa "XDR *xdrs"
+.Fa "u_int sendsize"
+.Fa "u_int recvsize"
+.Fa "char *handle"
+.Fa "int \*(lp*readit\*(rp\*(lp\*(rp"
+.Fa "int \*(lp*writeit\*(rp\*(lp\*(rp"
+.Fc
+.Xc
+.Pp
+This routine initializes the
+.Tn XDR
+stream object pointed to by
+.Fa xdrs .
+The stream's data is written to a buffer of size
+.Fa sendsize ;
+a value of zero indicates the system should use a suitable
+default.
+The stream's data is read from a buffer of size
+.Fa recvsize ;
+it too can be set to a suitable default by passing a zero
+value.
+When a stream's output buffer is full,
+.Fn writeit
+is called.
+Similarly, when a stream's input buffer is empty,
+.Fn readit
+is called.
+The behavior of these two routines is similar to
+the
+system calls
+.Xr read 2
+and
+.Xr write 2 ,
+except that
+.Fa handle
+is passed to the former routines as the first argument.
+Note: the
+.Tn XDR
+stream's
+.Fa op
+field must be set by the caller.
+.Pp
+Warning: this
+.Tn XDR
+stream implements an intermediate record stream.
+Therefore there are additional bytes in the stream
+to provide record boundary information.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdrrec_endofrecord "XDR *xdrs" "int sendnow"
+.Xc
+.Pp
+This routine can be invoked only on
+streams created by
+.Fn xdrrec_create .
+The data in the output buffer is marked as a completed
+record,
+and the output buffer is optionally written out if
+.Fa sendnow
+is non-zero.
+This routine returns one if it succeeds, zero
+otherwise.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdrrec_eof "XDR *xdrs"
+.Xc
+.Pp
+This routine can be invoked only on
+streams created by
+.Fn xdrrec_create .
+After consuming the rest of the current record in the stream,
+this routine returns one if the stream has no more input,
+zero otherwise.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdrrec_skiprecord "XDR *xdrs"
+.Xc
+.Pp
+This routine can be invoked only on
+streams created by
+.Fn xdrrec_create .
+It tells the
+.Tn XDR
+implementation that the rest of the current record
+in the stream's input buffer should be discarded.
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_reference "XDR *xdrs" "char **pp" "u_int size" "xdrproc_t proc"
+.Xc
+.Pp
+A primitive that provides pointer chasing within structures.
+The
+.Fa pp
+argument
+is the address of the pointer;
+.Fa size
+is the
+.Ic sizeof
+the structure that
+.Fa *pp
+points to; and
+.Fa proc
+is an
+.Tn XDR
+procedure that filters the structure
+between its C form and its external representation.
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+Warning: this routine does not understand
+.Dv NULL
+pointers.
+Use
+.Fn xdr_pointer
+instead.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_setpos "XDR *xdrs" "u_int pos"
+.Xc
+.Pp
+A macro that invokes the set position routine associated with
+the
+.Tn XDR
+stream
+.Fa xdrs .
+The
+.Fa pos
+argument
+is a position value obtained from
+.Fn xdr_getpos .
+This routine returns one if the
+.Tn XDR
+stream could be repositioned,
+and zero otherwise.
+.Pp
+Warning: it is difficult to reposition some types of
+.Tn XDR
+streams, so this routine may fail with one
+type of stream and succeed with another.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_short "XDR *xdrs" "short *sp"
+.Xc
+.Pp
+A filter primitive that translates between C
+.Vt short
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+.It Li "#ifdef _STDIO_H_"
+.It Li "/* XDR using stdio library */"
+.It Xo
+.Ft void
+.Xc
+.It Xo
+.Fn xdrstdio_create "XDR *xdrs" "FILE *file" "enum xdr_op op"
+.Xc
+.It Li "#endif"
+.Pp
+This routine initializes the
+.Tn XDR
+stream object pointed to by
+.Fa xdrs .
+The
+.Tn XDR
+stream data is written to, or read from, the Standard
+.Tn I/O
+stream
+.Fa file .
+The
+.Fa op
+argument
+determines the direction of the
+.Tn XDR
+stream (either
+.Dv XDR_ENCODE ,
+.Dv XDR_DECODE ,
+or
+.Dv XDR_FREE ) .
+.Pp
+Warning: the destroy routine associated with such
+.Tn XDR
+streams calls
+.Xr fflush 3
+on the
+.Fa file
+stream, but never
+.Xr fclose 3 .
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_string "XDR *xdrs" "char **sp" "u_int maxsize"
+.Xc
+.Pp
+A filter primitive that translates between C strings and
+their
+corresponding external representations.
+Strings cannot be longer than
+.Fa maxsize .
+Note:
+.Fa sp
+is the address of the string's pointer.
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_u_char "XDR *xdrs" "unsigned char *ucp"
+.Xc
+.Pp
+A filter primitive that translates between
+.Vt unsigned
+C characters and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_u_hyper "XDR *xdrs" "u_quad_t *ullp"
+.Xc
+A filter primitive that translates between
+.Vt unsigned
+ANSI C
+.Vt long long
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_u_int "XDR *xdrs" "unsigned *up"
+.Xc
+.Pp
+A filter primitive that translates between C
+.Vt unsigned
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_u_long "XDR *xdrs" "unsigned long *ulp"
+.Xc
+.Pp
+A filter primitive that translates between C
+.Vt "unsigned long"
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_u_longlong_t "XDR *xdrs" "u_quad_t *ullp"
+.Xc
+A filter primitive that translates between
+.Vt unsigned
+ANSI C
+.Vt "long long"
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_u_short "XDR *xdrs" "unsigned short *usp"
+.Xc
+.Pp
+A filter primitive that translates between C
+.Vt "unsigned short"
+integers and their external representations.
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fo xdr_union
+.Fa "XDR *xdrs"
+.Fa "enum_t *dscmp"
+.Fa "char *unp"
+.Fa "const struct xdr_discrim *choices"
+.Fa "xdrproc_t defaultarm"
+.Fc
+.Xc
+.Pp
+A filter primitive that translates between a discriminated C
+.Vt union
+and its corresponding external representation.
+It first
+translates the discriminant of the union located at
+.Fa dscmp .
+This discriminant is always an
+.Vt enum_t .
+Next the union located at
+.Fa unp
+is translated.
+The
+.Fa choices
+argument
+is a pointer to an array of
+.Vt xdr_discrim
+structures.
+Each structure contains an ordered pair of
+.Bq Va value , proc .
+If the union's discriminant is equal to the associated
+.Va value ,
+then the
+.Fn proc
+is called to translate the union.
+The end of the
+.Vt xdr_discrim
+structure array is denoted by a routine of value
+.Dv NULL .
+If the discriminant is not found in the
+.Fa choices
+array, then the
+.Fn defaultarm
+procedure is called (if it is not
+.Dv NULL ) .
+Returns one if it succeeds, zero otherwise.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fo xdr_vector
+.Fa "XDR *xdrs"
+.Fa "char *arrp"
+.Fa "u_int size"
+.Fa "u_int elsize"
+.Fa "xdrproc_t elproc"
+.Fc
+.Xc
+.Pp
+A filter primitive that translates between fixed-length
+arrays
+and their corresponding external representations.
+The
+.Fa arrp
+argument
+is the address of the pointer to the array, while
+.Fa size
+is the element count of the array.
+The
+.Fa elsize
+argument
+is the
+.Ic sizeof
+each of the array's elements, and
+.Fa elproc
+is an
+.Tn XDR
+filter that translates between
+the array elements' C form, and their external
+representation.
+This routine returns one if it succeeds, zero otherwise.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_void void
+.Xc
+.Pp
+This routine always returns one.
+It may be passed to
+.Tn RPC
+routines that require a function argument,
+where nothing is to be done.
+.Pp
+.It Xo
+.Ft int
+.Xc
+.It Xo
+.Fn xdr_wrapstring "XDR *xdrs" "char **sp"
+.Xc
+.Pp
+A primitive that calls
+.Fn xdr_string xdrs sp MAXUN.UNSIGNED ;
+where
+.Dv MAXUN.UNSIGNED
+is the maximum value of an unsigned integer.
+The
+.Fn xdr_wrapstring
+function
+is handy because the
+.Tn RPC
+package passes a maximum of two
+.Tn XDR
+routines as arguments, and
+.Fn xdr_string ,
+one of the most frequently used primitives, requires three.
+Returns one if it succeeds, zero otherwise.
+.El
+.Sh SEE ALSO
+.Xr rpc 3
+.Rs
+.%T "eXternal Data Representation Standard: Protocol Specification"
+.Re
+.Rs
+.%T "eXternal Data Representation: Sun Technical Notes"
+.Re
+.Rs
+.%T "XDR: External Data Representation Standard"
+.%O RFC1014
+.%Q "Sun Microsystems, Inc., USC\-ISI"
+.Re
index d9b60a538999e7e17b68e63800a7fb0b635cff4e..3cf13bb86f0ad53ec72184c567e7b0cc5c1d5807 100644 (file)
@@ -77,14 +77,25 @@ static char *sccsid = "@(#)xdr.c    2.1 88/07/29 4.0 RPCSRC";
 #include <rpc/types.h>
 #include <rpc/xdr.h>
 
+#ifdef __LP64__
+#define xdrlong_t int
+#else
+#define xdrlong_t long
+#endif
+
 typedef quad_t          longlong_t;     /* ANSI long long type */
 typedef u_quad_t        u_longlong_t;   /* ANSI unsigned long long type */
 
 /*
  * constants specific to the xdr "protocol"
  */
+#ifdef __LP64__
+#define XDR_FALSE      ((int) 0)
+#define XDR_TRUE       ((int) 1)
+#else
 #define XDR_FALSE      ((long) 0)
 #define XDR_TRUE       ((long) 1)
+#endif
 #define LASTUNSIGNED   ((u_int) 0-1)
 
 /*
@@ -126,19 +137,19 @@ xdr_int(xdrs, ip)
        XDR *xdrs;
        int *ip;
 {
-       long l;
+       xdrlong_t l;
 
        switch (xdrs->x_op) {
 
        case XDR_ENCODE:
-               l = (long) *ip;
-               return (XDR_PUTLONG(xdrs, &l));
+               l = *ip;
+               return (XDR_PUTLONG(xdrs, (const xdrlong_t *)&l));
 
        case XDR_DECODE:
                if (!XDR_GETLONG(xdrs, &l)) {
                        return (FALSE);
                }
-               *ip = (int) l;
+               *ip = l;
                return (TRUE);
 
        case XDR_FREE:
@@ -156,19 +167,19 @@ xdr_u_int(xdrs, up)
        XDR *xdrs;
        u_int *up;
 {
-       u_long l;
+       xdrlong_t l;
 
        switch (xdrs->x_op) {
 
        case XDR_ENCODE:
-               l = (u_long) *up;
-               return (XDR_PUTLONG(xdrs, (long *)&l));
+               l = *up;
+               return (XDR_PUTLONG(xdrs, (const xdrlong_t *)&l));
 
        case XDR_DECODE:
-               if (!XDR_GETLONG(xdrs, (long *)&l)) {
+               if (!XDR_GETLONG(xdrs, &l)) {
                        return (FALSE);
                }
-               *up = (u_int) l;
+               *up = l;
                return (TRUE);
 
        case XDR_FREE:
@@ -186,7 +197,11 @@ xdr_u_int(xdrs, up)
 bool_t
 xdr_long(xdrs, lp)
        XDR *xdrs;
+#ifdef __LP64__
+       int *lp;
+#else
        long *lp;
+#endif
 {
        switch (xdrs->x_op) {
        case XDR_ENCODE:
@@ -207,13 +222,17 @@ xdr_long(xdrs, lp)
 bool_t
 xdr_u_long(xdrs, ulp)
        XDR *xdrs;
+#ifdef __LP64__
+       unsigned int *ulp;
+#else
        u_long *ulp;
-{
+#endif
+{      
        switch (xdrs->x_op) {
        case XDR_ENCODE:
-               return (XDR_PUTLONG(xdrs, (long *)ulp));
+               return (XDR_PUTLONG(xdrs, (const xdrlong_t *)ulp));
        case XDR_DECODE:
-               return (XDR_GETLONG(xdrs, (long *)ulp));
+               return (XDR_GETLONG(xdrs, (xdrlong_t *)ulp));
        case XDR_FREE:
                return (TRUE);
        }
@@ -231,19 +250,19 @@ xdr_int32_t(xdrs, int32_p)
        XDR *xdrs;
        int32_t *int32_p;
 {
-       long l;
+       xdrlong_t l;
 
        switch (xdrs->x_op) {
 
        case XDR_ENCODE:
-               l = (long) *int32_p;
-               return (XDR_PUTLONG(xdrs, &l));
+               l = *int32_p;
+               return (XDR_PUTLONG(xdrs, (const xdrlong_t *)&l));
 
        case XDR_DECODE:
                if (!XDR_GETLONG(xdrs, &l)) {
                        return (FALSE);
                }
-               *int32_p = (int32_t) l;
+               *int32_p = l;
                return (TRUE);
 
        case XDR_FREE:
@@ -262,19 +281,17 @@ xdr_u_int32_t(xdrs, u_int32_p)
        XDR *xdrs;
        u_int32_t *u_int32_p;
 {
-       u_long l;
+       u_int32_t l;
 
        switch (xdrs->x_op) {
 
        case XDR_ENCODE:
-               l = (u_long) *u_int32_p;
-               return (XDR_PUTLONG(xdrs, (long *)&l));
+               l = *u_int32_p;
+               return (XDR_PUTLONG(xdrs, (xdrlong_t *)&l));
 
        case XDR_DECODE:
-               if (!XDR_GETLONG(xdrs, (long *)&l)) {
-                       return (FALSE);
-               }
-               *u_int32_p = (u_int32_t) l;
+               if (!XDR_GETLONG(xdrs, (xdrlong_t *)&l)) return (FALSE);
+               *u_int32_p = l;
                return (TRUE);
 
        case XDR_FREE:
@@ -293,19 +310,19 @@ xdr_short(xdrs, sp)
        XDR *xdrs;
        short *sp;
 {
-       long l;
+       xdrlong_t l;
 
        switch (xdrs->x_op) {
 
        case XDR_ENCODE:
-               l = (long) *sp;
-               return (XDR_PUTLONG(xdrs, &l));
+               l = *sp;
+               return (XDR_PUTLONG(xdrs, (const xdrlong_t *)&l));
 
        case XDR_DECODE:
                if (!XDR_GETLONG(xdrs, &l)) {
                        return (FALSE);
                }
-               *sp = (short) l;
+               *sp = l;
                return (TRUE);
 
        case XDR_FREE:
@@ -323,19 +340,19 @@ xdr_u_short(xdrs, usp)
        XDR *xdrs;
        u_short *usp;
 {
-       u_long l;
+       xdrlong_t l;
 
        switch (xdrs->x_op) {
 
        case XDR_ENCODE:
-               l = (u_long) *usp;
-               return (XDR_PUTLONG(xdrs, (long *)&l));
+               l = *usp;
+               return (XDR_PUTLONG(xdrs, (const xdrlong_t *)&l));
 
        case XDR_DECODE:
-               if (!XDR_GETLONG(xdrs, (long *)&l)) {
+               if (!XDR_GETLONG(xdrs, &l)) {
                        return (FALSE);
                }
-               *usp = (u_short) l;
+               *usp = l;
                return (TRUE);
 
        case XDR_FREE:
@@ -354,19 +371,19 @@ xdr_int16_t(xdrs, int16_p)
        XDR *xdrs;
        int16_t *int16_p;
 {
-       long l;
+       xdrlong_t l;
 
        switch (xdrs->x_op) {
 
        case XDR_ENCODE:
-               l = (long) *int16_p;
-               return (XDR_PUTLONG(xdrs, &l));
+               l = *int16_p;
+               return (XDR_PUTLONG(xdrs, (const xdrlong_t *)&l));
 
        case XDR_DECODE:
                if (!XDR_GETLONG(xdrs, &l)) {
                        return (FALSE);
                }
-               *int16_p = (int16_t) l;
+               *int16_p = l;
                return (TRUE);
 
        case XDR_FREE:
@@ -384,19 +401,19 @@ xdr_u_int16_t(xdrs, u_int16_p)
        XDR *xdrs;
        u_int16_t *u_int16_p;
 {
-       u_long l;
+       xdrlong_t l;
 
        switch (xdrs->x_op) {
 
        case XDR_ENCODE:
-               l = (u_long) *u_int16_p;
-               return (XDR_PUTLONG(xdrs, (long *)&l));
+               l = *u_int16_p;
+               return (XDR_PUTLONG(xdrs, (const xdrlong_t *)&l));
 
        case XDR_DECODE:
-               if (!XDR_GETLONG(xdrs, (long *)&l)) {
+               if (!XDR_GETLONG(xdrs, &l)) {
                        return (FALSE);
                }
-               *u_int16_p = (u_int16_t) l;
+               *u_int16_p = l;
                return (TRUE);
 
        case XDR_FREE:
@@ -433,7 +450,7 @@ xdr_u_char(xdrs, cp)
        XDR *xdrs;
        u_char *cp;
 {
-       u_int u;
+       u_int32_t u;
 
        u = (*cp);
        if (!xdr_u_int(xdrs, &u)) {
@@ -451,13 +468,13 @@ xdr_bool(xdrs, bp)
        XDR *xdrs;
        bool_t *bp;
 {
-       long lb;
+       xdrlong_t lb;
 
        switch (xdrs->x_op) {
 
        case XDR_ENCODE:
                lb = *bp ? XDR_TRUE : XDR_FALSE;
-               return (XDR_PUTLONG(xdrs, &lb));
+               return (XDR_PUTLONG(xdrs, (const xdrlong_t *)&lb));
 
        case XDR_DECODE:
                if (!XDR_GETLONG(xdrs, &lb)) {
@@ -486,8 +503,8 @@ xdr_enum(xdrs, ep)
        /*
         * enums are treated as ints
         */
-       /* LINTED */ if (sizeof (enum sizecheck) == sizeof (long)) {
-               return (xdr_long(xdrs, (long *)(void *)ep));
+       /* LINTED */ if (sizeof (enum sizecheck) == sizeof (int)) {
+               return (xdr_long(xdrs, (xdrlong_t *)(void *)ep));
        } else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (int)) {
                return (xdr_int(xdrs, (int *)(void *)ep));
        } else /* LINTED */ if (sizeof (enum sizecheck) == sizeof (short)) {
@@ -508,7 +525,7 @@ xdr_opaque(xdrs, cp, cnt)
        caddr_t cp;
        u_int cnt;
 {
-       u_int rndup;
+       u_int32_t rndup;
        static int crud[BYTES_PER_XDR_UNIT];
 
        /*
@@ -562,7 +579,7 @@ xdr_bytes(xdrs, cpp, sizep, maxsize)
        u_int maxsize;
 {
        char *sp = *cpp;  /* sp is the actual string pointer */
-       u_int nodesize;
+       u_int32_t nodesize;
 
        /*
         * first deal with the length since xdr bytes are counted
@@ -686,8 +703,8 @@ xdr_string(xdrs, cpp, maxsize)
        u_int maxsize;
 {
        char *sp = *cpp;  /* sp is the actual string pointer */
-       u_int size;
-       u_int nodesize;
+       u_int32_t size;
+       u_int32_t nodesize;
 
        /*
         * first deal with the length since xdr strings are counted-strings
@@ -770,19 +787,19 @@ xdr_int64_t(xdrs, llp)
        XDR *xdrs;
        int64_t *llp;
 {
-       u_long ul[2];
+       u_int32_t ul[2];
 
        switch (xdrs->x_op) {
        case XDR_ENCODE:
-               ul[0] = (u_long)((u_int64_t)*llp >> 32) & 0xffffffff;
-               ul[1] = (u_long)((u_int64_t)*llp) & 0xffffffff;
-               if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
+               ul[0] = (u_int32_t)((u_int64_t)*llp >> 32) & 0xffffffff;
+               ul[1] = (u_int32_t)((u_int64_t)*llp) & 0xffffffff;
+               if (XDR_PUTLONG(xdrs, (xdrlong_t *)&ul[0]) == FALSE)
                        return (FALSE);
-               return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
+               return (XDR_PUTLONG(xdrs, (xdrlong_t *)&ul[1]));
        case XDR_DECODE:
-               if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
+               if (XDR_GETLONG(xdrs, (xdrlong_t *)&ul[0]) == FALSE)
                        return (FALSE);
-               if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
+               if (XDR_GETLONG(xdrs, (xdrlong_t *)&ul[1]) == FALSE)
                        return (FALSE);
                *llp = (int64_t)
                    (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
@@ -803,19 +820,19 @@ xdr_u_int64_t(xdrs, ullp)
        XDR *xdrs;
        u_int64_t *ullp;
 {
-       u_long ul[2];
+       u_int32_t ul[2];
 
        switch (xdrs->x_op) {
        case XDR_ENCODE:
-               ul[0] = (u_long)(*ullp >> 32) & 0xffffffff;
-               ul[1] = (u_long)(*ullp) & 0xffffffff;
-               if (XDR_PUTLONG(xdrs, (long *)&ul[0]) == FALSE)
+               ul[0] = (u_int32_t)(*ullp >> 32) & 0xffffffff;
+               ul[1] = (u_int32_t)(*ullp) & 0xffffffff;
+               if (XDR_PUTLONG(xdrs, (xdrlong_t *)&ul[0]) == FALSE)
                        return (FALSE);
-               return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
+               return (XDR_PUTLONG(xdrs, (xdrlong_t *)&ul[1]));
        case XDR_DECODE:
-               if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
+               if (XDR_GETLONG(xdrs, (xdrlong_t *)&ul[0]) == FALSE)
                        return (FALSE);
-               if (XDR_GETLONG(xdrs, (long *)&ul[1]) == FALSE)
+               if (XDR_GETLONG(xdrs, (xdrlong_t *)&ul[1]) == FALSE)
                        return (FALSE);
                *ullp = (u_int64_t)
                    (((u_int64_t)ul[0] << 32) | ((u_int64_t)ul[1]));
@@ -836,7 +853,6 @@ xdr_hyper(xdrs, llp)
        XDR *xdrs;
        longlong_t *llp;
 {
-
        /*
         * Don't bother open-coding this; it's a fair amount of code.  Just
         * call xdr_int64_t().
@@ -853,7 +869,6 @@ xdr_u_hyper(xdrs, ullp)
        XDR *xdrs;
        u_longlong_t *ullp;
 {
-
        /*
         * Don't bother open-coding this; it's a fair amount of code.  Just
         * call xdr_u_int64_t().
@@ -870,7 +885,6 @@ xdr_longlong_t(xdrs, llp)
        XDR *xdrs;
        longlong_t *llp;
 {
-
        /*
         * Don't bother open-coding this; it's a fair amount of code.  Just
         * call xdr_int64_t().
index 24da1af3e956231a97bca8ddbdb16ba738eb102c..9492ccfbbf5eacd3407f9ff50cdc1bc4d6d206ee 100644 (file)
@@ -121,10 +121,17 @@ enum xdr_op {
 typedef struct __rpc_xdr {
        enum xdr_op     x_op;           /* operation; fast additional param */
        const struct xdr_ops {
+#ifdef __LP64__
+               /* get an int from underlying stream */
+               bool_t  (*x_getlong)(struct __rpc_xdr *, int *);
+               /* put an int to " */
+               bool_t  (*x_putlong)(struct __rpc_xdr *, const int *);
+#else
                /* get a long from underlying stream */
                bool_t  (*x_getlong)(struct __rpc_xdr *, long *);
                /* put a long to " */
                bool_t  (*x_putlong)(struct __rpc_xdr *, const long *);
+#endif
                /* get some bytes from " */
                bool_t  (*x_getbytes)(struct __rpc_xdr *, char *, unsigned int);
                /* put some bytes to " */
@@ -181,25 +188,48 @@ typedef   bool_t (*xdrproc_t)(XDR *, ...);
 #define xdr_putlong(xdrs, longp)                       \
        (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
 
+
+#ifdef __LP64__
 static __inline int
 xdr_getint32(XDR *xdrs, int32_t *ip)
 {
-       long l;
+       int32_t l;
 
        if (!xdr_getlong(xdrs, &l))
                return (FALSE);
-       *ip = (int32_t)l;
+       *ip = l;
        return (TRUE);
 }
 
 static __inline int
 xdr_putint32(XDR *xdrs, int32_t *ip)
 {
-       long l;
+       int32_t l;
 
-       l = (long)*ip;
+       l = *ip;
        return xdr_putlong(xdrs, &l);
 }
+#else
+static __inline int
+xdr_getint32(XDR *xdrs, int32_t *ip)
+{
+       int32_t l;
+
+       if (!xdr_getlong(xdrs, (long *)&l))
+               return (FALSE);
+       *ip = l;
+       return (TRUE);
+}
+
+static __inline int
+xdr_putint32(XDR *xdrs, int32_t *ip)
+{
+       int32_t l;
+
+       l = *ip;
+       return xdr_putlong(xdrs, (long *)&l);
+}
+#endif
 
 #define XDR_GETINT32(xdrs, int32p)     xdr_getint32(xdrs, int32p)
 #define XDR_PUTINT32(xdrs, int32p)     xdr_putint32(xdrs, int32p)
@@ -287,12 +317,21 @@ struct xdr_discrim {
 #define IXDR_GET_U_INT32(buf)          ((u_int32_t)IXDR_GET_INT32(buf))
 #define IXDR_PUT_U_INT32(buf, v)       IXDR_PUT_INT32((buf), ((int32_t)(v)))
 
+#ifdef __LP64__
+#define IXDR_GET_LONG(buf)             (ntohl((u_int32_t)*(buf)++))
+#define IXDR_PUT_LONG(buf, v)          (*(buf)++ = htonl((u_int32_t)v))
+#else
 #define IXDR_GET_LONG(buf)             ((long)ntohl((u_int32_t)*(buf)++))
 #define IXDR_PUT_LONG(buf, v)          (*(buf)++ =(int32_t)htonl((u_int32_t)v))
+#endif
 
 #define IXDR_GET_BOOL(buf)             ((bool_t)IXDR_GET_LONG(buf))
 #define IXDR_GET_ENUM(buf, t)          ((t)IXDR_GET_LONG(buf))
+#ifdef __LP64__
+#define IXDR_GET_U_LONG(buf)           ((unsigned int)IXDR_GET_LONG(buf))
+#else
 #define IXDR_GET_U_LONG(buf)           ((unsigned long)IXDR_GET_LONG(buf))
+#endif
 #define IXDR_GET_SHORT(buf)            ((short)IXDR_GET_LONG(buf))
 #define IXDR_GET_U_SHORT(buf)          ((unsigned short)IXDR_GET_LONG(buf))
 
@@ -309,8 +348,13 @@ __BEGIN_DECLS
 extern bool_t  xdr_void(void);
 extern bool_t  xdr_int(XDR *, int *);
 extern bool_t  xdr_u_int(XDR *, unsigned int *);
+#ifdef __LP64__
+extern bool_t  xdr_long(XDR *, int *);
+extern bool_t  xdr_u_long(XDR *, unsigned int *);
+#else
 extern bool_t  xdr_long(XDR *, long *);
 extern bool_t  xdr_u_long(XDR *, unsigned long *);
+#endif
 extern bool_t  xdr_short(XDR *, short *);
 extern bool_t  xdr_u_short(XDR *, unsigned short *);
 extern bool_t  xdr_int16_t(XDR *, int16_t *);
index ed2a65ab44a338372b85e878405b21ade1c18fbb..fc4dc82b8af860731451ee589d1fd8812723dfab 100644 (file)
@@ -71,6 +71,7 @@ static char *sccsid = "@(#)xdr_mem.c  2.1 88/07/29 4.0 RPCSRC";
  */
 
 #include <sys/types.h>
+#include <stddef.h>
 
 #include <netinet/in.h>
 
@@ -79,11 +80,17 @@ static char *sccsid = "@(#)xdr_mem.c        2.1 88/07/29 4.0 RPCSRC";
 #include <rpc/types.h>
 #include <rpc/xdr.h>
 
+#ifdef __LP64__
+#define xdrlong_t int
+#else
+#define xdrlong_t long
+#endif
+
 static void xdrmem_destroy(XDR *);
-static bool_t xdrmem_getlong_aligned(XDR *, long *);
-static bool_t xdrmem_putlong_aligned(XDR *, const long *);
-static bool_t xdrmem_getlong_unaligned(XDR *, long *);
-static bool_t xdrmem_putlong_unaligned(XDR *, const long *);
+static bool_t xdrmem_getlong_aligned(XDR *, xdrlong_t *);
+static bool_t xdrmem_putlong_aligned(XDR *, const xdrlong_t *);
+static bool_t xdrmem_getlong_unaligned(XDR *, xdrlong_t *);
+static bool_t xdrmem_putlong_unaligned(XDR *, const xdrlong_t *);
 static bool_t xdrmem_getbytes(XDR *, char *, u_int);
 static bool_t xdrmem_putbytes(XDR *, const char *, u_int);
 /* XXX: w/64-bit pointers, u_int not enough! */
@@ -125,7 +132,6 @@ xdrmem_create(xdrs, addr, size, op)
        u_int size;
        enum xdr_op op;
 {
-
        xdrs->x_op = op;
        xdrs->x_ops = ((unsigned long)addr & (sizeof(int32_t) - 1))
            ? &xdrmem_ops_unaligned : &xdrmem_ops_aligned;
@@ -138,15 +144,13 @@ static void
 xdrmem_destroy(xdrs)
        XDR *xdrs;
 {
-
 }
 
 static bool_t
 xdrmem_getlong_aligned(xdrs, lp)
        XDR *xdrs;
-       long *lp;
+       xdrlong_t *lp;
 {
-
        if (xdrs->x_handy < sizeof(int32_t))
                return (FALSE);
        xdrs->x_handy -= sizeof(int32_t);
@@ -158,9 +162,8 @@ xdrmem_getlong_aligned(xdrs, lp)
 static bool_t
 xdrmem_putlong_aligned(xdrs, lp)
        XDR *xdrs;
-       const long *lp;
+       const xdrlong_t *lp;
 {
-
        if (xdrs->x_handy < sizeof(int32_t))
                return (FALSE);
        xdrs->x_handy -= sizeof(int32_t);
@@ -172,7 +175,7 @@ xdrmem_putlong_aligned(xdrs, lp)
 static bool_t
 xdrmem_getlong_unaligned(xdrs, lp)
        XDR *xdrs;
-       long *lp;
+       xdrlong_t *lp;
 {
        u_int32_t l;
 
@@ -188,7 +191,7 @@ xdrmem_getlong_unaligned(xdrs, lp)
 static bool_t
 xdrmem_putlong_unaligned(xdrs, lp)
        XDR *xdrs;
-       const long *lp;
+       const xdrlong_t *lp;
 {
        u_int32_t l;
 
@@ -207,7 +210,6 @@ xdrmem_getbytes(xdrs, addr, len)
        char *addr;
        u_int len;
 {
-
        if (xdrs->x_handy < len)
                return (FALSE);
        xdrs->x_handy -= len;
@@ -222,7 +224,6 @@ xdrmem_putbytes(xdrs, addr, len)
        const char *addr;
        u_int len;
 {
-
        if (xdrs->x_handy < len)
                return (FALSE);
        xdrs->x_handy -= len;
@@ -235,9 +236,16 @@ static u_int
 xdrmem_getpos(xdrs)
        XDR *xdrs;
 {
+       ptrdiff_t delta;
+       u_int val;
 
-       /* XXX w/64-bit pointers, u_int not enough! */
-       return (u_int)((u_long)xdrs->x_private - (u_long)xdrs->x_base);
+       delta = xdrs->x_private - (void *)(xdrs->x_base);
+#ifdef __LP64__
+       if (delta > UINT32_MAX) return -1;
+#endif
+       
+       val = delta;
+       return val;
 }
 
 static bool_t
@@ -245,13 +253,18 @@ xdrmem_setpos(xdrs, pos)
        XDR *xdrs;
        u_int pos;
 {
+       ptrdiff_t delta;
        char *newaddr = xdrs->x_base + pos;
        char *lastaddr = (char *)xdrs->x_private + xdrs->x_handy;
 
        if (newaddr > lastaddr)
                return (FALSE);
        xdrs->x_private = newaddr;
-       xdrs->x_handy = (u_int)(lastaddr - newaddr); /* XXX sizeof(u_int) <? sizeof(ptrdiff_t) */
+       delta = lastaddr - newaddr;
+#ifdef __LP64__
+       if (delta > UINT32_MAX) return (FALSE);
+#endif
+       xdrs->x_handy = delta;
        return (TRUE);
 }
 
@@ -276,6 +289,5 @@ xdrmem_inline_unaligned(xdrs, len)
        XDR *xdrs;
        u_int len;
 {
-
        return (0);
 }
index 844c327673f03b0b1ce2edd3860981e3caee53f9..77fffecf074483f4d8c5f076752aa8bb3c1354f6 100644 (file)
@@ -71,7 +71,7 @@ static char *sccsid = "@(#)xdr_rec.c  2.2 88/08/01 4.0 RPCSRC";
  * 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
+ * is in network byte order.  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.
@@ -85,6 +85,7 @@ static char *sccsid = "@(#)xdr_rec.c  2.2 88/08/01 4.0 RPCSRC";
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include <rpc/types.h>
 #include <rpc/xdr.h>
@@ -92,8 +93,14 @@ static char *sccsid = "@(#)xdr_rec.c 2.2 88/08/01 4.0 RPCSRC";
 #include <rpc/svc.h>
 #include <rpc/clnt.h>
 
+#ifdef __LP64__
+static bool_t  xdrrec_getlong(XDR *, int *);
+static bool_t  xdrrec_putlong(XDR *, const int *);
+#else
 static bool_t  xdrrec_getlong(XDR *, long *);
 static bool_t  xdrrec_putlong(XDR *, const long *);
+#endif
+
 static bool_t  xdrrec_getbytes(XDR *, char *, u_int);
 
 static bool_t  xdrrec_putbytes(XDR *, const char *, u_int);
@@ -102,6 +109,8 @@ static bool_t       xdrrec_setpos(XDR *, u_int);
 static int32_t *xdrrec_inline(XDR *, u_int);
 static void    xdrrec_destroy(XDR *);
 
+bool_t __xdrrec_getrec(XDR *, enum xprt_stat *, bool_t);
+
 static const struct  xdr_ops xdrrec_ops = {
        xdrrec_getlong,
        xdrrec_putlong,
@@ -116,7 +125,7 @@ static const struct  xdr_ops xdrrec_ops = {
 /*
  * A record is composed of one or more record fragments.
  * A record fragment is a four-byte header followed by zero to
- * 2**32-1 bytes.  The header is treated as a long unsigned and is
+ * 2**32-1 bytes.  The header is treated as an unsigned 32-bit integer 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,
@@ -129,7 +138,7 @@ static const struct  xdr_ops xdrrec_ops = {
 #define LAST_FRAG ((u_int32_t)(1 << 31))
 
 typedef struct rec_strm {
-       char *tcp_handle;
+       void *tcp_handle;
        /*
         * out-goung bits
         */
@@ -143,11 +152,11 @@ typedef struct rec_strm {
         * in-coming bits
         */
        int (*readit)(void *, void *, int);
-       u_long in_size; /* fixed size of the input buffer */
+       size_t in_size; /* fixed size of the input buffer */
        char *in_base;
        char *in_finger;        /* location of next byte to be had */
        char *in_boundry;       /* can read up to this location */
-       long fbtbc;             /* fragment bytes to be consumed */
+       int fbtbc;              /* fragment bytes to be consumed */
        bool_t last_frag;
        u_int sendsize;
        u_int recvsize;
@@ -167,7 +176,7 @@ static bool_t       flush_out(RECSTREAM *, bool_t);
 static bool_t  fill_input_buf(RECSTREAM *);
 static bool_t  get_input_bytes(RECSTREAM *, char *, int);
 static bool_t  set_input_fragment(RECSTREAM *);
-static bool_t  skip_input_bytes(RECSTREAM *, long);
+static bool_t  skip_input_bytes(RECSTREAM *, int);
 static bool_t  realloc_stream(RECSTREAM *, int);
 
 
@@ -251,48 +260,58 @@ xdrrec_create(xdrs, sendsize, recvsize, tcp_handle, readit, writeit)
 static bool_t
 xdrrec_getlong(xdrs, lp)
        XDR *xdrs;
+#ifdef __LP64__
+       int *lp;
+#else
        long *lp;
+#endif
 {
        RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
        int32_t *buflp = (int32_t *)(void *)(rstrm->in_finger);
        int32_t mylong;
 
        /* first try the inline, fast case */
-       if ((rstrm->fbtbc >= sizeof(int32_t)) &&
-               (((long)rstrm->in_boundry - (long)buflp) >= sizeof(int32_t))) {
-               *lp = (long)ntohl((u_int32_t)(*buflp));
+       if ((rstrm->fbtbc >= sizeof(int32_t)) && ((rstrm->in_boundry - (char *)buflp) >= sizeof(int32_t)))
+       {
+               *lp = ntohl(*buflp);
                rstrm->fbtbc -= sizeof(int32_t);
                rstrm->in_finger += sizeof(int32_t);
-       } else {
-               if (! xdrrec_getbytes(xdrs, (char *)(void *)&mylong,
-                   sizeof(int32_t)))
-                       return (FALSE);
-               *lp = (long)ntohl((u_int32_t)mylong);
        }
+       else
+       {
+               if (! xdrrec_getbytes(xdrs, (char *)(void *)&mylong, sizeof(int32_t))) return (FALSE);
+               *lp = ntohl(mylong);
+       }
+
        return (TRUE);
 }
 
 static bool_t
 xdrrec_putlong(xdrs, lp)
        XDR *xdrs;
+#ifdef __LP64__
+       const int *lp;
+#else
        const long *lp;
+#endif
 {
        RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
        int32_t *dest_lp = ((int32_t *)(void *)(rstrm->out_finger));
 
-       if ((rstrm->out_finger += sizeof(int32_t)) > rstrm->out_boundry) {
+       if ((rstrm->out_finger += sizeof(int32_t)) > rstrm->out_boundry)
+       {
                /*
                 * this case should almost never happen so the code is
                 * inefficient
                 */
                rstrm->out_finger -= sizeof(int32_t);
                rstrm->frag_sent = TRUE;
-               if (! flush_out(rstrm, FALSE))
-                       return (FALSE);
+               if (! flush_out(rstrm, FALSE)) return (FALSE);
                dest_lp = ((int32_t *)(void *)(rstrm->out_finger));
                rstrm->out_finger += sizeof(int32_t);
        }
-       *dest_lp = (int32_t)htonl((u_int32_t)(*lp));
+
+       *dest_lp = htonl(*lp);
        return (TRUE);
 }
 
@@ -334,8 +353,7 @@ xdrrec_putbytes(xdrs, addr, len)
        size_t current;
 
        while (len > 0) {
-               current = (size_t)((u_long)rstrm->out_boundry -
-                   (u_long)rstrm->out_finger);
+               current = (size_t)(rstrm->out_boundry - rstrm->out_finger);
                current = (len < current) ? len : current;
                memmove(rstrm->out_finger, addr, current);
                rstrm->out_finger += current;
@@ -356,8 +374,13 @@ xdrrec_getpos(xdrs)
 {
        RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private;
        off_t pos;
+       int hfd;
+
+       /* tcp_handle is in actual fact just a file descriptor */
+       hfd = 0;
+       memcpy(&hfd, rstrm->tcp_handle, sizeof(hfd));
 
-       pos = lseek((int)(u_long)rstrm->tcp_handle, (off_t)0, 1);
+       pos = lseek(hfd, 0, 1);
        if (pos != -1)
                switch (xdrs->x_op) {
 
@@ -533,17 +556,15 @@ xdrrec_endofrecord(xdrs, sendnow)
        bool_t sendnow;
 {
        RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
-       u_long len;  /* fragment length */
+       unsigned int len;  /* fragment length */
 
        if (sendnow || rstrm->frag_sent ||
-               ((u_long)rstrm->out_finger + sizeof(u_int32_t) >=
-               (u_long)rstrm->out_boundry)) {
+               (rstrm->out_finger + sizeof(u_int32_t) >= 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_int32_t);
-       *(rstrm->frag_header) = htonl((u_int32_t)len | LAST_FRAG);
+       len = rstrm->out_finger - (char *)(rstrm->frag_header) - sizeof(u_int32_t);
+       *(rstrm->frag_header) = htonl(len | LAST_FRAG);
        rstrm->frag_header = (u_int32_t *)(void *)rstrm->out_finger;
        rstrm->out_finger += sizeof(u_int32_t);
        return (TRUE);
@@ -653,14 +674,11 @@ flush_out(rstrm, eor)
        bool_t eor;
 {
        u_int32_t eormask = (eor == TRUE) ? LAST_FRAG : 0;
-       u_int32_t len = (u_int32_t)((u_long)(rstrm->out_finger) - 
-               (u_long)(rstrm->frag_header) - sizeof(u_int32_t));
+       u_int32_t len = rstrm->out_finger - (char *)(rstrm->frag_header) - sizeof(u_int32_t);
 
        *(rstrm->frag_header) = htonl(len | eormask);
-       len = (u_int32_t)((u_long)(rstrm->out_finger) - 
-           (u_long)(rstrm->out_base));
-       if ((*(rstrm->writeit))(rstrm->tcp_handle, rstrm->out_base, (int)len)
-               != (int)len)
+       len = rstrm->out_finger - rstrm->out_base;
+       if ((*(rstrm->writeit))(rstrm->tcp_handle, rstrm->out_base, len) != len)
                return (FALSE);
        rstrm->frag_header = (u_int32_t *)(void *)rstrm->out_base;
        rstrm->out_finger = (char *)rstrm->out_base + sizeof(u_int32_t);
@@ -679,9 +697,9 @@ fill_input_buf(rstrm)
                return FALSE;
 
        where = rstrm->in_base;
-       i = (u_int32_t)((u_long)rstrm->in_boundry % BYTES_PER_XDR_UNIT);
+       i = (size_t)(rstrm->in_boundry) % BYTES_PER_XDR_UNIT;
        where += i;
-       len = (u_int32_t)(rstrm->in_size - i);
+       len = rstrm->in_size - i;
        if ((len = (*(rstrm->readit))(rstrm->tcp_handle, where, len)) == -1)
                return (FALSE);
        rstrm->in_finger = where;
@@ -707,8 +725,7 @@ get_input_bytes(rstrm, addr, len)
        }
 
        while (len > 0) {
-               current = (size_t)((long)rstrm->in_boundry -
-                   (long)rstrm->in_finger);
+               current = (size_t)(rstrm->in_boundry - rstrm->in_finger);
                if (current == 0) {
                        if (! fill_input_buf(rstrm))
                                return (FALSE);
@@ -752,19 +769,18 @@ set_input_fragment(rstrm)
 static bool_t  /* consumes input bytes; knows nothing about records! */
 skip_input_bytes(rstrm, cnt)
        RECSTREAM *rstrm;
-       long cnt;
+       int cnt;
 {
        u_int32_t current;
 
        while (cnt > 0) {
-               current = (size_t)((long)rstrm->in_boundry - 
-                   (long)rstrm->in_finger);
+               current = (size_t)(rstrm->in_boundry - rstrm->in_finger);
                if (current == 0) {
                        if (! fill_input_buf(rstrm))
                                return (FALSE);
                        continue;
                }
-               current = (u_int32_t)((cnt < current) ? cnt : current);
+               current = (cnt < current) ? cnt : current;
                rstrm->in_finger += current;
                cnt -= current;
        }
@@ -789,7 +805,7 @@ realloc_stream(rstrm, size)
        RECSTREAM *rstrm;
        int size;
 {
-       long diff;
+       int diff;
        char *buf;
 
        if (size > rstrm->recvsize) {
index a96c1e87fefb0902559c2d78c409708555184cbb..318a5b82da21fe1737a464cc75b6f7e2057d60eb 100644 (file)
 static bool_t
 x_putlong(xdrs, longp)
        XDR *xdrs;
+#ifdef __LP64__
+       int *longp;
+#else
        long *longp;
+#endif
 {
        xdrs->x_handy += BYTES_PER_XDR_UNIT;
        return (TRUE);
@@ -109,7 +113,7 @@ x_inline(xdrs, len)
        XDR *xdrs;
        u_int len;
 {
-       long llen;
+       size_t llen;
 
        if (len == 0) {
                return (NULL);
@@ -120,7 +124,7 @@ x_inline(xdrs, len)
 
        llen = len;
        
-       if (llen < xdrs->x_base) {
+       if (llen < (size_t)xdrs->x_base) {
                /* x_private was already allocated */
                xdrs->x_handy += llen;
                return ((int32_t *) xdrs->x_private);
@@ -158,7 +162,11 @@ x_destroy(xdrs)
        return;
 }
 
+#ifdef __LP64__
+unsigned int
+#else
 unsigned long
+#endif
 xdr_sizeof(func, data)
        xdrproc_t func;
        void *data;
@@ -167,7 +175,11 @@ xdr_sizeof(func, data)
        struct xdr_ops ops;
        bool_t stat;
        /* to stop ANSI-C compiler from complaining */
+#ifdef __LP64__
+       typedef  bool_t (* dummyfunc1)(XDR *, int *);
+#else
        typedef  bool_t (* dummyfunc1)(XDR *, long *);
+#endif
        typedef  bool_t (* dummyfunc2)(XDR *, caddr_t, u_int);
 
        ops.x_putlong = x_putlong;
index ec955bc32574f326e4e3775da3dba80d4b28c49f..2bdc4af7b436ffe926a53b5e8b0edf7c57f7016f 100644 (file)
@@ -76,8 +76,13 @@ static char *sccsid = "@(#)xdr_stdio.c       2.1 88/07/29 4.0 RPCSRC";
 #include <rpc/xdr.h>
 
 static void xdrstdio_destroy(XDR *);
+#ifdef __LP64__
+static bool_t xdrstdio_getlong(XDR *, int *);
+static bool_t xdrstdio_putlong(XDR *, const int *);
+#else
 static bool_t xdrstdio_getlong(XDR *, long *);
 static bool_t xdrstdio_putlong(XDR *, const long *);
+#endif
 static bool_t xdrstdio_getbytes(XDR *, char *, u_int);
 static bool_t xdrstdio_putbytes(XDR *, const char *, u_int);
 static u_int xdrstdio_getpos(XDR *);
@@ -109,7 +114,6 @@ xdrstdio_create(xdrs, file, op)
        FILE *file;
        enum xdr_op op;
 {
-
        xdrs->x_op = op;
        xdrs->x_ops = &xdrstdio_ops;
        xdrs->x_private = file;
@@ -126,31 +130,38 @@ xdrstdio_destroy(xdrs)
        XDR *xdrs;
 {
        (void)fflush((FILE *)xdrs->x_private);
-               /* XXX: should we close the file ?? */
+       /* XXX: should we close the file ?? */
 }
 
 static bool_t
 xdrstdio_getlong(xdrs, lp)
        XDR *xdrs;
+#ifdef __LP64__
+       int *lp;
+#else
        long *lp;
+#endif
 {
        u_int32_t temp;
 
        if (fread(&temp, sizeof(int32_t), 1, (FILE *)xdrs->x_private) != 1)
                return (FALSE);
-       *lp = (long)ntohl(temp);
+       *lp = ntohl(temp);
        return (TRUE);
 }
 
 static bool_t
 xdrstdio_putlong(xdrs, lp)
        XDR *xdrs;
+#ifdef __LP64__
+       const int *lp;
+#else
        const long *lp;
+#endif
 {
-       int32_t mycopy = htonl((u_int32_t)*lp);
+       int32_t mycopy = htonl(*lp);
 
-       if (fwrite(&mycopy, sizeof(int32_t), 1, (FILE *)xdrs->x_private) != 1)
-               return (FALSE);
+       if (fwrite(&mycopy, sizeof(int32_t), 1, (FILE *)xdrs->x_private) != 1) return (FALSE);
        return (TRUE);
 }
 
@@ -160,9 +171,9 @@ xdrstdio_getbytes(xdrs, addr, len)
        char *addr;
        u_int len;
 {
+       size_t flen = len;
 
-       if ((len != 0) && (fread(addr, (size_t)len, 1, (FILE *)xdrs->x_private) != 1))
-               return (FALSE);
+       if ((len != 0) && (fread(addr, flen, 1, (FILE *)xdrs->x_private) != 1)) return (FALSE);
        return (TRUE);
 }
 
@@ -172,29 +183,38 @@ xdrstdio_putbytes(xdrs, addr, len)
        const char *addr;
        u_int len;
 {
+       size_t flen = len;
 
-       if ((len != 0) && (fwrite(addr, (size_t)len, 1,
-           (FILE *)xdrs->x_private) != 1))
-               return (FALSE);
+       if ((len != 0) && (fwrite(addr, flen, 1, (FILE *)xdrs->x_private) != 1)) return (FALSE);
        return (TRUE);
 }
 
+/* This only works if file offsets are <= UINT32_MAX */
 static u_int
 xdrstdio_getpos(xdrs)
        XDR *xdrs;
 {
+       long offset;
+       u_int val;
 
-       return ((u_int) ftell((FILE *)xdrs->x_private));
+       offset = ftell((FILE *)xdrs->x_private);
+#ifdef __LP64__
+       if (offset > UINT32_MAX) return -1;
+#endif
+       val = offset;
+       return val;
 }
 
+/* This only works if file offsets are <= UINT32_MAX */
 static bool_t
 xdrstdio_setpos(xdrs, pos) 
        XDR *xdrs;
        u_int pos;
 { 
+       long offset;
 
-       return ((fseek((FILE *)xdrs->x_private, (long)pos, 0) < 0) ?
-               FALSE : TRUE);
+       offset = pos;
+       return ((fseek((FILE *)xdrs->x_private, offset, 0) < 0) ? FALSE : TRUE);
 }
 
 /* ARGSUSED */
index d5e61ec23ad9433826dd151a8977846122f8af8a..d1c33e53021ba1b1805f43a6501db9004ad96fee 100644 (file)
@@ -119,3 +119,4 @@ install-man-page:
        $(LN) -f "$(DSTROOT)/usr/share/man/man3/rcmd.3" "$(DSTROOT)/usr/share/man/man3/ruserok.3"
        mkdir -p "$(DSTROOT)/usr/share/man/man5"
        install -c -m 644 hosts.equiv.5 "$(DSTROOT)/usr/share/man/man5"
+       $(LN) -f "$(DSTROOT)/usr/share/man/man5//hosts.equiv.5" "$(DSTROOT)/usr/share/man/man5/.rhosts.5"
index 7b61caaab239a89d38a9b81f9d759e779d36c2c6..1d8f0c66ff2b8cacc75c40b44ca2bba8288ace2f 100644 (file)
@@ -1,5 +1,6 @@
 AFTER_POSTINSTALL += install-man-page
 OTHER_CFLAGS = \
+       -D__DARWIN_NON_CANCELABLE=1 \
        -DINET6=1 
 
 # for building 64-bit
index c96e48f604e132eacfa84e6352ed2b2e5f0ab3c9..b11dc7669ac20c813e895f2511ea1ce475ba796b 100755 (executable)
@@ -167,7 +167,6 @@ Per-user trusted host-user pairs list
 .Xr rcmd 3 ,
 .Xr ruserok 3 ,
 .Xr netgroup 5
-.Re
 .Sh HISTORY
 The
 .Nm .rhosts
index 976ef2ff0b75085e50d6dc5c791984cb7ac4599c..99894a49a42a5378444b00c0c14ecfa5923e0581 100644 (file)
  * 
  * @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 */
-           )
+putpwpasswd(char *login, char *old_passwd, char *new_passwd)
 {
-       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);
-}      
-
+       return 0;
+}
index 53e79f376eb37c8bdbc4d064f8bfe7f1c9f52ec3..ce31e7a9fb3a4d573fe4536403ad50b0b4c4ee10 100644 (file)
  * 
  * @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.
+ *
+ *     @(#)fstab.c     8.1 (Berkeley) 6/4/93
+ */
 
 #include <sys/types.h>
 
@@ -30,6 +38,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <utmp.h>
+#include <utmpx.h>
 
 #define        NCACHE  64                      /* power of 2 */
 #define        MASK    (NCACHE - 1)            /* bits to store with */
@@ -41,7 +50,7 @@ user_from_uid(uid, nouser)
 {
        static struct ncache {
                uid_t   uid;
-               char    name[UT_NAMESIZE + 1];
+               char    name[_UTX_USERSIZE + 1];
        } *c_uid[NCACHE];
        static int pwopen;
        static char nbuf[15];           /* 32 bits == 10 digits */
@@ -67,8 +76,8 @@ err:
                                goto err;
                }
                (*cp)->uid = uid;
-               (void)strncpy((*cp)->name, pw->pw_name, UT_NAMESIZE);
-               (*cp)->name[UT_NAMESIZE] = '\0';
+               (void)strncpy((*cp)->name, pw->pw_name, _UTX_USERSIZE);
+               (*cp)->name[_UTX_USERSIZE] = '\0';
        }
        return ((*cp)->name);
 }
@@ -80,7 +89,7 @@ group_from_gid(gid, nogroup)
 {
        static struct ncache {
                gid_t   gid;
-               char    name[UT_NAMESIZE + 1];
+               char    name[_UTX_USERSIZE + 1];
        } *c_gid[NCACHE];
        static int gropen;
        static char nbuf[15];           /* 32 bits == 10 digits */
@@ -106,8 +115,8 @@ err:
                                goto err;
                }
                (*cp)->gid = gid;
-               (void)strncpy((*cp)->name, gr->gr_name, UT_NAMESIZE);
-               (*cp)->name[UT_NAMESIZE] = '\0';
+               (void)strncpy((*cp)->name, gr->gr_name, _UTX_USERSIZE);
+               (*cp)->name[_UTX_USERSIZE] = '\0';
        }
        return ((*cp)->name);
 }
index 8472938e246ef5b455ed7281c643d5d4deaae092..02c497b21d822fc033d33f4df278ab46044884cf 100644 (file)
@@ -66,9 +66,7 @@ static char sccsid[] = "@(#)rcmd.c    8.3 (Berkeley) 3/26/94";
 #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>
@@ -79,6 +77,7 @@ static char sccsid[] = "@(#)rcmd.c    8.3 (Berkeley) 3/26/94";
 #include <stdio.h>
 #include <ctype.h>
 #include <string.h>
+#include <time.h>
 #ifdef YP
 #include <rpc/rpc.h>
 #include <rpcsvc/yp_prot.h>
@@ -234,7 +233,7 @@ rcmd_af(ahost, rport, locuser, remuser, cmd, fd2p, af)
        } else {
                char num[8];
                int s2 = rresvport_af(&lport, ai->ai_family), s3;
-               int len = ai->ai_addrlen;
+               unsigned int len = ai->ai_addrlen;
                int nfds;
 
                if (s2 < 0)
@@ -404,6 +403,9 @@ rresvport_af(alport, family)
 int    __check_rhosts_file = 1;
 char   *__rcmd_errstr;
 
+/*  Guess at the size of a password buffer for getpwnam_r (see lookup.subproj/lu_group.c) */
+#define MAXPWBUF (MAXLOGNAME + 1 + _PASSWORD_LEN + 1 + MAXPATHLEN + 1 + MAXPATHLEN + 1 + 4098)
+
 /*
  * AF independent extension of iruserok.
  *
@@ -418,13 +420,14 @@ iruserok_sa(ra, rlen, superuser, ruser, luser)
 {
        register char *cp;
        struct stat sbuf;
-       struct passwd *pwd;
+       struct passwd p, *pwd;
        FILE *hostf;
        uid_t uid;
-       int first;
+       int first, status;
        char pbuf[MAXPATHLEN];
        const struct sockaddr *raddr;
        struct sockaddr_storage ss;
+       char pwbuf[MAXPWBUF];
 
        /* avoid alignment issue */
        if (rlen > sizeof(ss)) 
@@ -444,8 +447,14 @@ again:
        }
        if (first == 1 && (__check_rhosts_file || superuser)) {
                first = 0;
-               if ((pwd = getpwnam(luser)) == NULL)
-                       return (-1);
+
+               memset(&p, 0, sizeof(struct passwd));
+               memset(pwbuf, 0, sizeof(pwbuf));
+               pwd = NULL;
+
+               status = getpwnam_r(luser, &p, pwbuf, MAXPWBUF, &pwd);
+               if (status != 0) return -1;
+
                (void)strcpy(pbuf, pwd->pw_dir);
                (void)strcat(pbuf, "/.rhosts");