Implement _autofssys, _cladm, _lgrpsys, and _lgrp_home_fast
[kopensolaris-gnu/glibc.git] / sunrpc / pmap_clnt.c
index f93efaa..3e42960 100644 (file)
@@ -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
  * 2550 Garcia Avenue
  * Mountain View, California  94043
  */
-#if !defined(lint) && defined(SCCSIDS)
-static char sccsid[] = "@(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro";
-#endif
-
+/*
+ * Copyright (C) 1984, Sun Microsystems, Inc.
+ */
 /*
  * pmap_clnt.c
  * Client interface to pmap rpc service.
- *
- * Copyright (C) 1984, Sun Microsystems, Inc.
  */
 
+#include <stdio.h>
+#include <unistd.h>
+#include <libintl.h>
+#include <net/if.h>
+#include <ifaddrs.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>
 
-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)
+{
+  struct ifaddrs *ifa;
+
+  if (getifaddrs (&ifa) != 0)
+    {
+      perror ("get_myaddress: getifaddrs");
+      exit (1);
+    }
+
+  int loopback = 1;
+  struct ifaddrs *run;
 
-void clnt_perror();
+ again:
+  run = ifa;
+  while (run != NULL)
+    {
+      if ((run->ifa_flags & IFF_UP)
+         && run->ifa_addr != NULL
+         && run->ifa_addr->sa_family == AF_INET
+         && ((run->ifa_flags & IFF_LOOPBACK) || loopback == 0))
+       {
+         *addr = *((struct sockaddr_in *) run->ifa_addr);
+         addr->sin_port = htons (PMAPPORT);
+         goto out;
+       }
 
+      run = run->ifa_next;
+    }
+
+  if (loopback == 1)
+    {
+      loopback = 0;
+      goto again;
+    }
+ out:
+  freeifaddrs (ifa);
+
+  return run == NULL ? FALSE : TRUE;
+}
+
+
+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;
+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, xdr_pmap, &parms, xdr_bool, &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 = INTUSE(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)INTUSE(xdr_pmap),
+                (caddr_t)&parms, (xdrproc_t)INTUSE(xdr_bool), (caddr_t)&rslt,
+                tottimeout) != RPC_SUCCESS)
+    {
+      clnt_perror (client, _("Cannot register service"));
+      rslt = FALSE;
+    }
+  CLNT_DESTROY (client);
+  /* (void)close(socket); CLNT_DESTROY closes it */
+  return rslt;
 }
+libc_hidden_def (pmap_set)
 
 /*
  * 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;
+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, xdr_pmap, &parms, xdr_bool, &rslt,
-           tottimeout);
-       CLNT_DESTROY(client);
-       (void)close(socket);
-       return (rslt);
+  if (!__get_myaddress (&myaddress))
+    return FALSE;
+  client = INTUSE(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)INTUSE(xdr_pmap),
+            (caddr_t)&parms, (xdrproc_t)INTUSE(xdr_bool), (caddr_t)&rslt,
+            tottimeout);
+  CLNT_DESTROY (client);
+  /* (void)close(socket); CLNT_DESTROY already closed it */
+  return rslt;
 }
+libc_hidden_def (pmap_unset)