]> 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\
 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
 
 
 OTHERSRCS = Makefile.preamble Makefile Makefile.postamble
 
index 34ca56b41febeb94d7caa7dda86cd8cc461f76f8..314f8be9c1b12eb9c5cb43a3a8cb2c66d31a769b 100644 (file)
@@ -14,8 +14,7 @@
             netinfo.subproj, 
             nis.subproj, 
             rpc.subproj, 
             netinfo.subproj, 
             nis.subproj, 
             rpc.subproj, 
-            util.subproj, 
-            mdns.subproj
+            util.subproj
         ); 
     }; 
     LANGUAGE = English; 
         ); 
     }; 
     LANGUAGE = English; 
index c775255faf955d27cb6c045cab134823920479bd..f88e7ffc0190d5b58666a6e456ef23da76c74fef 100644 (file)
@@ -1,4 +1,5 @@
 OTHER_CFLAGS = \
 OTHER_CFLAGS = \
+       -D__DARWIN_NON_CANCELABLE=1 \
        -Dsethostent=_res_sethostent \
        -Dgethostent=_res_gethostent \
        -Dendhostent=_res_endhostent \
        -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];
                          "gethostby*.getanswer: asked for \"%s\", got \"%s\"";
 
 static char *h_addr_ptrs[MAXADDRS + 1];
+#ifdef NOTDEF
 static struct hostent *gethostbyname_ipv4 __P((const char *));
 static struct hostent *gethostbyname_ipv4 __P((const char *));
-
+#endif
 static struct hostent host;
 static char *host_aliases[MAXALIASES];
 static char *hostbuf = NULL;
 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 h_errno;
 
-extern int _lu_running(void);
-
 #ifdef DEBUG
 static void
 dprintf(msg, num)
 #ifdef DEBUG
 static void
 dprintf(msg, num)
@@ -442,6 +441,7 @@ gethostbyname(name)
        return (gethostbyname2(name, AF_INET));
 }
 
        return (gethostbyname2(name, AF_INET));
 }
 
+#ifdef NOTDEF
 static struct hostent *
 gethostbyname_ipv4(name)
        const char *name;
 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));
 }
        }
        return (getanswer(&buf, n, name, C_IN, T_A));
 }
+#endif
 
 struct hostent *
 gethostbyaddr(vaddr, len, type)
 
 struct hostent *
 gethostbyaddr(vaddr, len, type)
index 6091ed930036b466c9c12739b9b93ff3644e780c..2d75a40c1f338aca574bf42f92fe78c917bbb0b9 100644 (file)
@@ -78,7 +78,7 @@
 
 /*
  *     @(#)inet.h      8.1 (Berkeley) 6/2/93
 
 /*
  *     @(#)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_
  */
 
 #ifndef _INET_H_
 
 /* External definitions for functions in inet(3) */
 
 
 /* External definitions for functions in inet(3) */
 
+#include <_types.h>
 #include <stdint.h>            /* uint32_t uint16_t */
 #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 <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);
 
 __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 *);
 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 *);
 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 *);
 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);
 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
 
 
 __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)*/
 
 #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
     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
  */
 
  *      gns = Greg Shapiro of WPI
  */
 
+#ifndef DEBUG
 #define DEBUG          /* enable -d flag and SIGUSR[12] support (ucb) */
 #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) */
 /*#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;
        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;
        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) {
        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);
                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
 
 # 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
 #if defined(USE_OPTIONS_H)
 # include "options.h"
 #endif
@@ -403,9 +374,6 @@ res_init()
 #endif
            (void) fclose(fp);
        }
 #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 &&
 
        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
 
 }
 #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()
 {
 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;
                        struct timeval timeout;
                        fd_set dsmask;
                        struct sockaddr_in from;
-                       int fromlen;
+                       unsigned int fromlen;
 
                        if ((s < 0) || vc) {
                                if (vc)
 
                        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\
          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
 
             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
 
 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"
        $(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"
        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 = \
 AFTER_POSTINSTALL += install-man-page
 OTHER_CFLAGS = \
+       -D__DARWIN_NON_CANCELABLE=1 \
        -DINET6=1 \
        -Dsetservent=_old_setservent \
        -Dgetservent=_old_getservent \
        -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)
 # 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, 
             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, 
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@
  */
  * 
  * @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>
 
 #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);
 }
 
        return((_gr_fp = fopen(_PATH_GROUP, "r")) ? 1 : 0);
 }
 
-int
+void
 setgrent()
 {
 setgrent()
 {
-       return(setgroupent(0));
+       setgroupent(0);
 }
 
 int
 }
 
 int
index 779383ec50971122d76a9b5248175c0c700936aa..1789cb51e006e535a1b4ec104763a481a8b44507 100644 (file)
 .Dt GETHOSTBYNAME 3
 .Os
 .Sh NAME
 .Dt GETHOSTBYNAME 3
 .Os
 .Sh NAME
+.Nm endhostent ,
+.Nm gethostbyaddr ,
 .Nm gethostbyname ,
 .Nm gethostbyname2 ,
 .Nm gethostbyname ,
 .Nm gethostbyname2 ,
-.Nm gethostbyaddr ,
 .Nm gethostent ,
 .Nm gethostent ,
-.Nm sethostent ,
-.Nm endhostent ,
 .Nm herror ,
 .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 ;
 .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 *
 .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 *
 .Ft struct hostent *
-.Fn gethostbyname2 "const char *name" "int af"
+.Fo gethostbyname
+.Fa "const char *name"
+.Fc
 .Ft struct hostent *
 .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 *
 .Ft struct hostent *
-.Fn gethostent void
-.Ft void
-.Fn sethostent "int stayopen"
-.Ft void
-.Fn endhostent void
+.Fo gethostent
+.Fa void
+.Fc
 .Ft void
 .Ft void
-.Fn herror "const char *string"
+.Fo herror
+.Fa "const char *string"
+.Fc
 .Ft const char *
 .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 ,
 .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
 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 ,
 .Sh SEE ALSO
 .Xr getaddrinfo 3 ,
 .Xr resolver 3 ,
index b2e286e7c292ec989177eee646cb6cb2b1a1a5be..63c4bfcb6ce8d17c964d422222d6a53000a15bfc 100644 (file)
 
 #include <errno.h>
 #include <ifaddrs.h>
 
 #include <errno.h>
 #include <ifaddrs.h>
+#include <netinet/in.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdint.h>
 
 #if !defined(AF_LINK)
 #define        SA_LEN(sa)      sizeof(struct sockaddr)
 
 #if !defined(AF_LINK)
 #define        SA_LEN(sa)      sizeof(struct sockaddr)
@@ -50,7 +52,7 @@
 #define        SA_LEN(sa)      (sa)->sa_len
 #endif
 
 #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        SA_RLEN(sa)     ((sa)->sa_len ? (((sa)->sa_len + SALIGN) & ~SALIGN) : (SALIGN + 1))
 
 #ifndef        ALIGNBYTES
 #define HAVE_IFM_DATA
 #endif
 
 #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;
 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;
 #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 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];
        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 */
        struct ifreq *ifr;
        struct ifreq *lifr;
 #endif /* NET_RT_IFLIST */
-       int i;
+       int i, status;
        size_t len, alen;
        char *data;
        char *names;
        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 */
        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);
                free(buf);
-               return (-1);
+               buf = NULL;
+               needed *= 2;
        }
 
        for (next = buf; next < buf + needed; next += rtm->rtm_msglen) {
        }
 
        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);
 
        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);
                return (-1);
+       }
+
        i =  ioctl(sock, SIOCGIFCONF, (char *)&ifc);
        close(sock);
        i =  ioctl(sock, SIOCGIFCONF, (char *)&ifc);
        close(sock);
-       if (i < 0)
+       if (i < 0) {
+               free(buf);
                return (-1);
                return (-1);
+       }
 
        ifr = ifc.ifc_req;
        lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len];
 
        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;
                ++icnt;
                dcnt += SA_RLEN(sa);
                ncnt += sizeof(ifr->ifr_name) + 1;
-               
+
                ifr = (struct ifreq *)(((char *)sa) + SA_LEN(sa));
        }
 #endif /* NET_RT_IFLIST */
                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);
                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);
        }
                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);
        }
                *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);
 }
 
        return (0);
 }
 
index 18bbd70b6d313c057ab8cbaf44f072ef6a3e7430..7786ce0a0de706156a02d2d45d4ad2e0b9491c2c 100644 (file)
 .Dt GETNETENT 3
 .Os
 .Sh NAME
 .Dt GETNETENT 3
 .Os
 .Sh NAME
-.Nm getnetent ,
+.Nm endnetent ,
 .Nm getnetbyaddr ,
 .Nm getnetbyname ,
 .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>
 .Nd get network entry
 .Sh LIBRARY
 .Lb libc
 .Sh SYNOPSIS
 .Fd #include <netdb.h>
+.Ft void
+.Fo endnetent
+.Fa void
+.Fc
 .Ft struct netent *
 .Ft struct netent *
-.Fn getnetent void
+.Fo getnetbyaddr
+.Fa "uint32_t net"
+.Fa "int type"
+.Fc
 .Ft struct netent *
 .Ft struct netent *
-.Fn getnetbyname "const char *name"
+.Fo getnetbyname
+.Fa "const char *name"
+.Fc
 .Ft struct netent *
 .Ft struct netent *
-.Fn getnetbyaddr "uint32_t net" "int type"
-.Ft void
-.Fn setnetent "int stayopen"
+.Fo getnetent
+.Fa void
+.Fc
 .Ft void
 .Ft void
-.Fn endnetent void
+.Fo setnetent
+.Fa "int stayopen"
+.Fc
 .Sh DESCRIPTION
 The
 .Fn getnetent ,
 .Sh DESCRIPTION
 The
 .Fn getnetent ,
index e0fd91c9e90a593d52ff4e4a64cd7c7a63877a2f..5a22328c127dbd7f9002c71e4511686034971069 100644 (file)
 .Dt GETPROTOENT 3
 .Os
 .Sh NAME
 .Dt GETPROTOENT 3
 .Os
 .Sh NAME
-.Nm getprotoent ,
-.Nm getprotobynumber ,
+.Nm endprotoent ,
 .Nm getprotobyname ,
 .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>
 .Nd get protocol entry
 .Sh LIBRARY
 .Lb libc
 .Sh SYNOPSIS
 .Fd #include <netdb.h>
+.Ft void
+.Fo endprotoent
+.Fa void
+.Fc
 .Ft struct protoent *
 .Ft struct protoent *
-.Fn getprotoent void
+.Fo getprotobyname
+.Fa "const char *name"
+.Fc
 .Ft struct protoent *
 .Ft struct protoent *
-.Fn getprotobyname "const char *name"
+.Fo getprotobynumber
+.Fa "int proto"
+.Fc
 .Ft struct protoent *
 .Ft struct protoent *
-.Fn getprotobynumber "int proto"
-.Ft void
-.Fn setprotoent "int stayopen"
+.Fo getprotoent
+.Fa void
+.Fc
 .Ft void
 .Ft void
-.Fn endprotoent void
+.Fo setprotoent
+.Fa "int stayopen"
+.Fc
 .Sh DESCRIPTION
 The
 .Fn getprotoent ,
 .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@
  * 
  *
  * @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
  * 
  * /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
  * 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 <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 (;;)
 #include <unistd.h>
 
 #define forever for (;;)
 #define _PWUID_ 2
 
 static struct passwd _pw = { 0 };
 #define _PWUID_ 2
 
 static struct passwd _pw = { 0 };
-static FILE *_pfp;
-static int _pwStayOpen;
+static FILE *_pfp = NULL;
 static int _pwFileFormat = 1;
 
 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)
 
 static void
 freeList(char **l)
@@ -143,7 +138,6 @@ appendString(char *s, char **l)
        return insertString(s, l, (unsigned int)-1);
 }
 
        return insertString(s, l, (unsigned int)-1);
 }
 
-
 static char **
 tokenize(const char *data, const char *sep)
 {
 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;
                        }
                }
                                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';
                /* 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 */
                tokens = appendString(buf, tokens);
 
                /* check for end of line */
@@ -220,11 +214,49 @@ tokenize(const char *data, const char *sep)
                        return tokens;
                }
        }
                        return tokens;
                }
        }
+
        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;
 {
        char **tokens;
        int ntokens;
@@ -234,13 +266,13 @@ parseUser(char *data)
        tokens = tokenize(data, ":");
        ntokens = listLength(tokens);
        if (( _pwFileFormat && (ntokens != 10)) ||
        tokens = tokenize(data, ":");
        ntokens = listLength(tokens);
        if (( _pwFileFormat && (ntokens != 10)) ||
-           (!_pwFileFormat && (ntokens !=  7)))
+               (!_pwFileFormat && (ntokens !=  7)))
        {
                freeList(tokens);
                return NULL;
        }
 
        {
                freeList(tokens);
                return NULL;
        }
 
-       free_pw();
+       LI_files_free_user();
 
        _pw.pw_name = tokens[0];
        _pw.pw_passwd = tokens[1];
 
        _pw.pw_name = tokens[0];
        _pw.pw_passwd = tokens[1];
@@ -275,32 +307,79 @@ parseUser(char *data)
        return &_pw;
 }
 
        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)
 {
 }
 
 int
 setpassent(int stayopen)
 {
-       _pwStayOpen = stayopen;
-       return(1);
+       return 1;
 }
 
 }
 
-int
-setpwent()
+__private_extern__ void
+LI_files_setpwent()
 {
        if (_pfp == NULL)
        {
 {
        if (_pfp == NULL)
        {
@@ -314,20 +393,14 @@ setpwent()
                        pwFile = _PATH_PASSWD;
                        _pwFileFormat = 0;
                }
                        pwFile = _PATH_PASSWD;
                        _pwFileFormat = 0;
                }
+
                _pfp = fopen(pwFile, "r");
                _pfp = fopen(pwFile, "r");
-               if (_pfp == NULL)
-               {
-                       perror(pwFile);
-                       return(0);
-               }
        }
        else rewind(_pfp);
        }
        else rewind(_pfp);
-       _pwStayOpen = 0;
-       return(1);
 }
 
 }
 
