]> git.saurik.com Git - apple/libinfo.git/commitdiff
Libinfo-89.tar.gz mac-os-x-101 mac-os-x-1011 v89
authorApple <opensource@apple.com>
Thu, 23 Aug 2001 01:25:01 +0000 (01:25 +0000)
committerApple <opensource@apple.com>
Thu, 23 Aug 2001 01:25:01 +0000 (01:25 +0000)
14 files changed:
gen.subproj/getaddrinfo.c
gen.subproj/getpwent.c
lookup.subproj/lu_group.c
lookup.subproj/lu_protocol.c
lookup.subproj/lu_service.c
netinfo.subproj/Makefile
netinfo.subproj/PB.project
netinfo.subproj/ni_glue.c
netinfo.subproj/ni_pwdomain.c
netinfo.subproj/ni_useful.c
netinfo.subproj/ni_util.c
netinfo.subproj/sys_interfaces.c [new file with mode: 0644]
netinfo.subproj/sys_interfaces.h [new file with mode: 0644]
rpc.subproj/svc.c

index bce133fcf518100841a8fd8f414477457c87e9a7..0d105eada28f5dc9173701a5114e81e82b7ce5a7 100644 (file)
@@ -478,7 +478,7 @@ gai_files(struct lu_dict *q, struct lu_dict **list)
                memset(d, 0, sizeof(struct lu_dict));
 
                if (s->s_name != NULL) d->name = strdup(s->s_name);
-               sprintf(str, "%u", s->s_port);
+               sprintf(str, "%u", ntohl(s->s_port));
                d->port = strdup(str);
                if (s->s_proto != NULL) d->protocol = strdup(s->s_proto);
 
