*
* @APPLE_LICENSE_HEADER_START@
*
- * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
- * Reserved. This file contains Original Code and/or Modifications of
+ * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
+ * Reserved. This file contains Original Code and/or Modifications of
* Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.1 (the "License"). You may not use this file
- * except in compliance with the License. Please obtain a copy of the
+ * Source License Version 1.1 (the "License"). You may not use this file
+ * except in compliance with the License. Please obtain a copy of the
* License at http://www.apple.com/publicsource and read it before using
* this file.
*
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
+ * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
* License for the specific language governing rights and limitations
* under the License.
*
* 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/xdr.h>
#include <net/if.h>
#include <ctype.h>
+#include <errno.h>
#include "clib.h"
#include "sys_interfaces.h"
#define NI_TIMEOUT_SHORT 5 /* 5 second timeout for transactions */
#define NI_TIMEOUT_LONG 60 /* 60 second timeout for writes */
-#define NI_TRIES 5 /* number of retries per timeout (udp only) */
+#define NI_TRIES 5 /* number of retries per timeout (udp only) */
#define NI_SLEEPTIME 4 /* 4 second sleeptime, in case of errors */
-#define NI_MAXSLEEPTIME 64 /* 64 second max sleep time */
+#define NI_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 */
#endif
#define debug(msg) syslog(LOG_ERR, msg)
-#define clnt_debug(ni, msg) /* do nothing */
+#define clnt_debug(ni, msg) /* do nothing */
-typedef struct ni_private {
+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 */
#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_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.
+ * Keep track of our port, in case somebody closes our socket on us.
*/
static int
-getmyport(
- int sock
- )
+getmyport(int sock)
{
struct sockaddr_in sin;
int sinlen;
- sinlen = sizeof(sin);
- if (getsockname(sock, (struct sockaddr *)&sin, &sinlen) == 0) {
- if (sin.sin_port == 0) {
- (void)bind(sock, (struct sockaddr *)&sin, sizeof(sin));
- sinlen = sizeof(sin);
- (void)getsockname(sock, (struct sockaddr *)&sin,
- &sinlen);
- }
- return (ntohs(sin.sin_port));
+ 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 (-1);
+
+ return ntohs(sin.sin_port);
}
static void
-createauth(
- ni_private *ni
- )
+createauth(ni_private *ni)
{
- if (ni->passwd != NULL && ni->tc != NULL) {
+ 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);
+ ni->tc->cl_auth = authunix_create(ni->passwd, ni->uid, 0, 0, NULL);
}
}
static void
-fixtimeout(
- struct timeval *tv,
- long sec,
- int tries
- )
+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
- )
+ni_settimeout(ni_private *ni, int timeout)
{
struct timeval tv;
tv.tv_sec = timeout;
tv.tv_usec = 0;
ni->tv_sec = timeout;
- if (ni->tc != NULL) {
- clnt_control(ni->tc, CLSET_TIMEOUT, &tv);
- }
+ if (ni->tc != NULL) clnt_control(ni->tc, CLSET_TIMEOUT, (char *)&tv);
}
connectit(ni_private *ni)
{
struct sockaddr_in sin;
- int sock;
+ 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"))
{
- interface_list_t *ilist;
+ 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);
+ }
- ilist = sys_interfaces();
- if (sys_is_my_address(ilist, &ni->addrs[0]))
+ 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);
}
- 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 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_addr = ni->addrs[0];
sock = socket_open(&sin, NIBIND_PROG, NIBIND_VERS, ni->tv_sec, NI_TRIES, IPPROTO_UDP);
- if (sock < 0) return (0);
+ if (sock < 0) return 0;
cl = clntudp_create(&sin, NIBIND_PROG, NIBIND_VERS, tv, &sock);
if (cl == NULL)
{
close(sock);
- return (0);
+ 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);
+ 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);
-
+ 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);
+ if (sock < 0) return 0;
cl = clnttcp_create(&sin, NI_PROG, NI_VERS, &sock, 0, 0);
if (cl == NULL)
{
close(sock);
- return (0);
+ return 0;
}
- clnt_control(cl, CLSET_TIMEOUT, &tv);
+ 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);
+ return 1;
}
void
-ni_setabort(
- void *ni,
- int abort
- )
+ni_setabort(void *ni, int abort)
{
+ if (ni == NULL) return;
+
((ni_private *)ni)->abort = abort;
}
void
-ni_setwritetimeout(
- void *ni,
- int timeout
- )
+ni_setwritetimeout(void *ni, int timeout)
{
+ if (ni == NULL) return;
+
((ni_private *)ni)->wtv_sec = timeout;
}
void
-ni_setreadtimeout(
- void *ni,
- int timeout
- )
+ni_setreadtimeout(void *ni, int timeout)
{
+ if (ni == NULL) return;
+
((ni_private *)ni)->rtv_sec = timeout;
}
void
-ni_needwrite(
- void *ni,
- int needwrite
- )
+ni_needwrite(void *ni, int needwrite)
{
+ if (ni == NULL) return;
+
((ni_private *)ni)->needwrite = needwrite;
}
ni->tags[0] = ni_name_dup("local");
ni->whichwrite = 0;
- while (!connectit(ni))
+ while (connectit(ni) == 0)
{
- if (!printed)
+ if (printed == 0)
{
syslog(LOG_ERR, "NetInfo timeout connecting to local domain, sleeping");
- printed++;
+ printed = 1;
}
sleep(NI_SLEEPTIME);
/* wait forever */
}
- if (printed)
- {
- syslog(LOG_ERR, "NetInfo connection to local domain waking");
- }
+ if (printed != 0) syslog(LOG_INFO, "NetInfo connection to local domain waking");
- return (1);
+ return 1;
}
* Destroy the client handle
*/
static void
-clnt_kill(
- CLIENT *cl,
- int sock,
- int port
- )
+clnt_kill(CLIENT *cl, int sock, int port)
{
int save = 0;
+ int p;
- if (sock >= 0 && getmyport(sock) != port) {
- /*
- * Somebody else has the descriptor open. Do not close it,
- * it's not ours.
- */
- save++;
+ p = getmyport(sock);
+
+ if ((sock >= 0) && (p != -1) && (p != port))
+ {
+ /* Somebody has the reused the socket. */
+ save = 1;
}
- if (cl != NULL) {
- auth_destroy(cl->cl_auth);
+
+ if (cl != NULL)
+ {
+ if (cl->cl_auth != NULL) auth_destroy(cl->cl_auth);
clnt_destroy(cl);
}
- if (!save) {
- /*
- * It's ours and we can close it
- */
- (void)close(sock);
- }
+
+ if (save == 0) close(sock);
}
* Reinitialize everything
*/
static void
-reinit(
- ni_private *ni
- )
+reinit(ni_private *ni)
{
- if (ni->tc != NULL) {
+ 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
- )
+ni_switch(ni_private *ni, ni_index which)
{
struct in_addr tmp_addr;
ni_name tmp_tag;
- if (which == 0) {
- return;
- }
+ 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;
- }
+ 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
- )
+ni_swap(ni_private *ni, ni_index a, ni_index b)
{
struct in_addr tmp_addr;
ni_name tmp_tag;
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;
- }
+ 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
- )
+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);
- }
+
+ 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);
+ return TRUE;
}
shuffle(ni_private *ni)
{
int *shuffle;
- int i, j;
- int rfd;
+ 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--) {
- unsigned int rEnt;
- long rVal;
- int tEnt;
-
+ for (i = 0, j = ni->naddrs; j > 0; i++, j--)
+ {
/* get a random number */
- if ((rfd < 0) ||
- (read(rfd, &rVal, sizeof(rVal)) != sizeof(rVal))) {
+ if ((rfd < 0) || (read(rfd, &rv, sizeof(rv)) != sizeof(rv)))
+ {
/* if we could not read from /dev/random */
- static int initialized = 0;
- if (!initialized)
+ if (initialized == 0)
{
srandom(gethostid() ^ time(NULL));
- initialized++;
+ initialized = 1;
}
- rVal = random();
+ rv = 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 */
+ 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) (void)close(rfd);
+ if (rfd > 0) close(rfd);
return;
}
static int
-rebind(
- ni_private *ni
- )
+rebind(ni_private *ni)
{
enum clnt_stat stat;
getreg_stuff stuff;
interface_list_t *ilist;
int i;
- if (ni->naddrs == 1) {
+ if (ni->naddrs == 1)
+ {
ni->whichwrite = 0;
- return (1);
+ return 1;
}
/*
* all other servers are next
*/
- ilist = sys_interfaces();
+ ilist = _libinfo_ni_sys_interfaces();
/*
* shuffle addresses
* move local servers to the head of the list
*/
nlocal = 0;
- for (i = nlocal; i < ni->naddrs; i++) {
- if (sys_is_my_address(ilist, &ni->addrs[i]))
+ 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 (sys_is_my_network(ilist, &ni->addrs[i]) ||
- IS_BROADCASTADDR(ni->addrs[i].s_addr))
+ 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++;
}
}
- sys_interfaces_release(ilist);
+ _libinfo_ni_sys_interfaces_release(ilist);
stuff.ni = ni;
- for (;;) {
+ for (;;)
+ {
/*
* call local servers first
*/
- if (nlocal > 0) {
- for (i = 0; i < nlocal; i++) {
- syslog(LOG_DEBUG, "NetInfo connect call to: %s/%s (local %d)",
- inet_ntoa(ni->addrs[i]), ni->tags[i], i);
- }
- stat = multi_call(nlocal, ni->addrs,
- NIBIND_PROG, NIBIND_VERS, NIBIND_GETREGISTER,
- xdr_ni_name, ni->tags,
- sizeof(ni_name),
- xdr_nibind_getregister_res,
- &stuff, eachresult,
- NI_TIMEOUT_SHORT);
- if (stat == RPC_SUCCESS) {
- break;
+ 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,
- xdr_ni_name, ni->tags,
- sizeof(ni_name),
- xdr_nibind_getregister_res,
- &stuff, eachresult,
- NI_TIMEOUT_SHORT);
- if (stat == RPC_SUCCESS) {
- break;
+ 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,
- xdr_ni_name, ni->tags,
- sizeof(ni_name),
- xdr_nibind_getregister_res,
- &stuff, eachresult,
- ni->rtv_sec == 0 ? NI_TIMEOUT_SHORT : ni->rtv_sec);
- if (stat == RPC_SUCCESS) {
- break;
+ 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) {
- if (ni->whichwrite >= 0) {
- syslog(LOG_ERR,
- "NetInfo connect timeout (domain with master %s/%s), sleeping",
- inet_ntoa(ni->addrs[ni->whichwrite]), ni->tags[ni->whichwrite]);
+ 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_ERR, "NetInfo connect timeout (domain with server %s/%s), sleeping",
- inet_ntoa(ni->addrs[0]), ni->tags[0]);
+ else
+ {
+ syslog(LOG_WARNING, "NetInfo connect timeout (domain with server %s/%s), sleeping", inet_ntoa(ni->addrs[0]), ni->tags[0]);
}
- printed++;
+
+ printed = 1;
}
+
sleep(sleeptime);
- if (sleeptime < NI_MAXSLEEPTIME) {
- sleeptime *= 2; /* backoff */
+ if (sleeptime < NI_MAXSLEEPTIME)
+ {
+ /* backoff */
+ sleeptime *= 2;
}
}
syslog(LOG_INFO, "NetInfo connected to %s/%s", inet_ntoa(ni->addrs[0]), ni->tags[0]);
- if (printed) {
- syslog(LOG_ERR, "NetInfo connected to %s/%s", inet_ntoa(ni->addrs[0]), ni->tags[0]);
- }
- return (1);
+ return 1;
}
* Confirm that our tcp socket is still valid
*/
static int
-confirm_tcp(
- ni_private *ni,
- int needwrite
- )
+confirm_tcp(ni_private *ni, int needwrite)
{
- if (ni->tsock != -1) {
- if (getmyport(ni->tsock) == ni->tport) {
- return (1);
+ 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 closed our socket. Do not close it, it could
- * be owned by somebody else now.
+ * Somebody has reused our socket.
*/
- auth_destroy(ni->tc->cl_auth);
- clnt_destroy(ni->tc);
- ni->tc = NULL;
- }
- if (!needwrite && !rebind(ni) && ni->abort) {
- return (0);
+ if (ni->tc != NULL)
+ {
+ if (ni->tc->cl_auth != NULL) auth_destroy(ni->tc->cl_auth);
+ clnt_destroy(ni->tc);
+ ni->tc = NULL;
+ }
}
- return (connectit(ni));
+
+ if ((needwrite == 0) && (rebind(ni) == 0) && (ni->abort != 0)) return 0;
+
+ return connectit(ni);
}
static int
-setmaster(
- ni_private *ni
- )
+setmaster(ni_private *ni)
{
ni_id root;
ni_namelist nl;
struct in_addr addr;
int needwrite;
- if (ni->naddrs == 1) {
- /*
- * One server - must be the master
- */
+ if (ni->naddrs == 1)
+ {
+ /* One server - must be the master */
ni->whichwrite = 0;
- return (1);
+ return 1;
}
+
needwrite = ni->needwrite;
ni->needwrite = 0;
- if (ni_root(ni, &root) != NI_OK) {
+ if (ni_root(ni, &root) != NI_OK)
+ {
ni->needwrite = needwrite;
- return (0);
+ return 0;
}
+
NI_INIT(&nl);
- if (ni_lookupprop(ni, &root, NAME_MASTER, &nl) != NI_OK) {
+ if (ni_lookupprop(ni, &root, NAME_MASTER, &nl) != NI_OK)
+ {
ni->needwrite = needwrite;
- return (0);
+ return 0;
}
- if (nl.ninl_len == 0) {
+
+ if (nl.ninl_len == 0)
+ {
ni->needwrite = needwrite;
- return (0);
+ return 0;
}
+
sep = index(nl.ninl_val[0], '/');
- if (sep == NULL) {
+ if (sep == NULL)
+ {
ni->needwrite = needwrite;
- return (0);
+ return 0;
}
+
*sep++ = 0;
master = nl.ninl_val[0];
+
NI_INIT(&idl);
- if (ni_lookup(ni, &root, NAME_NAME, NAME_MACHINES, &idl) != NI_OK) {
+ if (ni_lookup(ni, &root, NAME_NAME, NAME_MACHINES, &idl) != NI_OK)
+ {
ni->needwrite = needwrite;
ni_namelist_free(&nl);
- return (0);
+ return 0;
}
- if (idl.niil_len < 1) {
+
+ if (idl.niil_len < 1)
+ {
ni->needwrite = needwrite;
- return (0);
+ 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) {
+ if (ni_lookup(ni, &id, NAME_NAME, master, &idl) != NI_OK)
+ {
ni_namelist_free(&nl);
ni->needwrite = needwrite;
- return (0);
+ return 0;
}
+
ni_namelist_free(&nl);
- if (idl.niil_len < 1) {
+ if (idl.niil_len < 1)
+ {
ni->needwrite = needwrite;
- return (0);
+ 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++) {
+ 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) {
+ 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);
+ return 1;
}
}
}
+
ni->needwrite = needwrite;
ni_namelist_free(&nl);
- return (0);
+ return 0;
}
static void *
-callit(
- ni_private *ni,
- void *(*stub)(),
- void *args,
- int needwrite
- )
+callit(ni_private *ni, void *(*stub)(), void *args, int needwrite)
{
void *resp;
struct rpc_err err;
int sleeptime = 0;
int printed = 0;
- if (getpid() != ni->pid) {
- reinit(ni);
- }
- if (needwrite || ni->needwrite) {
- if (ni->whichwrite >= 0) {
+ if (getpid() != ni->pid) reinit(ni);
+
+ if (needwrite || ni->needwrite)
+ {
+ if (ni->whichwrite >= 0)
+ {
ni_switch(ni, ni->whichwrite);
- } else {
- if (!setmaster(ni)) {
- return (NULL);
- }
+ }
+ else
+ {
+ if (setmaster(ni) == 0) return NULL;
ni_switch(ni, ni->whichwrite);
}
- if (!needwrite) {
- ni_settimeout(ni, (ni->rtv_sec == 0 ?
- NI_TIMEOUT_SHORT : ni->rtv_sec));
+
+ 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));
+ 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 (;;) {
+
+ for (;;)
+ {
/*
* Try more than once, in case server closed connection.
*/
- for (i = 0; i < NI_MAXCONNTRIES; i++) {
- if (!confirm_tcp(ni, needwrite)) {
- break;
- }
- if ((resp = (*stub)(args, ni->tc)) != NULL) {
- if (printed) {
- syslog(LOG_ERR, "NetInfo connected to %s/%s",
- inet_ntoa(ni->addrs[0]), ni->tags[0]);
- }
- return (resp);
+ 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;
}
- clnt_geterr(ni->tc, &err);
- if (err.re_status != RPC_CANTRECV) {
- break;
+
+ 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.
- */
+
+ 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) {
+
+ 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 (ni->abort) reinit(ni);
+
+ syslog(LOG_ERR, "NetInfo connection failed for server %s/%s", inet_ntoa(ni->addrs[0]), ni->tags[0]);
+ return NULL;
}
- if (!printed) {
- if (ni->tc != NULL) {
- if (!(sleeptime == 0 &&
- err.re_status == RPC_TIMEDOUT)) {
+
+ 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
* 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++;
+ 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 {
+ else
+ {
/* first attempt failed */
- syslog(LOG_ERR, "%s on initial connection to %s/%s",
- clnt_sperror(ni->tc,"NetInfo connection timeout"),
- inet_ntoa(ni->addrs[0]), ni->tags[0]);
+ 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++;
+ }
+ else
+ {
+ syslog(LOG_ERR, "NetInfo connection failed for server %s/%s", inet_ntoa(ni->addrs[0]), ni->tags[0]);
+ printed = 1;
}
}
- if (sleeptime > 0) {
+
+ if (sleeptime > 0)
+ {
sleep(sleeptime);
- if (sleeptime < NI_MAXSLEEPTIME) {
- sleeptime *= 2; /* backoff */
- }
- } else {
+ /* 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);
- (void)rebind(ni);
+ rebind(ni);
}
}
-#define RCALLIT(a, b, c) callit((ni_private *)(a), (void *(*)())(b), \
- (void *)c, 0)
-
-
-#define WCALLIT(a, b, c) callit((ni_private *)(a), (void *(*)())(b), \
- (void *)c, 1)
-
-
static void
-ni_clear(
- ni_private *ni
- )
+ni_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;
+ 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_alloc(void)
{
ni_private *ni;
ni->passwd = NULL;
ni->uid = getuid();
ni->needwrite = 0;
- return ((void *)ni);
+ return (void *)ni;
}
void *
-_ni_dup(
- void *ni
- )
+_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++) {
+ 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);
+
+ 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
- )
+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] == '/') {
+ if (sep == NULL) return 0;
+
+ if ((strncmp(domain, domtag, len) == 0) && (domtag[len] == '/'))
+ {
*tag = ni_name_dup(sep + 1);
- return (1);
+ return 1;
}
- return (0);
+
+ 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
- )
+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);
- if (ni_lookupprop(ni, &id, NAME_IP_ADDRESS, &nl) != NI_OK) {
- return (0);
- }
- if (nl.ninl_len == 0) {
- return(0);
- }
- if (target_ni->naddrs == 0) {
- target_ni->addrs =
- (struct in_addr *)malloc(nl.ninl_len * sizeof(struct in_addr));
- target_ni->tags =
- (ni_name *)malloc(nl.ninl_len * sizeof(ni_name));
- } else {
- target_ni->addrs =
- (struct in_addr *)realloc(target_ni->addrs,
- ((target_ni->naddrs + nl.ninl_len) * sizeof(struct in_addr)));
- target_ni->tags =
- (ni_name *)realloc(target_ni->tags,
- ((target_ni->naddrs + nl.ninl_len) * sizeof(ni_name)));
+ 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.ninl_len; i++) {
- addr.s_addr = inet_addr(nl.ninl_val[i]);
+ 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);
+ return 1;
}
-
static int
-get_daddr(
- ni_private *ni,
- ni_name dom,
- ni_private *target_ni
- )
+get_daddr(ni_private *ni, ni_name dom, ni_private *target_ni)
{
- ni_id id;
+ ni_id nid;
ni_idlist ids;
- ni_namelist nl;
ni_entrylist entries;
+ ni_proplist pl;
ni_index i;
ni_index j;
ni_name tag;
- if (ni_root(ni, &id) != NI_OK) {
- return(0);
+ 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, &id, NAME_NAME, NAME_MACHINES, &ids) != NI_OK) {
- return (0);
- }
+ if (ni_lookup(ni, &nid, NAME_NAME, NAME_MACHINES, &ids) != NI_OK) return 0;
- id.nii_object = ids.niil_val[0];
+ nid.nii_object = ids.niil_val[0];
ni_idlist_free(&ids);
NI_INIT(&entries);
- if (ni_list(ni, &id, NAME_SERVES, &entries) != NI_OK) {
- return (0);
- }
-
- for (i = 0; i < entries.niel_len; i++) {
- if (entries.niel_val[i].names != NULL) {
- nl = *entries.niel_val[i].names;
- for (j = 0; j < nl.ninl_len; j++) {
- if (match(dom, nl.ninl_val[j], &tag)) {
- if (addaddr(ni,
- entries.niel_val[i].id,
- tag,
- target_ni)) {
- ni_name_free(&tag);
- break;
- }
- ni_name_free(&tag);
- }
+ 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);
}
-
-#ifdef notdef
-static int
-get_haddr(
- ni_private *ni,
- ni_name hname,
- ni_name tag,
- ni_private *target_ni
- )
-{
- ni_id id;
- ni_idlist ids;
-
- if (ni_root(ni, &id) != NI_OK) {
- return(0);
- }
- NI_INIT(&ids);
- if (ni_lookup(ni, &id, NAME_NAME, NAME_MACHINES, &ids) != NI_OK) {
- return (0);
- }
- id.nii_object = ids.niil_val[0];
- ni_idlist_free(&ids);
-
- NI_INIT(&ids);
- if (ni_lookup(ni, &id, NAME_NAME, hname, &ids) != NI_OK) {
- return (0);
- }
- id.nii_object = ids.niil_val[0];
- ni_idlist_free(&ids);
- if (!addaddr(ni, id.nii_object, tag, target_ni)) {
- return (0);
- }
- return (1);
-}
-#endif
-
-
static ni_status
getparent(ni_private *oldni, ni_private **newni)
{
ni_rparent_res *resp;
- ni_private *ni;
+ ni_private *ni = NULL;
ni_private *dupni;
- int found;
+ int found = 0;
ni_index i;
struct in_addr raddr;
int printed = 0;
int inlist = 0;
- found = 0;
- while (!found) {
+ if (oldni == NULL) return 0;
+ if (newni == NULL) return 0;
+
+ while (found == 0)
+ {
/*
* First, find our parent, any parent
*/
- for (;;) {
+ for (;;)
+ {
resp = RCALLIT(oldni, _ni_rparent_2, NULL);
- if (resp == NULL) {
- return (NI_FAILED);
- }
- if (resp->status != NI_NORESPONSE) {
- break;
- }
- if (!printed) {
- syslog(LOG_ERR, "NetInfo timeout finding server for parent of %s/%s, sleeping",
- inet_ntoa(oldni->addrs[0]), oldni->tags[0]);
- printed++;
+ 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) {
+
+ if (printed)
+ {
raddr.s_addr = htonl(resp->ni_rparent_res_u.binding.addr);
-
- syslog(LOG_ERR, "NetInfo %s/%s found parent %s/%s",
- inet_ntoa(oldni->addrs[0]), oldni->tags[0],
- inet_ntoa(raddr), resp->ni_rparent_res_u.binding.tag);
- }
- if (resp->status != NI_OK) {
- return (resp->status);
+
+ 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->addrs[0].s_addr=htonl(resp->ni_rparent_res_u.binding.addr);
ni->tags = (ni_name *)malloc(sizeof(ni_name));
ni->tags[0] = ni_name_dup(resp->ni_rparent_res_u.binding.tag);
-
- xdr_free(xdr_ni_rparent_res, resp);
-
+
+ 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)) {
-
+ if (get_daddr(dupni, ".", ni) == 0)
+ {
+ if (oldni->abort == 1)
+ {
+ ni_free(dupni);
+ break;
+ }
+ }
+ else
+ {
/*
- * Now make sure returned parent is head of
- * list
+ * 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) {
+ for (i = 0; i < ni->naddrs; i++)
+ {
+ if (ni->addrs[i].s_addr == dupni->addrs[0].s_addr)
+ {
ni_switch(ni, i);
inlist++;
break;
dupni->tsock = -1;
dupni->tport = -1;
dupni->tc = NULL;
- found++;
+ 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]);
+ 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) {
+
+ if (found)
+ {
*newni = ni;
- return (NI_OK);
- } else {
- ni_free(ni);
- return (NI_FAILED);
+ return NI_OK;
}
+
+ if (ni != NULL) ni_free(ni);
+ return NI_FAILED;
}
void *
-ni_connect(
- struct sockaddr_in *sin,
- const char *tag
- )
+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 = (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);
+ return ni;
}
ni_status
-ni_addrtag(
- void *ni,
- struct sockaddr_in *addr,
- ni_name *tag
- )
+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;
- 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);
+
+ return NI_OK;
}
void *
-ni_new(
- void *oldni,
- const char *domain
- )
+ni_new(void *oldni, const char *domain)
{
ni_private *ni;
ni_status status;
struct sockaddr_in sin;
struct hostent *he;
- if (oldni == NULL) {
+ 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)) {
+ if (connectlocal(ni) == 0)
+ {
free(ni);
- return (NULL);
+ return NULL;
}
- if (strcmp(domain, "..") == 0) {
+
+ 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);
- }
- } else if ((sep = index(domain, '@')) != NULL) {
- free(ni);
- tag = strncpy((char *)malloc(sep-domain+1), domain, sep-domain);
- tag[sep-domain] = '\0';
- addr = strcpy ((char *)malloc(strlen(sep+1)), sep+1);
- sin.sin_addr.s_addr = inet_addr(addr);
- if (sin.sin_addr.s_addr == INADDR_NONE) {
- he = gethostbyname(addr);
- if (he == NULL) {
- free(addr);
- free(tag);
- return (NULL);
- }
- bcopy(he->h_addr_list[0], &sin.sin_addr.s_addr, he->h_length);
- }
- ni = ni_connect(&sin, tag);
- free(addr);
- free(tag);
- } else if (strcmp(domain, ".") != 0) {
- /*
- * nothing else makes sense
- */
- free(ni);
- return (NULL);
- }
- } else {
- if (strcmp(domain, "..") == 0) {
- status = getparent((ni_private *)oldni, &ni);
- if (status != NI_OK) {
- return (NULL);
- }
- } else if ((sep = index(domain, '@')) != NULL) {
- tag = strncpy((char *)malloc(sep-domain+1), domain, sep-domain);
- tag[sep-domain] = '\0';
- addr = strcpy ((char *)malloc(strlen(sep+1)), sep+1);
- sin.sin_addr.s_addr = inet_addr(addr);
- if (sin.sin_addr.s_addr == INADDR_NONE) {
- he = gethostbyname(addr);
- if (he == NULL) {
- free(addr);
- free(tag);
- return (NULL);
- }
- bcopy(he->h_addr_list[0], &sin.sin_addr.s_addr, he->h_length);
- }
- ni = ni_connect(&sin, tag);
- free(addr);
- free(tag);
- } else {
- ni = ni_alloc();
- *ni = *NIP(oldni);
- ni_clear(ni);
- if (!get_daddr(oldni, (ni_name)domain, ni)) {
- ni_free(ni);
- ni = NULL;
- }
+ 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;
}
- 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_free(void *ni)
{
ni_index i;
- if (NIP(ni)->tc != NULL) {
- clnt_kill(NIP(ni)->tc, NIP(ni)->tsock, NIP(ni)->tport);
- }
- if (NIP(ni)->naddrs > 0) {
- free(NIP(ni)->addrs);
- for (i = 0; i < NIP(ni)->naddrs; i++) {
- ni_name_free(&NIP(ni)->tags[i]);
- }
+ 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);
- }
+
+ if (NIP(ni)->passwd != NULL) ni_name_free(&NIP(ni)->passwd);
+
free(ni);
}
* RPC calls to the local NetInfo server.
*/
ni_status
-ni_statistics(
- void *ni,
- ni_proplist *pl
- )
+ni_statistics(void *ni, ni_proplist *pl)
{
ni_proplist *resp;
- if ((resp = (ni_proplist *)RCALLIT(ni, _ni_statistics_2, NULL))
- == NULL) {
- return (NI_FAILED);
+ 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);
+ return NI_OK;
}
ni_status
-ni_root(
- void *ni,
- ni_id *id
- )
+ni_root(void *ni, ni_id *id)
{
ni_id_res *resp;
- if ((resp = RCALLIT(ni, _ni_root_2, id)) == NULL) {
+ 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 NI_FAILED;
}
- return (resp->status);
+
+ 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_self(void *ni, ni_id *id)
{
ni_id_res *resp;
- if ((resp = RCALLIT(ni, _ni_self_2, id)) == NULL) {
+ 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 NI_FAILED;
}
- return (resp->status);
+
+ 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(void *ni, ni_id *id, ni_index *parent_id_p)
{
ni_parent_res *resp;
- if ((resp = RCALLIT(ni, _ni_parent_2, id)) == NULL) {
+ 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);
+ return NI_FAILED;
}
- if (resp->status == NI_OK) {
+
+ 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);
+
+ return resp->status;
}
ni_status
-ni_children(
- void *ni,
- ni_id *id,
- ni_idlist *children
- )
+ni_children(void *ni, ni_id *id, ni_idlist *children)
{
ni_children_res *resp;
- if ((resp = RCALLIT(ni, _ni_children_2, id)) == NULL) {
+ 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);
+ return NI_FAILED;
}
- if (resp->status == NI_OK) {
+
+ 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);
+
+ 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(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;
- if ((resp = WCALLIT(ni, _ni_create_2, &args)) == NULL) {
+
+ resp = WCALLIT(ni, _ni_create_2, &args);
+ if (resp == NULL)
+ {
clnt_debug(ni, "_ni_create");
- return (NI_FAILED);
+ return NI_FAILED;
}
- if (resp->status == NI_OK) {
+
+ 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);
+
+ return resp->status;
}
ni_status
-ni_destroy(
- void *ni,
- ni_id *parent_id,
- ni_id self_id
- )
+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;
- if ((resp = WCALLIT(ni, _ni_destroy_2, &args)) == NULL) {
+
+ resp = WCALLIT(ni, _ni_destroy_2, &args);
+ if (resp == NULL)
+ {
clnt_debug(ni, "_ni_destroy");
- return (NI_FAILED);
+ return NI_FAILED;
}
- if (resp->status == NI_OK) {
- *parent_id = resp->ni_id_res_u.id;
- }
- return (resp->status);
+
+ 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_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;
- if ((resp = WCALLIT(ni, _ni_write_2, &args)) == NULL) {
+
+ 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 NI_FAILED;
}
- return (resp->status);
+
+ 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_read(void *ni, ni_id *self_id, ni_proplist *pl)
{
ni_proplist_res *resp;
- if ((resp = RCALLIT(ni, _ni_read_2, self_id)) == NULL) {
+ 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);
+ return NI_FAILED;
}
- if (resp->status == NI_OK) {
+
+ 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);
+
+ 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(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;
- if ((resp = RCALLIT(ni, _ni_lookup_2, &args)) == NULL) {
+
+ resp = RCALLIT(ni, _ni_lookup_2, &args);
+ if (resp == NULL)
+ {
clnt_debug(ni, "_ni_lookup");
- return (NI_FAILED);
+ return NI_FAILED;
}
- if (resp->status == NI_OK) {
+
+ 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);
+
+ return resp->status;
}
ni_status
-ni_lookupread(
- void *ni,
- ni_id *id,
- ni_name_const pname,
- ni_name_const pval,
- ni_proplist *props
- )
+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;
- if ((resp = RCALLIT(ni, _ni_lookupread_2, &args)) == NULL) {
+
+ resp = RCALLIT(ni, _ni_lookupread_2, &args);
+ if (resp == NULL)
+ {
clnt_debug(ni, "_ni_lookupread");
- return (NI_FAILED);
+ return NI_FAILED;
}
- if (resp->status == NI_OK) {
+
+ if (resp->status == NI_OK)
+ {
*props = resp->ni_proplist_res_u.stuff.props;
*id = resp->ni_proplist_res_u.stuff.id;
}
- return (resp->status);
+
+ return resp->status;
}
ni_status
-ni_list(
- void *ni,
- ni_id *id,
- ni_name_const pname,
- ni_entrylist *entries
- )
+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;
- if ((resp = RCALLIT(ni, _ni_list_2, &args)) == NULL) {
+
+ resp = RCALLIT(ni, _ni_list_2, &args);
+ if (resp == NULL)
+ {
clnt_debug(ni, "_ni_list");
- return (NI_FAILED);
+ return NI_FAILED;
}
- if (resp->status == NI_OK) {
+
+ 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);
+
+ return resp->status;
}
ni_status
-ni_listall(
- void *ni,
- ni_id *id,
- ni_proplist_list *entries
- )
+ni_listall(void *ni, ni_id *id, ni_proplist_list *entries)
{
ni_listall_res *resp;
- if ((resp = RCALLIT(ni, _ni_listall_2, id)) == NULL) {
+ 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);
+ return NI_FAILED;
}
- if (resp->status == NI_OK) {
+
+ 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);
+
+ return resp->status;
}
ni_status
-ni_readprop(
- void *ni,
- ni_id *id,
- ni_index which,
- ni_namelist *propval_p
- )
+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;
- if ((resp = RCALLIT(ni, _ni_readprop_2, &args)) == NULL) {
+
+ resp = RCALLIT(ni, _ni_readprop_2, &args);
+ if (resp == NULL)
+ {
clnt_debug(ni, "_ni_readprop");
- return (NI_FAILED);
+ return NI_FAILED;
}
- if (resp->status == NI_OK) {
+
+ 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);
+
+ return resp->status;
}
ni_status
-ni_writeprop(
- void *ni,
- ni_id *id,
- ni_index which,
- ni_namelist propval
- )
+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;
- if ((resp = WCALLIT(ni, _ni_writeprop_2, &args)) == NULL) {
+
+ 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 NI_FAILED;
}
- return (resp->status);
+
+ 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_listprops(void *ni, ni_id *id, ni_namelist *propnames)
{
ni_namelist_res *resp;
- if ((resp = RCALLIT(ni, _ni_listprops_2, id)) == NULL) {
+ 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);
+ return NI_FAILED;
}
- if (resp->status == NI_OK) {
+
+ 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);
+
+ return resp->status;
}
-
+
ni_status
-ni_createprop(
- void *ni,
- ni_id *id,
- ni_property prop,
- ni_index where
- )
+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;
- if ((resp = WCALLIT(ni, _ni_createprop_2, &args)) == NULL) {
+
+ 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 NI_FAILED;
}
- return (resp->status);
+
+ 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_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;
- if ((resp = WCALLIT(ni, _ni_destroyprop_2, &args)) == NULL) {
+
+ resp = WCALLIT(ni, _ni_destroyprop_2, &args);
+ if (resp == NULL)
+ {
clnt_debug(ni, "_ni_destroyprop");
- return (NI_FAILED);
+ return NI_FAILED;
}
- if (resp->status == NI_OK) {
- *id = resp->ni_id_res_u.id;
- }
- return (resp->status);
+
+ 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_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;
- if ((resp = WCALLIT(ni, _ni_renameprop_2, &args)) == NULL) {
+
+ 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 NI_FAILED;
}
- return (resp->status);
+
+ 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_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;
- if ((resp = WCALLIT(ni, _ni_createname_2, &args)) == NULL) {
+
+ resp = WCALLIT(ni, _ni_createname_2, &args);
+ if (resp == NULL)
+ {
clnt_debug(ni, "_ni_createname");
- return (NI_FAILED);
+ return NI_FAILED;
}
- if (resp->status == NI_OK) {
- *id = resp->ni_id_res_u.id;
- }
- return (resp->status);
+
+ 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_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;
- if ((resp = WCALLIT(ni, _ni_destroyname_2, &args)) == NULL) {
+
+ 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 NI_FAILED;
}
- return (resp->status);
+
+ 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_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;
- if ((resp = WCALLIT(ni, _ni_writename_2, &args)) == NULL) {
+
+ resp = WCALLIT(ni, _ni_writename_2, &args);
+ if (resp == NULL)
+ {
clnt_debug(ni, "_ni_writename");
- return (NI_FAILED);
+ return NI_FAILED;
}
- if (resp->status == NI_OK) {
- *id = resp->ni_id_res_u.id;
- }
- return (resp->status);
+
+ 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(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;
- if ((resp = RCALLIT(ni, _ni_readname_2, &args)) == NULL) {
+
+ resp = RCALLIT(ni, _ni_readname_2, &args);
+ if (resp == NULL)
+ {
clnt_debug(ni, "_ni_readname");
- return (NI_FAILED);
+ return NI_FAILED;
}
- if (resp->status == NI_OK) {
+
+ if (resp->status == NI_OK)
+ {
*id = resp->ni_readname_res_u.stuff.id;
*name = resp->ni_readname_res_u.stuff.name;
}
- return (resp->status);
+
+ return resp->status;
}
ni_status
-ni_resync(
- void *ni
- )
+ni_resync(void *ni)
{
ni_status *resp;
- if ((resp = (ni_status *)RCALLIT(ni, _ni_resync_2, NULL)) == NULL) {
- return (NI_FAILED);
+ 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);
+
+ return *resp;
}
ni_status
-ni_setuser(
- void *ni,
- ni_name_const user
- )
+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) {
+ if (user == NULL)
+ {
NIP(ni)->uid = getuid();
- return (ni_setpassword(ni, NULL));
+ return ni_setpassword(ni, NULL);
}
- if (ni_root(ni, &id) != NI_OK) {
- return(NI_NOUSER);
- }
+ status = ni_root(ni, &id);
+ if (status != NI_OK) return NI_NOUSER;
+
NI_INIT(&ids);
- if (ni_lookup(ni, &id, NAME_NAME, NAME_USERS, &ids) != NI_OK) {
- return (NI_NOUSER);
- }
+ 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);
- if (ni_lookup(ni, &id, NAME_NAME, user, &ids) != NI_OK) {
- return (NI_NOUSER);
- }
+ 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);
- if (ni_lookupprop(ni, &id, NAME_UID, &nl) != NI_OK) {
- return (NI_NOUSER);
- }
- if (nl.ninl_len == 0) {
- return (NI_NOUSER);
- }
- for (p = nl.ninl_val[0]; *p; p++) {
- if (!isdigit(*p)) {
+ 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);
+ return NI_NOUSER;
}
}
+
NIP(ni)->uid = atoi(nl.ninl_val[0]);
- if (NIP(ni)->passwd == NULL) {
- NIP(ni)->passwd = ni_name_dup("");
- }
+ if (NIP(ni)->passwd == NULL) NIP(ni)->passwd = ni_name_dup("");
+
createauth(NIP(ni));
- return (NI_OK);
+ return NI_OK;
}
ni_status
-ni_setpassword(
- void *ni,
- ni_name_const passwd
- )
+ni_setpassword(void *ni, ni_name_const passwd)
{
char *p;
- if (NIP(ni)->passwd != NULL) {
- ni_name_free(&NIP(ni)->passwd);
- }
- if (passwd == NULL) {
+ 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) {
+ if (NIP(ni)->tc != NULL)
+ {
auth_destroy(NIP(ni)->tc->cl_auth);
NIP(ni)->tc->cl_auth = authnone_create();
}
- return (NI_OK);
+ return NI_OK;
}
+
NIP(ni)->passwd = ni_name_dup(passwd);
- /*
- * Our trivial encryption scheme
- */
- for (p = NIP(ni)->passwd; *p; p++) {
- *p = ~(*p);
- }
+
+ /* Our trivial encryption scheme */
+ for (p = NIP(ni)->passwd; *p; p++) *p = ~(*p);
createauth(NIP(ni));
- return (NI_OK);
+ return NI_OK;
}
-extern int bindresvport(int, struct sockaddr_in *);
-
-
/*
- * NeXT note:
* The procedure pmap_getport_to below is derived
- * from Sun Microsystems RPC source code. As such the following
+ * 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
+ * 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 Microsystems, Inc.
* 2550 Garcia Avenue
- * Mountain View, California 94043
+ * Mountain View, California 94043
*/
/*
* Client interface to pmap rpc service.
register CLIENT *client;
struct pmap parms;
struct timeval timeout;
-
+
sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
- if (sock < 0) {
- return (0);
- }
+ if (sock < 0) return 0;
+
address->sin_port = htons(PMAPPORT);
timeout.tv_usec = ((timeout_secs % ntries) * 1000000) / ntries;
timeout.tv_sec = (timeout_secs / ntries);
- client = clntudp_bufcreate(address, PMAPPROG,
- PMAPVERS, timeout, &sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
- if (client != (CLIENT *)NULL) {
+
+ 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 */
+ parms.pm_port = 0; /* not needed or used */
timeout.tv_usec = 0;
timeout.tv_sec = timeout_secs;
- if (CLNT_CALL(client, PMAPPROC_GETPORT, xdr_pmap, &parms,
- xdr_u_short, &port, timeout) != RPC_SUCCESS){
+
+ 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) {
+ }
+ else if (port == 0)
+ {
rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
}
}
- if (client != NULL) {
- clnt_destroy(client);
- }
- (void)close(sock);
+
+ if (client != NULL) clnt_destroy(client);
+
+ close(sock);
address->sin_port = 0;
- return (port);
+ 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
- )
+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) {
- u_short port;
- if ((port = pmap_getport_to(raddr, prog, vers,
- IPPROTO_UDP, timeout,
- ntries)) == 0) {
- return (-1);
- }
+ 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);
+ 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;
+ }
}
- (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) {
- (void)close(sock);
- return (-1);
+ 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);
+
+ return sock;
}