-void
-endpwent()
+__private_extern__ void
+LI_files_endpwent()
 {
        if (_pfp != NULL)
        {
 {
        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
        {
        forever
        {
-               line = getLine(_pfp);
+               line = getLine(_hfp);
                if (line == NULL) break;
 
                if (line[0] == '#') 
                if (line == NULL) break;
 
                if (line[0] == '#') 
@@ -359,42 +522,84 @@ getpw(const char *nam, uid_t uid, int which)
                        continue;
                }
 
                        continue;
                }
 
-               pw = parseUser(line);
+               h = LI_files_parse_host(line);
                free(line);
                line = NULL;
 
                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;
 }
 
        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
 .Dt GETSERVENT 3
 .Os
 .Sh NAME
-.Nm getservent ,
-.Nm getservbyport ,
+.Nm endservent ,
 .Nm getservbyname ,
 .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>
 .Nd get service entry
 .Sh LIBRARY
 .Lb libc
 .Sh SYNOPSIS
 .Fd #include <netdb.h>
+.Ft void
+.Fo endservent
+.Fa void
+.Fc
 .Ft struct servent *
 .Ft struct servent *
-.Fn getservent
+.Fo getservbyname
+.Fa "const char *name"
+.Fa "const char *proto"
+.Fc
 .Ft struct servent *
 .Ft struct servent *
-.Fn getservbyname "const char *name" "const char *proto"
+.Fo getservbyport
+.Fa "int port"
+.Fa "const char *proto"
+.Fc
 .Ft struct servent *
 .Ft struct servent *
-.Fn getservbyport "int port" "const char *proto"
-.Ft void
-.Fn setservent "int stayopen"
+.Fo getservent
+.Fa void
+.Fc
 .Ft void
 .Ft void
-.Fn endservent void
+.Fo setservent
+.Fa "int stayopen"
+.Fc
 .Sh DESCRIPTION
 The
 .Fn getservent ,
 .Sh DESCRIPTION
 The
 .Fn getservent ,
index 9327c1252d558c40584d8e2294bc66ea8fa3a956..5d550f3d3e5af0b38bcdeb07e76fc4b26fbf53b0 100644 (file)
 .Dt IF_NAMETOINDEX 3
 .Os
 .Sh NAME
 .Dt IF_NAMETOINDEX 3
 .Os
 .Sh NAME
-.Nm if_nametoindex ,
+.Nm if_freenameindex ,
 .Nm if_indextoname ,
 .Nm if_nameindex ,
 .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
 .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>
 .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 *"
 .Ft "char *"
-.Fn if_indextoname "unsigned int ifindex" "char *ifname"
+.Fo if_indextoname
+.Fa "unsigned ifindex"
+.Fa "char *ifname"
+.Fc
 .Ft "struct if_nameindex *"
 .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
 .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 <stdio.h>
 #include <stdint.h>
 #include <string.h>
+#include <errno.h>
 #include <sys/socket.h>
 
 void __res_close()
 {
 }
 
 #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 *
 #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];
 {
        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;
        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);
        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);
        /*  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;
                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;
        }
                memcpy(dst, tmp, len);
                return dst;
        }
-       
+
        k = 0;
        for (i = 0; i < 16; i += 2)
        {
                j = 0;
                skip = 1;
        k = 0;
        for (i = 0; i < 16; i += 2)
        {
                j = 0;
                skip = 1;
-               
+
                memset(hexa[k], 0, 5);
                memset(hexa[k], 0, 5);
-               
+
                x8 = addr->__u6_addr.__u6_addr8[i];
                x8 = addr->__u6_addr.__u6_addr8[i];
-               
+
                hx8 = x8 >> 4;
                if (hx8 != 0)
                {
                        skip = 0;
                        hexa[k][j++] = hexchars[hx8];
                }
                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];
                }
                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];
                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 >> 4;
                if ((skip == 0) || ((skip == 1) && (hx8 != 0)))
                {
                        hexa[k][j++] = hexchars[hx8];
                }
-               
+
                hx8 = x8 & 0x0f;
                hexa[k][j++] = hexchars[hx8];
                hx8 = x8 & 0x0f;
                hexa[k][j++] = hexchars[hx8];
-               
+
                k++;
        }
                k++;
        }
-       
+
        /* find runs of zeros for :: convention */
        j = 0;
        for (i = 7; i >= 0; i--)
        /* 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;
        }
                else j = 0;
                zr[i] = j;
        }
-       
+
        /* find longest run of zeros */
        k = -1;
        j = 0;
        /* 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];
                }
        }
                        j = zr[i];
                }
        }
-       
+
        for(i = 0; i < 8; i++)
        {
                if (i != k) zr[i] = 0;
        }
        for(i = 0; i < 8; i++)
        {
                if (i != k) zr[i] = 0;
        }
-       
+
        len = 0;
        for (i = 0; i < 8; i++)
        {
        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++;
 
        /* trailing NULL */
        len++;
 
-       if (len > size) return NULL;
+       if (len > size)
+       {
+               errno = ENOSPC;
+               return NULL;
+       }
+
        memcpy(dst, tmp, len);
        return dst;
 }
 
 const char *
        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;
        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++)
        {
        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 *
 }
 
 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;
 }
        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 <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>
 #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;
 inet_pton(int af, const char *src, void *dst)
 {
        int status;
+       unsigned short ifnum;
        char *p, *s;
 
        switch (af)
        {
        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:
 
 #ifdef INET6
                case AF_INET6:
-                       /* Ignore trailing %xxx (interface specification) */
-
+               {
+                       ifnum = 0;
                        p = NULL;
                        s = (char *)src;
 
                        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 (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);
                                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:
 #endif
 
                default:
+               {
                        errno = EAFNOSUPPORT;
                        return -1;
                        errno = EAFNOSUPPORT;
                        return -1;
+               }
        }
        }
+
        /* NOTREACHED */
        /* NOTREACHED */
+       return -1;
 }
 
 /* int
 }
 
 /* int
@@ -125,23 +150,21 @@ inet_pton(int af, const char *src, void *dst)
  *     Paul Vixie, 1996.
  */
 static int
  *     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;
 {
        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;
        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 ((pch = strchr(digits, ch)) != NULL) {
                        u_int new = *tp * 10 + (pch - digits);
-
+                       
                        if (new > 255)
                                return (0);
                        *tp = new;
                        if (new > 255)
                                return (0);
                        *tp = new;
@@ -179,17 +202,15 @@ inet_pton4(src, dst)
  *     Paul Vixie, 1996.
  */
 static int
  *     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",
 {
        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;
        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;
        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;
        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) {
                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;
                 */
                const int n = tp - colonp;
                int i;
-
+               
                if (tp == endp)
                        return (0);
                for (i = 1; i <= n; 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>
 
 #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;
 int
 initgroups(uname, agroup)
        const char *uname;
@@ -75,7 +78,7 @@ initgroups(uname, agroup)
        struct passwd *pw;
 
        /* get the UID for this user */
        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 */
                return(-1);
 
        /* fetch the initial (advisory) group list */
index c1ec9fea1f5a4d4b7f86743be0cc9f9e2866c89d..26bde6218c3306f20b3ef89c46e7a4305e822f9a 100644 (file)
  */
 #include <stdlib.h>
 #include <stdio.h>
  */
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 #include <printerdb.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 *);
 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
 
 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\
 
 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
 
 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
 
 %_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)
        $(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-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 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/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
 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
 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
 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
 
 # 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, 
         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, 
             lookup_types.h, 
             lu_overrides.h, 
             lu_host.h, 
             lu_utils.h, 
             netdb.h, 
             netdb_async.h, 
-            netgr.h, 
             printerdb.h
         ); 
         OTHER_LINKED = (
             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
 .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
 .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>
 .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
 .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
 .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
 and service
 .Fa servname .
 It is a replacement for and provides more flexibility than the
@@ -49,12 +54,12 @@ and
 functions.
 .Pp
 The
 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
 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
 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
 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.
 and
 .Fa servname
 must be non-null.
@@ -136,7 +141,7 @@ structure returned.
 If the
 .Dv AI_NUMERICHOST
 bit is set, it indicates that
 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
 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
 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
 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
 .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.
 is the null pointer and
 .Dv AI_PASSIVE
 is not set.
@@ -379,6 +384,14 @@ if (nsock == 0) {
 }
 freeaddrinfo(res0);
 .Ed
 }
 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 ,
 .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 .
 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 <arpa/inet.h>
 #include <string.h>
 #include <stdlib.h>
-#include <errno.h>
 #include <stdio.h>
 #include <stdio.h>
+#include <errno.h>
 #include <ctype.h>
 #include <rpc/types.h>
 #include <rpc/xdr.h>
 #include <ctype.h>
 #include <rpc/types.h>
 #include <rpc/xdr.h>
 #define SOCK_UNSPEC 0
 #define IPPROTO_UNSPEC 0
 
 #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
 
 #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;
 
 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)
 {
 void
 freeaddrinfo(struct addrinfo *a)
 {
@@ -248,7 +230,7 @@ freeaddrinfo(struct addrinfo *a)
 }
 
 static struct addrinfo *
 }
 
 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;
 {
        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 *
 }
 
 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;
 {
        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;
 
        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;
        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;
        sa->sin6_scope_id = scopeid;
+
        a->ai_addr = (struct sockaddr *)sa;
 
        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;
        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
  * 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 *
  */
 
 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;
        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;
 
        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)
 
        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);
        }
 
                a = new_addrinfo_v6(flags, socktype, protocol, port, a6, scopeid, canonname);
        }
 
-       if (addr != NULL) free(addr);
-       if (canonname != NULL) free(canonname);
-
        return a;
 }
 
        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;
 
        char str[64], *cname;
 
-       numerichost = 0;
+       flags = 0;
        family = PF_UNSPEC;
        proto = IPPROTO_UNSPEC;
        socktype = SOCK_UNSPEC;
        family = PF_UNSPEC;
        proto = IPPROTO_UNSPEC;
        socktype = SOCK_UNSPEC;
-       canonname = 0;
-       passive = 0;
-       parallel = 0;
        cname = NULL;
 
        if (hints != NULL)
        {
                family = hints->ai_family;
        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;
 
                proto = hints->ai_protocol;
+
                if (hints->ai_socktype == SOCK_DGRAM)
                {
                        socktype = SOCK_DGRAM;
                        proto = IPPROTO_UDP;
                }
                if (hints->ai_socktype == SOCK_DGRAM)
                {
                        socktype = SOCK_DGRAM;
                        proto = IPPROTO_UDP;
                }
+
                if (hints->ai_socktype == SOCK_STREAM)
                {
                        socktype = SOCK_STREAM;
                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 (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 (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)
        {
        }
 
        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)
        {
        }
 
        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)
        {
        }
 
        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
 }
 
 static int32_t
@@ -699,7 +611,7 @@ gai_trivial(struct in_addr *in4, struct in6_addr *in6, int16_t port, const struc
        }
        else
        {
        }
        else
        {
-               return EAI_NODATA;
+               return EAI_NONAME;
        }
 
        proto = IPPROTO_UNSPEC;
        }
 
        proto = IPPROTO_UNSPEC;
@@ -759,10 +671,11 @@ gai_trivial(struct in_addr *in4, struct in6_addr *in6, int16_t port, const struc
        return 0;
 }
 
        return 0;
 }
 
-int
+static int
 gai_files(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
 {
 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;
        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;
 
        struct in6_addr a6;
        struct addrinfo *a;
 
+       count = 0;
+       scopeid = 0;
+
        numericserv = 0;
        if (servname != NULL) numericserv = is_a_number(servname);
 
        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;
                        {
                                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);
                        {
                                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);
                        }
 
                        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);
                        }
 
                        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))
                        {
                {
                        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);
                                append_addrinfo(res, a);
+                               count++;
                        }
 
                        if ((proto == IPPROTO_UNSPEC) || (proto == IPPROTO_TCP))
                        {
                        }
 
                        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);
                                append_addrinfo(res, a);
+                               count++;
                        }
 
                        if (proto == IPPROTO_ICMPV6)
                        {
                        }
 
                        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);
                                append_addrinfo(res, a);
+                               count++;
                        }
                }
 
                        }
                }
 
+               if (count == 0) return EAI_AGAIN;
                return 0;
        }
 
        if (wantv4 == 1)
        {
                h = gethostbyname(nodename);
                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++)
                {
 
                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);
                        {
                                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);
                        }
 
                        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
        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;
        char *cname;
-       mach_port_t server_port;
        kern_return_t status;
        struct addrinfo *a;
 
        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)
        {
                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;
                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;
        }
 
                return EAI_SYSTEM;
        }
 
+       if (reply == NULL) return EAI_NONAME;
+
        cname = NULL;
        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);
        }
 
                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))
        {
 
        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 ((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;
 }
 
        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;
 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;
 
 
        *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;
 
        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)
        {
        if (gai_proc < 0)
        {
-               status = _lookup_link(server_port, "getaddrinfo", &gai_proc);
+               status = LI_DSLookupGetProcedureNumber("getaddrinfo", &gai_proc);
                if (status != KERN_SUCCESS)
                {
                        errno = ECONNREFUSED;
                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;
        {
                errno = ECONNREFUSED;
                return EAI_SYSTEM;
@@ -1164,76 +1094,54 @@ getaddrinfo_async_start(mach_port_t *p, const char *nodename, const char *servna
        return 0;
 }
 
        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);
 }
 
 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;
        char *cname;
+       kvarray_t *reply;
+       uint32_t i;
        struct addrinfo *a;
 
        struct addrinfo *a;
 
+       if (res == NULL) return 0;
        *res = NULL;
 
        *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;
 
        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);
        }
 
                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 ((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;
 }
 
        return 0;
 }
@@ -1243,40 +1151,57 @@ getaddrinfo_async_handle_reply(void *msg)
 {
        getaddrinfo_async_callback callback;
        void *context;
 {
        getaddrinfo_async_callback callback;
        void *context;
-       char *buf;
-       uint32_t len;
+       char *buf, *cname;
+       uint32_t i, len;
        int status;
        int status;
-       struct addrinfo *res;
+       kvarray_t *reply;
+       struct addrinfo *l, *a, **res;
 
        callback = (getaddrinfo_async_callback)NULL;
        context = NULL;
        buf = NULL;
        len = 0;
 
        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 (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;
 }
 
        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
  * Input dict may contain the following
  *
  * ip_address: node address
@@ -1305,10 +1230,11 @@ getaddrinfo_async_handle_reply(void *msg)
  */
 
 static int
  */
 
 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))
        {
 
        if ((host == NULL) || (serv == NULL))
        {
@@ -1316,75 +1242,63 @@ gni_lookupd_process_dictionary(XDR *inxdr, char **host, char **serv)
                return EAI_SYSTEM;
        }
 
                return EAI_SYSTEM;
        }
 
-       if (!xdr_int(inxdr, &nkeys))
-       {
-               errno = EIO;
-               return EAI_SYSTEM;
-       }
-
        *host = NULL;
        *serv = NULL;
 
        *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;
 }
 
        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;
 
        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;
        isll = 0;
-       issl = 0;
 
        offset = INET_NTOP_AF_INET_OFFSET;
 
        offset = INET_NTOP_AF_INET_OFFSET;
-       key = "ip_address";
        port = 0;
 
        if (sa->sa_family == PF_INET)
        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;
 
                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)
        {
        }
        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:
                switch (s6->sin6_addr.s6_addr[0])
                {
                        case 0x00:
+                       {
                                if (IN6_IS_ADDR_V4MAPPED(&s6->sin6_addr))
                                {
                                }
                                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;
                                        flags |= NI_NUMERICHOST;
                                }
                                break;
+                       }
                        default:
                        default:
+                       {
                                if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr))
                                {
                                        isll = 1;
                                }
                                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;
                                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;
                        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;
 
                        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;
                }
 
                offset = INET_NTOP_AF_INET6_OFFSET;
-               key = "ipv6_address";
-               port = s6->sin6_port;
+               port = ntohs(s6->sin6_port);
        }
        else
        {
        }
        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)
        {
 
        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;
                {
                        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);
                        }
                }
 
                        {
                                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)
 {
 }
 
 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;
        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;
 
        /* Check input */
        if (sa == NULL) return EAI_FAIL;
 
        isll = 0;
-       issl = 0;
        ifnum = 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_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.
                 */
                 * 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;
                {
                        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)))
                {
                /* 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);
 
                        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;
 
        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))
        {
         */
        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)
                {
                        /* 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)
                {
        {
                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;
                }
                        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;
                }
                        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;
 
 
                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;
        {
                errno = ECONNREFUSED;
                return EAI_SYSTEM;
@@ -1706,7 +1543,7 @@ getnameinfo(const struct sockaddr * __restrict sa, socklen_t salen, char * __res
 
        if (gni_proc < 0)
        {
 
        if (gni_proc < 0)
        {
-               status = _lookup_link(server_port, "getnameinfo", &gni_proc);
+               status = LI_DSLookupGetProcedureNumber("getnameinfo", &gni_proc);
                if (status != KERN_SUCCESS)
                {
                        errno = ECONNREFUSED;
                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;
        }
 
                return EAI_SYSTEM;
        }
 
-       if (n != 1)
-       {
-               xdr_destroy(&inxdr);
-               return EAI_NONAME;
-       }
+       if (reply == NULL) return EAI_NONAME;
 
        hval = NULL;
        sval = NULL;
 
 
        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))
        {
 
        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);
                memcpy(host, hval, i);
-               free(hval);
        }
 
        i = 0;
        if (sval != NULL) i = strlen(sval) + 1;
        if ((serv != NULL) && (servlen != 0) && (i != 0))
        {
        }
 
        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);
                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)
 {
        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;
 
 
        /* 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)
        {
        if (gni_proc < 0)
        {
-               status = _lookup_link(server_port, "getnameinfo", &gni_proc);
+               status = LI_DSLookupGetProcedureNumber("getnameinfo", &gni_proc);
                if (status != KERN_SUCCESS)
                {
                        errno = ECONNREFUSED;
                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;
        {
                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;
 }
 
        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;
 }
 
 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 (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;
 }
 
        return 0;
 }
 
@@ -1882,17 +1691,19 @@ getnameinfo_async_handle_reply(void *msg)
 {
        getnameinfo_async_callback callback;
        void *context;
 {
        getnameinfo_async_callback callback;
        void *context;
-       char *buf, *hval, *sval;
+       const char *hval, *sval;
+       char *host, *serv;
        uint32_t len;
        int status;
        uint32_t len;
        int status;
+       kvarray_t *reply;
 
        callback = (getnameinfo_async_callback)NULL;
        context = NULL;
 
        callback = (getnameinfo_async_callback)NULL;
        context = NULL;
-       buf = NULL;
+       reply = NULL;
        len = 0;
 
        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);
        {
                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;
 
        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);
        if (status != 0)
        {
                if (callback != NULL) callback(status, NULL, NULL, context);
+               kvarray_free(reply);
                return status;
        }
 
                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;
 }
        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
 .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
 .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
 .Sh DESCRIPTION
 The
 .Fn getnameinfo
@@ -59,19 +65,19 @@ bytes long.
 The host and service names associated with
 .Fa sa
 are stored in
 The host and service names associated with
 .Fa sa
 are stored in
-.Fa host
+.Fa node
 and
 and
-.Fa serv
+.Fa service
 which have length parameters
 which have length parameters
-.Fa hostlen
+.Fa nodelen
 and
 and
-.Fa servlen .
+.Fa servicelen .
 The maximum value for
 The maximum value for
-.Fa hostlen
+.Fa nodelen
 is
 .Dv NI_MAXHOST
 and the maximum value for
 is
 .Dv NI_MAXHOST
 and the maximum value for
-.Fa servlen
+.Fa servicelen
 is
 .Dv NI_MAXSERV ,
 as defined by
 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
 }
 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 ,
 .Sh SEE ALSO
 .Xr gai_strerror 3 ,
 .Xr getaddrinfo 3 ,
@@ -256,10 +287,6 @@ if (error == 0) {
            NULL, 0, NI_NUMERICHOST);
 }
 .Ed
            NULL, 0, NI_NUMERICHOST);
 }
 .Ed
-.Sh BUGS
-The implementation of
-.Fn getnameinfo
-is not thread-safe.
 .\".Pp
 .\".Ox
 .\"intentionally uses a different
 .\".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@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include <mach/mach.h>
 #include <stdio.h>
 #include <string.h>
 #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 <aliasdb.h>
 #include <pthread.h>
-
-#include "_lu_types.h"
-#include "lookup.h"
 #include "lu_utils.h"
 #include "lu_overrides.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 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 *
 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;
        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
 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
 }
 
 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 *
 static struct aliasent *
-lu_alias_getent(void)
+ds_alias_getent(void)
 {
        static int proc = -1;
 {
        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 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
        {
        }
        else
        {
@@ -384,8 +159,8 @@ alias_getbyname(const char *name)
                pthread_mutex_unlock(&_alias_lock);
        }
 
                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;
 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
        {
        }
        else
        {
@@ -413,21 +184,21 @@ alias_getent(void)
                pthread_mutex_unlock(&_alias_lock);
        }
 
                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)
 {
 
 }
 
 void
 alias_setent(void)
 {
-       if (_lu_running()) lu_alias_setent();
+       if (_ds_running()) ds_alias_setent();
        else _old_alias_setent();
 }
 
 void
 alias_endent(void)
 {
        else _old_alias_setent();
 }
 
 void
 alias_endent(void)
 {
-       if (_lu_running()) lu_alias_endent();
+       if (_ds_running()) ds_alias_endent();
        else _old_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 <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 <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <net/ethernet.h>
 #include <pthread.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)
 {
 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)
 {
        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;
 }
 
        return 0;
 }
 
index 9fe1b8472ff638df2bd2fb8eebf4203f1abbecc8..ea452e127dc258d761b741fb9fdb36646c1f2c0a 100644 (file)
 #include <mach/mach.h>
 #include <stdio.h>
 #include <string.h>
 #include <mach/mach.h>
 #include <stdio.h>
 #include <string.h>
-#include <rpc/types.h>
-#include <rpc/xdr.h>
 #include <bootparams.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 *
 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)
 {
        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)
 {
        return NULL;
 }
 
 void
 bootparams_setent(void)
 {
-       if (_lu_running()) lu_bootparams_setent();
 }
 
 void
 bootparams_endent(void)
 {
 }
 
 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 <mach/mach.h>
 #include <stdio.h>
 #include <string.h>
-#include <rpc/types.h>
-#include <rpc/xdr.h>
 #include <fstab.h>
 #include <pthread.h>
 #include <fstab.h>
 #include <pthread.h>
-
-#include "lookup.h"
-#include "_lu_types.h"
 #include "lu_utils.h"
 #include "lu_overrides.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 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 *
 }
 
 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;
        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
 }
 
 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
 }
 
 static int
-lu_setfsent(void)
+ds_setfsent(void)
 {
 {
-       lu_endfsent();
+       ds_endfsent();
        return 1;
 }
 
 static struct fstab *
        return 1;
 }
 
 static struct fstab *
-lu_getfsent()
+ds_getfsent()
 {
        static int proc = -1;
 {
        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 *
 }
 
 static struct fstab *
-lu_getfsfile(const char *name)
+ds_getfsfile(const char *name)
 {
        struct fstab *fs;
 
 {
        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;
                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;
 }
 
 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:
        {
                switch (source)
                {
                        case FS_GET_SPEC:
-                               res = lu_getfsspec(spec);
+                               res = ds_getfsspec(spec);
                                break;
                        case FS_GET_FILE:
                                break;
                        case FS_GET_FILE:
-                               res = lu_getfsfile(file);
+                               res = ds_getfsfile(file);
                                break;
                        case FS_GET_ENT:
                                break;
                        case FS_GET_ENT:
-                               res = lu_getfsent();
-                               break;
+                               res = ds_getfsent();
+                       break;
                        default: res = NULL;
                }
        }
        else
        {
                pthread_mutex_lock(&_fstab_lock);
                        default: res = NULL;
                }
        }
        else
        {
                pthread_mutex_lock(&_fstab_lock);
+
                switch (source)
                {
                        case FS_GET_SPEC:
                switch (source)
                {
                        case FS_GET_SPEC:
@@ -434,11 +220,12 @@ getfs(const char *spec, const char *file, int source)
                                break;
                        default: res = NULL;
                }
                                break;
                        default: res = NULL;
                }
+
                pthread_mutex_unlock(&_fstab_lock);
        }
 
                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)
 {
 int
 setfsent(void)
 {
-       if (_lu_running()) return (lu_setfsent());
+       if (_ds_running()) return (ds_setfsent());
        return (_old_setfsent());
 }
 
 void
 endfsent(void)
 {
        return (_old_setfsent());
 }
 
 void
 endfsent(void)
 {
-       if (_lu_running()) lu_endfsent();
+       if (_ds_running()) ds_endfsent();
        else _old_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@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
@@ -31,9 +31,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
 #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 <pwd.h>
 #include <netinet/in.h>
 #include <sys/param.h>
 #include <pthread.h>
 #include <errno.h>
 #include <servers/bootstrap.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"
 
 #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 GROUP_CACHE_SIZE 10
-#define DEFAULT_GROUP_CACHE_TTL 10
 
 static pthread_mutex_t _group_cache_lock = PTHREAD_MUTEX_INITIALIZER;
 
 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_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;
 
 
 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"
 /*
  * Support for memberd calls
  */
 #define MEMBERD_NAME "com.apple.memberd"
-static mach_port_t mbr_port = MACH_PORT_NULL;
 typedef uint32_t GIDArray[16];
 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
 
 
 #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
 }
 
 static int
