]> sourceware.org Git - glibc.git/blobdiff - nis/ypclnt.c
Update.
[glibc.git] / nis / ypclnt.c
index 9b936457a548dea779c3025ea3eff694c6e8603d..67ac42597b33fbbbd99a110781aa7737258e2bf2 100644 (file)
@@ -1,6 +1,6 @@
-/* Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
+/* Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
-   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996.
+   Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public License as
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
+#include <errno.h>
 #include <fcntl.h>
 #include <string.h>
 #include <unistd.h>
+#include <libintl.h>
 #include <rpc/rpc.h>
 #include <rpcsvc/nis.h>
 #include <rpcsvc/yp.h>
@@ -40,13 +42,12 @@ struct dom_binding
     struct sockaddr_in dom_server_addr;
     int dom_socket;
     CLIENT *dom_client;
-    long int dom_vers;
   };
 typedef struct dom_binding dom_binding;
 
 static struct timeval RPCTIMEOUT = {25, 0};
 static struct timeval UDPTIMEOUT = {5, 0};
-static int const MAXTRIES = 5;
+static int const MAXTRIES = 2;
 static char __ypdomainname[NIS_MAXNAMELEN + 1] = "\0";
 __libc_lock_define_initialized (static, ypbindlist_lock)
 static dom_binding *__ypbindlist = NULL;
@@ -61,9 +62,8 @@ __yp_bind (const char *domain, dom_binding **ypdb)
   int clnt_sock;
   CLIENT *client;
   int is_new = 0;
-  int try;
 
-  if ((domain == NULL) || (strlen (domain) == 0))
+  if (domain == NULL || domain[0] == '\0')
     return YPERR_BADARGS;
 
   if (ypdb != NULL)
@@ -81,146 +81,129 @@ __yp_bind (const char *domain, dom_binding **ypdb)
     {
       is_new = 1;
       ysd = (dom_binding *) calloc (1, sizeof *ysd);
-      ysd->dom_socket = -1;
-      ysd->dom_vers = -1;
+      if (__builtin_expect (ysd == NULL, 0))
+       return YPERR_RESRC;
     }
 
-  try = 0;
-
-  do
-    {
-      try++;
-      if (try > MAXTRIES)
-        {
-          if (is_new)
-            free (ysd);
-          return YPERR_YPBIND;
-        }
-
 #if USE_BINDINGDIR
-      if (ysd->dom_vers < 1 && try < 3)
+  if (ysd->dom_client == NULL)
+    {
+      /* Try binding dir at first if we have no binding */
+      char path[sizeof (BINDINGDIR) + strlen (domain) + 10];
+      struct iovec vec[2];
+      unsigned short port;
+      int fd;
+
+      sprintf (path, "%s/%s.%d", BINDINGDIR, domain, YPBINDVERS);
+      fd = open (path, O_RDONLY);
+      if (fd >= 0)
        {
-         char path[sizeof (BINDINGDIR) - 1 + strlen (domain) + 10];
-         struct iovec vec[2];
-         u_short port;
-         int fd;
-
-         sprintf (path, "%s/%s.%ld", BINDINGDIR, domain, YPBINDVERS);
-         fd = open (path, O_RDONLY);
-         if (fd >= 0)
+         /* We have a binding file and could save a RPC call */
+         vec[0].iov_base = &port;
+         vec[0].iov_len = sizeof (port);
+         vec[1].iov_base = &ypbr;
+         vec[1].iov_len = sizeof (ypbr);
+
+         if (readv (fd, vec, 2) == sizeof (port) + sizeof (ypbr))
            {
-             /* We have a binding file and could save a RPC call */
-             vec[0].iov_base = &port;
-             vec[0].iov_len = sizeof (port);
-             vec[1].iov_base = &ypbr;
-             vec[1].iov_len = sizeof (ypbr);
-
-             if (readv (fd, vec, 2) == vec[0].iov_len + vec[1].iov_len)
-               {
-                 memset (&ysd->dom_server_addr, '\0',
-                         sizeof ysd->dom_server_addr);
-                 ysd->dom_server_addr.sin_family = AF_INET;
-                 memcpy (&ysd->dom_server_addr.sin_port,
-                         ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port,
-                         sizeof (ysd->dom_server_addr.sin_port));
-                 memcpy (&ysd->dom_server_addr.sin_addr.s_addr,
-                         ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
-                         sizeof (ysd->dom_server_addr.sin_addr.s_addr));
-                 ysd->dom_vers = YPVERS;
-                 strncpy (ysd->dom_domain, domain, YPMAXDOMAIN);
-                 ysd->dom_domain[YPMAXDOMAIN] = '\0';
-               }
-             close (fd);
+             ysd->dom_server_addr.sin_family = AF_INET;
+             memcpy (&ysd->dom_server_addr.sin_port,
+                     ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port,
+                     sizeof (ysd->dom_server_addr.sin_port));
+             memcpy (&ysd->dom_server_addr.sin_addr.s_addr,
+                     ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
+                     sizeof (ysd->dom_server_addr.sin_addr.s_addr));
+             strncpy (ysd->dom_domain, domain, YPMAXDOMAIN);
+             ysd->dom_domain[YPMAXDOMAIN] = '\0';
+
+             ysd->dom_socket = RPC_ANYSOCK;
+             ysd->dom_client = clntudp_create (&ysd->dom_server_addr, YPPROG,
+                                               YPVERS, UDPTIMEOUT,
+                                               &ysd->dom_socket);
+
+             if (ysd->dom_client != NULL)
+               /* If the program exits, close the socket */
+               if (fcntl (ysd->dom_socket, F_SETFD, 1) == -1)
+                 perror ("fcntl: F_SETFD");
            }
+         close (fd);
        }
