summaryrefslogtreecommitdiff
path: root/libc/inet/rpc/pmap_clnt.c
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2002-06-17 21:12:16 +0000
committerEric Andersen <andersen@codepoet.org>2002-06-17 21:12:16 +0000
commitcdb3c81f36283df4b53f24a374d78c695e9d8b06 (patch)
tree9494bff7c98929e44c41dcdde32dc3fc6faf4330 /libc/inet/rpc/pmap_clnt.c
parent6ba832b158c91c6b35e1832220b3fc5ebf76333f (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_clnt.c')
-rw-r--r--libc/inet/rpc/pmap_clnt.c189
1 files changed, 123 insertions, 66 deletions
diff --git a/libc/inet/rpc/pmap_clnt.c b/libc/inet/rpc/pmap_clnt.c
index ccd912363..2382c153b 100644
--- a/libc/inet/rpc/pmap_clnt.c
+++ b/libc/inet/rpc/pmap_clnt.c
@@ -1,4 +1,3 @@
-/* @(#)pmap_clnt.c 2.2 88/08/01 4.0 RPCSRC */
/*
* Sun RPC is a product of Sun Microsystems, Inc. and is provided for
* unrestricted use provided that this legend is included on all tape
@@ -6,111 +5,169 @@
* 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
*/
-#define __FORCE_GLIBC
-#include <features.h>
-
+/*
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
/*
* pmap_clnt.c
* Client interface to pmap rpc service.
- *
- * Copyright (C) 1984, Sun Microsystems, Inc.
*/
+#define __FORCE_GLIBC
+#include <features.h>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
#include <rpc/rpc.h>
#include <rpc/pmap_prot.h>
#include <rpc/pmap_clnt.h>
-#include <unistd.h>
-static struct timeval timeout = { 5, 0 };
-static struct timeval tottimeout = { 60, 0 };
+/*
+ * Same as get_myaddress, but we try to use the loopback
+ * interface. portmap caches interfaces, and on DHCP clients,
+ * it could be that only loopback is started at this time.
+ */
+static bool_t
+__get_myaddress (struct sockaddr_in *addr)
+{
+ int s;
+ char buf[BUFSIZ];
+ struct ifconf ifc;
+ struct ifreq ifreq, *ifr;
+ int len, loopback = 1;
+
+ if ((s = socket (AF_INET, SOCK_DGRAM, 0)) < 0)
+ {
+ perror ("__get_myaddress: socket");
+ exit (1);
+ }
+ ifc.ifc_len = sizeof (buf);
+ ifc.ifc_buf = buf;
+ if (ioctl (s, SIOCGIFCONF, (char *) &ifc) < 0)
+ {
+ perror (_("__get_myaddress: ioctl (get interface configuration)"));
+ exit (1);
+ }
+
+ again:
+ ifr = ifc.ifc_req;
+ for (len = ifc.ifc_len; len; len -= sizeof ifreq)
+ {
+ ifreq = *ifr;
+ if (ioctl (s, SIOCGIFFLAGS, (char *) &ifreq) < 0)
+ {
+ perror ("__get_myaddress: ioctl");
+ exit (1);
+ }
+ if ((ifreq.ifr_flags & IFF_UP) && (ifr->ifr_addr.sa_family == AF_INET)
+ && ((ifreq.ifr_flags & IFF_LOOPBACK) || (loopback == 0)))
+ {
+ *addr = *((struct sockaddr_in *) &ifr->ifr_addr);
+ addr->sin_port = htons (PMAPPORT);
+ close (s);
+ return TRUE;
+ }
+ ifr++;
+ }
+ if (loopback == 1)
+ {
+ loopback = 0;
+ goto again;
+ }
+ close (s);
+ return FALSE;
+}
-void clnt_perror();
+static const struct timeval timeout = {5, 0};
+static const struct timeval tottimeout = {60, 0};
/*
* Set a mapping between program,version and port.
* Calls the pmap service remotely to do the mapping.
*/
-bool_t pmap_set(program, version, protocol, port)
-u_long program;
-u_long version;
-int protocol;
-u_short port;
+bool_t
+pmap_set (u_long program, u_long version, int protocol, u_short port)
{
- struct sockaddr_in myaddress;
- int socket = -1;
- register CLIENT *client;
- struct pmap parms;
- bool_t rslt;
+ struct sockaddr_in myaddress;
+ int socket = -1;
+ CLIENT *client;
+ struct pmap parms;
+ bool_t rslt;
- get_myaddress(&myaddress);
- client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
- timeout, &socket, RPCSMALLMSGSIZE,
- RPCSMALLMSGSIZE);
- if (client == (CLIENT *) NULL)
- return (FALSE);
- parms.pm_prog = program;
- parms.pm_vers = version;
- parms.pm_prot = protocol;
- parms.pm_port = port;
- if (CLNT_CALL(client, PMAPPROC_SET, (xdrproc_t) xdr_pmap, (caddr_t) &parms,
- (xdrproc_t) xdr_bool, (caddr_t) &rslt,
- tottimeout) != RPC_SUCCESS) {
- clnt_perror(client, "Cannot register service");
- return (FALSE);
- }
- CLNT_DESTROY(client);
- (void) close(socket);
- return (rslt);
+ if (!__get_myaddress (&myaddress))
+ return FALSE;
+ client = clntudp_bufcreate (&myaddress, PMAPPROG, PMAPVERS,
+ timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+ if (client == (CLIENT *) NULL)
+ return (FALSE);
+ parms.pm_prog = program;
+ parms.pm_vers = version;
+ parms.pm_prot = protocol;
+ parms.pm_port = port;
+ if (CLNT_CALL (client, PMAPPROC_SET, (xdrproc_t)xdr_pmap, (caddr_t)&parms,
+ (xdrproc_t)xdr_bool, (caddr_t)&rslt,
+ tottimeout) != RPC_SUCCESS)
+ {
+ clnt_perror (client, _("Cannot register service"));
+ return FALSE;
+ }
+ CLNT_DESTROY (client);
+ /* (void)close(socket); CLNT_DESTROY closes it */
+ return rslt;
}
/*
* Remove the mapping between program,version and port.
* Calls the pmap service remotely to do the un-mapping.
*/
-bool_t pmap_unset(program, version)
-u_long program;
-u_long version;
+bool_t
+pmap_unset (u_long program, u_long version)
{
- struct sockaddr_in myaddress;
- int socket = -1;
- register CLIENT *client;
- struct pmap parms;
- bool_t rslt;
+ struct sockaddr_in myaddress;
+ int socket = -1;
+ CLIENT *client;
+ struct pmap parms;
+ bool_t rslt;
- get_myaddress(&myaddress);
- client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS,
- timeout, &socket, RPCSMALLMSGSIZE,
- RPCSMALLMSGSIZE);
- if (client == (CLIENT *) NULL)
- return (FALSE);
- parms.pm_prog = program;
- parms.pm_vers = version;
- parms.pm_port = parms.pm_prot = 0;
- CLNT_CALL(client, PMAPPROC_UNSET, (xdrproc_t) xdr_pmap, (caddr_t) &parms,
- (xdrproc_t) xdr_bool, (caddr_t) &rslt, tottimeout);
- CLNT_DESTROY(client);
- (void) close(socket);
- return (rslt);
+ if (!__get_myaddress (&myaddress))
+ return FALSE;
+ client = clntudp_bufcreate (&myaddress, PMAPPROG, PMAPVERS,
+ timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+ if (client == (CLIENT *) NULL)
+ return FALSE;
+ parms.pm_prog = program;
+ parms.pm_vers = version;
+ parms.pm_port = parms.pm_prot = 0;
+ CLNT_CALL (client, PMAPPROC_UNSET, (xdrproc_t)xdr_pmap, (caddr_t)&parms,
+ (xdrproc_t)xdr_bool, (caddr_t)&rslt, tottimeout);
+ CLNT_DESTROY (client);
+ /* (void)close(socket); CLNT_DESTROY already closed it */
+ return rslt;
}