@@ -298,110 +234,75 @@ copy_group_r(struct group *in, struct group *out, char *buffer, int buflen)
 }
 
 static void
 }
 
 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);
 
        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);
 
        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;
 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 (name == NULL) return NULL;
+       if (group_cache_check() != 0) return NULL;
 
        pthread_mutex_lock(&_group_cache_lock);
 
 
        pthread_mutex_lock(&_group_cache_lock);
 
-       gettimeofday(&now, NULL);
-
        for (i = 0; i < GROUP_CACHE_SIZE; i++)
        {
        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];
                gr = (struct group *)_group_cache[i];
+               if (gr == NULL) continue;
 
                if (gr->gr_name == NULL) continue;
 
 
                if (gr->gr_name == NULL) continue;
 
@@ -422,20 +323,15 @@ cache_getgrgid(int gid)
 {
        int i;
        struct group *gr, *res;
 {
        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);
 
 
        pthread_mutex_lock(&_group_cache_lock);
 
-       gettimeofday(&now, NULL);
-
        for (i = 0; i < GROUP_CACHE_SIZE; i++)
        {
        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];
                gr = (struct group *)_group_cache[i];
+               if (gr == NULL) continue;
 
                if ((gid_t)gid == gr->gr_gid)
                {
 
                if ((gid_t)gid == gr->gr_gid)
                {
@@ -450,122 +346,21 @@ cache_getgrgid(int gid)
 }
 
 static struct group *
 }
 
 static struct group *
-lu_getgrgid(int gid)
+ds_getgrgid(int gid)
 {
 {
-       struct group *g;
-       unsigned int datalen;
-       XDR inxdr;
        static int proc = -1;
        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 *
 }
 
 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;
        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
  *
  */
  * 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;
        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 (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
 _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;
 
        status = 0;
-       maxgroups = *grpcnt;
+       maxgroups = (uint32_t)*grpcnt;
        *grpcnt = 0;
 
        *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.
         */
        /*
         * 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.
 
        /*
         * 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))
                        {
                {
                        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();
                                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 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;
 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 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;
        *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);
 
        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;
 
        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;
 }
 
        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;
 }
 
        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)
 {
 }
 
 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 *
 }
 
 static struct group *
-lu_getgrent()
+ds_getgrent()
 {
 {
-       struct group *g;
        static int proc = -1;
        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;
 }
 
 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)
        res = NULL;
 
        switch (source)
@@ -917,27 +744,29 @@ getgr_internal(const char *name, gid_t gid, int source)
 
        if (res != NULL)
        {
 
        if (res != NULL)
        {
-               from_cache = 1;
        }
        }
-       else if (_lu_running())
+       else if (_ds_running())
        {
                switch (source)
                {
                        case GR_GET_NAME:
        {
                switch (source)
                {
                        case GR_GET_NAME:
-                               res = lu_getgrnam(name);
+                               res = ds_getgrnam(name);
                                break;
                        case GR_GET_GID:
                                break;
                        case GR_GET_GID:
-                               res = lu_getgrgid(gid);
+                               res = ds_getgrgid(gid);
                                break;
                        case GR_GET_ENT:
                                break;
                        case GR_GET_ENT:
-                               res = lu_getgrent();
+                               res = ds_getgrent();
                                break;
                        default: res = NULL;
                }
                                break;
                        default: res = NULL;
                }
+
+               if (res != NULL) add_to_cache = 1;
        }
        else
        {
                pthread_mutex_lock(&_group_lock);
        }
        else
        {
                pthread_mutex_lock(&_group_lock);
+
                switch (source)
                {
                        case GR_GET_NAME:
                switch (source)
                {
                        case GR_GET_NAME:
@@ -951,10 +780,11 @@ getgr_internal(const char *name, gid_t gid, int source)
                                break;
                        default: res = NULL;
                }
                                break;
                        default: res = NULL;
                }
+
                pthread_mutex_unlock(&_group_lock);
        }
 
                pthread_mutex_unlock(&_group_lock);
        }
 
-       if (from_cache == 0) cache_group(res);
+       if (add_to_cache == 1) cache_group(res);
 
        return res;
 }
 
        return res;
 }
@@ -963,19 +793,15 @@ static struct group *
 getgr(const char *name, gid_t gid, int source)
 {
        struct group *res = NULL;
 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);
 
 
        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
 }
 
 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;
        int status;
 
        *result = NULL;
-       errno = 0;
 
        res = getgr_internal(name, gid, source);
 
        res = getgr_internal(name, gid, source);
-       if (res == NULL) return -1;
+       if (res == NULL) return 0;
 
        status = copy_group_r(res, grp, buffer, bufsize);
 
        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;
 
        *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
 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;
 
 
        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 *
 }
 
 struct group *
@@ -1037,7 +873,7 @@ getgrent(void)
 int
 setgrent(void)
 {
 int
 setgrent(void)
 {
-       if (_lu_running()) lu_setgrent();
+       if (_ds_running()) ds_setgrent();
        else _old_setgrent();
        return 1;
 }
        else _old_setgrent();
        return 1;
 }
@@ -1045,7 +881,7 @@ setgrent(void)
 void
 endgrent(void)
 {
 void
 endgrent(void)
 {
-       if (_lu_running()) lu_endgrent();
+       if (_ds_running()) ds_endgrent();
        else _old_endgrent();
 }
 
        else _old_endgrent();
 }
 
index d9d178efaf23be50c2ffef851ddb1b1a074d94e4..d671afa0ac00adc5cb83e1f2bd90bb257974431a 100644 (file)
 #include <ifaddrs.h>
 #include <sys/types.h>
 #include <netinet/if_ether.h>
 #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_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;
 
 #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 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_byaddr_cache_index = 0;
 
+static unsigned int _host_cache_init = 0;
+
 static pthread_mutex_t _host_lock = PTHREAD_MUTEX_INITIALIZER;
 
 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 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
 
 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;
 
 {
        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);
 
 
        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);
        }
                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
 }
 
 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 *
 }
 
 __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_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;
 
        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;
        {
                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)
 {
 }
 
 __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;
 
 
        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)
 {
 }
 
 __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;
 
 
        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)
 {
 }
 
 static void
 cache_host(struct hostent *h, int want, int how)
 {
-       struct timeval now;
        struct hostent *hcache;
 
        struct hostent *hcache;
 
-       if (_host_cache_ttl == 0) return;
        if (h == NULL) return;
 
        pthread_mutex_lock(&_host_cache_lock);
 
        hcache = copy_host(h);
 
        if (h == NULL) return;
 
        pthread_mutex_lock(&_host_cache_lock);
 
        hcache = copy_host(h);
 
-       gettimeofday(&now, NULL);
-
        if (how == CACHE_BYNAME)
        {
        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[_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
        {
                _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[_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_byaddr_cache_index = (_host_byaddr_cache_index + 1) % HOST_CACHE_SIZE;
        }
 
+       _host_cache_init = 1;
+
        pthread_mutex_unlock(&_host_cache_lock);
 }
 
        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;
 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 (name == NULL) return NULL;
+       if (host_cache_check() != 0) return NULL;
 
        pthread_mutex_lock(&_host_cache_lock);
 
 
        pthread_mutex_lock(&_host_cache_lock);
 
-       gettimeofday(&now, NULL);
-
        for (i = 0; i < HOST_CACHE_SIZE; i++)
        {
        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 (_host_byname_cache_flavor[i] != want) continue;
 
                h = (struct hostent *)_host_byname_cache[i];
+               if (h == NULL) continue;
 
                if (h->h_name != NULL) 
                {
 
                if (h->h_name != NULL) 
                {
@@ -568,26 +529,21 @@ cache_gethostbyaddr(const char *addr, int want)
 {
        int i, j, len;
        struct hostent *h, *res;
 {
        int i, j, len;
        struct hostent *h, *res;
-       struct timeval now;
 
        if (addr == NULL) return NULL;
 
        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);
 
 
        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++)
        {
        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 (_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;
 
 
                if (h->h_addr_list == NULL) continue;
 
@@ -607,316 +563,277 @@ cache_gethostbyaddr(const char *addr, int want)
 }
 
 static struct hostent *
 }
 
 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;
        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;
                }
        }
                        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;
                }
        }
                        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
        {
        }
        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;
        }
 
                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;
        }
 
                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;
        }
 
                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 *
 }
 
 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;
                }
        }
 
                        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;
        }
 
                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;
        }
 
                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
 }
 
 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
 }
 
 static void
-lu_sethostent()
+ds_sethostent()
 {
 {
-       lu_endhostent();
+       ds_endhostent();
 }
 
 static struct hostent *
 }
 
 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;
        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)
        {
        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 (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;
                        }
                }
 
                                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;
                }
 
                        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;
        }
 
                return NULL;
        }
 
-       *err = 0;
-       tdata->lu_vm_cursor--;
-       
-       return h;
+       return entry;
 }
 
 static struct hostent *
 }
 
 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;
 {
        struct hostent *res = NULL;
-       int want, from_cache;
+       int want, add_to_cache;
 
 
-       *err = 0;
+       if (err != NULL) *err = 0;
 
        want = WANT_A4_ONLY;
 
        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;
        {
                addr += 12;
                len = 4;
-               type = AF_INET;
+               family = AF_INET;
                want = WANT_MAPPED_A4_ONLY;
        }
 
                want = WANT_MAPPED_A4_ONLY;
        }
 
-       from_cache = 0;
+       add_to_cache = 0;
        res = cache_gethostbyaddr(addr, want);
 
        if (res != NULL)
        {
        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);
        }
        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);
        }
 
                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;
 }
 
        return res;
 }
@@ -925,33 +842,26 @@ struct hostent *
 gethostbyaddr(const void *addr, socklen_t len, int type)
 {
        struct hostent *res;
 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);
 
        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;
 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, 
 
        /* 
         * If name is all dots and digits without a trailing dot, 
@@ -962,13 +872,13 @@ gethostbynameerrno(const char *name, int *err)
         */
        if (name == NULL)
        {
         */
        if (name == NULL)
        {
-               *err = HOST_NOT_FOUND;
+               if (err != NULL) *err = HOST_NOT_FOUND;
                return NULL;
        }
 
        if (name[0] == '\0')
        {
                return NULL;
        }
 
        if (name[0] == '\0')
        {
-               *err = HOST_NOT_FOUND;
+               if (err != NULL) *err = HOST_NOT_FOUND;
                return NULL;
        }
 
                return NULL;
        }
 
@@ -984,13 +894,13 @@ gethostbynameerrno(const char *name, int *err)
        if ((is_addr == 1) && (name[i-1] == '.')) is_addr = 0;
 
        res = NULL;
        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)
                {
 
        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);
                        return NULL;
                }
                res = fake_hostent(name, addr);
@@ -1003,17 +913,17 @@ gethostbynameerrno(const char *name, int *err)
 
        if (res != NULL)
        {
 
        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);
        }
        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);
        }
 
                pthread_mutex_unlock(&_host_lock);
        }
 
@@ -1021,7 +931,7 @@ gethostbynameerrno(const char *name, int *err)
        {
                if (inet_aton(name, &addr) == 0)
                {
        {
                if (inet_aton(name, &addr) == 0)
                {
-                       *err = HOST_NOT_FOUND;
+                       if (err != NULL) *err = HOST_NOT_FOUND;
                        return NULL;
                }
 
                        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;
 }
 
        return res;
 }
@@ -1041,89 +951,74 @@ struct hostent *
 gethostbyname(const char *name)
 {
        struct hostent *res;
 gethostbyname(const char *name)
 {
        struct hostent *res;
-       struct lu_thread_info *tdata;
+       struct li_thread_info *tdata;
 
        res = gethostbynameerrno(name, &h_errno);
 
        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 *
 }
 
 struct hostent *
-gethostbyname2(const char *name, int af)
+gethostbyname2(const char *name, int family)
 {
        struct hostent *res;
 {
        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;
        }
 
        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 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);
        }
        else
        {
                pthread_mutex_lock(&_host_lock);
-               res = copy_host(_old_gethostent());
+               res = copy_host(LI_files_gethostent());
                pthread_mutex_unlock(&_host_lock);
        }
 
                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)
 {
 }
 
 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)
 {
 }
 
 void
 endhostent(void)
 {
-       if (_lu_running()) lu_endhostent();
-       else _old_endhostent();
+       if (_ds_running()) ds_endhostent();
+       else LI_files_endhostent();
 }
 
 __private_extern__ int
 }
 
 __private_extern__ int
@@ -1148,7 +1043,7 @@ is_a4_mapped(const char *s)
 
        return 1;
 }
 
        return 1;
 }
-       
+
 __private_extern__ int
 is_a4_compat(const char *s)
 {
 __private_extern__ int
 is_a4_compat(const char *s)
 {
@@ -1180,17 +1075,14 @@ is_a4_compat(const char *s)
 }
 
 struct hostent *
 }
 
 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;
 
 {
        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)
        {
 
        if (res->h_name == NULL)
        {
@@ -1202,9 +1094,9 @@ getipnodebyaddr(const void *src, size_t len, int af, int *err)
 }
 
 struct hostent *
 }
 
 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;
        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));
 
        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)
        {
                status = inet_aton(name, &addr4);
                if (status == 1)
@@ -1225,21 +1117,22 @@ getipnodebyname(const char *name, int af, int flags, int *err)
                        return res;
                }
        }
                        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;
                }
                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)))
                        {
                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;
                        }
 
                                return NULL;
                        }
 
@@ -1255,7 +1148,7 @@ getipnodebyname(const char *name, int af, int flags, int *err)
        }
        else
        {
        }
        else
        {
-               *err = NO_RECOVERY;
+               if (err != NULL) *err = NO_RECOVERY;
                return NULL;
        }
 
                return NULL;
        }
 
@@ -1270,7 +1163,7 @@ getipnodebyname(const char *name, int af, int flags, int *err)
        {
                if (getifaddrs(&ifa) < 0)
                {
        {
                if (getifaddrs(&ifa) < 0)
                {
-                       *err = NO_RECOVERY;
+                       if (err != NULL) *err = NO_RECOVERY;
                        return NULL;
                }
 
                        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))
                {
                /* Bail out if there are no interfaces */
                if ((if4 == 0) && (if6 == 0))
                {
-                       *err = NO_ADDRESS;
+                       if (err != NULL) *err = NO_ADDRESS;
                        return NULL;
                }
        }
                        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;
         * 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))
                {
                if ((flags & AI_ADDRCONFIG) && (if4 == 0))
                {
-                       *err = NO_ADDRESS;
+                       if (err != NULL) *err = NO_ADDRESS;
                        return NULL;
                }
        }
        else
        {
                        return NULL;
                }
        }
        else
        {
-               /* af == AF_INET6 */
+               /* family == AF_INET6 */
                want = WANT_A6_ONLY;
                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;
                {
                        if (flags & AI_ALL)
                        {
                                want = WANT_A6_PLUS_MAPPED_A4;
-                               really_want = want;
                        }
                        else
                        {
                        }
                        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)) 
                        {
                        }
                }
                else
                {
                        if ((flags & AI_ADDRCONFIG) && (if6 == 0)) 
                        {
-                               *err = NO_ADDRESS;
+                               if (err != NULL) *err = NO_ADDRESS;
                                return NULL;
                        }
                }
        }
 
                                return NULL;
                        }
                }
        }
 