@@ -665,6 +665,7 @@ freeaddrinfo(struct addrinfo *a)
        while (a != NULL)
        {
                next = a->ai_next;
+               if (a->ai_addr != NULL) free(a->ai_addr);
                if (a->ai_canonname != NULL) free(a->ai_canonname);
                free(a);
                a = next;
@@ -1053,7 +1054,8 @@ static int
 gai_serv(const char *servname, const struct addrinfo *hints, struct addrinfo **res)
 {
        struct lu_dict *list, *d;
-       int port, proto, family, socktype, setcname, wantv4, wantv6;
+       int proto, family, socktype, setcname, wantv4, wantv6;
+       unsigned short port;
        char *loopv4, *loopv6;
        struct addrinfo *a;
        struct in_addr a4;
@@ -1097,7 +1099,7 @@ gai_serv(const char *servname, const struct addrinfo *hints, struct addrinfo **r
                /* We only want records with port and protocol specified */
                if ((d->port == NULL) || (d->protocol == NULL)) continue;
 
-               port = atoi(d->port);
+               port = htons(atoi(d->port));
                proto = IPPROTO_UDP;
                socktype = SOCK_DGRAM;
                if (!strcasecmp(d->protocol, "tcp"))
@@ -1320,7 +1322,7 @@ gai_nodeserv_lookupd(const char *nodename, const char *servname, const struct ad
 }
 
 static void
-gai_node_pp(const char *nodename, int port, int proto, int family, int setcname, struct addrinfo **res)
+gai_node_pp(const char *nodename, unsigned short port, int proto, int family, int setcname, struct addrinfo **res)
 {
        struct lu_dict *list, *d;
        int i, wantv4, wantv6, a_list_count, socktype;
@@ -1425,8 +1427,9 @@ static int
 gai_nodeserv(const char *nodename, const char *servname, const struct addrinfo *hints, struct addrinfo **res)
 {
        struct lu_dict *srv_list, *node_list, *s, *n;
-       int numerichost, family, port, proto, setcname;
+       int numerichost, family, proto, setcname;
        int wantv4, wantv6, i, j, gotmx, p_list_count;
+       unsigned short port;
        char *cname;
        struct sockaddr **p_list;
        struct sockaddr_in *sa4;
@@ -1466,7 +1469,7 @@ gai_nodeserv(const char *nodename, const char *servname, const struct addrinfo *
                        if (s->port == NULL) continue;
                        if (s->protocol == NULL) continue;
 
-                       i = atoi(s->port);
+                       i = htons(atoi(s->port));
                        j = IPPROTO_UDP;
                        if (!strcmp(s->protocol, "tcp")) j = IPPROTO_TCP;
                        gai_node_pp(s->target, i, j, family, setcname, res);
@@ -1518,7 +1521,7 @@ gai_nodeserv(const char *nodename, const char *servname, const struct addrinfo *
                if (s->port == NULL) continue;
                if (s->protocol == NULL) continue;
 
-               i = atoi(s->port);
+               i = htons(atoi(s->port));
                j = IPPROTO_UDP;
                if (!strcmp(s->protocol, "tcp")) j = IPPROTO_TCP;
 
index a9f4798b40186dabc0243fdd5195383b85bd14cb..0f2d8c42bdea10897454c8f1adad773e3e48e8b2 100644 (file)
@@ -36,6 +36,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <pwd.h>
+#include <unistd.h>
 
 #define forever for (;;)
 
@@ -46,6 +47,7 @@
 static struct passwd _pw = { 0 };
 static FILE *_pfp;
 static int _pwStayOpen;
+static int _pwFileFormat = 1;
 
 static void
 free_pw()
@@ -223,11 +225,14 @@ struct passwd *
 parseUser(char *data)
 {
        char **tokens;
+       int ntokens;
 
        if (data == NULL) return NULL;
 
        tokens = tokenize(data, ":");
-       if (listLength(tokens) != 10)
+       ntokens = listLength(tokens);
+       if (( _pwFileFormat && (ntokens != 10)) ||
+           (!_pwFileFormat && (ntokens !=  7)))
        {
                freeList(tokens);
                return NULL;
@@ -241,14 +246,27 @@ parseUser(char *data)
        free(tokens[2]);
        _pw.pw_gid = atoi(tokens[3]);
        free(tokens[3]);
-       _pw.pw_class = tokens[4];
-       _pw.pw_change = atoi(tokens[5]);
-       free(tokens[5]);
-       _pw.pw_expire = atoi(tokens[6]);
-       free(tokens[6]);
-       _pw.pw_gecos = tokens[7];
-       _pw.pw_dir = tokens[8];
-       _pw.pw_shell = tokens[9];
+
+       if (_pwFileFormat)
+       {
+               _pw.pw_class = tokens[4];
+               _pw.pw_change = atoi(tokens[5]);
+               free(tokens[5]);
+               _pw.pw_expire = atoi(tokens[6]);
+               free(tokens[6]);
+               _pw.pw_gecos = tokens[7];
+               _pw.pw_dir = tokens[8];
+               _pw.pw_shell = tokens[9];
+       }
+       else
+       {
+               _pw.pw_class = copyString("");
+               _pw.pw_change = 0;
+               _pw.pw_expire = 0;
+               _pw.pw_gecos = tokens[4];
+               _pw.pw_dir = tokens[5];
+               _pw.pw_shell = tokens[6];
+       }
 
        free(tokens); 
 
@@ -284,10 +302,20 @@ setpwent()
 {
        if (_pfp == NULL)
        {
-               _pfp = fopen(_PATH_MASTERPASSWD, "r");
+               char *pwFile;
+               if (geteuid() == 0)
+               {
+                       pwFile = _PATH_MASTERPASSWD;
+               }
+               else
+               {
+                       pwFile = _PATH_PASSWD;
+                       _pwFileFormat = 0;
+               }
+               _pfp = fopen(pwFile, "r");
                if (_pfp == NULL)
                {
-                       perror(_PATH_MASTERPASSWD);
+                       perror(pwFile);
                        return(0);
                }
        }
index 5022f9c00781e58fdaea28622eb7d50515707c87..2ec8e031d3c3ec6070b46887ebceaddc23b126ee 100644 (file)
@@ -362,6 +362,8 @@ initgroups(const char *name, int basegid)
 {
        int res;
 
+       if (name == NULL) return -1;
+
        if (_lu_running())
        {
                if ((res = lu_initgroups(name, basegid)))
index f3c0e4b0d73d4277977faf7b0b48c82958b538d0..f2c346fbc029a007a89c9902de2804f846a531c8 100644 (file)
@@ -235,7 +235,10 @@ lu_getprotoent()
                        return (NULL);
                }
 
+#ifdef NOTDEF 
+/* NOTDEF because OOL buffers are counted in bytes with untyped IPC */  
                p_datalen *= BYTES_PER_XDR_UNIT;
+#endif
                xdrmem_create(&p_xdr, p_data, p_datalen,
                        XDR_DECODE);
                if (!xdr_int(&p_xdr, &p_nentries))
index 2fd3e2aea3378e15d5aac42c9de4fa14424b0180..4dc60e59dbafe0d3f5e35cb13f09f8085685219e 100644 (file)
@@ -60,13 +60,18 @@ freeold(void)
 
        if (global_free == 1) return;
 
-       free(global_s.s_name);
+       if (global_s.s_name != NULL) free(global_s.s_name);
+       global_s.s_name = NULL;
+
+       if (global_s.s_proto != NULL) free(global_s.s_proto);
+       global_s.s_proto = NULL;
 
        aliases = global_s.s_aliases;
        if (aliases != NULL)
        {
                while (*aliases != NULL) free(*aliases++);
                free(global_s.s_aliases);
+               global_s.s_aliases = NULL;
        }
 
        global_free = 1;
@@ -91,7 +96,7 @@ convert_s(_lu_servent *lu_s)
 
        global_s.s_aliases[len] = NULL;
 
-       global_s.s_proto = lu_s->s_proto;
+       if (lu_s->s_proto != NULL) global_s.s_proto = strdup(lu_s->s_proto);
        global_s.s_port = lu_s->s_port;
 
        global_free = 0;
index baf23151decaf315872df9198c3c2ed319ff2936..ea95aa2b068e9f8f31e9a286b2654df74a0da19f 100644 (file)
@@ -12,10 +12,10 @@ NAME = netinfo
 PROJECTVERSION = 2.8
 PROJECT_TYPE = Component
 
-HFILES = clib.h mm.h ni.h ni_util.h
+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
+         ni_util.c sys_interfaces.c
 
 OTHERSRCS = Makefile.preamble Makefile Makefile.postamble nibind_prot.x\
             ni_prot.x
index ecd1da8805a622cf3e29b482a665f6e747cec6be..789dee70ae71e00f3c533a4f18c9d4639fdab38c 100644 (file)
@@ -1,8 +1,8 @@
 {
     DYNAMIC_CODE_GEN = YES; 
     FILESTABLE = {
-        H_FILES = (clib.h, mm.h, ni.h, ni_util.h); 
-        OTHER_LINKED = (multi_call.c, ni_error.c, ni_glue.c, ni_pwdomain.c, ni_useful.c, ni_util.c); 
+        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); 
         PUBLIC_HEADERS = (ni.h, ni_util.h); 
     }; 
index 0a22e74740e32839eac98b91dcf06668f6b63c65..751cd9306a9d0cfb02a33bcd75d971e0bbeb24ba 100644 (file)
@@ -34,6 +34,9 @@
 #include <net/if.h>
 #include <ctype.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 */
@@ -44,7 +47,7 @@
 
 /* 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
@@ -117,46 +120,6 @@ getmyport(
 }
 
 
-/*
- * Is the NetInfo binder running?
- */
-static int
-nibind_up(
-       ni_private *ni
-       )
-{
-       int sock;
-       struct sockaddr_in sin;
-       int res;
-
-       sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-       if (sock < 0) {
-               return (0);
-       }
-       sin.sin_family = AF_INET;
-       sin.sin_port = htons(PMAPPORT);
-       sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
-       bzero(sin.sin_zero, sizeof(sin.sin_zero));
-       res = connect(sock, (struct sockaddr *)&sin, sizeof(sin));
-       close(sock);
-       if (res != 0) {
-               return (0);
-       }
-       sin.sin_port = htons(pmap_getport(&sin, NIBIND_PROG, NIBIND_VERS, 
-                                         IPPROTO_TCP));
-       if (sin.sin_port == 0) {
-               return (0);
-       }
-       sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-       if (sock < 0) {
-               return (0);
-       }
-       res = connect(sock, (struct sockaddr *)&sin, sizeof(sin));
-       close(sock);
-       return (res == 0);
-}
-       
-
 static void
 createauth(
           ni_private *ni
@@ -203,9 +166,7 @@ ni_settimeout(
  * Connect to a given address/tag
  */
 static int
-connectit(
-         ni_private *ni
-         )
+connectit(ni_private *ni)
 {
        struct sockaddr_in sin;
        int sock;
@@ -213,54 +174,82 @@ connectit(
        struct timeval tv;
        enum clnt_stat stat;
        nibind_getregister_res res;
-       
+
+       sock = -1;
        bzero(&sin, sizeof(sin));
        sin.sin_port = 0;
        sin.sin_family = AF_INET;
-       sin.sin_addr = ni->addrs[0];
-       ni_settimeout(ni, ni->rtv_sec == 0 ? NI_TIMEOUT_SHORT : ni->rtv_sec);
-       fixtimeout(&tv, ni->tv_sec, NI_TRIES);
-       sock = socket_open(&sin, NIBIND_PROG, NIBIND_VERS, ni->tv_sec, 
-                          NI_TRIES, IPPROTO_UDP);
-       if (sock < 0) {
-               return (0);
-       }
-       cl = clntudp_create(&sin, NIBIND_PROG, NIBIND_VERS, tv,
-                           &sock);
-       if (cl == NULL) {
-               close(sock);
-               return (0);
-       }
+       
        tv.tv_sec = ni->rtv_sec == 0 ? NI_TIMEOUT_SHORT : ni->rtv_sec;
        tv.tv_usec = 0;
-       stat = clnt_call(cl, NIBIND_GETREGISTER, xdr_ni_name, &ni->tags[0],
-                        xdr_nibind_getregister_res, &res, tv);
-       clnt_destroy(cl);
-       close(sock);
-       if (stat != RPC_SUCCESS || res.status != NI_OK) {
-               return (0);
-       }
        
+       ni_settimeout(ni, tv.tv_sec);
+       fixtimeout(&tv, ni->tv_sec, NI_TRIES);
+
        /*
-        * Found the address, now connect to it. 
+        * If connecting to local domain, try using the "well-known" port first.
         */
-       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);
+       if (!strcmp(ni->tags[0], "local"))
+       {
+               interface_list_t *ilist;
+
+               ilist = sys_interfaces();
+               if (sys_is_my_address(ilist, &ni->addrs[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);
+               }
+               sys_interfaces_release(ilist);
+       }
+
+       /*
+        * 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, xdr_ni_name, &ni->tags[0], xdr_nibind_getregister_res, &res, tv);
+               clnt_destroy(cl);
+               close(sock);
+               if (stat != RPC_SUCCESS || res.status != NI_OK) return (0);
+       
+               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) {
+       if (cl == NULL)
+       {
                close(sock);
                return (0);
        }
+
        clnt_control(cl, CLSET_TIMEOUT, &tv);
        ni->tc = cl;
        ni->tsock = sock;
        ni->tport = getmyport(sock);
        createauth(ni);
-       (void) fcntl(ni->tsock, F_SETFD, 1);
+       fcntl(ni->tsock, F_SETFD, 1);
        return (1);
 }
 
@@ -305,118 +294,6 @@ ni_needwrite(
 }
 
 
-static unsigned long
-sys_netmask(void)
-{
-       struct ifconf ifc;
-       struct ifreq *ifr;
-       char buf[1024]; /* XXX */
-       int i, len, ifreq_size, offset, sockaddr_size, size;
-       int sock;
-       struct sockaddr_in *sin;
-       unsigned long n_addr;
-
-       sock = socket(AF_INET, SOCK_DGRAM, 0);
-
-       if (sock < 0) return (htonl(IN_CLASSA_NET));
-
-       ifc.ifc_len = sizeof(buf);
-       ifc.ifc_buf = buf;
-
-       if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0)
-       {
-               close(sock);
-               return (htonl(IN_CLASSA_NET));
-       }
-
-       ifreq_size = sizeof(struct ifreq);
-       sockaddr_size = sizeof(struct sockaddr);
-
-       offset = 0;
-       len = ifc.ifc_len / ifreq_size;
-       for (i = 0; i < len; i++)
-       {
-               ifr = (struct ifreq *)(ifc.ifc_buf + offset);
-               offset += IFNAMSIZ;
-               offset += sockaddr_size;
-
-               size = ifr->ifr_addr.sa_len;
-               if (size > sockaddr_size) offset += (size - sockaddr_size);
-
-               if (ifr->ifr_addr.sa_family != AF_INET) continue;
-               if (ioctl(sock, SIOCGIFFLAGS, (char *)ifr) < 0) continue;
-
-               sin = (struct sockaddr_in *)&ifr->ifr_addr;
-               if ((ifr->ifr_flags & IFF_UP) &&
-                       !(ifr->ifr_flags & IFF_LOOPBACK) &&
-                       (sin->sin_addr.s_addr != 0))
-               {
-                       ioctl(sock, SIOCGIFNETMASK, (char *)ifr);
-                       n_addr = ((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr;
-                       close(sock);
-                       return (n_addr);
-               }
-       }
-
-       close(sock);
-       return (htonl(IN_CLASSA_NET));
-}
-
-
-static unsigned long
-sys_address(void)
-{
-       struct ifconf ifc;
-       struct ifreq *ifr;
-       char buf[1024]; /* XXX */
-       int i, len, ifreq_size, offset, sockaddr_size, size;
-       int sock;
-
-       sock = socket(AF_INET, SOCK_DGRAM, 0);
-
-       if (sock < 0) 
-       {
-               return (htonl(INADDR_LOOPBACK));
-       }
-
-       ifc.ifc_len = sizeof(buf);
-       ifc.ifc_buf = buf;
-
-       if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0)
-       {
-               close(sock);
-               return (htonl(INADDR_LOOPBACK));
-       }
-
-       ifreq_size = sizeof(struct ifreq);
-       sockaddr_size = sizeof(struct sockaddr);
-
-       offset = 0;
-       len = ifc.ifc_len / ifreq_size;
-       for (i = 0; i < len; i++)
-       {
-               ifr = (struct ifreq *)(ifc.ifc_buf + offset);
-               offset += IFNAMSIZ;
-               offset += sockaddr_size;
-
-               size = ifr->ifr_addr.sa_len;
-               if (size > sockaddr_size) offset += (size - sockaddr_size);
-
-               if (ifr->ifr_addr.sa_family != AF_INET) continue;
-               if (ioctl(sock, SIOCGIFFLAGS, ifr) < 0) continue;
-
-               if ((ifr->ifr_flags & IFF_UP) && (!(ifr->ifr_flags & IFF_LOOPBACK)))
-               {
-                       close(sock);
-                       return (((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr);
-               }
-       }
-
-       close(sock);
-       return (htonl(INADDR_LOOPBACK));
-}
-
-
 /*
  * Returns a client handle to the NetInfo server, if it's running
  */
@@ -425,26 +302,30 @@ connectlocal(ni_private *ni)
 {
        int printed = 0;
 
-       if (!nibind_up(ni)) {
-               return (0);
-       }
        ni->naddrs = 1;
        ni->addrs = (struct in_addr *)malloc(sizeof(struct in_addr));
        ni->addrs[0].s_addr = htonl(INADDR_LOOPBACK);
        ni->tags = (ni_name *)malloc(sizeof(ni_name));
        ni->tags[0] = ni_name_dup("local");
        ni->whichwrite = 0;
-       while (!connectit(ni)) {
-               if (!printed) {
+
+       while (!connectit(ni))
+       {
+               if (!printed)
+               {
                        syslog(LOG_ERR, "NetInfo timeout connecting to local domain, sleeping");
                        printed++;
                }
+
                sleep(NI_SLEEPTIME);
                /* wait forever */
        }
-       if (printed) {
+
+       if (printed)
+       {
                syslog(LOG_ERR, "NetInfo connection to local domain waking");
        }
+
        return (1);
 }
 
@@ -546,6 +427,8 @@ ni_swap(
        struct in_addr tmp_addr;
        ni_name tmp_tag;
 
+       if (a == b) return;
+
        tmp_addr = ni->addrs[a];
        tmp_tag = ni->tags[a];
 
@@ -585,6 +468,51 @@ eachresult(
 }
 
 
+/*
+ * shuffle addresses
+ */
+static void
+shuffle(ni_private *ni)
+{
+       int *shuffle;
+       int i, j;
+       int rfd;
+
+       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--) {
+               unsigned int rEnt;
+               long rVal;
+               int tEnt;
+
+               /* get a random number */
+               if ((rfd < 0) ||
+                   (read(rfd, &rVal, sizeof(rVal)) != sizeof(rVal))) {
+                       /* if we could not read from /dev/random */
+                       static int initialized = 0;
+                       if (!initialized)
+                       {
+                               srandom(gethostid() ^ time(NULL));
+                               initialized++;
+                       }
+                       rVal = random();
+               }
+
+               rEnt = (unsigned int)rVal % j;  /* pick one of the remaining entries */
+               tEnt = shuffle[rEnt];           /* grab the random entry */
+               shuffle[rEnt] = shuffle[j-1];   /* the last entry moves to the random slot */ 
+               shuffle[j-1]  = tEnt;           /* the last slot gets the random entry */
+               ni_swap(ni, rEnt, j-1);         /* and swap the actual NI addresses */
+       }
+       free(shuffle);
+       if (rfd > 0) (void)close(rfd);
+       return;
+}
+
+
 static int
 rebind(
        ni_private *ni
@@ -596,9 +524,7 @@ rebind(
        int printed = 0;
        int nlocal;
        int nnetwork;
-       unsigned long myaddr;
-       unsigned long mynetmask;
-       unsigned long mynetwork;
+       interface_list_t *ilist;
        int i;
 
        if (ni->naddrs == 1) {
@@ -614,17 +540,19 @@ rebind(
         * all other servers are next
         */
 
-       myaddr = sys_address();
-       mynetmask = sys_netmask();
-       mynetwork = myaddr & mynetmask;
+       ilist = 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 ((ni->addrs[i].s_addr == myaddr) ||
-                       (ni->addrs[i].s_addr == htonl(INADDR_LOOPBACK)))
+               if (sys_is_my_address(ilist, &ni->addrs[i]))
                {
                        ni_swap(ni, nlocal, i);
                        nlocal++;
@@ -636,7 +564,7 @@ rebind(
         */
        nnetwork = nlocal;
        for (i = nnetwork; i < ni->naddrs; i++) {
-               if (((ni->addrs[i].s_addr & mynetmask) == mynetwork) ||
+               if (sys_is_my_network(ilist, &ni->addrs[i]) ||
                        IS_BROADCASTADDR(ni->addrs[i].s_addr))
                {
                        ni_swap(ni, nnetwork, i);
@@ -644,6 +572,8 @@ rebind(
                }
        }
 
+       sys_interfaces_release(ilist);
+
        stuff.ni = ni;
        for (;;) {
                /*
@@ -2220,7 +2150,8 @@ socket_open(
            )
 {
        int sock;
-       
+       int reuse = 1;
+
        /*
         * If no port number given ask the pmap for one
         */
@@ -2240,6 +2171,7 @@ socket_open(
                return (-1);
        }
        (void)bindresvport(sock, (struct sockaddr_in *)0);
+       setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, &reuse, sizeof(int));
        if (proto == IPPROTO_TCP) {
                if (connect(sock, (struct sockaddr *)raddr,
                            sizeof(*raddr)) < 0) {
index c872cc85511cef8e1fda806e16c35c1feada2f78..9d9c541550091f713b782b1f1e398b8c8cc17242 100644 (file)
@@ -44,6 +44,7 @@
 #include <sys/socket.h>
 #include <net/if.h>
 #include <sys/ioctl.h>
+#include "sys_interfaces.h"
 
 extern char *inet_ntoa();
 
@@ -53,99 +54,6 @@ static const char NAME_IP_ADDRESS[] = "ip_address";
 static const char NAME_SERVES[] = "serves";
 static const char NAME_UNKNOWN[] = "###UNKNOWN###";
 
-typedef struct
-{
-       char name[IFNAMSIZ];
-       short flags;
-       struct in_addr addr;
-       struct in_addr mask;
-       struct in_addr netaddr;
-       struct in_addr bcast;
-} interface_t;
-
-typedef struct
-{
-       unsigned int count;
-       interface_t *interface;
-} interface_list_t;
-
-static interface_list_t *my_interfaces = NULL;
-
-static interface_list_t *
-sys_interfaces(void)
-{
-       struct ifconf ifc;
-       struct ifreq *ifr;
-       char buf[1024]; /* XXX */
-       int offset, addrlen, extra, delta;
-       int sock;
-       interface_t *iface;
-
-       if (my_interfaces != NULL) return my_interfaces;
-
-       sock = socket(AF_INET, SOCK_DGRAM, 0);
-
-       if (sock < 0) return NULL;
-
-       ifc.ifc_len = sizeof(buf);
-       ifc.ifc_buf = buf;
-
-       if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0)
-       {
-               close(sock);
-               return NULL;
-       }
-
-       my_interfaces = (interface_list_t *)malloc(sizeof(interface_list_t));
-       my_interfaces->count = 0;
-       my_interfaces->interface = NULL;
-
-       delta = sizeof(struct ifreq);
-       addrlen = delta - IFNAMSIZ;
-       extra = 0;
-
-       offset = 0;
-
-       while (offset <= ifc.ifc_len)
-       {
-               ifr = (struct ifreq *)(ifc.ifc_buf + offset);
-
-#ifndef _NO_SOCKADDR_LENGTH_
-               extra = ifr->ifr_addr.sa_len - addrlen;
-               if (extra < 0) extra = 0;
-#endif
-
-               offset = offset + delta + extra;
-
-               if (ifr->ifr_addr.sa_family != AF_INET) continue;
-               if (ioctl(sock, SIOCGIFFLAGS, (char *)ifr) < 0) continue;
-
-               my_interfaces->count++;
-               if (my_interfaces->count == 1)
-               {
-                       my_interfaces->interface = (interface_t *)malloc(sizeof(interface_t));
-               }
-               else
-               {
-                       my_interfaces->interface = (interface_t *)realloc(my_interfaces->interface, my_interfaces->count * sizeof(interface_t));
-               }
-
-               iface = &(my_interfaces->interface[my_interfaces->count - 1]);
-               memset(iface, 0, sizeof(interface_t));
-
-               memmove(iface->name, ifr->ifr_name, IFNAMSIZ);
-               iface->flags = ifr->ifr_ifru.ifru_flags;
-               iface->addr.s_addr = ((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr;
-               ioctl(sock, SIOCGIFNETMASK, (char *)ifr);
-               iface->mask.s_addr = ((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr;
-               iface->netaddr.s_addr = iface->addr.s_addr & iface->mask.s_addr;
-               iface->bcast.s_addr = iface->netaddr.s_addr | (~iface->mask.s_addr);
-       }
-
-       close(sock);
-       return my_interfaces;
-}
-
 static ni_name
 escape_domain(ni_name name)
 {
@@ -221,22 +129,6 @@ finddomain(void *ni, struct in_addr addr, ni_name tag)
        return NULL;
 }
 
-static int
-sys_is_my_address(struct in_addr *a)
-{
-       int i;
-       interface_list_t *l;
-
-       l = sys_interfaces();
-       if (l == NULL) return 0;
-       
-       for (i = 0; i < l->count; i++)
-       {
-               if (a->s_addr == l->interface[i].addr.s_addr) return 1;
-       }
-       return 0;
-}
-
 static char *
 ni_domainof(void *ni, void *parent)
 {
@@ -257,12 +149,11 @@ ni_domainof(void *ni, void *parent)
                return dom;
        }
 
-       if (sys_is_my_address(&(addr.sin_addr)))
+       ilist = sys_interfaces();
+       if (ilist == NULL) return ni_name_dup(NAME_UNKNOWN);
+       if (sys_is_my_address(ilist, &(addr.sin_addr)))
        {
                /* Try all my non-loopback interfaces */
-               ilist = sys_interfaces();
-               if (ilist == NULL) return ni_name_dup(NAME_UNKNOWN);
-
                for (i = 0; i < ilist->count; i++)
                {
                        if (ilist->interface[i].addr.s_addr == htonl(INADDR_LOOPBACK)) continue;
@@ -272,10 +163,12 @@ ni_domainof(void *ni, void *parent)
                        if (dom != NULL)
                        {
                                ni_name_free(&tag);
+                               sys_interfaces_release(ilist);
                                return dom;
                        }
                }
        }
+       sys_interfaces_release(ilist);
 
        dom = malloc(strlen(tag) + 256);
        sprintf(dom, "%s@%s", tag, inet_ntoa(addr.sin_addr.s_addr));
index a3d3df645d3d69c15e4a61bb5bc3e7a466cb6cc2..eaed642e6e17a9ede396a3499e7ecbc80bc5963f 100644 (file)
@@ -123,8 +123,8 @@ ni_relopen(
        char *component;
 
        /* look for <tag>@<address> in last component of domain */
-       start = domain;
-       while ((slash = escindex(start, '/')) != NULL) {
+       start = (char *)domain;
+       while ((slash = (char *)escindex(start, '/')) != NULL) {
                /* found a slash, keep looking for the last one */
                start = slash + 1;
        }
index 2f6f81d9e93e5af6bf1bde5af8e3a37ea0bf7742..1f881e97a7d7b52bf6faa98301aa3e23f6e18146 100644 (file)
@@ -498,11 +498,10 @@ ni_search(void *handle, ni_id *dir, ni_name name, ni_name expr, int flags, ni_en
 
                nl = el.ni_entrylist_val[i].names;
 
+               found = 0;
                for (j = 0; j < nl->ni_namelist_len; j++)
                {
-                       found = 0;
                        if (regexec(cexp, nl->ni_namelist_val[j], 0, NULL, 0) != 0) continue;
-
                        found = 1;
                        break;
                }
diff --git a/netinfo.subproj/sys_interfaces.c b/netinfo.subproj/sys_interfaces.c
new file mode 100644 (file)
index 0000000..d04f3e0
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * 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 "sys_interfaces.h"
+
+__private_extern__ interface_list_t *
+sys_interfaces(void)
+{
+       struct ifconf ifc;
+       struct ifreq *ifr;
+       char buf[1024]; /* XXX */
+       int offset, addrlen, extra, delta;
+       int sock;
+       interface_t *iface;
+       interface_list_t *my_interfaces;
+
+       sock = socket(AF_INET, SOCK_DGRAM, 0);
+
+       if (sock < 0) return NULL;
+
+       ifc.ifc_len = sizeof(buf);
+       ifc.ifc_buf = buf;
+
+       if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0)
+       {
+               close(sock);
+               return NULL;
+       }
+
+       my_interfaces = (interface_list_t *)malloc(sizeof(interface_list_t));
+       my_interfaces->count = 0;
+       my_interfaces->interface = NULL;
+
+       delta = sizeof(struct ifreq);
+       addrlen = delta - IFNAMSIZ;
+       extra = 0;
+
+       offset = 0;
+
+       while (offset <= ifc.ifc_len)
+       {
+               ifr = (struct ifreq *)(ifc.ifc_buf + offset);
+
+#ifndef _NO_SOCKADDR_LENGTH_
+               extra = ifr->ifr_addr.sa_len - addrlen;
+               if (extra < 0) extra = 0;
+#endif
+
+               offset = offset + delta + extra;
+
+               if (ifr->ifr_addr.sa_family != AF_INET) continue;
+               if (ioctl(sock, SIOCGIFFLAGS, (char *)ifr) < 0) continue;
+
+               my_interfaces->count++;
+               if (my_interfaces->count == 1)
+               {
+                       my_interfaces->interface = (interface_t *)malloc(sizeof(interface_t));
+               }
+               else
+               {
+                       my_interfaces->interface = (interface_t *)realloc(my_interfaces->interface, my_interfaces->count * sizeof(interface_t));
+               }
+
+               iface = &(my_interfaces->interface[my_interfaces->count - 1]);
+               memset(iface, 0, sizeof(interface_t));
+
+               memmove(iface->name, ifr->ifr_name, IFNAMSIZ);
+               iface->flags = ifr->ifr_ifru.ifru_flags;
+               iface->addr.s_addr = ((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr;
+               ioctl(sock, SIOCGIFNETMASK, (char *)ifr);
+               iface->mask.s_addr = ((struct sockaddr_in *)&(ifr->ifr_addr))->sin_addr.s_addr;
+               iface->netaddr.s_addr = iface->addr.s_addr & iface->mask.s_addr;
+               iface->bcast.s_addr = iface->netaddr.s_addr | (~iface->mask.s_addr);
+       }
+
+       close(sock);
+       return my_interfaces;
+}
+
+__private_extern__  void
+sys_interfaces_release(interface_list_t *l)
+{
+       if (l == NULL) return;
+
+       if (l->interface != NULL) free(l->interface);
+       free(l);
+}
+
+__private_extern__ int
+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
+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
new file mode 100644 (file)
index 0000000..154ac5b
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+ * 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 <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <netinet/in.h>
+
+typedef struct
+{
+       char name[IFNAMSIZ];
+       short flags;
+       struct in_addr addr;
+       struct in_addr mask;
+       struct in_addr netaddr;
+       struct in_addr bcast;
+} interface_t;
+
+typedef struct
+{
+       unsigned int count;
+       interface_t *interface;
+} interface_list_t;
+
+interface_list_t * sys_interfaces(void);
+void sys_interfaces_release(interface_list_t *l);
+int sys_is_my_address(interface_list_t *l, struct in_addr *a);
+int sys_is_my_network(interface_list_t *l, struct in_addr *a);
+
+#endif /* __SYS_INTERFACES__ */
index fffefc0b9824a767a622cc1fbb14db869590e98e..a559c034dab81a7904b7cdeb71f75c05795f3f20 100644 (file)
@@ -53,7 +53,7 @@
 #if defined(LIBC_SCCS) && !defined(lint) 
 /*static char *sccsid = "from: @(#)svc.c 1.44 88/02/08 Copyr 1984 Sun Micro";*/
 /*static char *sccsid = "from: @(#)svc.c       2.4 88/08/11 4.0 RPCSRC";*/
-static char *rcsid = "$Id: svc.c,v 1.2 1999/10/14 21:56:54 wsanchez Exp $";
+static char *rcsid = "$Id: svc.c,v 1.3 2001/08/23 01:25:01 ajn Exp $";
 #endif
 
 /*
@@ -411,8 +411,11 @@ svc_getreqset(readfds)
 
 
        maskp = (u_long *)readfds->fds_bits;
-       for (sock = 0; sock < FD_SETSIZE; sock += NFDBITS) {
+       for (sock = 0; sock <= svc_maxfd; sock += NFDBITS) {
            for (mask = *maskp++; bit = ffs(mask); mask ^= (1 << (bit - 1))) {
+               if ((sock + bit) > (svc_maxfd + 1))
+                       /* if we're past our sockets */
+                       return;
                /* sock has input waiting */
                xprt = xports[sock + bit - 1];
                if (xprt == NULL)