Implement _autofssys, _cladm, _lgrpsys, and _lgrp_home_fast
[kopensolaris-gnu/glibc.git] / sunrpc / pmap_clnt.c
index 68bdfab..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>
 
+/*
+ * 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;
+
+ 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};
 
@@ -58,26 +111,29 @@ pmap_set (u_long program, u_long version, int protocol, u_short port)
   struct pmap parms;
   bool_t rslt;
 
-  get_myaddress (&myaddress);
-  client = clntudp_bufcreate (&myaddress, PMAPPROG, PMAPVERS,
-                       timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+  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)xdr_pmap, (caddr_t)&parms,
-                (xdrproc_t)xdr_bool, (caddr_t)&rslt,
+  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"));
-      return FALSE;
+      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.
@@ -92,17 +148,21 @@ pmap_unset (u_long program, u_long version)
   struct pmap parms;
   bool_t rslt;
 
-  get_myaddress (&myaddress);
-  client = clntudp_bufcreate (&myaddress, PMAPPROG, PMAPVERS,
-                       timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
+  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)xdr_pmap, (caddr_t)&parms,
-            (xdrproc_t)xdr_bool, (caddr_t)&rslt, tottimeout);
+  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)