-       from_cache = 0;
+       add_to_cache = 0;
        res = cache_gethostbyname(name, want);
 
        if (res != NULL)
        {
        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);
        }
        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)
        {
                pthread_mutex_unlock(&_host_lock);
        }
 
        if (res == NULL)
        {
-               *err = HOST_NOT_FOUND;
+               if (err != NULL) *err = HOST_NOT_FOUND;
                return NULL;
        }
 
                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;
 }
 
 
        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.
  */
 /*
  * 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 (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.
  */
 }
 
 /*
  * 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];
        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 (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]);
        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)
 {
 }
 
 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)
 {
        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);
 }
        return _old_ether_ntohost(host, e);
 }
index 3261116e7c84be718b8ac4b1d8e7088ecbd01ba2..109fb71bf64434365c9338c585625e91209151f5 100644 (file)
 #define _LU_HOST_H_
 
 #include <sys/cdefs.h>
 #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 */
 
 /* 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);
 
 
 __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);
 
 int is_a4_mapped(const char *s);
 int is_a4_compat(const char *s);
 
index 6b5047133024b67331d85985a02a8ae7b7edbe76..14a0eca0d8dca56c1979d49277d915c1cd63ff2f 100644 (file)
  */
 
 #include <netdb.h>
  */
 
 #include <netdb.h>
-/* async gethostbyXXX function prototypes */
 #include <netdb_async.h>
 #include <pthread.h>
 #include <stdlib.h>
 #include <mach/mach.h>
 #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 <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"
 
 
 #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;
 
        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;
        {
                addr += 12;
                len = 4;
-               type = AF_INET;
+               family = AF_INET;
                want = WANT_MAPPED_A4_ONLY;
        }
 
                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)
 {
        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)
 {
        return mp;
 }
 
 void
 gethostbyname_async_cancel(mach_port_t port)
 {
-       _async_cancel(port);
-       return;
+       LI_async_call_cancel(port, NULL);
 }
 
 void
 }
 
 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
 }
 
 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 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)
                {
        if (flags & AI_ADDRCONFIG)
        {
                if (getifaddrs(&ifa) < 0)
                {
-                       *error = NO_RECOVERY;
+                       if (err != NULL) *err = NO_RECOVERY;
                        return MACH_PORT_NULL;
                }
 
                        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 == 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);
                }
 
                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))
                {
                /* 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;
                }
        }
                        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.
         */
         * 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
                        {
                        }
                        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)
 {
        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
 }
 
 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.
  */
  * 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 <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"
 
 #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;
 };
 
 {
        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
 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;
        static int proc = -1;
-       int size;
-       int res;
-       _lu_innetgr_args args;
-       char *lookup_buf;
 
        if (proc < 0)
        {
 
        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
 }
 
 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
 /* 
  * 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;
        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 (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;
                }
        }
 
                        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 == 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;
        }
 
                return NULL;
        }
 
-       tdata->lu_vm_cursor--;
-       
-       return ng;
+       return entry;
 }
 
 int 
 innetgr(const char *group, const char *host, const char *user,
        const char *domain)
 {
 }
 
 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)
 {
        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;
 
        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;
        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)
 {
 void
 setnetgrent(const char *name)
 {
-       if (_lu_running()) lu_setnetgrent(name);
+       if (_ds_running()) ds_setnetgrent(name);
 }
 
 void
 endnetgrent(void)
 {
 }
 
 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 <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 <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;
 #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 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 *
 }
 
 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;
        static int proc = -1;
-       char *lookup_buf;
-       int count;
+       unsigned char f1, f2, f3;
+       char val[64];
 
        if (type != AF_INET) return NULL;
 
 
        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 *
 }
 
 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;
        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
 }
 
 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
 }
 
 static void
-lu_setnetent()
+ds_setnetent()
 {
 {
-       lu_endnetent();
+       ds_endnetent();
 }
 
 static struct netent *
 }
 
 static struct netent *
-lu_getnetent()
+ds_getnetent()
 {
        static int proc = -1;
 {
        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 *
 }
 
 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 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:
        {
                switch (source)
                {
                        case N_GET_NAME:
-                               res = lu_getnetbyname(name);
+                               res = ds_getnetbyname(name);
                                break;
                        case N_GET_ADDR:
                                break;
                        case N_GET_ADDR:
-                               res = lu_getnetbyaddr(addr, type);
+                               res = ds_getnetbyaddr(addr, type);
                                break;
                        case N_GET_ENT:
                                break;
                        case N_GET_ENT:
-                               res = lu_getnetent();
+                               res = ds_getnetent();
                                break;
                        default: res = NULL;
                }
                                break;
                        default: res = NULL;
                }
@@ -465,6 +197,7 @@ getnet(const char *name, long addr, int type, int source)
        else
        {
                pthread_mutex_lock(&_network_lock);
        else
        {
                pthread_mutex_lock(&_network_lock);
+
                switch (source)
                {
                        case N_GET_NAME:
                switch (source)
                {
                        case N_GET_NAME:
@@ -478,11 +211,12 @@ getnet(const char *name, long addr, int type, int source)
                                break;
                        default: res = NULL;
                }
                                break;
                        default: res = NULL;
                }
+
                pthread_mutex_unlock(&_network_lock);
        }
 
                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 *
 }
 
 struct netent *
@@ -506,13 +240,13 @@ getnetent(void)
 void
 setnetent(int stayopen)
 {
 void
 setnetent(int stayopen)
 {
-       if (_lu_running()) lu_setnetent();
+       if (_ds_running()) ds_setnetent();
        else _old_setnetent(stayopen);
 }
 
 void
 endnetent(void)
 {
        else _old_setnetent(stayopen);
 }
 
 void
 endnetent(void)
 {
-       if (_lu_running()) lu_endnetent();
+       if (_ds_running()) ds_endnetent();
        else _old_endnetent();
 }
        else _old_endnetent();
 }
index c7134b24298001eafe07ab4f12912feccbd50dfd..a83713e12bc656d511dcad2c1756be420f9a9fcd 100644 (file)
 #include <sys/types.h>
 
 __BEGIN_DECLS
 #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 group *_old_getgrnam __P((const char *));
 struct group *_old_getgrgid __P((gid_t));
 int _old_setgrent __P((void));
 struct group *_old_getgrent __P((void));
 void _old_endgrent __P((void));
 
-struct hostent *_old_gethostbyname __P((const char *));
-struct hostent *_old_gethostbyaddr __P((const char *, int, int));
-void _old_sethostent __P((int));
-struct hostent *_old_gethostent __P((void));
-void _old_endhostent __P((void));
-void _old_sethostfile __P((const char *));
-
 struct netent *_old_getnetbyname();
 struct netent *_old_getnetbyaddr();
 void _old_setnetent();
 struct netent *_old_getnetbyname();
 struct netent *_old_getnetbyaddr();
 void _old_setnetent();
index e455b4cc1ded4607f15da93f2c1b79ad901966d7..0b7d1950859f4dff559598594877b8714893ba12 100644 (file)
 #include <mach/mach.h>
 #include <stdio.h>
 #include <string.h>
 #include <mach/mach.h>
 #include <stdio.h>
 #include <string.h>
-#include <rpc/types.h>
-#include <rpc/xdr.h>
 #include <pthread.h>
 #include <pthread.h>
-
-#include "_lu_types.h"
-#include "lookup.h"
 #include "printerdb.h"
 #include "lu_utils.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)
 {
 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)
 {
 }
 
 const prdb_ent *
 prdb_get(void)
 {
-       return (const prdb_ent *)getprinter(NULL, P_GET_ENT);
+       return NULL;
 }
 
 void
 prdb_set(const char *name)
 {
 }
 
 void
 prdb_set(const char *name)
 {
-       if (_lu_running()) lu_prdb_set();
-       else _old_prdb_set();
 }
 
 void
 prdb_end(void)
 {
 }
 
 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 <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 <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();
 #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();
 
 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
 
 #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 *
 static struct protoent *
-lu_getprotobynumber(long number)
+ds_getprotobynumber(uint32_t number)
 {
 {
-       struct protoent *p;
-       unsigned int datalen;
-       XDR inxdr;
        static int proc = -1;
        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 *
 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;
        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
 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
 }
 
 static void
-lu_setprotoent()
+ds_setprotoent()
 {
 {
-       lu_endprotoent();
+       ds_endprotoent();
 }
 
 }
 
-
 static struct protoent *
 static struct protoent *
-lu_getprotoent()
+ds_getprotoent()
 {
 {
-       struct protoent *p;
        static int proc = -1;
        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;
 }
 
 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:
        {
                switch (source)
                {
                        case PROTO_GET_NAME:
-                               res = lu_getprotobyname(name);
+                               res = ds_getprotobyname(name);
                                break;
                        case PROTO_GET_NUM:
                                break;
                        case PROTO_GET_NUM:
-                               res = lu_getprotobynumber(number);
+                               res = ds_getprotobynumber(number);
                                break;
                        case PROTO_GET_ENT:
                                break;
                        case PROTO_GET_ENT:
-                               res = lu_getprotoent();
+                               res = ds_getprotoent();
                                break;
                        default: res = NULL;
                }
        }
        else
        {
                                break;
                        default: res = NULL;
                }
        }
        else
        {
+               pthread_mutex_lock(&_protocol_lock);
+
                switch (source)
                {
                        case PROTO_GET_NAME:
                switch (source)
                {
                        case PROTO_GET_NAME:
@@ -461,10 +197,12 @@ getproto(const char *name, int number, int source)
                                break;
                        default: res = NULL;
                }
                                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 *
 }
 
 struct protoent *
@@ -488,13 +226,13 @@ getprotoent(void)
 void
 setprotoent(int stayopen)
 {
 void
 setprotoent(int stayopen)
 {
-       if (_lu_running()) lu_setprotoent();
+       if (_ds_running()) ds_setprotoent();
        else _old_setprotoent(stayopen);
 }
 
 void
 endprotoent(void)
 {
        else _old_setprotoent(stayopen);
 }
 
 void
 endprotoent(void)
 {
-       if (_lu_running()) lu_endprotoent();
+       if (_ds_running()) ds_endprotoent();
        else _old_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@
  * 
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
 #include <mach/mach.h>
 #include <stdio.h>
 #include <string.h>
 #include <mach/mach.h>
 #include <stdio.h>
 #include <string.h>
+#include <stdint.h>
 #include <netinet/in.h>
 #include <pthread.h>
 #include <netinet/in.h>
 #include <pthread.h>
-
-#include "_lu_types.h"
-#include "lookup.h"
 #include "lu_utils.h"
 #include "lu_overrides.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
 
 #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 *
 static struct rpcent *
-lu_getrpcbynumber(long number)
+ds_getrpcbynumber(uint32_t number)
 {
 {
-       struct rpcent *r;
-       unsigned datalen;
-       XDR inxdr;
        static int proc = -1;
        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 *
 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;
        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
 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
 }
 
 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 *
 static struct rpcent *
-lu_getrpcent()
+ds_getrpcent(void)
 {
 {
-       struct rpcent *r;
        static int proc = -1;
        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 *
 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 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:
        {
                switch (source)
                {
                        case RPC_GET_NAME:
-                               res = lu_getrpcbyname(name);
+                               res = ds_getrpcbyname(name);
                                break;
                        case RPC_GET_NUM:
                                break;
                        case RPC_GET_NUM:
-                               res = lu_getrpcbynumber(number);
+                               res = ds_getrpcbynumber(number);
                                break;
                        case RPC_GET_ENT:
                                break;
                        case RPC_GET_ENT:
-                               res = lu_getrpcent();
+                               res = ds_getrpcent();
                                break;
                        default: res = NULL;
                }
                                break;
                        default: res = NULL;
                }
@@ -447,6 +192,7 @@ getrpc(const char *name, long number, int source)
        else
        {
                pthread_mutex_lock(&_rpc_lock);
        else
        {
                pthread_mutex_lock(&_rpc_lock);
+
                switch (source)
                {
                        case RPC_GET_NAME:
                switch (source)
                {
                        case RPC_GET_NAME:
@@ -460,11 +206,12 @@ getrpc(const char *name, long number, int source)
                                break;
                        default: res = NULL;
                }
                                break;
                        default: res = NULL;
                }
+
                pthread_mutex_unlock(&_rpc_lock);
        }
 
                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 *
 }
 
 struct rpcent *
@@ -474,9 +221,16 @@ getrpcbyname(const char *name)
 }
 
 struct rpcent *
 }
 
 struct rpcent *
+#ifdef __LP64__
+getrpcbynumber(int number)
+#else
 getrpcbynumber(long number)
 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 *
 }
 
 struct rpcent *
@@ -488,13 +242,13 @@ getrpcent(void)
 void
 setrpcent(int stayopen)
 {
 void
 setrpcent(int stayopen)
 {
-       if (_lu_running()) lu_setrpcent();
+       if (_ds_running()) ds_setrpcent();
        else _old_setrpcent(stayopen);
 }
 
 void
 endrpcent(void)
 {
        else _old_setrpcent(stayopen);
 }
 
 void
 endrpcent(void)
 {
-       if (_lu_running()) lu_endrpcent();
+       if (_ds_running()) ds_endrpcent();
        else _old_endrpcent();
 }
        else _old_endrpcent();
 }
index 58b3996af4f0f209951510d6b1855947b0b33ed5..f249e966e83edc3c677a84552a5c5013fb529770 100644 (file)
 #include <mach/mach.h>
 #include <stdio.h>
 #include <string.h>
 #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 <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
 #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 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_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;
 
 
 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();
 
 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);
 
        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);
 
        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;
 static struct servent *
 cache_getservbyname(const char *name, const char *proto)
 {
        int i;
        struct servent *s, *res;
-       struct timeval now;
        char **aliases;
 
        char **aliases;
 
-       if (_service_cache_ttl == 0) return NULL;
        if (name == NULL) return NULL;
        if (name == NULL) return NULL;
+       if (service_cache_check() != 0) return NULL;
 
        pthread_mutex_lock(&_service_cache_lock);
 
 
        pthread_mutex_lock(&_service_cache_lock);
 
-       gettimeofday(&now, NULL);
-
        for (i = 0; i < SERVICE_CACHE_SIZE; i++)
        {
        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];
                s = (struct servent *)_service_cache[i];
+               if (s == NULL) continue;
 
                if (s->s_name != NULL) 
                {
 
                if (s->s_name != NULL) 
                {
@@ -363,20 +238,15 @@ cache_getservbyport(int port, const char *proto)
 {
        int i;
        struct servent *s, *res;
 {
        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);
 
 
        pthread_mutex_lock(&_service_cache_lock);
 
-       gettimeofday(&now, NULL);
-
        for (i = 0; i < SERVICE_CACHE_SIZE; i++)
        {
        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];
                s = (struct servent *)_service_cache[i];
+               if (s == NULL) continue;
 
                if (port == s->s_port)
                {
 
                if (port == s->s_port)
                {
@@ -394,258 +264,108 @@ cache_getservbyport(int port, const char *proto)
 }
 
 static struct servent *
 }
 
 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;
        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 (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 *
 }
 
 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;
        static int proc = -1;
-       int count;
 
        if (proc < 0)
        {
 
        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 = "";
 
        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
 }
 
 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
 }
 
 static void
-lu_setservent()
+ds_setservent()
 {
 {
-       lu_endservent();
+       ds_endservent();
 }
 
 static struct servent *
 }
 
 static struct servent *
-lu_getservent()
+ds_getservent()
 {
 {
-       struct servent *s;
        static int proc = -1;
        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;
 }
 
 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)
        res = NULL;
 
        switch (source)
@@ -661,23 +381,24 @@ getserv(const char *name, const char *proto, int port, int source)
 
        if (res != NULL)
        {
 
        if (res != NULL)
        {
-               from_cache = 1;
        }
        }
-       else if (_lu_running())
+       else if (_ds_running())
        {
                switch (source)
                {
                        case S_GET_NAME:
        {
                switch (source)
                {
                        case S_GET_NAME:
-                               res = lu_getservbyname(name, proto);
+                               res = ds_getservbyname(name, proto);
                                break;
                        case S_GET_PORT:
                                break;
                        case S_GET_PORT:
-                               res = lu_getservbyport(port, proto);
+                               res = ds_getservbyport(port, proto);
                                break;
                        case S_GET_ENT:
                                break;
                        case S_GET_ENT:
-                               res = lu_getservent();
+                               res = ds_getservent();
                                break;
                        default: res = NULL;
                }
                                break;
                        default: res = NULL;
                }
+
+               if (res != NULL) add_to_cache = 1;
        }
        else
        {
        }
        else
        {
@@ -698,10 +419,10 @@ getserv(const char *name, const char *proto, int port, int source)
                pthread_mutex_unlock(&_service_lock);
        }
 
                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 *
 }
 
 struct servent *
@@ -725,13 +446,13 @@ getservent(void)
 void
 setservent(int stayopen)
 {
 void
 setservent(int stayopen)
 {
-       if (_lu_running()) lu_setservent();
+       if (_ds_running()) ds_setservent();
        else _old_setservent();
 }
 
 void
 endservent(void)
 {
        else _old_setservent();
 }
 
 void
 endservent(void)
 {
-       if (_lu_running()) lu_endservent();
+       if (_ds_running()) ds_endservent();
        else _old_endservent();
 }
        else _old_endservent();
 }
index e7f92af4067e22d6ff12b8861408bd4577f56338..b44cd41a88776f62aa9910d09cb957425fd9e566 100644 (file)
 #include <mach/mach.h>
 #include <stdio.h>
 #include <string.h>
 #include <mach/mach.h>
 #include <stdio.h>
 #include <string.h>
-#include <rpc/types.h>
-#include <rpc/xdr.h>
 #include <pwd.h>
 #include <netinet/in.h>
 #include <pthread.h>
 #include <errno.h>
 #include <unistd.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
 #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 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_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;
 
 
 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
 
 #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
 }
 
 static int
@@ -317,117 +258,74 @@ copy_user_r(struct passwd *in, struct passwd *out, char *buffer, int buflen)
 }
 
 static void
 }
 
 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);
 
        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);
 
        pthread_mutex_unlock(&_user_cache_lock);
+
+       /* don't consult cache - it's now empty */
+       return 1;
 }
 
 static struct passwd *
 cache_getpwnam(const char *name)
 {
 }
 
 static struct passwd *
 cache_getpwnam(const char *name)
 {
-       int i;
+       uint32_t i;
        struct passwd *pw, *res;
        struct passwd *pw, *res;
-       struct timeval now;
 
 
-       if (_user_cache_ttl == 0) return NULL;
        if (name == NULL) return NULL;
        if (name == NULL) return NULL;
+       if (user_cache_check() != 0) return NULL;
 
        pthread_mutex_lock(&_user_cache_lock);
 
 
        pthread_mutex_lock(&_user_cache_lock);
 
-       gettimeofday(&now, NULL);
-
        for (i = 0; i < USER_CACHE_SIZE; i++)
        {
        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];
                pw = (struct passwd *)_user_cache[i];
-
+               if (pw == NULL) continue;
                if (pw->pw_name == NULL) continue;
 
                if (!strcmp(name, pw->pw_name))
                if (pw->pw_name == NULL) continue;
 
                if (!strcmp(name, pw->pw_name))
@@ -443,26 +341,21 @@ cache_getpwnam(const char *name)
 }
 
 static struct passwd *
 }
 
 static struct passwd *