+    }
 #endif /* USE_BINDINGDIR */
 
-      if (ysd->dom_vers == -1)
-        {
-          if(ysd->dom_client)
-            {
-              clnt_destroy(ysd->dom_client);
-              ysd->dom_client = NULL;
-              ysd->dom_socket = -1;
-            }
-          memset (&clnt_saddr, '\0', sizeof clnt_saddr);
-          clnt_saddr.sin_family = AF_INET;
-          clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
-          clnt_sock = RPC_ANYSOCK;
-          client = clnttcp_create (&clnt_saddr, YPBINDPROG, YPBINDVERS,
-                                   &clnt_sock, 0, 0);
-          if (client == NULL)
-            {
-              if (is_new)
-                free (ysd);
-              return YPERR_YPBIND;
-            }
-          /*
-          ** Check the port number -- should be < IPPORT_RESERVED.
-          ** If not, it's possible someone has registered a bogus
-          ** ypbind with the portmapper and is trying to trick us.
-          */
-          if (ntohs (clnt_saddr.sin_port) >= IPPORT_RESERVED)
-            {
-              clnt_destroy (client);
-              if (is_new)
-                free (ysd);
-              return YPERR_YPBIND;
-            }
-
-          if (clnt_call (client, YPBINDPROC_DOMAIN,
-                         (xdrproc_t) xdr_domainname, (caddr_t) &domain,
-                         (xdrproc_t) xdr_ypbind_resp,
-                         (caddr_t) &ypbr, RPCTIMEOUT) != RPC_SUCCESS)
-            {
-              clnt_destroy (client);
-             close (clnt_sock);
-              if (is_new)
-                free (ysd);
-              return YPERR_YPBIND;
-            }
-
-          clnt_destroy (client);
-         close (clnt_sock);
-
-          if (ypbr.ypbind_status != YPBIND_SUCC_VAL)
-            {
-             fprintf (stderr, _("YPBINDPROC_DOMAIN: %s\n"),
-                      ypbinderr_string (ypbr.ypbind_resp_u.ypbind_error));
-             if (is_new)
-               free (ysd);
-             return YPERR_DOMAIN;
-           }
-          memset (&ysd->dom_server_addr, '\0', sizeof ysd->dom_server_addr);
-          ysd->dom_server_addr.sin_family = AF_INET;
-          memcpy (&ysd->dom_server_addr.sin_port,
-                  ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port,
-                  sizeof (ysd->dom_server_addr.sin_port));
-          memcpy (&ysd->dom_server_addr.sin_addr.s_addr,
-                  ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
-                  sizeof (ysd->dom_server_addr.sin_addr.s_addr));
-          ysd->dom_vers = YPVERS;
-          strncpy (ysd->dom_domain, domain, YPMAXDOMAIN);
-         ysd->dom_domain[YPMAXDOMAIN] = '\0';
-        }
+  if (ysd->dom_client == NULL)
+    {
+      memset (&clnt_saddr, '\0', sizeof clnt_saddr);
+      clnt_saddr.sin_family = AF_INET;
+      clnt_saddr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
+      clnt_sock = RPC_ANYSOCK;
+      client = clnttcp_create (&clnt_saddr, YPBINDPROG, YPBINDVERS,
+                              &clnt_sock, 0, 0);
+      if (client == NULL)
+       {
+         if (is_new)
+           free (ysd);
+         return YPERR_YPBIND;
+       }
+      /* Check the port number -- should be < IPPORT_RESERVED.
+        If not, it's possible someone has registered a bogus
+        ypbind with the portmapper and is trying to trick us. */
+      if (ntohs (clnt_saddr.sin_port) >= IPPORT_RESERVED)
+       {
+         clnt_destroy (client);
+         if (is_new)
+           free (ysd);
+         return YPERR_YPBIND;
+       }
 
-      if (ysd->dom_client)
+      if (clnt_call (client, YPBINDPROC_DOMAIN,
+                    (xdrproc_t) xdr_domainname, (caddr_t) &domain,
+                    (xdrproc_t) xdr_ypbind_resp,
+                    (caddr_t) &ypbr, RPCTIMEOUT) != RPC_SUCCESS)
        {
-         clnt_destroy (ysd->dom_client);
-         close (ysd->dom_socket);
+         clnt_destroy (client);
+         if (is_new)
+           free (ysd);
+         return YPERR_YPBIND;
        }
+
+      clnt_destroy (client);
+
+      if (ypbr.ypbind_status != YPBIND_SUCC_VAL)
+       {
+         fprintf (stderr, _("YPBINDPROC_DOMAIN: %s\n"),
+                  ypbinderr_string (ypbr.ypbind_resp_u.ypbind_error));
+         if (is_new)
+           free (ysd);
+         return YPERR_DOMAIN;
+       }
+      memset (&ysd->dom_server_addr, '\0', sizeof ysd->dom_server_addr);
+      ysd->dom_server_addr.sin_family = AF_INET;
+      memcpy (&ysd->dom_server_addr.sin_port,
+             ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_port,
+             sizeof (ysd->dom_server_addr.sin_port));
+      memcpy (&ysd->dom_server_addr.sin_addr.s_addr,
+             ypbr.ypbind_resp_u.ypbind_bindinfo.ypbind_binding_addr,
+             sizeof (ysd->dom_server_addr.sin_addr.s_addr));
+      strncpy (ysd->dom_domain, domain, YPMAXDOMAIN);
+      ysd->dom_domain[YPMAXDOMAIN] = '\0';
+
       ysd->dom_socket = RPC_ANYSOCK;
       ysd->dom_client = clntudp_create (&ysd->dom_server_addr, YPPROG, YPVERS,
                                         UDPTIMEOUT, &ysd->dom_socket);
-      if (ysd->dom_client == NULL)
-        ysd->dom_vers = -1;
 
+      if (ysd->dom_client != NULL)
+       /* If the program exits, close the socket */
+       if (fcntl (ysd->dom_socket, F_SETFD, 1) == -1)
+         perror ("fcntl: F_SETFD");
     }
