diff options
author | Eric Andersen <andersen@codepoet.org> | 2002-06-17 21:12:16 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2002-06-17 21:12:16 +0000 |
commit | cdb3c81f36283df4b53f24a374d78c695e9d8b06 (patch) | |
tree | 9494bff7c98929e44c41dcdde32dc3fc6faf4330 /libc/inet/rpc/pmap_rmt.c | |
parent | 6ba832b158c91c6b35e1832220b3fc5ebf76333f (diff) |
Re-backport all the rpc stuff from glibc 2.2.5. This allows us to make this
junk (and I do mean that ;-) thread safe without undue pain. Adds 12k worth to
the code size I'm afraid, but since I never use NFS and therefore never include
this stuff, I guess thats acceptable. I still need to enable the multi-threaded
bits...
-Erik
Diffstat (limited to 'libc/inet/rpc/pmap_rmt.c')
-rw-r--r-- | libc/inet/rpc/pmap_rmt.c | 615 |
1 files changed, 308 insertions, 307 deletions
diff --git a/libc/inet/rpc/pmap_rmt.c b/libc/inet/rpc/pmap_rmt.c index 13b557d71..0fee124d6 100644 --- a/libc/inet/rpc/pmap_rmt.c +++ b/libc/inet/rpc/pmap_rmt.c @@ -6,27 +6,30 @@ * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. - * + * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. - * + * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. - * + * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. - * + * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. - * + * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro"; +#endif /* * pmap_rmt.c @@ -38,25 +41,27 @@ #define __FORCE_GLIBC #include <features.h> + #include <unistd.h> #include <string.h> -#include <sys/time.h> -#include <sys/types.h> #include <rpc/rpc.h> #include <rpc/pmap_prot.h> #include <rpc/pmap_clnt.h> #include <rpc/pmap_rmt.h> +#include <sys/poll.h> #include <sys/socket.h> #include <stdio.h> #include <errno.h> -//#include <net/if.h> +#undef _POSIX_SOURCE /* Ultrix <sys/param.h> needs --roland@gnu */ +#include <sys/param.h> /* Ultrix needs before net/if --roland@gnu */ +#include <net/if.h> #include <sys/ioctl.h> #include <arpa/inet.h> #define MAX_BROADCAST_SIZE 1400 -extern int errno; -static struct timeval timeout = { 3, 0 }; +extern u_long _create_xid (void); +static const struct timeval timeout = {3, 0}; /* * pmapper remote-call-service interface. @@ -64,44 +69,46 @@ static struct timeval timeout = { 3, 0 }; * which will look up a service program in the port maps, and then * remotely call that routine with the given parameters. This allows * programs to do a lookup and call in one step. -*/ + */ enum clnt_stat -pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, - port_ptr) -struct sockaddr_in *addr; -u_long prog, vers, proc; -xdrproc_t xdrargs, xdrres; -caddr_t argsp, resp; -struct timeval tout; -u_long *port_ptr; +pmap_rmtcall (addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_ptr) + struct sockaddr_in *addr; + u_long prog, vers, proc; + xdrproc_t xdrargs, xdrres; + caddr_t argsp, resp; + struct timeval tout; + u_long *port_ptr; { - int socket = -1; - register CLIENT *client; - struct rmtcallargs a; - struct rmtcallres r; - enum clnt_stat stat; + int socket = -1; + CLIENT *client; + struct rmtcallargs a; + struct rmtcallres r; + enum clnt_stat stat; - addr->sin_port = htons(PMAPPORT); - client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &socket); - if (client != (CLIENT *) NULL) { - a.prog = prog; - a.vers = vers; - a.proc = proc; - a.args_ptr = argsp; - a.xdr_args = xdrargs; - r.port_ptr = port_ptr; - r.results_ptr = resp; - r.xdr_results = xdrres; - stat = CLNT_CALL(client, PMAPPROC_CALLIT, - (xdrproc_t) xdr_rmtcall_args, (caddr_t) &a, - (xdrproc_t) xdr_rmtcallres, (caddr_t) &r, tout); - CLNT_DESTROY(client); - } else { - stat = RPC_FAILED; - } - (void) close(socket); - addr->sin_port = 0; - return (stat); + addr->sin_port = htons (PMAPPORT); + client = clntudp_create (addr, PMAPPROG, PMAPVERS, timeout, &socket); + if (client != (CLIENT *) NULL) + { + a.prog = prog; + a.vers = vers; + a.proc = proc; + a.args_ptr = argsp; + a.xdr_args = xdrargs; + r.port_ptr = port_ptr; + r.results_ptr = resp; + r.xdr_results = xdrres; + stat = CLNT_CALL (client, PMAPPROC_CALLIT, (xdrproc_t)xdr_rmtcall_args, + (caddr_t)&a, (xdrproc_t)xdr_rmtcallres, + (caddr_t)&r, tout); + CLNT_DESTROY (client); + } + else + { + stat = RPC_FAILED; + } + /* (void)__close(socket); CLNT_DESTROY already closed it */ + addr->sin_port = 0; + return stat; } @@ -109,304 +116,298 @@ u_long *port_ptr; * XDR remote call arguments * written for XDR_ENCODE direction only */ -bool_t xdr_rmtcall_args(XDR *xdrs, struct rmtcallargs *cap) +bool_t +xdr_rmtcall_args (XDR *xdrs, struct rmtcallargs *cap) { - u_int lenposition, argposition, position; + u_int lenposition, argposition, position; - if (xdr_u_long(xdrs, &(cap->prog)) && - xdr_u_long(xdrs, &(cap->vers)) && xdr_u_long(xdrs, &(cap->proc))) { - lenposition = XDR_GETPOS(xdrs); - if (!xdr_u_long(xdrs, &(cap->arglen))) - return (FALSE); - argposition = XDR_GETPOS(xdrs); - if (!(*(cap->xdr_args)) (xdrs, cap->args_ptr)) - return (FALSE); - position = XDR_GETPOS(xdrs); - cap->arglen = (u_long) position - (u_long) argposition; - XDR_SETPOS(xdrs, lenposition); - if (!xdr_u_long(xdrs, &(cap->arglen))) - return (FALSE); - XDR_SETPOS(xdrs, position); - return (TRUE); - } - return (FALSE); + if (xdr_u_long (xdrs, &(cap->prog)) && + xdr_u_long (xdrs, &(cap->vers)) && + xdr_u_long (xdrs, &(cap->proc))) + { + lenposition = XDR_GETPOS (xdrs); + if (!xdr_u_long (xdrs, &(cap->arglen))) + return FALSE; + argposition = XDR_GETPOS (xdrs); + if (!(*(cap->xdr_args)) (xdrs, cap->args_ptr)) + return FALSE; + position = XDR_GETPOS (xdrs); + cap->arglen = (u_long) position - (u_long) argposition; + XDR_SETPOS (xdrs, lenposition); + if (!xdr_u_long (xdrs, &(cap->arglen))) + return FALSE; + XDR_SETPOS (xdrs, position); + return TRUE; + } + return FALSE; } /* * XDR remote call results * written for XDR_DECODE direction only */ -bool_t xdr_rmtcallres(xdrs, crp) -register XDR *xdrs; -register struct rmtcallres *crp; +bool_t +xdr_rmtcallres (xdrs, crp) + XDR *xdrs; + struct rmtcallres *crp; { - caddr_t port_ptr; + caddr_t port_ptr; - port_ptr = (caddr_t) crp->port_ptr; - if (xdr_reference(xdrs, &port_ptr, sizeof(u_long), - (xdrproc_t) xdr_u_long) && xdr_u_long(xdrs, &crp->resultslen)) { - crp->port_ptr = (u_long *) port_ptr; - return ((*(crp->xdr_results)) (xdrs, crp->results_ptr)); - } - return (FALSE); + port_ptr = (caddr_t) crp->port_ptr; + if (xdr_reference (xdrs, &port_ptr, sizeof (u_long), (xdrproc_t) xdr_u_long) + && xdr_u_long (xdrs, &crp->resultslen)) + { + crp->port_ptr = (u_long *) port_ptr; + return (*(crp->xdr_results)) (xdrs, crp->results_ptr); + } + return FALSE; } -void get_myaddress( struct sockaddr_in *addr); /* * The following is kludged-up support for simple rpc broadcasts. - * Someday a large, complicated system will replace these trivial + * Someday a large, complicated system will replace these trivial * routines which only support udp/ip . */ -static int getbroadcastnets(addrs, sock, buf) -struct in_addr *addrs; -int sock; /* any valid socket will do */ -char *buf; /* why allocxate more when we can use existing... */ +static int +internal_function +getbroadcastnets (struct in_addr *addrs, int sock, char *buf) + /* int sock: any valid socket will do */ + /* char *buf: why allocate more when we can use existing... */ { -#ifdef __linux__ - struct sockaddr_in addr; - - get_myaddress(&addr); -#if 1 - printf("%s(%d): no inet_makeaddr()\n", __FILE__, __LINE__); -#else - addrs[0] = inet_makeaddr(inet_netof(addr.sin_addr), INADDR_ANY); -#endif - return 1; -#else - struct ifconf ifc; - struct ifreq ifreq, *ifr; - struct sockaddr_in *sin; - int n, i; + struct ifconf ifc; + struct ifreq ifreq, *ifr; + struct sockaddr_in *sin; + int n, i; - ifc.ifc_len = UDPMSGSIZE; - ifc.ifc_buf = buf; - if (ioctl(sock, SIOCGIFCONF, (char *) &ifc) < 0) { - perror("broadcast: ioctl (get interface configuration)"); - return (0); + ifc.ifc_len = UDPMSGSIZE; + ifc.ifc_buf = buf; + if (ioctl (sock, SIOCGIFCONF, (char *) &ifc) < 0) + { + perror (_("broadcast: ioctl (get interface configuration)")); + return (0); + } + ifr = ifc.ifc_req; + for (i = 0, n = ifc.ifc_len / sizeof (struct ifreq); n > 0; n--, ifr++) + { + ifreq = *ifr; + if (ioctl (sock, SIOCGIFFLAGS, (char *) &ifreq) < 0) + { + perror (_("broadcast: ioctl (get interface flags)")); + continue; } - ifr = ifc.ifc_req; - for (i = 0, n = ifc.ifc_len / sizeof(struct ifreq); n > 0; n--, ifr++) { - ifreq = *ifr; - if (ioctl(sock, SIOCGIFFLAGS, (char *) &ifreq) < 0) { - perror("broadcast: ioctl (get interface flags)"); - continue; - } - if ((ifreq.ifr_flags & IFF_BROADCAST) && - (ifreq.ifr_flags & IFF_UP) && - ifr->ifr_addr.sa_family == AF_INET) { - sin = (struct sockaddr_in *) &ifr->ifr_addr; -#ifdef SIOCGIFBRDADDR /* 4.3BSD */ - if (ioctl(sock, SIOCGIFBRDADDR, (char *) &ifreq) < 0) { -#if 1 - printf("%s(%d): no inet_makeaddr()\n", __FILE__, __LINE__); -#else - addrs[i++] = inet_makeaddr(inet_netof - (sin->sin_addr.s_addr), - INADDR_ANY); -#endif - } else { - addrs[i++] = ((struct sockaddr_in *) - &ifreq.ifr_addr)->sin_addr; - } -#else /* 4.2 BSD */ -#if 1 - printf("%s(%d): no inet_makeaddr()\n", __FILE__, __LINE__); -#else - addrs[i++] = inet_makeaddr(inet_netof - (sin->sin_addr.s_addr), INADDR_ANY); -#endif + if ((ifreq.ifr_flags & IFF_BROADCAST) && + (ifreq.ifr_flags & IFF_UP) && + ifr->ifr_addr.sa_family == AF_INET) + { + sin = (struct sockaddr_in *) &ifr->ifr_addr; +#ifdef SIOCGIFBRDADDR /* 4.3BSD */ + if (ioctl (sock, SIOCGIFBRDADDR, (char *) &ifreq) < 0) + { + addrs[i++] = inet_makeaddr (inet_netof + /* Changed to pass struct instead of s_addr member + by roland@gnu. */ + (sin->sin_addr), INADDR_ANY); + } + else + { + addrs[i++] = ((struct sockaddr_in *) + &ifreq.ifr_addr)->sin_addr; + } +#else /* 4.2 BSD */ + addrs[i++] = inet_makeaddr (inet_netof + (sin->sin_addr.s_addr), INADDR_ANY); #endif - } } - return (i); -#endif + } + return i; } -//typedef bool_t(*resultproc_t) (); -//void _rpc_dtablesize(void ); - enum clnt_stat -clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, - eachresult) -u_long prog; /* program number */ -u_long vers; /* version number */ -u_long proc; /* procedure number */ -xdrproc_t xargs; /* xdr routine for args */ -caddr_t argsp; /* pointer to args */ -xdrproc_t xresults; /* xdr routine for results */ -caddr_t resultsp; /* pointer to results */ -resultproc_t eachresult; /* call with each result obtained */ +clnt_broadcast (prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult) + u_long prog; /* program number */ + u_long vers; /* version number */ + u_long proc; /* procedure number */ + xdrproc_t xargs; /* xdr routine for args */ + caddr_t argsp; /* pointer to args */ + xdrproc_t xresults; /* xdr routine for results */ + caddr_t resultsp; /* pointer to results */ + resultproc_t eachresult; /* call with each result obtained */ { - enum clnt_stat stat; - AUTH *unix_auth = authunix_create_default(); - XDR xdr_stream; - register XDR *xdrs = &xdr_stream; - int outlen, inlen, fromlen, nets; - register int sock; - int on = 1; - -#ifdef FD_SETSIZE - fd_set mask; - fd_set readfds; -#else - int readfds; - register int mask; -#endif /* def FD_SETSIZE */ - register int i; - bool_t done = FALSE; - register u_long xid; - u_long port; - struct in_addr addrs[20]; - struct sockaddr_in baddr, raddr; /* broadcast and response addresses */ - struct rmtcallargs a; - struct rmtcallres r; - struct rpc_msg msg; - struct timeval t; - char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE]; + enum clnt_stat stat = RPC_FAILED; + AUTH *unix_auth = authunix_create_default (); + XDR xdr_stream; + XDR *xdrs = &xdr_stream; + struct timeval t; + int outlen, inlen, nets; + socklen_t fromlen; + int sock; + int on = 1; + struct pollfd fd; + int milliseconds; + int i; + bool_t done = FALSE; + u_long xid; + u_long port; + struct in_addr addrs[20]; + struct sockaddr_in baddr, raddr; /* broadcast and response addresses */ + struct rmtcallargs a; + struct rmtcallres r; + struct rpc_msg msg; + char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE]; - /* - * initialization: create a socket, a broadcast address, and - * preserialize the arguments into a send buffer. - */ - if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { - perror("Cannot create socket for broadcast rpc"); - stat = RPC_CANTSEND; - goto done_broad; - } + /* + * initialization: create a socket, a broadcast address, and + * preserialize the arguments into a send buffer. + */ + if ((sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) + { + perror (_("Cannot create socket for broadcast rpc")); + stat = RPC_CANTSEND; + goto done_broad; + } #ifdef SO_BROADCAST - if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on)) < 0) { - perror("Cannot set socket option SO_BROADCAST"); - stat = RPC_CANTSEND; - goto done_broad; + if (setsockopt (sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) + { + perror (_("Cannot set socket option SO_BROADCAST")); + stat = RPC_CANTSEND; + goto done_broad; + } +#endif /* def SO_BROADCAST */ + fd.fd = sock; + fd.events = POLLIN; + nets = getbroadcastnets (addrs, sock, inbuf); + bzero ((char *) &baddr, sizeof (baddr)); + baddr.sin_family = AF_INET; + baddr.sin_port = htons (PMAPPORT); + baddr.sin_addr.s_addr = htonl (INADDR_ANY); +/* baddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); */ + msg.rm_xid = xid = _create_xid (); + t.tv_usec = 0; + msg.rm_direction = CALL; + msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; + msg.rm_call.cb_prog = PMAPPROG; + msg.rm_call.cb_vers = PMAPVERS; + msg.rm_call.cb_proc = PMAPPROC_CALLIT; + msg.rm_call.cb_cred = unix_auth->ah_cred; + msg.rm_call.cb_verf = unix_auth->ah_verf; + a.prog = prog; + a.vers = vers; + a.proc = proc; + a.xdr_args = xargs; + a.args_ptr = argsp; + r.port_ptr = &port; + r.xdr_results = xresults; + r.results_ptr = resultsp; + xdrmem_create (xdrs, outbuf, MAX_BROADCAST_SIZE, XDR_ENCODE); + if ((!xdr_callmsg (xdrs, &msg)) || (!xdr_rmtcall_args (xdrs, &a))) + { + stat = RPC_CANTENCODEARGS; + goto done_broad; + } + outlen = (int) xdr_getpos (xdrs); + xdr_destroy (xdrs); + /* + * Basic loop: broadcast a packet and wait a while for response(s). + * The response timeout grows larger per iteration. + */ + for (t.tv_sec = 4; t.tv_sec <= 14; t.tv_sec += 2) + { + for (i = 0; i < nets; i++) + { + baddr.sin_addr = addrs[i]; + if (sendto (sock, outbuf, outlen, 0, + (struct sockaddr *) &baddr, + sizeof (struct sockaddr)) != outlen) + { + perror (_("Cannot send broadcast packet")); + stat = RPC_CANTSEND; + goto done_broad; + } } -#endif /* def SO_BROADCAST */ -#ifdef FD_SETSIZE - FD_ZERO(&mask); - FD_SET(sock, &mask); -#else - mask = (1 << sock); -#endif /* def FD_SETSIZE */ - nets = getbroadcastnets(addrs, sock, inbuf); - bzero((char *) &baddr, sizeof(baddr)); - baddr.sin_family = AF_INET; - baddr.sin_port = htons(PMAPPORT); - baddr.sin_addr.s_addr = htonl(INADDR_ANY); -/* baddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); */ - (void) gettimeofday(&t, (struct timezone *) 0); - msg.rm_xid = xid = getpid() ^ t.tv_sec ^ t.tv_usec; - t.tv_usec = 0; - msg.rm_direction = CALL; - msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; - msg.rm_call.cb_prog = PMAPPROG; - msg.rm_call.cb_vers = PMAPVERS; - msg.rm_call.cb_proc = PMAPPROC_CALLIT; - msg.rm_call.cb_cred = unix_auth->ah_cred; - msg.rm_call.cb_verf = unix_auth->ah_verf; - a.prog = prog; - a.vers = vers; - a.proc = proc; - a.xdr_args = xargs; - a.args_ptr = argsp; - r.port_ptr = &port; - r.xdr_results = xresults; - r.results_ptr = resultsp; - xdrmem_create(xdrs, outbuf, MAX_BROADCAST_SIZE, XDR_ENCODE); - if ((!xdr_callmsg(xdrs, &msg)) || (!xdr_rmtcall_args(xdrs, &a))) { - stat = RPC_CANTENCODEARGS; - goto done_broad; + if (eachresult == NULL) + { + stat = RPC_SUCCESS; + goto done_broad; } - outlen = (int) xdr_getpos(xdrs); - xdr_destroy(xdrs); - /* - * Basic loop: broadcast a packet and wait a while for response(s). - * The response timeout grows larger per iteration. - */ - for (t.tv_sec = 4; t.tv_sec <= 14; t.tv_sec += 2) { - for (i = 0; i < nets; i++) { - baddr.sin_addr = addrs[i]; - if (sendto(sock, outbuf, outlen, 0, - (struct sockaddr *) &baddr, - sizeof(struct sockaddr)) != outlen) { - perror("Cannot send broadcast packet"); - stat = RPC_CANTSEND; - goto done_broad; - } - } - if (eachresult == NULL) { - stat = RPC_SUCCESS; - goto done_broad; - } - recv_again: - msg.acpted_rply.ar_verf = _null_auth; - msg.acpted_rply.ar_results.where = (caddr_t) & r; - msg.acpted_rply.ar_results.proc = (xdrproc_t) xdr_rmtcallres; - readfds = mask; - switch (select(_rpc_dtablesize(), &readfds, NULL, NULL, &t)) { - - case 0: /* timed out */ - stat = RPC_TIMEDOUT; - continue; + recv_again: + msg.acpted_rply.ar_verf = _null_auth; + msg.acpted_rply.ar_results.where = (caddr_t) & r; + msg.acpted_rply.ar_results.proc = (xdrproc_t) xdr_rmtcallres; + milliseconds = t.tv_sec * 1000 + t.tv_usec / 1000; + switch (poll(&fd, 1, milliseconds)) + { - case -1: /* some kind of error */ - if (errno == EINTR) - goto recv_again; - perror("Broadcast select problem"); - stat = RPC_CANTRECV; - goto done_broad; + case 0: /* timed out */ + stat = RPC_TIMEDOUT; + continue; - } /* end of select results switch */ - try_again: - fromlen = sizeof(struct sockaddr); + case -1: /* some kind of error */ + if (errno == EINTR) + goto recv_again; + perror (_("Broadcast poll problem")); + stat = RPC_CANTRECV; + goto done_broad; - inlen = recvfrom(sock, inbuf, UDPMSGSIZE, 0, - (struct sockaddr *) &raddr, &fromlen); - if (inlen < 0) { - if (errno == EINTR) - goto try_again; - perror("Cannot receive reply to broadcast"); - stat = RPC_CANTRECV; - goto done_broad; - } - if (inlen < sizeof(u_long)) - goto recv_again; - /* - * see if reply transaction id matches sent id. - * If so, decode the results. - */ - xdrmem_create(xdrs, inbuf, (u_int) inlen, XDR_DECODE); - if (xdr_replymsg(xdrs, &msg)) { - if ((msg.rm_xid == xid) && - (msg.rm_reply.rp_stat == MSG_ACCEPTED) && - (msg.acpted_rply.ar_stat == SUCCESS)) { - raddr.sin_port = htons((u_short) port); - done = (*eachresult) (resultsp, &raddr); - } - /* otherwise, we just ignore the errors ... */ - } else { + } /* end of poll results switch */ + try_again: + fromlen = sizeof (struct sockaddr); + inlen = recvfrom (sock, inbuf, UDPMSGSIZE, 0, + (struct sockaddr *) &raddr, &fromlen); + if (inlen < 0) + { + if (errno == EINTR) + goto try_again; + perror (_("Cannot receive reply to broadcast")); + stat = RPC_CANTRECV; + goto done_broad; + } + if ((size_t) inlen < sizeof (u_long)) + goto recv_again; + /* + * see if reply transaction id matches sent id. + * If so, decode the results. + */ + xdrmem_create (xdrs, inbuf, (u_int) inlen, XDR_DECODE); + if (xdr_replymsg (xdrs, &msg)) + { + if (((u_int32_t) msg.rm_xid == (u_int32_t) xid) && + (msg.rm_reply.rp_stat == MSG_ACCEPTED) && + (msg.acpted_rply.ar_stat == SUCCESS)) + { + raddr.sin_port = htons ((u_short) port); + done = (*eachresult) (resultsp, &raddr); + } + /* otherwise, we just ignore the errors ... */ + } + else + { #ifdef notdef - /* some kind of deserialization problem ... */ - if (msg.rm_xid == xid) - fprintf(stderr, "Broadcast deserialization problem"); - /* otherwise, just random garbage */ + /* some kind of deserialization problem ... */ + if ((u_int32_t) msg.rm_xid == (u_int32_t) xid) + fprintf (stderr, "Broadcast deserialization problem"); + /* otherwise, just random garbage */ #endif - } - xdrs->x_op = XDR_FREE; - msg.acpted_rply.ar_results.proc = (xdrproc_t) xdr_void; - (void) xdr_replymsg(xdrs, &msg); - (void) (*xresults) (xdrs, resultsp); - xdr_destroy(xdrs); - if (done) { - stat = RPC_SUCCESS; - goto done_broad; - } else { - goto recv_again; - } } - done_broad: - (void) close(sock); - AUTH_DESTROY(unix_auth); - return (stat); + xdrs->x_op = XDR_FREE; + msg.acpted_rply.ar_results.proc = (xdrproc_t)xdr_void; + (void) xdr_replymsg (xdrs, &msg); + (void) (*xresults) (xdrs, resultsp); + xdr_destroy (xdrs); + if (done) + { + stat = RPC_SUCCESS; + goto done_broad; + } + else + { + goto recv_again; + } + } +done_broad: + (void) close (sock); + AUTH_DESTROY (unix_auth); + return stat; } |