-cache_getpwuid(int uid)
+cache_getpwuid(uid_t uid)
 {
 {
-       int i;
+       uint32_t i;
        struct passwd *pw, *res;
        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);
 
 
        pthread_mutex_lock(&_user_cache_lock);
 
-       gettimeofday(&now, NULL);
-
        for (i = 0; i < USER_CACHE_SIZE; i++)
        {
        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];
                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);
                {
                        res = copy_user(pw);
                        pthread_mutex_unlock(&_user_cache_lock);
@@ -471,274 +364,56 @@ cache_getpwuid(int uid)
        }
 
        pthread_mutex_unlock(&_user_cache_lock);
        }
 
        pthread_mutex_unlock(&_user_cache_lock);
+
        return NULL;
 }
 
 static struct passwd *
        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;
        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 *
 }
 
 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;
        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
 }
 
 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
 }
 
 static int
-lu_setpwent(void)
+ds_setpwent(void)
 {
 {
-       lu_endpwent();
+       ds_endpwent();
        return 1;
 }
 
 static struct passwd *
        return 1;
 }
 
 static struct passwd *
-lu_getpwent()
+ds_getpwent()
 {
 {
-       struct passwd *p;
        static int proc = -1;
        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 struct passwd *
 getpw_internal(const char *name, uid_t uid, int source)
 {
-       static char *loginName = NULL;
-       static struct passwd *loginEnt  = NULL;
        struct passwd *res;
        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)
        res = NULL;
 
        switch (source)
@@ -754,44 +429,47 @@ getpw_internal(const char *name, uid_t uid, int source)
 
        if (res != NULL)
        {
 
        if (res != NULL)
        {
-               from_cache = 1;
        }
        }
-       else if (_lu_running())
+       else if (_ds_running())
        {
                switch (source)
                {
                        case PW_GET_NAME:
        {
                switch (source)
                {
                        case PW_GET_NAME:
-                               res = lu_getpwnam(name);
+                               res = ds_getpwnam(name);
                                break;
                        case PW_GET_UID:
                                break;
                        case PW_GET_UID:
-                               res = lu_getpwuid(uid);
+                               res = ds_getpwuid(uid);
                                break;
                        case PW_GET_ENT:
                                break;
                        case PW_GET_ENT:
-                               res = lu_getpwent();
+                               res = ds_getpwent();
                                break;
                        default: res = NULL;
                }
                                break;
                        default: res = NULL;
                }
+
+               if (res != NULL) add_to_cache = 1;
        }
        else
        {
                pthread_mutex_lock(&_user_lock);
        }
        else
        {
                pthread_mutex_lock(&_user_lock);
+
                switch (source)
                {
                        case PW_GET_NAME:
                switch (source)
                {
                        case PW_GET_NAME:
-                               res = copy_user(_old_getpwnam(name));
+                               res = copy_user(LI_files_getpwnam(name));
                                break;
                        case PW_GET_UID:
                                break;
                        case PW_GET_UID:
-                               res = copy_user(_old_getpwuid(uid));
+                               res = copy_user(LI_files_getpwuid(uid));
                                break;
                        case PW_GET_ENT:
                                break;
                        case PW_GET_ENT:
-                               res = copy_user(_old_getpwent());
+                               res = copy_user(LI_files_getpwent());
                                break;
                        default: res = NULL;
                }
                                break;
                        default: res = NULL;
                }
+
                pthread_mutex_unlock(&_user_lock);
        }
 
                pthread_mutex_unlock(&_user_lock);
        }
 
-       if (from_cache == 0) cache_user(res);
+       if (add_to_cache == 1) cache_user(res);
 
        return res;
 }
 
        return res;
 }
@@ -800,20 +478,15 @@ static struct passwd *
 getpw(const char *name, uid_t uid, int source)
 {
        struct passwd *res = NULL;
 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);
 
 
        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
 }
 
 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;
        int status;
 
        *result = NULL;
-       errno = 0;
 
        res = getpw_internal(name, uid, source);
 
        res = getpw_internal(name, uid, source);
-       if (res == NULL) return -1;
+       if (res == NULL) return 0;
 
        status = copy_user_r(res, pwd, buffer, bufsize);
 
        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;
 
        *result = pwd;
        return 0;
@@ -859,19 +528,18 @@ getpwent(void)
        return getpw(NULL, -2, PW_GET_ENT);
 }
 
        return getpw(NULL, -2, PW_GET_ENT);
 }
 
-int
+void
 setpwent(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)
 {
 }
 
 void
 endpwent(void)
 {
-       if (_lu_running()) lu_endpwent();
-       else _old_endpwent();
+       if (_ds_running()) ds_endpwent();
+       else LI_files_endpwent();
 }
 
 int
 }
 
 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_START@
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
 
  * @APPLE_LICENSE_HEADER_END@
  */
 
+#include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <mach/mach.h>
 #include <stdlib.h>
 #include <string.h>
 #include <mach/mach.h>
+#include <servers/bootstrap.h>
 #include <pthread.h>
 #include <pthread.h>
-#ifdef DEBUG
+#include <errno.h>
+#include <notify.h>
 #include <syslog.h>
 #include <syslog.h>
+#include <unistd.h>
+#ifdef DEBUG
+#include <asl.h>
 #endif
 #endif
-#include "_lu_types.h"
-#include "lookup.h"
 #include "lu_utils.h"
 #include "netdb_async.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 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;
 
 
 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;
-       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;
 {
        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
 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;
        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 == 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)
        {
 
        if (status == MACH_SEND_INVALID_REPLY)
        {
@@ -124,25 +127,25 @@ _lu_async_send(_lu_async_request_t *r)
        return status;
 }
 
        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 (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;
        }
 
                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;
        {
                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;
                if (n->reply_port == p)
                {
                        r->next = n->next;
-                       pthread_mutex_unlock(&_lu_worklist_lock);
+                       pthread_mutex_unlock(&_li_worklist_lock);
                        return n;
                }
        }
 
                        return n;
                }
        }
 
-       pthread_mutex_unlock(&_lu_worklist_lock);
+       pthread_mutex_unlock(&_li_worklist_lock);
        return NULL;
 }
 
        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 (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)
                {
        {
                if (r->reply_port == p)
                {
-                       pthread_mutex_unlock(&_lu_worklist_lock);
+                       pthread_mutex_unlock(&_li_worklist_lock);
                        return r;
                }
        }
 
                        return r;
                }
        }
 
-       pthread_mutex_unlock(&_lu_worklist_lock);
+       pthread_mutex_unlock(&_li_worklist_lock);
        return NULL;
 }
 
 static void
        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 == 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);
 }
 
        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
 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;
        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;
        }
 
                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
        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;
 
 
        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;
        }
 
                return;
        }
 
-       for (p = _lu_worklist; p->next != NULL; p = p->next);
+       for (p = _li_worklist; p->next != NULL; p = p->next);
        p->next = r;
 
        p->next = r;
 
-       pthread_mutex_unlock(&_lu_worklist_lock);
+       pthread_mutex_unlock(&_li_worklist_lock);
 }
 
 void
 }
 
 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;
        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)
        {
        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;
        }
 
                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->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;
 
 
        r->next = NULL;
 
@@ -318,9 +377,9 @@ _lu_create_request(uint32_t proc, const char *buf, uint32_t len, void *callback,
 }
 
 kern_return_t
 }
 
 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;
 
        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;
 
 
        *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 */
 
        /* 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++)
        {
        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)
        {
        }
 
        if (status != KERN_SUCCESS)
        {
-               _lu_free_request(r);
+               _LI_free_request(r);
                return status;
        }
 
        /* Add request to worklist */
                return status;
        }
 
        /* Add request to worklist */
-       _lu_worklist_append(r);
+       _LI_worklist_append(r);
 
        *p = r->reply_port;
 
        *p = r->reply_port;
+
        return KERN_SUCCESS;
 }
 
 kern_return_t
        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;
        kern_return_t status;
        uint32_t retry;
-       boolean_t msgh_simple;
+       mig_reply_error_t *bufReply;
 
        if (msg == NULL) return -1;
 
        if (msg == NULL) return -1;
-       r = (_lu_reply_msg_t *)msg;
 
        /* If reply status was an error, resend */
 
        /* 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)
        {
        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
 }
 
 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;
 
        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++)
        {
 
        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[i] = NULL;
-               t->idata_destructor[i] = NULL;
        }
 
        if (t->ikey != NULL) free(t->ikey);
        }
 
        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 != NULL) free(t->idata);
        t->idata = NULL;
 
-       if (t->idata_destructor != NULL) free(t->idata_destructor);
-       t->idata_destructor = NULL;
-
        free(t);
 }
 
 static void
        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;
 }
 
        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
         */
 
        /*
         * 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;
 
 
        /* 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;
 }
 
        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++)
        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];
        }
 
                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)
        {
 
        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 = (void **)malloc(sizeof(void *));
-               libinfo_data->idata_destructor = (void (**)(void *))malloc(sizeof(void (*)(void *)));
        }
        else
        {
        }
        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 = (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);
        {
                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 != NULL) free(libinfo_data->idata);
-               if (libinfo_data->idata_destructor != NULL) free(libinfo_data->idata_destructor);
+               libinfo_data->idata = NULL;
+
                return 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->ikey[i] = key;
-       libinfo_data->idata[i] = NULL;
-       libinfo_data->idata_destructor[i] = destructor;
+       libinfo_data->idata[i] = tdata;
        libinfo_data->icount++;
 
        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;
        }
 
 
        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
 }
 
 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;
 
        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 *
 
        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;
 
        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];
 }
 
 
        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 == 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
 #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;
 }
 #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_
 
 #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>
 
 #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_ */
 
 #endif /* ! _LU_UTILS_H_ */
index 916842e9d27dfdfb05459be73f4508dda921b40c..95e485d151452125c493a81c2f53a70462ad444d 100644 (file)
@@ -81,8 +81,8 @@
 #ifndef _NETDB_H_
 #define _NETDB_H_
 
 #ifndef _NETDB_H_
 #define _NETDB_H_
 
-#include <stdint.h>
 #include <_types.h>
 #include <_types.h>
+#include <stdint.h>
 #include <netinet/in.h>                /* IPPORT_RESERVED */
 
 #ifndef        _SIZE_T
 #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 */
        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 */
 #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 */
 };
 
        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 */
 };
 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).
  */
 
 /*
  * 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 */
 #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 */
 #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 */
 #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()
  */
 /*
  * 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 */
 #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 */
 #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 */
 #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 */
 #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
 #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 */
 #define EAI_OVERFLOW    14     /* An argument buffer overflowed */
-#endif /* !_POSIX_C_SOURCE */
+#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
 
 /*
  * Flag values for getaddrinfo()
 
 /*
  * 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 */
 #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)
 #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) */
 #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 */
 #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 */
 #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)
 #define        AI_DEFAULT      (AI_V4MAPPED_CFG | AI_ADDRCONFIG)
-#endif /* !_POSIX_C_SOURCE */
+#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
 
 /*
  * Constants for getnameinfo()
  */
 
 /*
  * Constants for getnameinfo()
  */
-#ifndef _POSIX_C_SOURCE
+#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE)
 #define        NI_MAXHOST      1025
 #define        NI_MAXSERV      32
 #define        NI_MAXHOST      1025
 #define        NI_MAXSERV      32
-#endif /* !_POSIX_C_SOURCE */
+#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
 /*
  * Flag values for getnameinfo()
  */
 /*
  * Flag values for getnameinfo()
  */
@@ -243,16 +243,17 @@ struct rpcent {
 #define        NI_NAMEREQD     0x00000004
 #define        NI_NUMERICSERV  0x00000008
 #define        NI_DGRAM        0x00000010
 #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        '%'
 #define NI_WITHSCOPEID 0x00000020
 
 /*
  * Scope delimit character
  */
 #define SCOPE_DELIMITER        '%'
-#endif /* !_POSIX_C_SOURCE */
+#endif /* (!_POSIX_C_SOURCE || _DARWIN_C_SOURCE) */
 
 __BEGIN_DECLS
 
 __BEGIN_DECLS
+
 void           endhostent(void);
 void           endnetent(void);
 void           endprotoent(void);
 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);
 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);
 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);
 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);
 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_ */
 __END_DECLS
 
 #endif /* !_NETDB_H_ */
index 6b721117b58c32a85e1e2ba709b26e294266e3f8..3f6b347d600da00e01bf7318946f40d5149aa615 100644 (file)
 
 __BEGIN_DECLS
 
 
 __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
  
 /*
  * 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);
 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);
 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
 
 /*
  * 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);
 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
 
 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
 
 
 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
 
 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
 
 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
 
 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 = (
     DYNAMIC_CODE_GEN = YES; 
     FILESTABLE = {
         H_FILES = (
-                       membership.h,
                        membershipPriv.h,
                        membershipPriv.h,
-                       memberd_defines.h,
                        ntsid.h
         ); 
         OTHER_LINKED = (membership.c); 
                        ntsid.h
         ); 
         OTHER_LINKED = (membership.c); 
@@ -12,7 +10,7 @@
             Makefile.preamble, 
                        Makefile, 
                        Makefile.postamble, 
             Makefile.preamble, 
                        Makefile, 
                        Makefile.postamble, 
-                       memberd.defs
+                       DSmemberdMIG.defs
                ); 
         PRECOMPILED_HEADERS = (); 
         PROJECT_HEADERS = (); 
                ); 
         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@
  *
  *
  * @APPLE_LICENSE_HEADER_START@
  *
 
 #include "membership.h"
 #include "membershipPriv.h"
 
 #include "membership.h"
 #include "membershipPriv.h"
-#include "memberd.h"
-
+#include "DSmemberdMIG.h"
+#include "DSmemberdMIG_types.h"
 #include <sys/errno.h>
 #include <sys/errno.h>
-#include <servers/bootstrap.h>
 #include <mach/mach.h>
 #include <mach/mach.h>
+#include <servers/bootstrap.h>
 #include <stdlib.h>
 #include <libkern/OSByteOrder.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;
 }
 
 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;
        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;
 }
 
 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;
        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;
 }
 
 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));
        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)
        {
 
        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
        {
        }
        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;
 }
 
 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));
        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;
 {
        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));
        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));
                memcpy(sid, &request.el_gsid, sizeof(nt_sid_t));
+       }
        else
        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;
 }
 
 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));
        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;
 {
        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));
        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;
 }
 
 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;
        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()
 {
 }
 
 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)
 {
 }
 
 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)
 {
 }
 
 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)
 }
 
 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;
        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);
 
        /* 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';
 
        buffer[24] = '\0';
        buffer[23] = '0';
 
-       if (value == 0) return &buffer[23];
+       if (value == 0)
+               return &buffer[23];
 
        temp = &buffer[24];
        while (value != 0)
 
        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));
 
        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 = '-';
        {
                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)
 {
 
 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;
 
        int count = 0;
        long long temp;
 
+       if (string == NULL) return EINVAL;
+
        memset(sid, 0, sizeof(nt_sid_t));
        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;
 
        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);
        /* 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);
        {
                current++;
                sid->sid_authorities[count] = strtol(current, &current, 10);
@@ -442,7 +485,7 @@ static void ConvertBytesToHex(char **string, char **data, int numBytes)
 {
        int i;
 
 {
        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;
        {
                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)
 {
 
 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++;
        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;
 
        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;
 
 
        while (*string != '\0' && dataIndex < 16)
        {
                char nibble;
 
-               if ((*string >= '0') && (*string <= '9'))
-               {
+               if (*string >= '0' && *string <= '9')
                        nibble = *string - '0';
                        nibble = *string - '0';
-               }
-               else if ((*string >= 'A') && (*string <= 'F'))
-               {
+               else if (*string >= 'A' && *string <= 'F')
                        nibble = *string - 'A' + 10;
                        nibble = *string - 'A' + 10;
-               }
-               else if ((*string >= 'a') && (*string <= 'f'))
-               {
+               else if (*string >= 'a' && *string <= 'f')
                        nibble = *string - 'a' + 10;
                        nibble = *string - 'a' + 10;
-               }
                else
                {
                else
                {
-                       if (*string != '-') return EINVAL;
+                       if (*string != '-')
+                               return EINVAL;
                        string++;
                        continue;
                }
                        string++;
                        continue;
                }
@@ -531,3 +569,4 @@ int mbr_string_to_uuid(const char *string, uuid_t uu)
 
        return 0;
 }
 
        return 0;
 }
+
index 580b8db901c053199166dddc4b7b4704481c3c7e..35a6fe375beba2deeeff8e47485e0facfcf74995 100644 (file)
 #include <uuid/uuid.h>
 #include <ntsid.h>
 
 #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
 
 #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_ */
 
 #endif /* !_MEMBERSHIPPRIV_H_ */