-  while (ysd->dom_client == NULL);
 
-  /* If the program exists, close the socket */
-  if (fcntl (ysd->dom_socket, F_SETFD, 1) == -1)
-    perror ("fcntl: F_SETFD");
+  if (ysd->dom_client == NULL)
+    {
+      if (is_new)
+       free (ysd);
+      return YPERR_YPSERV;
+    }
 
   if (is_new && ypdb != NULL)
     {
@@ -236,7 +219,60 @@ __yp_unbind (dom_binding *ydb)
 {
   clnt_destroy (ydb->dom_client);
   ydb->dom_client = NULL;
-  ydb->dom_socket = -1;
+}
+
+int
+yp_bind (const char *indomain)
+{
+  int status;
+
+  __libc_lock_lock (ypbindlist_lock);
+
+  status = __yp_bind (indomain, &__ypbindlist);
+
+  __libc_lock_unlock (ypbindlist_lock);
+
+  return status;
+}
+
+static void
+yp_unbind_locked (const char *indomain)
+{
+  dom_binding *ydbptr, *ydbptr2;
+
+  ydbptr2 = NULL;
+  ydbptr = __ypbindlist;
+
+  while (ydbptr != NULL)
+    {
+      if (strcmp (ydbptr->dom_domain, indomain) == 0)
+       {
+         dom_binding *work;
+
+         work = ydbptr;
+         if (ydbptr2 == NULL)
+           __ypbindlist = __ypbindlist->dom_pnext;
+         else
+           ydbptr2 = ydbptr->dom_pnext;
+         __yp_unbind (work);
+         free (work);
+         break;
+       }
+      ydbptr2 = ydbptr;
+      ydbptr = ydbptr->dom_pnext;
+    }
+}
+
+void
+yp_unbind (const char *indomain)
+{
+  __libc_lock_lock (ypbindlist_lock);
+
+  yp_unbind_locked (indomain);
+
+  __libc_lock_unlock (ypbindlist_lock);
+
+  return;
 }
 
 static int
@@ -247,6 +283,7 @@ do_ypcall (const char *domain, u_long prog, xdrproc_t xargs,
   bool_t use_ypbindlist = FALSE;
   int try, status;
   enum clnt_stat result;
+  int saved_errno = errno;
 
   try = 0;
   status = YPERR_YPERR;
@@ -275,6 +312,7 @@ do_ypcall (const char *domain, u_long prog, xdrproc_t xargs,
        {
          if (use_ypbindlist)
            __libc_lock_unlock (ypbindlist_lock);
+         __set_errno (saved_errno);
          return YPERR_DOMAIN;
        }
 
@@ -283,15 +321,27 @@ do_ypcall (const char *domain, u_long prog, xdrproc_t xargs,
 
       if (result != RPC_SUCCESS)
        {
-         clnt_perror (ydb->dom_client, "do_ypcall: clnt_call");
-         ydb->dom_vers = -1;
-         if (!use_ypbindlist)
+         /* Don't print the error message on the first try. It
+            could be that we use cached data which is now invalid. */
+         if (try != 0)
+           clnt_perror (ydb->dom_client, "do_ypcall: clnt_call");
+
+         if (use_ypbindlist)
+           {
+             /* We use ypbindlist, and the old cached data is
+                invalid. unbind now and create a new binding */
+             yp_unbind_locked (domain);
+             __libc_lock_unlock (ypbindlist_lock);
+             use_ypbindlist = FALSE;
+           }
+         else
            {
              __yp_unbind (ydb);
              free (ydb);
-             ydb = NULL;
            }
-         status = YPERR_RPC;;
+
+         ydb = NULL;
+         status = YPERR_RPC;
        }
       else
        status = YPERR_SUCCESS;
@@ -311,55 +361,11 @@ do_ypcall (const char *domain, u_long prog, xdrproc_t xargs,
        ydb = NULL;
       }
 
-  return status;
-}
-
-int
-yp_bind (const char *indomain)
-{
-  int status;
-
-  __libc_lock_lock (ypbindlist_lock);
-
-  status = __yp_bind (indomain, &__ypbindlist);
-
-  __libc_lock_unlock (ypbindlist_lock);
+  __set_errno (saved_errno);
 
   return status;
 }
 
-void
-yp_unbind (const char *indomain)
-{
-  dom_binding *ydbptr, *ydbptr2;
-
-  __libc_lock_lock (ypbindlist_lock);
-
-  ydbptr2 = NULL;
-  ydbptr = __ypbindlist;
-  while (ydbptr != NULL)
-    {
-      if (strcmp (ydbptr->dom_domain, indomain) == 0)
-       {
-         dom_binding *work;
-
-         work = ydbptr;
-         if (ydbptr2 == NULL)
-           __ypbindlist = __ypbindlist->dom_pnext;
-         else
-           ydbptr2 = ydbptr->dom_pnext;
-         __yp_unbind (work);
-         free (work);
-         break;
-       }
-      ydbptr2 = ydbptr;
-      ydbptr = ydbptr->dom_pnext;
-    }
-
-  __libc_lock_unlock (ypbindlist_lock);
-
-  return;
-}
 
 __libc_lock_define_initialized (static, domainname_lock)
 
@@ -375,6 +381,12 @@ yp_get_default_domain (char **outdomain)
     {
       if (getdomainname (__ypdomainname, NIS_MAXNAMELEN))
        result = YPERR_NODOM;
+      else if (strcmp (__ypdomainname, "(none)") == 0)
+       {
+         /* If domainname is not set, some systems will return "(none)" */
+         __ypdomainname[0] = '\0';
+         result = YPERR_NODOM;
+       }
       else
        *outdomain = __ypdomainname;
     }
@@ -394,8 +406,6 @@ __yp_check (char **domain)
   if (__ypdomainname[0] == '\0')
     if (yp_get_default_domain (&unused))
       return 0;
-    else if (strcmp (__ypdomainname, "(none)") == 0)
-      return 0;
 
   if (domain)
     *domain = __ypdomainname;
@@ -431,13 +441,15 @@ yp_match (const char *indomain, const char *inmap, const char *inkey,
                      (caddr_t) & req, (xdrproc_t) xdr_ypresp_val,
                      (caddr_t) & resp);
 
-  if (result != RPC_SUCCESS)
-    return YPERR_RPC;
+  if (result != YPERR_SUCCESS)
+    return result;
   if (resp.stat != YP_TRUE)
     return ypprot_err (resp.stat);
 
   *outvallen = resp.val.valdat_len;
   *outval = malloc (*outvallen + 1);
+  if (__builtin_expect (*outval == NULL, 0))
+    return YPERR_RESRC;
   memcpy (*outval, resp.val.valdat_val, *outvallen);
   (*outval)[*outvallen] = '\0';
 
@@ -476,10 +488,14 @@ yp_first (const char *indomain, const char *inmap, char **outkey,
 
   *outkeylen = resp.key.keydat_len;
   *outkey = malloc (*outkeylen + 1);
+  if (__builtin_expect (*outkey == NULL, 0))
+    return YPERR_RESRC;
   memcpy (*outkey, resp.key.keydat_val, *outkeylen);
   (*outkey)[*outkeylen] = '\0';
   *outvallen = resp.val.valdat_len;
   *outval = malloc (*outvallen + 1);
+  if (__builtin_expect (*outval == NULL, 0))
+    return YPERR_RESRC;
   memcpy (*outval, resp.val.valdat_val, *outvallen);
   (*outval)[*outvallen] = '\0';
 
@@ -515,17 +531,21 @@ yp_next (const char *indomain, const char *inmap, const char *inkey,
                      (caddr_t) & req, (xdrproc_t) xdr_ypresp_key_val,
                      (caddr_t) & resp);
 
-  if (result != RPC_SUCCESS)
-    return YPERR_RPC;
+  if (result != YPERR_SUCCESS)
+    return result;
   if (resp.stat != YP_TRUE)
     return ypprot_err (resp.stat);
 
   *outkeylen = resp.key.keydat_len;
   *outkey = malloc (*outkeylen + 1);
+  if (__builtin_expect (*outkey == NULL, 0))
+    return YPERR_RESRC;
   memcpy (*outkey, resp.key.keydat_val, *outkeylen);
   (*outkey)[*outkeylen] = '\0';
   *outvallen = resp.val.valdat_len;
   *outval = malloc (*outvallen + 1);
+  if (__builtin_expect (*outval == NULL, 0))
+    return YPERR_RESRC;
   memcpy (*outval, resp.val.valdat_val, *outvallen);
   (*outval)[*outvallen] = '\0';
 
@@ -553,8 +573,8 @@ yp_master (const char *indomain, const char *inmap, char **outname)
   result = do_ypcall (indomain, YPPROC_MASTER, (xdrproc_t) xdr_ypreq_nokey,
          (caddr_t) & req, (xdrproc_t) xdr_ypresp_master, (caddr_t) & resp);
 
-  if (result != RPC_SUCCESS)
-    return YPERR_RPC;
+  if (result != YPERR_SUCCESS)
+    return result;
   if (resp.stat != YP_TRUE)
     return ypprot_err (resp.stat);
 
@@ -583,8 +603,8 @@ yp_order (const char *indomain, const char *inmap, unsigned int *outorder)
   result = do_ypcall (indomain, YPPROC_ORDER, (xdrproc_t) xdr_ypreq_nokey,
           (caddr_t) & req, (xdrproc_t) xdr_ypresp_order, (caddr_t) & resp);
 
-  if (result != RPC_SUCCESS)
-    return YPERR_RPC;
+  if (result != YPERR_SUCCESS)
+    return result;
   if (resp.stat != YP_TRUE)
     return ypprot_err (resp.stat);
 
@@ -595,11 +615,11 @@ yp_order (const char *indomain, const char *inmap, unsigned int *outorder)
 }
 
 static void *ypall_data;
-static int (*ypall_foreach) __P ((int status, char *key, int keylen,
-                                 char *val, int vallen, char *data));
+static int (*ypall_foreach) (int status, char *key, int keylen,
+                            char *val, int vallen, char *data);
 
 static bool_t
-__xdr_ypresp_all (XDR * xdrs, u_long * objp)
+__xdr_ypresp_all (XDR *xdrs, u_long *objp)
 {
   while (1)
     {
@@ -628,6 +648,10 @@ __xdr_ypresp_all (XDR * xdrs, u_long * objp)
            int keylen = resp.ypresp_all_u.val.key.keydat_len;
            int vallen = resp.ypresp_all_u.val.val.valdat_len;
 
+           /* We are not allowed to modify the key and val data.
+              But we are allowed to add data behind the buffer,
+              if we don't modify the length. So add an extra NUL
+              character to avoid trouble with broken code. */
            *objp = YP_TRUE;
            memcpy (key, resp.ypresp_all_u.val.key.keydat_val, keylen);
            key[keylen] = '\0';
@@ -639,14 +663,13 @@ __xdr_ypresp_all (XDR * xdrs, u_long * objp)
              return TRUE;
          }
          break;
-       case YP_NOMORE:
-         *objp = YP_NOMORE;
-         xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
-         return TRUE;
-         break;
        default:
          *objp = resp.ypresp_all_u.val.stat;
          xdr_free ((xdrproc_t) xdr_ypresp_all, (char *) &resp);
+         /* Sun says we don't need to make this call, but must return
+            immediatly. Since Solaris makes this call, we will call
+            the callback function, too. */
+         (*ypall_foreach) (*objp, NULL, 0, NULL, 0, ypall_data);
          return TRUE;
        }
     }
@@ -664,6 +687,7 @@ yp_all (const char *indomain, const char *inmap,
   CLIENT *clnt;
   unsigned long status;
   int clnt_sock;
+  int saved_errno = errno;
 
   if (indomain == NULL || indomain[0] == '\0' ||
       inmap == NULL || inmap == '\0')
@@ -676,16 +700,23 @@ yp_all (const char *indomain, const char *inmap,
     {
       if (__yp_bind (indomain, &ydb) != 0)
        {
+         __set_errno (saved_errno);
          return YPERR_DOMAIN;
        }
 
-      /* YPPROC_ALL get its own TCP channel to ypserv */
+      /* YPPROC_ALL get its own TCP channel to ypserv.  Therefore we
+        close the socket opened by the __yp_bind call.  */
+      close (ydb->dom_socket);
       clnt_sock = RPC_ANYSOCK;
       clnt_sin = ydb->dom_server_addr;
       clnt_sin.sin_port = 0;
       clnt = clnttcp_create (&clnt_sin, YPPROG, YPVERS, &clnt_sock, 0, 0);
       if (clnt == NULL)
-       return YPERR_PMAP;
+       {
+         __yp_unbind (ydb);
+         __set_errno (saved_errno);
+         return YPERR_PMAP;
+       }
       req.domain = (char *) indomain;
       req.map = (char *) inmap;
 
@@ -698,20 +729,27 @@ yp_all (const char *indomain, const char *inmap,
 
       if (result != RPC_SUCCESS)
        {
-         clnt_perror (clnt, "yp_all: clnt_call");
+         /* Print the error message only on the last try */
+         if (try == MAXTRIES - 1)
+           clnt_perror (clnt, "yp_all: clnt_call");
          res = YPERR_RPC;
        }
       else
        res = YPERR_SUCCESS;
 
+      __yp_unbind (ydb);
       clnt_destroy (clnt);
-      close (clnt_sock);
 
-      if (status != YP_NOMORE)
-       return ypprot_err (status);
-      try++;
+      if (res == YPERR_SUCCESS && status != YP_NOMORE)
+       {
+         __set_errno (saved_errno);
+         return ypprot_err (status);
+       }
+      ++try;
     }
 
+  __set_errno (saved_errno);
+
   return res;
 }
 
@@ -729,8 +767,8 @@ yp_maplist (const char *indomain, struct ypmaplist **outmaplist)
   result = do_ypcall (indomain, YPPROC_MAPLIST, (xdrproc_t) xdr_domainname,
     (caddr_t) & indomain, (xdrproc_t) xdr_ypresp_maplist, (caddr_t) & resp);
 
-  if (result != RPC_SUCCESS)
-    return YPERR_RPC;
+  if (result != YPERR_SUCCESS)
+    return result;
   if (resp.stat != YP_TRUE)
     return ypprot_err (resp.stat);
 
This page took 0.042504 seconds and 5 git commands to generate.