index 015435bd661a78e1093956b68c1234f4c30f6d49..1be3deab37f96dd0744de9aa67d66bce8c069492 100644 (file)
@@ -12,14 +12,10 @@ NAME = netinfo
 PROJECTVERSION = 2.8
 PROJECT_TYPE = Component
 
 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
 
 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
 CODE_GEN_STYLE = DYNAMIC
@@ -28,12 +24,9 @@ LIBS =
 DEBUG_LIBS = $(LIBS)
 PROF_LIBS = $(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
 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
 
 # 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 = {
 {
     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"; 
     }; 
     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\
 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
 
 
 MAKEFILEDIR = $(MAKEFILEPATH)/pb_makefiles
index e8f240ca82ae170fa0fc0422afa8e4857e960623..019c45f6bed0ea47e63dd07b97b80c623b959c61 100644 (file)
 
 MAN3DIR=/usr/share/man/man3
 MAN5DIR=/usr/share/man/man5
 
 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-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)"
        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 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
 
 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)
 # 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,
                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,
                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)) {
        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) {
                        *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;
                        return FALSE;
                }
                status = out.ypresp_all_u.val.stat;
@@ -118,7 +118,7 @@ u_long *objp;
                                free(key);
                                key = NULL;
                        }
                                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;
 
                        if (key == NULL || val == NULL)
                                return FALSE;
@@ -133,10 +133,10 @@ u_long *objp;
                                return TRUE;
                        break;
                case YP_NOMORE:
                                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:
                        return TRUE;
                default:
-                       xdr_free(xdr_ypresp_all, (char *)&out);
+                       xdr_free((xdrproc_t)xdr_ypresp_all, (char *)&out);
                        *objp = status;
                        return TRUE;
                }
                        *objp = status;
                        return TRUE;
                }
@@ -183,7 +183,7 @@ yp_all(indomain, inmap, incallback)
        ypresp_data = (void *) incallback->data;
 
        (void) clnt_call(clnt, YPPROC_ALL,
        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);
        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 <rpc/xdr.h>
 #include <rpcsvc/yp.h>
 #include <rpcsvc/ypclnt.h>
+#include <notify.h>
+#include <pthread.h>
 #include "ypinternal.h"
 
 #include "ypinternal.h"
 
+extern int notify_register_plain(char *, int *);
+
 struct dom_binding *_ypbindlist = NULL;
 char _yp_domain[MAXHOSTNAMELEN] = { '\0' };
 
 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;
        struct dom_binding **ypdb;
 {
        static int      pid = -1;
-       char            path[MAXPATHLEN];
        struct dom_binding *ysd, *ysd2;
        struct ypbind_resp ypbr;
        struct timeval  tv;
        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;
        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             count = 0;
        u_short         port;
+       int status, notify_token;
+       uint64_t abort;
+       char *notify_name;
 
        /*
         * test if YP is running or not
         */
 
        /*
         * 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;
        }
                return YPERR_YPBIND;
        }
-       (void)close(fd);
+
+       close(fd);
 
        gpid = getpid();
 
        gpid = getpid();
-       if (!(pid == -1 || pid == gpid)) {
+       if (!((pid == -1) || (pid == gpid)))
+       {
                ysd = _ypbindlist;
                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;
                }
                        ysd2 = ysd->dom_pnext;
                        free(ysd);
                        ysd = ysd2;
                }
+
                _ypbindlist = NULL;
        }
                _ypbindlist = NULL;
        }
+
        pid = gpid;
 
        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)
 
        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;
        }
                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;
                }
        }
                        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;
                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");
                        clnt_pcreateerror("clnttcp_create");
-                       if (new)
-                               free(ysd);
+                       if (new) free(ysd);
+                       if (notify_token != -1) notify_cancel(notify_token);
                        return YPERR_YPBIND;
                }
                        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);
                        /*
                         * 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;
                }
                        return YPERR_YPBIND;
                }
+
                tv.tv_sec = _yplib_timeout;
                tv.tv_usec = 0;
                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);
                        count++;
                        clnt_destroy(client);
-                       ysd->dom_vers = -1;
+                       ysd->dom_vers = proto;
                        goto again;
                }
                        goto again;
                }
+
                clnt_destroy(client);
                clnt_destroy(client);
-gotdata:
+
                bn = &ypbr.ypbind_resp_u.ypbind_bindinfo;
                memcpy(&port, &bn->ypbind_binding_port, sizeof port);
                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
                        /*
                         * 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.
                         */
                         * 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;
                }
                        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;
                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;
                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';
        }
                ysd->dom_domain[sizeof ysd->dom_domain-1] = '\0';
        }
+
        tv.tv_sec = _yplib_timeout / 2;
        tv.tv_usec = 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_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;
        }
                goto again;
        }
+
+       if (notify_token != -1) notify_cancel(notify_token);
+
        if (fcntl(ysd->dom_socket, F_SETFD, 1) == -1)
                perror("fcntl: F_SETFD");
 
        if (fcntl(ysd->dom_socket, F_SETFD, 1) == -1)
                perror("fcntl: F_SETFD");
 
-       if (new) {
+       if (new != 0)
+       {
                ysd->dom_pnext = _ypbindlist;
                _ypbindlist = ysd;
        }
                ysd->dom_pnext = _ypbindlist;
                _ypbindlist = ysd;
        }
-       if (ypdb != NULL)
-               *ypdb = ysd;
+
+       if (ypdb != NULL) *ypdb = ysd;
        return 0;
 }
 
        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;
        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 ||
 
        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);
 
        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;
        }
                goto again;
        }
+
        if (!(r = ypprot_err(yprkv.stat))) {
                *outkeylen = yprkv.key.keydat_len;
                if ((*outkey = malloc(*outkeylen + 1)) == NULL)
        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';
                }
        }
                        (*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;
 }
        _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;
        struct ypresp_maplist ypml;
        struct timeval  tv;
        int tries = 0, r;
+       static int proto = YP_BIND_UDP;
 
 again:
        if (_yp_dobind(indomain, &ysd) != 0)
 
 again:
        if (_yp_dobind(indomain, &ysd) != 0)
@@ -91,14 +92,18 @@ again:
 
        memset(&ypml, 0, sizeof ypml);
 
 
        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;
        }
                goto again;
        }
+
        *outmaplist = ypml.maps;
        /* NO: xdr_free(xdr_ypresp_maplist, &ypml); */
        _yp_unbind(ysd);
        *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;
        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 ||
 
        if (indomain == NULL || *indomain == '\0' ||
            strlen(indomain) > YPMAXDOMAIN || inmap == NULL ||
@@ -101,19 +102,23 @@ again:
 
        (void)memset(&yprm, 0, sizeof yprm);
 
 
        (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;
        }
                goto again;
        }
+
        if (!(r = ypprot_err(yprm.stat))) {
                if ((*outname = strdup(yprm.peer)) == NULL)
                        r = YPERR_RESRC;
        }
        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;
 }
        _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;
        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 ||
 
        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,
        (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
        /*
         * XXX
         * NIS+ YP emulation package does not impliment YPPROC_ORDER
@@ -111,13 +112,21 @@ again:
                r = YPERR_YPERR;
                goto bail;
        }
                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;
        }
                goto again;
        }
+
        *outorder = ypro.ordernum;
        *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);
        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
 .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
 .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
 .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 **));
 
 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 *,
 #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;
        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 ||
 
        if (indomain == NULL || *indomain == '\0' || 
            strlen(indomain) > YPMAXDOMAIN || inmap == NULL ||
@@ -227,14 +228,19 @@ again:
 
        memset(&yprv, 0, sizeof yprv);
 
 
        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;
        }
                goto again;
        }
+
        if (!(r = ypprot_err(yprv.stat))) {
                *outvallen = yprv.val.valdat_len;
                if ((*outval = malloc(*outvallen + 1)) == NULL) {
        if (!(r = ypprot_err(yprv.stat))) {
                *outvallen = yprv.val.valdat_len;
                if ((*outval = malloc(*outvallen + 1)) == NULL) {
@@ -251,7 +257,7 @@ again:
 #endif
        }
 out:
 #endif
        }
 out:
-       xdr_free(xdr_ypresp_val, (char *) &yprv);
+       xdr_free((xdrproc_t)xdr_ypresp_val, (char *) &yprv);
        _yp_unbind(ysd);
        return r;
 }
        _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;
        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 ||
 
        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);
 
        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;
        }
                goto again;
        }
+
        if (!(r = ypprot_err(yprkv.stat))) {
                *outkeylen = yprkv.key.keydat_len;
                if ((*outkey = malloc(*outkeylen + 1)) == NULL)
        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';
                }
        }
                        (*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;
 }
        _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
 
          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
 
 
 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 = \
 OTHER_CFLAGS = \
+       -D__DARWIN_NON_CANCELABLE=1 \
        -Dsetrpcent=_old_setrpcent \
        -Dgetrpcent=_old_getrpcent \
        -Dendrpcent=_old_endrpcent \
        -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)
 # 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 */
 };
 
        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 {
 
 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;
        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();
 
        if (gethostname(machname, MAX_MACHINE_NAME) == -1)
                abort();
@@ -232,7 +232,7 @@ authunix_create_default()
         if (len > maxgrplist) {
             len = maxgrplist;
         }
         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 {
  * Unix style credentials.
  */
 struct authunix_parms {
+#ifdef __LP64__
+       unsigned int     aup_time;
+#else
        unsigned long    aup_time;
        unsigned long    aup_time;
+#endif
        char    *aup_machname;
        int      aup_uid;
        int      aup_gid;
        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),
            && 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);
                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;
        struct sockaddr_in6 *sin6;
        int proto, portrange, portlow;
        u_int16_t port;
-       int salen;
+       u_int32_t salen;
 
        if (sa == NULL) {
                salen = sizeof(myaddr);
 
        if (sa == NULL) {
                salen = sizeof(myaddr);
@@ -120,7 +120,7 @@ bindresvport_sa(sd, sa)
        sa->sa_len = salen;
 
        if (port == 0) {
        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)
 
                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 {
                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 */
                        unsigned long low;      /* lowest verion supported */
                        unsigned long high;     /* highest verion supported */
+#endif
                } RE_vers;
                struct {                /* maybe meaningful if RPC_FAILED */
                } RE_vers;
                struct {                /* maybe meaningful if RPC_FAILED */
+#ifdef __LP64__
+                       int s1;
+                       int s2;
+#else
                        long s1;
                        long s2;
                        long s1;
                        long s2;
+#endif
                } RE_lb;                /* life boot & debugging only */
        } ru;
 #define        re_errno        ru.RE_errno
                } 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 {
 {
        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 */
                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 */
                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;
  * 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;
  *     xdrproc_t xargs;
  *     caddr_t argsp;
  *     xdrproc_t xres;
@@ -245,16 +259,27 @@ struct CLIENT
  * and network administration.
  */
 
  * 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)
 #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
  */
 
 
 /*
  * By convention, procedure 0 takes null arguments and returns them
  */
 
+#ifdef __LP64__
+#define NULLPROC ((unsigned int)0)
+#else
 #define NULLPROC ((unsigned long)0)
 #define NULLPROC ((unsigned long)0)
+#endif
 
 /*
  * Below are the client handle creation routines for the various
 
 /*
  * 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)
  * 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
  */
 __BEGIN_DECLS
+#ifdef __LP64__
+extern CLIENT *clntraw_create  __P((unsigned int, unsigned int));
+#else
 extern CLIENT *clntraw_create  __P((unsigned long, unsigned long));
 extern CLIENT *clntraw_create  __P((unsigned long, unsigned long));
+#endif
 __END_DECLS
 
 
 __END_DECLS
 
 
@@ -279,12 +308,16 @@ __END_DECLS
  * CLIENT *
  * clnt_create(host, prog, vers, prot);
  *     char *host;     -- hostname
  * 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
  *     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 *));
 extern CLIENT *clnt_create     __P((char *, unsigned long, unsigned long, char *));
+#endif
 __END_DECLS
 
 
 __END_DECLS
 
 
@@ -293,19 +326,28 @@ __END_DECLS
  * CLIENT *
  * clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz)
  *     struct sockaddr_in *raddr;
  * 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
  *     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 *,
 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
 
 
 __END_DECLS
 
 
@@ -314,8 +356,8 @@ __END_DECLS
  * CLIENT *
  * clntudp_create(raddr, program, version, wait, sockp)
  *     struct sockaddr_in *raddr;
  * 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;
  *
  *     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;
  * 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
  *     struct timeval wait;
  *     int *sockp;
  *     unsigned int sendsz;
  *     unsigned int recvsz;
  */
 __BEGIN_DECLS
+#ifdef __LP64__
 extern CLIENT *clntudp_create  __P((struct sockaddr_in *,
 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 *,
 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
 
 
 __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)
  */
 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;
        char *hostname;
        u_long prog;
        u_long vers;
        char *proto;
+#endif
 {
        struct hostent *h;
        struct protoent *p;
 {
        struct hostent *h;
        struct protoent *p;
index 84db7359dc3dc686ad14d03c51cc08c3479f42da..a48c79a73a6d8a7ca6f16c600707d4d7edf0d3b9 100644 (file)
@@ -131,9 +131,11 @@ clnt_sperror(rpch, s)
                break;
 
        case RPC_VERSMISMATCH:
                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;
 
                str += strlen(str);
                break;
 
@@ -152,16 +154,20 @@ clnt_sperror(rpch, s)
                break;
 
        case RPC_PROGVERSMISMATCH:
                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 */
                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;
        }
                str += strlen(str);
                break;
        }
index 0fccf080cbc0431d6a052c0829fa264e7f75e04b..75a44aa4dd2595ae344d56763dc11d9094910b85 100644 (file)
@@ -109,13 +109,18 @@ void      svc_getreq();
  */
 CLIENT *
 clntraw_create(prog, vers)
  */
 CLIENT *
 clntraw_create(prog, vers)
+#ifdef __LP64__
+       uint32_t prog;
+       uint32_t vers;
+#else
        u_long prog;
        u_long vers;
        u_long prog;
        u_long vers;
+#endif
 {
        register struct clntraw_private *clp = clntraw_private;
        struct rpc_msg call_msg;
        XDR *xdrs = &clp->xdr_stream;
 {
        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));
 
        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;
 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;
        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 ++ ;
        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)) ||
        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)) ||
            (! 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 */
 
        /*
        (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
  *
  * 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).
  *
  * 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();
 
 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();
 
 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 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 */
        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 *
  * 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;
 {
        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;
        }
                rpc_createerr.cf_stat = RPC_SYSTEMERROR;
                rpc_createerr.cf_error.re_errno = errno;
                goto fooy;
        }
+
        ct = (struct ct_data *)mem_alloc(sizeof(*ct));
        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;
                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 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));
                        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
         */
                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);
                *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;
                        rpc_createerr.cf_stat = RPC_SYSTEMERROR;
                        rpc_createerr.cf_error.re_errno = errno;
-                       (void)close(*sockp);
+                       close(*sockp);
                        goto fooy;
                }
                        goto fooy;
                }
+
                ct->ct_closeit = TRUE;
                ct->ct_closeit = TRUE;
-       } else {
+       }
+       else
+       {
                ct->ct_closeit = FALSE;
        }
 
                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;
         * 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;
 
        /*
        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;
        }
                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;
        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
         */
        /*
         * 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;
        }
                goto fooy;
        }
+
        ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
        XDR_DESTROY(&(ct->ct_xdrs));
 
        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.
         */
         * 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_ops = &tcp_ops;
-       h->cl_private = (caddr_t) ct;
+       h->cl_private = (caddr_t)ct;
        h->cl_auth = authnone_create();
        h->cl_auth = authnone_create();
-       return (h);
+       return h;
 
 fooy:
 
 fooy:
-       /*
-        * Something goofed, free stuff and barf
-        */
        mem_free((caddr_t)ct, sizeof(struct ct_data));
        mem_free((caddr_t)h, sizeof(CLIENT));
        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
 }
 
 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;
 
        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 =
        }
 
        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));
        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)) ||
        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)) ||
            (! 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);
                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;
        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 */
                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:
 
        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:
                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;
                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;
        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);
                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@
  * 
  *
  * @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();
 
 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;
 
 /*
 extern int errno;
 
 /*
@@ -106,8 +108,8 @@ struct cu_data {
        bool_t             cu_closeit;
        struct sockaddr_in cu_raddr;
        int                cu_rlen;
        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;
        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.
  */
  * 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;
 {
        CLIENT *cl;
-       register struct cu_data *cu = NULL;
+       struct cu_data *cu = NULL;
        struct timeval now;
        struct rpc_msg call_msg;
        int rfd;
        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));
 
        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;
        }
                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);
        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;
        }
                rpc_createerr.cf_stat = RPC_SYSTEMERROR;
                rpc_createerr.cf_error.re_errno = errno;
                goto fooy;
        }
+
        cu->cu_outbuf = &cu->cu_inbuf[recvsz];
 
        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);
        }
                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);
        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_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)))
        
        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;
        }
                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;
        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));
        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);
                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;
                }
                        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);
                /* 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;
                (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_closeit = FALSE;
        }
+
        cu->cu_sock = *sockp;
        cl->cl_auth = authnone_create();
        return (cl);
        cu->cu_sock = *sockp;
        cl->cl_auth = authnone_create();
        return (cl);
+
 fooy:
 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)
 }
 
 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;
        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 
 }
 
 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;
        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;
        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;
 
        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;
        }
 
        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);
 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))++;
        /*
         * 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);
        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:
        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);
        }
                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
         */
        /*
         * 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);
        }
                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.
        /*
         * 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);
        reply_msg.acpted_rply.ar_results.proc = xresults;
        FD_ZERO(&mask);
        FD_SET(cu->cu_sock, &mask);
-       for (;;) {
+       for (;;)
+       {
                readfds = mask;
                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:
                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;
                        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:
 
        switch (request) {
        case CLSET_TIMEOUT:
-               cu->cu_total = *(struct timeval *)info;
+               cu->cu_total_timeout = *(struct timeval *)info;
                break;
        case CLGET_TIMEOUT:
                break;
        case CLGET_TIMEOUT:
-               *(struct timeval *)info = cu->cu_total;
+               *(struct timeval *)info = cu->cu_total_timeout;
                break;
        case CLSET_RETRY_TIMEOUT:
                break;
        case CLSET_RETRY_TIMEOUT:
-               cu->cu_wait = *(struct timeval *)info;
+               cu->cu_retry_timeout = *(struct timeval *)info;
                break;
        case CLGET_RETRY_TIMEOUT:
                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;
                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)
 
 struct rpcent *
 getrpcbynumber(number)
+#ifdef __LP64__
+       int32_t number;
+#else
        register long number;
        register long number;
+#endif
 {
        register struct rpcdata *d = _rpcdata();
        register struct rpcent *p;
 {
        register struct rpcdata *d = _rpcdata();
        register struct rpcent *p;
+#ifdef __LP64__
+       int x;
+       
+       x = number;
+#endif
 
        if (d == 0)
                return (0);
        setrpcent(0);
 
        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);
        }
        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"
 
 
 #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.
 
 /*
  * Set a mapping between program,version and port.
@@ -88,10 +92,17 @@ void clnt_perror();
  */
 bool_t
 pmap_set(program, version, protocol, port)
  */
 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;
        u_long program;
        u_long version;
        int protocol;
        u_short port;
+#endif
 {
        struct sockaddr_in myaddress;
        int socket = -1;
 {
        struct sockaddr_in myaddress;
        int socket = -1;
@@ -99,28 +110,24 @@ pmap_set(program, version, protocol, port)
        struct pmap parms;
        bool_t rslt;
 
        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);
 
 
        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;
        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);
        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)
  */
 bool_t
 pmap_unset(program, version)
+#ifdef __LP64__
+       uint32_t program;
+       uint32_t version;
+#else
        u_long program;
        u_long version;
        u_long program;
        u_long version;
+#endif
 {
        struct sockaddr_in myaddress;
        int socket = -1;
 {
        struct sockaddr_in myaddress;
        int socket = -1;
@@ -138,22 +150,23 @@ pmap_unset(program, version)
        struct pmap parms;
        bool_t rslt;
 
        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);
 
 
        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_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);
        CLNT_DESTROY(client);
-       (void)close(socket);
-       return (rslt);
+       close(socket);
+       return rslt;
 }
 }
index f89b81e4653ec42202eb9d264e1b09cab81c4c03..c07a81902bd3f6eacdd30800d4a0c24bbd4ed68b 100644 (file)
 #include <sys/cdefs.h>
 
 __BEGIN_DECLS
 #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 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 *,
 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,
 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 *,
 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 */
 __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
 
 #define NAMELEN 255
 #define MAX_BROADCAST_SIZE 1400
 
-#include "pmap_wakeup.h"
-
 extern int errno;
 
 /*
 extern int errno;
 
 /*
@@ -94,16 +92,13 @@ pmap_getmaps(address)
        struct timeval minutetimeout;
        register CLIENT *client;
 
        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) {
        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);
                        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 <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.
  */
 
 /*
  * 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;
        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);
        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_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);
                        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;
                }
                        rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
                }
+
                CLNT_DESTROY(client);
        }
                CLNT_DESTROY(client);
        }
-       (void)close(socket);
+
+       close(socket);
        address->sin_port = 0;
        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)
 #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 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)
 #define PMAPPROC_GETPORT       ((unsigned long)3)
 #define PMAPPROC_DUMP          ((unsigned long)4)
 #define PMAPPROC_CALLIT                ((unsigned long)5)
+#endif
 
 struct pmap {
 
 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;
        long unsigned pm_prog;
        long unsigned pm_vers;
        long unsigned pm_prot;
        long unsigned pm_port;
+#endif
 };
 
 struct pmaplist {
 };
 
 struct pmaplist {
index a5bd77d0a464bd9404afbecc5e72e6c660a821b9..6c286c7d6652f4ce8a229f90b668e0d16aa834f7 100644 (file)
@@ -133,8 +133,7 @@ xdr_pmaplist(xdrs, rp)
                 */
                if (freeing)
                        next = &((*rp)->pml_next); 
                 */
                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);
        }
                        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 <arpa/inet.h>
 #define MAX_BROADCAST_SIZE 1400
 
-#include "pmap_wakeup.h"
-
 static struct timeval timeout = { 3, 0 };
 
 
 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)
 */
 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;
        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;
 {
        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;
 
        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) {
        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;
                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;
                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;
        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);
                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)
 
 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 */
        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 */
        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;
 {
        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;
        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;
        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;
 
        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.
        /*
         * 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;
        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)) {
 
                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);
                }  /* 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;
                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;
 #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);
                (void)xdr_replymsg(xdrs, &msg);
                (void)(*xresults)(xdrs, resultsp);
                xdr_destroy(xdrs);
index a768d462cb5d84da598190e3261139377299800a..9ffbd1cb458c7dfc8a738128722c9693d6876844 100644 (file)
 #include <sys/cdefs.h>
 
 struct rmtcallargs {
 #include <sys/cdefs.h>
 
 struct rmtcallargs {
+#ifdef __LP64__
+       unsigned int prog, vers, proc, arglen;
+#else
        unsigned long prog, vers, proc, arglen;
        unsigned long prog, vers, proc, arglen;
+#endif
        caddr_t args_ptr;
        xdrproc_t xdr_args;
 };
 
 struct rmtcallres {
        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;
        unsigned long *port_ptr;
        unsigned long resultslen;
+#endif
        caddr_t results_ptr;
        xdrproc_t xdr_results;
 };
        caddr_t results_ptr;
        xdrproc_t xdr_results;
 };
index 4d302e6087497f01143d18141ee0fe0129ddf3c3..920ae867baf069e4d4c6119a7fd8c17f1e2ae0de 100644 (file)
@@ -6,7 +6,7 @@
 
 #include "pmap_wakeup.h"
 
 
 #include "pmap_wakeup.h"
 
-void pmap_wakeup(void)
+int pmap_wakeup(void)
 {
        struct sockaddr_un sun;
        int fd;
 {
        struct sockaddr_un sun;
        int fd;
@@ -19,13 +19,14 @@ void pmap_wakeup(void)
 
        fd = socket(AF_UNIX, SOCK_STREAM, 0);
        if (fd == -1)
 
        fd = socket(AF_UNIX, SOCK_STREAM, 0);
        if (fd == -1)
-               return;
+               return -1;
 
        if (connect(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
                close(fd);
 
        if (connect(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) {
                close(fd);
-               return;
+               return -1;
        }
 
        read(fd, &b, sizeof(b));
        close(fd);
        }
 
        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__
 
 #ifndef __PMAP_WAKEUP_H__
 #define __PMAP_WAKEUP_H__
 
-void pmap_wakeup(void);
+int pmap_wakeup(void);
 
 #endif
 
 #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;
 {
        register XDR *xdrs;
        register struct rpc_msg *cmsg;
 {
+#ifdef __LP64__
+       int *buf;
+#else
        register long *buf;
        register long *buf;
+#endif
        register struct opaque_auth *oa;
 
        if (xdrs->x_op == XDR_ENCODE) {
        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);
                }
                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
                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);
                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);
                        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);
                                buf += RNDUP(oa->oa_length) / sizeof (long);
+#endif
                        }
                        oa = &cmsg->rm_call.cb_verf;
                        IXDR_PUT_ENUM(buf, oa->oa_flavor);
                        }
                        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....
                        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);
                                */
                        }
                                buf += RNDUP(oa->oa_length) / sizeof (long);
                                */
                        }
@@ -126,7 +142,11 @@ xdr_callmsg(xdrs, cmsg)
                }
        }
        if (xdrs->x_op == XDR_DECODE) {
                }
        }
        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);
                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);
                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);
                                }
                                        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));
                                buf = (long *)XDR_INLINE(xdrs, RNDUP(oa->oa_length));
+#endif
                                if (buf == NULL) {
                                        if (xdr_opaque(xdrs, oa->oa_base,
                                            oa->oa_length) == FALSE) {
                                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....
                                        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;
                                        */
                                }
                        }
                        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);
                        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) {
                        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);
                                }
                                        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));
                                buf = (long *)XDR_INLINE(xdrs, RNDUP(oa->oa_length));
+#endif
                                if (buf == NULL) {
                                        if (xdr_opaque(xdrs, oa->oa_base,
                                            oa->oa_length) == FALSE) {
                                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...
                                        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
 
 #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)
 #define RPC_MSG_VERSION                ((unsigned long) 2)
+#endif
 #define RPC_SERVICE_PORT       ((unsigned short) 2048)
 
 /*
 #define RPC_SERVICE_PORT       ((unsigned short) 2048)
 
 /*
@@ -111,8 +115,13 @@ struct accepted_reply {
        enum accept_stat        ar_stat;
        union {
                struct {
        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;
                } AR_versions;
                struct {
                        caddr_t where;
@@ -131,8 +140,13 @@ struct rejected_reply {
        enum reject_stat rj_stat;
        union {
                struct {
        enum reject_stat rj_stat;
        union {
                struct {
+#ifdef __LP64__
+                       unsigned int low;
+                       unsigned int high;
+#else
                        unsigned long low;
                        unsigned long high;
                        unsigned long low;
                        unsigned long high;
+#endif
                } RJ_versions;
                enum auth_stat RJ_why;  /* why authentication did not work */
        } ru;
                } 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 {
  * 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;
        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 */
 };
        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 {
  * The rpc message
  */
 struct rpc_msg {
+#ifdef __LP64__
+       unsigned int                    rm_xid;
+#else
        unsigned long                   rm_xid;
        unsigned long                   rm_xid;
+#endif
        enum msg_type           rm_direction;
        union {
                struct call_body RM_cmb;
        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] = {
 }
 
 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 } };
 
 /*
        { __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;
        }
        /* 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;
        error->re_lb.s1 = (long)MSG_ACCEPTED;
        error->re_lb.s2 = (long)acpt_stat;
+#endif
 }
 
 static void 
 }
 
 static void 
@@ -266,8 +271,13 @@ rejected(rjct_stat, error)
        }
        /* something's wrong, but we don't know what ... */
        error->re_status = RPC_FAILED;
        }
        /* 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;
        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;
 
        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);
                error->re_lb.s1 = (long)(msg->rm_reply.rp_stat);
+#endif
                break;
        }
        switch (error->re_status) {
                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)
  */
 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;
        SVCXPRT *xprt;
        u_long prog;
        u_long vers;
        void (*dispatch)();
        int protocol;
+#endif
 {
        struct svc_callout *prev;
        register struct svc_callout *s;
 {
        struct svc_callout *prev;
        register struct svc_callout *s;
@@ -186,8 +194,13 @@ pmap_it:
  */
 void
 svc_unregister(prog, vers)
  */
 void
 svc_unregister(prog, vers)
+#ifdef __LP64__
+       uint32_t prog;
+       uint32_t vers;
+#else
        u_long prog;
        u_long vers;
        u_long prog;
        u_long vers;
+#endif
 {
        struct svc_callout *prev;
        register struct svc_callout *s;
 {
        struct svc_callout *prev;
        register struct svc_callout *s;
@@ -347,9 +360,15 @@ svcerr_noprog(xprt)
  */
 void  
 svcerr_progvers(xprt, low_vers, high_vers)
  */
 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;
        register SVCXPRT *xprt; 
        u_long low_vers;
        u_long high_vers;
+#endif
 {
        struct rpc_msg rply;
 
 {
        struct rpc_msg rply;
 
index 55df0fdafb27f680e891a9f9fb7da321d5041456..ca1270db2a75f584a56cae515a2936869dc74a61 100644 (file)
@@ -171,9 +171,15 @@ typedef struct {
  * Service request
  */
 struct svc_req {
  * 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 */
        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 */
        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;
  *
  * 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
  *     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));
 extern bool_t  svc_register __P((SVCXPRT *, unsigned long, unsigned long, void (*)(), int));
+#endif
 __END_DECLS
 
 /*
  * Service un-registration
  *
  * svc_unregister(prog, vers)
 __END_DECLS
 
 /*
  * Service un-registration
  *
  * svc_unregister(prog, vers)
- *     unsigned long prog;
- *     unsigned long vers;
+ *     u_long prog;
+ *     u_long vers;
  */
 __BEGIN_DECLS
  */
 __BEGIN_DECLS
+#ifdef __LP64__
+extern void    svc_unregister __P((unsigned int, unsigned int));
+#else
 extern void    svc_unregister __P((unsigned long, unsigned long));
 extern void    svc_unregister __P((unsigned long, unsigned long));
+#endif
 __END_DECLS
 
 /*
 __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 *));
 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));
 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 *));
 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;
        register enum auth_stat stat;
        XDR xdrs;
        register struct authunix_parms *aup;
+#ifdef __LP64__
+       int *buf;
+#else
        register long *buf;
        register long *buf;
+#endif
        struct area {
                struct authunix_parms area_aup;
                char area_machname[MAX_MACHINE_NAME+1];
        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);
        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);
        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);
        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);
                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);
                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);
                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
                 */
                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;
                        */
                        stat = AUTH_BADCRED;
                        goto done;
index 22687327ddc149c4163fed9b2efc1e1670ff99bf..3796844273ee89d9d3d2aea2ac50422a3c7054d7 100644 (file)
@@ -89,8 +89,11 @@ registerrpc(prognum, versnum, procnum, progname, inproc, outproc)
 {
        
        if (procnum == NULLPROC) {
 {
        
        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) {
                return (-1);
        }
        if (transp == 0) {
@@ -136,7 +139,7 @@ universal(rqstp, transp)
         * enforce "procnum 0 is echo" convention
         */
        if (rqstp->rq_proc == NULLPROC) {
         * 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);
                }
                        (void) fprintf(stderr, "xxx\n");
                        exit(1);
                }
@@ -153,7 +156,7 @@ universal(rqstp, transp)
                                return;
                        }
                        outdata = (*(pl->p_progname))(xdrbuf);
                                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)) {
                                /* 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;
        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) {
 
        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 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);
 
        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);
                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;
        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) {
 
        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);
 
     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))
        if (rlen == -1 && errno == EINTR)
                goto again;
        if (rlen < 4*sizeof(u_long))
index 33ae11ca47fa49a6dc0a33ddb9099bdbf21e1827..0fe5adc1c01341898991cc5f4fe8650d9102f0ae 100644 (file)
 #endif
 #include <sys/time.h>
 
 #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 */
 #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>
 
 #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"
  */
 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)
 #define XDR_FALSE      ((long) 0)
 #define XDR_TRUE       ((long) 1)
+#endif
 #define LASTUNSIGNED   ((u_int) 0-1)
 
 /*
 #define LASTUNSIGNED   ((u_int) 0-1)
 
 /*
@@ -126,19 +137,19 @@ xdr_int(xdrs, ip)
        XDR *xdrs;
        int *ip;
 {
        XDR *xdrs;
        int *ip;
 {
-       long l;
+       xdrlong_t l;
 
        switch (xdrs->x_op) {
 
        case XDR_ENCODE:
 
        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);
                }
 
        case XDR_DECODE:
                if (!XDR_GETLONG(xdrs, &l)) {
                        return (FALSE);
                }
-               *ip = (int) l;
+               *ip = l;
                return (TRUE);
 
        case XDR_FREE:
                return (TRUE);
 
        case XDR_FREE:
@@ -156,19 +167,19 @@ xdr_u_int(xdrs, up)
        XDR *xdrs;
        u_int *up;
 {
        XDR *xdrs;
        u_int *up;
 {
-       u_long l;
+       xdrlong_t l;
 
        switch (xdrs->x_op) {
 
        case XDR_ENCODE:
 
        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:
 
        case XDR_DECODE:
-               if (!XDR_GETLONG(xdrs, (long *)&l)) {
+               if (!XDR_GETLONG(xdrs, &l)) {
                        return (FALSE);
                }
                        return (FALSE);
                }
-               *up = (u_int) l;
+               *up = l;
                return (TRUE);
 
        case XDR_FREE:
                return (TRUE);
 
        case XDR_FREE:
@@ -186,7 +197,11 @@ xdr_u_int(xdrs, up)
 bool_t
 xdr_long(xdrs, lp)
        XDR *xdrs;
 bool_t
 xdr_long(xdrs, lp)
        XDR *xdrs;
+#ifdef __LP64__
+       int *lp;
+#else
        long *lp;
        long *lp;
+#endif
 {
        switch (xdrs->x_op) {
        case XDR_ENCODE:
 {
        switch (xdrs->x_op) {
        case XDR_ENCODE:
@@ -207,13 +222,17 @@ xdr_long(xdrs, lp)
 bool_t
 xdr_u_long(xdrs, ulp)
        XDR *xdrs;
 bool_t
 xdr_u_long(xdrs, ulp)
        XDR *xdrs;
+#ifdef __LP64__
+       unsigned int *ulp;
+#else
        u_long *ulp;
        u_long *ulp;
-{
+#endif
+{      
        switch (xdrs->x_op) {
        case XDR_ENCODE:
        switch (xdrs->x_op) {
        case XDR_ENCODE:
-               return (XDR_PUTLONG(xdrs, (long *)ulp));
+               return (XDR_PUTLONG(xdrs, (const xdrlong_t *)ulp));
        case XDR_DECODE:
        case XDR_DECODE:
-               return (XDR_GETLONG(xdrs, (long *)ulp));
+               return (XDR_GETLONG(xdrs, (xdrlong_t *)ulp));
        case XDR_FREE:
                return (TRUE);
        }
        case XDR_FREE:
                return (TRUE);
        }
@@ -231,19 +250,19 @@ xdr_int32_t(xdrs, int32_p)
        XDR *xdrs;
        int32_t *int32_p;
 {
        XDR *xdrs;
        int32_t *int32_p;
 {
-       long l;
+       xdrlong_t l;
 
        switch (xdrs->x_op) {
 
        case XDR_ENCODE:
 
        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);
                }
 
        case XDR_DECODE:
                if (!XDR_GETLONG(xdrs, &l)) {
                        return (FALSE);
                }
-               *int32_p = (int32_t) l;
+               *int32_p = l;
                return (TRUE);
 
        case XDR_FREE:
                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;
 {
        XDR *xdrs;
        u_int32_t *u_int32_p;
 {
-       u_long l;
+       u_int32_t l;
 
        switch (xdrs->x_op) {
 
        case XDR_ENCODE:
 
        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:
 
        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:
                return (TRUE);
 
        case XDR_FREE:
@@ -293,19 +310,19 @@ xdr_short(xdrs, sp)
        XDR *xdrs;
        short *sp;
 {
        XDR *xdrs;
        short *sp;
 {
-       long l;
+       xdrlong_t l;
 
        switch (xdrs->x_op) {
 
        case XDR_ENCODE:
 
        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);
                }
 
        case XDR_DECODE:
                if (!XDR_GETLONG(xdrs, &l)) {
                        return (FALSE);
                }
-               *sp = (short) l;
+               *sp = l;
                return (TRUE);
 
        case XDR_FREE:
                return (TRUE);
 
        case XDR_FREE:
@@ -323,19 +340,19 @@ xdr_u_short(xdrs, usp)
        XDR *xdrs;
        u_short *usp;
 {
        XDR *xdrs;
        u_short *usp;
 {
-       u_long l;
+       xdrlong_t l;
 
        switch (xdrs->x_op) {
 
        case XDR_ENCODE:
 
        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:
 
        case XDR_DECODE:
-               if (!XDR_GETLONG(xdrs, (long *)&l)) {
+               if (!XDR_GETLONG(xdrs, &l)) {
                        return (FALSE);
                }
                        return (FALSE);
                }
-               *usp = (u_short) l;
+               *usp = l;
                return (TRUE);
 
        case XDR_FREE:
                return (TRUE);
 
        case XDR_FREE:
@@ -354,19 +371,19 @@ xdr_int16_t(xdrs, int16_p)
        XDR *xdrs;
        int16_t *int16_p;
 {
        XDR *xdrs;
        int16_t *int16_p;
 {
-       long l;
+       xdrlong_t l;
 
        switch (xdrs->x_op) {
 
        case XDR_ENCODE:
 
        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);
                }
 
        case XDR_DECODE:
                if (!XDR_GETLONG(xdrs, &l)) {
                        return (FALSE);
                }
-               *int16_p = (int16_t) l;
+               *int16_p = l;
                return (TRUE);
 
        case XDR_FREE:
                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;
 {
        XDR *xdrs;
        u_int16_t *u_int16_p;
 {
-       u_long l;
+       xdrlong_t l;
 
        switch (xdrs->x_op) {
 
        case XDR_ENCODE:
 
        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:
 
        case XDR_DECODE:
-               if (!XDR_GETLONG(xdrs, (long *)&l)) {
+               if (!XDR_GETLONG(xdrs, &l)) {
                        return (FALSE);
                }
                        return (FALSE);
                }
-               *u_int16_p = (u_int16_t) l;
+               *u_int16_p = l;
                return (TRUE);
 
        case XDR_FREE:
                return (TRUE);
 
        case XDR_FREE:
@@ -433,7 +450,7 @@ xdr_u_char(xdrs, cp)
        XDR *xdrs;
        u_char *cp;
 {
        XDR *xdrs;
        u_char *cp;
 {
-       u_int u;
+       u_int32_t u;
 
        u = (*cp);
        if (!xdr_u_int(xdrs, &u)) {
 
        u = (*cp);
        if (!xdr_u_int(xdrs, &u)) {
@@ -451,13 +468,13 @@ xdr_bool(xdrs, bp)
        XDR *xdrs;
        bool_t *bp;
 {
        XDR *xdrs;
        bool_t *bp;
 {
-       long lb;
+       xdrlong_t lb;
 
        switch (xdrs->x_op) {
 
        case XDR_ENCODE:
                lb = *bp ? XDR_TRUE : XDR_FALSE;
 
        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)) {
 
        case XDR_DECODE:
                if (!XDR_GETLONG(xdrs, &lb)) {
@@ -486,8 +503,8 @@ xdr_enum(xdrs, ep)
        /*
         * enums are treated as ints
         */
        /*
         * 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)) {
        } 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;
 {
        caddr_t cp;
        u_int cnt;
 {
-       u_int rndup;
+       u_int32_t rndup;
        static int crud[BYTES_PER_XDR_UNIT];
 
        /*
        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 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
 
        /*
         * 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 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
 
        /*
         * 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;
 {
        XDR *xdrs;
        int64_t *llp;
 {
-       u_long ul[2];
+       u_int32_t ul[2];
 
        switch (xdrs->x_op) {
        case XDR_ENCODE:
 
        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 (FALSE);
-               return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
+               return (XDR_PUTLONG(xdrs, (xdrlong_t *)&ul[1]));
        case XDR_DECODE:
        case XDR_DECODE:
-               if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
+               if (XDR_GETLONG(xdrs, (xdrlong_t *)&ul[0]) == FALSE)
                        return (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]));
                        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;
 {
        XDR *xdrs;
        u_int64_t *ullp;
 {
-       u_long ul[2];
+       u_int32_t ul[2];
 
        switch (xdrs->x_op) {
        case XDR_ENCODE:
 
        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 (FALSE);
-               return (XDR_PUTLONG(xdrs, (long *)&ul[1]));
+               return (XDR_PUTLONG(xdrs, (xdrlong_t *)&ul[1]));
        case XDR_DECODE:
        case XDR_DECODE:
-               if (XDR_GETLONG(xdrs, (long *)&ul[0]) == FALSE)
+               if (XDR_GETLONG(xdrs, (xdrlong_t *)&ul[0]) == FALSE)
                        return (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]));
                        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;
 {
        XDR *xdrs;
        longlong_t *llp;
 {
-
        /*
         * Don't bother open-coding this; it's a fair amount of code.  Just
         * call xdr_int64_t().
        /*
         * 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;
 {
        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().
        /*
         * 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;
 {
        XDR *xdrs;
        longlong_t *llp;
 {
-
        /*
         * Don't bother open-coding this; it's a fair amount of code.  Just
         * call xdr_int64_t().
        /*
         * 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 {
 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 *);
                /* 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 " */
                /* 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)
 
 #define xdr_putlong(xdrs, longp)                       \
        (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
 
+
+#ifdef __LP64__
 static __inline int
 xdr_getint32(XDR *xdrs, int32_t *ip)
 {
 static __inline int
 xdr_getint32(XDR *xdrs, int32_t *ip)
 {
-       long l;
+       int32_t l;
 
        if (!xdr_getlong(xdrs, &l))
                return (FALSE);
 
        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)
 {
        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);
 }
        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)
 
 #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)))
 
 #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))
 #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))
 
 #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))
 #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))
 
 #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 *);
 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 *);
 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 *);
 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 <sys/types.h>
+#include <stddef.h>
 
 #include <netinet/in.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>
 
 #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 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! */
 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;
 {
        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;
        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;
 {
 xdrmem_destroy(xdrs)
        XDR *xdrs;
 {
-
 }
 
 static bool_t
 xdrmem_getlong_aligned(xdrs, lp)
        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);
        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;
 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);
        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;
 static bool_t
 xdrmem_getlong_unaligned(xdrs, lp)
        XDR *xdrs;
-       long *lp;
+       xdrlong_t *lp;
 {
        u_int32_t l;
 
 {
        u_int32_t l;
 
@@ -188,7 +191,7 @@ xdrmem_getlong_unaligned(xdrs, lp)
 static bool_t
 xdrmem_putlong_unaligned(xdrs, lp)
        XDR *xdrs;
 static bool_t
 xdrmem_putlong_unaligned(xdrs, lp)
        XDR *xdrs;
-       const long *lp;
+       const xdrlong_t *lp;
 {
        u_int32_t l;
 
 {
        u_int32_t l;
 
@@ -207,7 +210,6 @@ xdrmem_getbytes(xdrs, addr, len)
        char *addr;
        u_int len;
 {
        char *addr;
        u_int len;
 {
-
        if (xdrs->x_handy < len)
                return (FALSE);
        xdrs->x_handy -= 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;
 {
        const char *addr;
        u_int len;
 {
-
        if (xdrs->x_handy < len)
                return (FALSE);
        xdrs->x_handy -= len;
        if (xdrs->x_handy < len)
                return (FALSE);
        xdrs->x_handy -= len;
@@ -235,9 +236,16 @@ static u_int
 xdrmem_getpos(xdrs)
        XDR *xdrs;
 {
 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
 }
 
 static bool_t
@@ -245,13 +253,18 @@ xdrmem_setpos(xdrs, pos)
        XDR *xdrs;
        u_int 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;
        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);
 }
 
        return (TRUE);
 }
 
@@ -276,6 +289,5 @@ xdrmem_inline_unaligned(xdrs, len)
        XDR *xdrs;
        u_int len;
 {
        XDR *xdrs;
        u_int len;
 {
-
        return (0);
 }
        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
  * 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.
  * 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 <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <unistd.h>
 
 #include <rpc/types.h>
 #include <rpc/xdr.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>
 
 #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 *);
 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);
 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 *);
 
 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,
 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
 /*
  * 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,
  * 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 {
 #define LAST_FRAG ((u_int32_t)(1 << 31))
 
 typedef struct rec_strm {
-       char *tcp_handle;
+       void *tcp_handle;
        /*
         * out-goung bits
         */
        /*
         * out-goung bits
         */
@@ -143,11 +152,11 @@ typedef struct rec_strm {
         * in-coming bits
         */
        int (*readit)(void *, void *, int);
         * 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 */
        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;
        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  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);
 
 
 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;
 static bool_t
 xdrrec_getlong(xdrs, lp)
        XDR *xdrs;
+#ifdef __LP64__
+       int *lp;
+#else
        long *lp;
        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 */
 {
        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);
                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;
        return (TRUE);
 }
 
 static bool_t
 xdrrec_putlong(xdrs, lp)
        XDR *xdrs;
+#ifdef __LP64__
+       const int *lp;
+#else
        const long *lp;
        const long *lp;
+#endif
 {
        RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
        int32_t *dest_lp = ((int32_t *)(void *)(rstrm->out_finger));
 
 {
        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;
                /*
                 * 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 *)(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);
 }
 
        return (TRUE);
 }
 
@@ -334,8 +353,7 @@ xdrrec_putbytes(xdrs, addr, len)
        size_t current;
 
        while (len > 0) {
        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;
                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;
 {
        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) {
 
        if (pos != -1)
                switch (xdrs->x_op) {
 
@@ -533,17 +556,15 @@ xdrrec_endofrecord(xdrs, sendnow)
        bool_t sendnow;
 {
        RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
        bool_t sendnow;
 {
        RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private);
-       u_long len;  /* fragment length */
+       unsigned int len;  /* fragment length */
 
        if (sendnow || rstrm->frag_sent ||
 
        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));
        }
                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);
        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;
        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);
 
        *(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);
                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;
                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;
        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;
        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) {
        }
 
        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);
                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;
 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) {
 {
        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;
                }
                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;
        }
                rstrm->in_finger += current;
                cnt -= current;
        }
@@ -789,7 +805,7 @@ realloc_stream(rstrm, size)
        RECSTREAM *rstrm;
        int size;
 {
        RECSTREAM *rstrm;
        int size;
 {
-       long diff;
+       int diff;
        char *buf;
 
        if (size > rstrm->recvsize) {
        char *buf;
 
        if (size > rstrm->recvsize) {
index a96c1e87fefb0902559c2d78c409708555184cbb..318a5b82da21fe1737a464cc75b6f7e2057d60eb 100644 (file)
 static bool_t
 x_putlong(xdrs, longp)
        XDR *xdrs;
 static bool_t
 x_putlong(xdrs, longp)
        XDR *xdrs;
+#ifdef __LP64__
+       int *longp;
+#else
        long *longp;
        long *longp;
+#endif
 {
        xdrs->x_handy += BYTES_PER_XDR_UNIT;
        return (TRUE);
 {
        xdrs->x_handy += BYTES_PER_XDR_UNIT;
        return (TRUE);
@@ -109,7 +113,7 @@ x_inline(xdrs, len)
        XDR *xdrs;
        u_int len;
 {
        XDR *xdrs;
        u_int len;
 {
-       long llen;
+       size_t llen;
 
        if (len == 0) {
                return (NULL);
 
        if (len == 0) {
                return (NULL);
@@ -120,7 +124,7 @@ x_inline(xdrs, len)
 
        llen = 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);
                /* x_private was already allocated */
                xdrs->x_handy += llen;
                return ((int32_t *) xdrs->x_private);
@@ -158,7 +162,11 @@ x_destroy(xdrs)
        return;
 }
 
        return;
 }
 
+#ifdef __LP64__
+unsigned int
+#else
 unsigned long
 unsigned long
+#endif
 xdr_sizeof(func, data)
        xdrproc_t func;
        void *data;
 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 */
        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 *);
        typedef  bool_t (* dummyfunc1)(XDR *, long *);
+#endif
        typedef  bool_t (* dummyfunc2)(XDR *, caddr_t, u_int);
 
        ops.x_putlong = x_putlong;
        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 *);
 #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 *);
 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 *);
 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;
 {
        FILE *file;
        enum xdr_op op;
 {
-
        xdrs->x_op = op;
        xdrs->x_ops = &xdrstdio_ops;
        xdrs->x_private = file;
        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);
        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;
 }
 
 static bool_t
 xdrstdio_getlong(xdrs, lp)
        XDR *xdrs;
+#ifdef __LP64__
+       int *lp;
+#else
        long *lp;
        long *lp;
+#endif
 {
        u_int32_t temp;
 
        if (fread(&temp, sizeof(int32_t), 1, (FILE *)xdrs->x_private) != 1)
                return (FALSE);
 {
        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;
        return (TRUE);
 }
 
 static bool_t
 xdrstdio_putlong(xdrs, lp)
        XDR *xdrs;
+#ifdef __LP64__
+       const int *lp;
+#else
        const long *lp;
        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);
 }
 
        return (TRUE);
 }
 
@@ -160,9 +171,9 @@ xdrstdio_getbytes(xdrs, addr, len)
        char *addr;
        u_int 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);
 }
 
        return (TRUE);
 }
 
@@ -172,29 +183,38 @@ xdrstdio_putbytes(xdrs, addr, len)
        const char *addr;
        u_int 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);
 }
 
        return (TRUE);
 }
 
+/* This only works if file offsets are <= UINT32_MAX */
 static u_int
 xdrstdio_getpos(xdrs)
        XDR *xdrs;
 {
 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;
 { 
 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 */
 }
 
 /* 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/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 = \
 AFTER_POSTINSTALL += install-man-page
 OTHER_CFLAGS = \
+       -D__DARWIN_NON_CANCELABLE=1 \
        -DINET6=1 
 
 # for building 64-bit
        -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
 .Xr rcmd 3 ,
 .Xr ruserok 3 ,
 .Xr netgroup 5
-.Re
 .Sh HISTORY
 The
 .Nm .rhosts
 .Sh HISTORY
 The
 .Nm .rhosts
index 976ef2ff0b75085e50d6dc5c791984cb7ac4599c..99894a49a42a5378444b00c0c14ecfa5923e0581 100644 (file)
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
  * 
  * @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
 
 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@
  */
  * 
  * @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>
 
 
 #include <sys/types.h>
 
@@ -30,6 +38,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <utmp.h>
 #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 */
 
 #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;
 {
        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 */
        } *c_uid[NCACHE];
        static int pwopen;
        static char nbuf[15];           /* 32 bits == 10 digits */
@@ -67,8 +76,8 @@ err:
                                goto err;
                }
                (*cp)->uid = uid;
                                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);
 }
        }
        return ((*cp)->name);
 }
@@ -80,7 +89,7 @@ group_from_gid(gid, nogroup)
 {
        static struct ncache {
                gid_t   gid;
 {
        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 */
        } *c_gid[NCACHE];
        static int gropen;
        static char nbuf[15];           /* 32 bits == 10 digits */
@@ -106,8 +115,8 @@ err:
                                goto err;
                }
                (*cp)->gid = gid;
                                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);
 }
        }
        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 <sys/socket.h>
 #include <sys/stat.h>
 
-#include <netinet/in.h>
 #include <arpa/inet.h>
 #include <arpa/inet.h>
-#include <netinfo/ni_util.h>
 
 #include <signal.h>
 #include <fcntl.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 <stdio.h>
 #include <ctype.h>
 #include <string.h>
+#include <time.h>
 #ifdef YP
 #include <rpc/rpc.h>
 #include <rpcsvc/yp_prot.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;
        } 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)
                int nfds;
 
                if (s2 < 0)
@@ -404,6 +403,9 @@ rresvport_af(alport, family)
 int    __check_rhosts_file = 1;
 char   *__rcmd_errstr;
 
 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.
  *
 /*
  * AF independent extension of iruserok.
  *
@@ -418,13 +420,14 @@ iruserok_sa(ra, rlen, superuser, ruser, luser)
 {
        register char *cp;
        struct stat sbuf;
 {
        register char *cp;
        struct stat sbuf;
-       struct passwd *pwd;
+       struct passwd p, *pwd;
        FILE *hostf;
        uid_t uid;
        FILE *hostf;
        uid_t uid;
-       int first;
+       int first, status;
        char pbuf[MAXPATHLEN];
        const struct sockaddr *raddr;
        struct sockaddr_storage ss;
        char pbuf[MAXPATHLEN];
        const struct sockaddr *raddr;
        struct sockaddr_storage ss;
+       char pwbuf[MAXPWBUF];
 
        /* avoid alignment issue */
        if (rlen > sizeof(ss)) 
 
        /* avoid alignment issue */
        if (rlen > sizeof(ss)) 
@@ -444,8 +447,14 @@ again:
        }
        if (first == 1 && (__check_rhosts_file || superuser)) {
                first = 0;
        }
        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");
 
                (void)strcpy(pbuf, pwd->pw_dir);
                (void)strcat(pbuf, "/.rhosts");