about summary refs log tree commit diff
path: root/nis/nis_table.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1998-07-28 16:26:04 +0000
committerUlrich Drepper <drepper@redhat.com>1998-07-28 16:26:04 +0000
commite852e889444a8bf27f3e5075d064e9922b38e7e2 (patch)
tree75d2d4b1010a26d723daefef7909d1a6355929bc /nis/nis_table.c
parentc9243dacea19b7dcf36bb69ca83877d3ea905831 (diff)
downloadglibc-e852e889444a8bf27f3e5075d064e9922b38e7e2.tar.gz
glibc-e852e889444a8bf27f3e5075d064e9922b38e7e2.tar.xz
glibc-e852e889444a8bf27f3e5075d064e9922b38e7e2.zip
Update.
1998-07-28  Ulrich Drepper  <drepper@cygnus.com>

	* math/libm-test.c (tgamma_test): Remove redundant tests.

1998-07-28 16:20  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/generic/glob.c: Correct problems with */foo and GLOB_NOCHECK
	where foo does not exist in any of the subdirectories.
	Reported by Paul D. Smith <psmith@BayNetworks.COM>.

	* posix/globtest.sh: Add test for this bug.

1998-07-28  Mark Kettenis  <kettenis@phys.uva.nl>

	* io/sys/statfs.h: Fix typos.
	* io/sys/statvfs.h: Fix typos.

1998-07-28  Ulrich Drepper  <drepper@cygnus.com>

	* version.h (VERSION): Bump to 2.0.95.

	* math/Makefile (libm-calls): Remove w_gamma, add w_tgamma.
	* math/Versions [GLIBC_2.1]: Add tgamma, tgammaf, and tgammal.
	* math/libm-test.c: Split old gamma_test and move half of it in new
	function tgamma_test.
	* math/bits/mathcalls.h: Add declaration of tgamma.
	* sysdeps/libm-ieee754/k_standard.c: Change gamma errors into
	tgamma errors.
	* sysdeps/libm-ieee754/w_gamma.c: Remove lgamma compatibility code
	and rename to ...
	* sysdeps/libm-ieee754/w_tgamma.c: ... this.  New file.
	* sysdeps/libm-ieee754/w_gammaf.c: Remove lgammaf compatibility code
	and rename to ...
	* sysdeps/libm-ieee754/w_tgammaf.c: ... this.  New file.
	* sysdeps/libm-ieee754/w_gammal.c: Remove lgammal compatibility code
	and rename to ...
	* sysdeps/libm-ieee754/w_tgammal.c: ... this.  New file.
	* sysdeps/libm-ieee754/w_lgamma.c: Add gamma as weak alias.
	* sysdeps/libm-ieee754/w_lgammaf.c: Likewise.
	* sysdeps/libm-ieee754/w_lgammal.c: Likewise.

	* stgdio-common/printf-parse.h: Implement handling of j, t, and z
	modifiers.
	* stdio-common/vfprintf.c: Likewise.
	* stdio-common/vfscanf.c: Likewise.
	* manual/stdio.texi: Document new printf/scanf modifiers.

	* sysdeps/unix/sysv/linux/recvmsg.c: Remove alias __recvmsg.
	* sysdeps/unix/sysv/linux/sendmsg.c: Remove alias __sendmsg.

1998-07-28  Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>

	* sunrpc/Makefile (routines): Add clnt_unix and svc_unix.
	* sunrpc/Versions: Add new *unix_create functions.
	* sunrpc/clnt_gen.c: Add support for RPC over AF_UNIX.
	* sunrpc/clnt_unix.c: New, client side of RPC over AF_UNIX.
	* sunrpc/key_call.c: Use RPC over AF_UNIX for communication
	with keyserv daemon.
	* sunrpc/rpc/clnt.h: Add AF_UNIX based RPC function prototypes.
	* sunrpc/rpc/svc.h: Likewise.
	* sunrpc/svc_authux.c: Copy internal auth flavor if none is given.
	* sunrpc/svc_tcp.c: Fix typos.
	* sunrpc/svc_unix.c: New, server side of AF_UNIX based RPC.

	* nis/Makefile: Remove currently not working cache functions.
	* nis/Versions: Add __nisbind_* functions for rpc.nisd.
	* nis/nis_call.c: Rewrite binding to a NIS+ server to reuse
	CLIENT handles.
	* nis/nis_file.c: Fix memory leaks.
	* nis/nis_intern.h: Move internal structs from here ...
	* nis/rpcsvc/nislib.h: ... to here for NIS+ server and tools.
	* nis/nis_lookup.c: Try at first if last client handle works.
	* nis/nis_table.c: Likewise.
	* nis/nis_checkpoint.c: Adjust __do_niscall2 parameters.
	* nis/nis_mkdir.c: Likewise.
	* nis/nis_ping.c: Likewise.
	* nis/nis_rmdir.c: Likewise.
	* nis/nis_server.c: Likewise.
	* nis/nis_util.c: Likewise.
	* nis/nis_findserv.c (__nis_findfastest): Little optimization.

1998-07-28  Andreas Jaeger  <aj@arthur.rhein-neckar.de>

	* stdlib/strtol.c (STRTOL_LONG_MAX): Correct typo in last patch -
	define as LONG_MAX.

1998-07-28 09:31  Ulrich Drepper  <drepper@cygnus.com>

	* nscd/connections.c (gr_send_answer): Deal with missing UIO_MAXIOV.
	Correct test whether writev send all data.
	* nscd/nscd_getgr_r.c (__nscd_getgr_r): Correct test whether readv
	received all data.

1998-07-28  Mark Kettenis  <kettenis@phys.uva.nl>

	* nscd/nscd_getgr_r.c (__nscd_getgr_r): Deal with missing UIO_MAXIOV.

1998-07-28  Mark Kettenis  <kettenis@phys.uva.nl>

	* sysdeps/mach/hurd/dl-sysdep.c (open_file): Change assert call to
	allow mode to be 0.
	(__xstat): New function.
	(__fxstat): New function.
	(_dl_sysdep_read_whole_file): Removed.  The implementation in
	`elf/dl-misc.c' now also works for the Hurd.
Diffstat (limited to 'nis/nis_table.c')
-rw-r--r--nis/nis_table.c399
1 files changed, 239 insertions, 160 deletions
diff --git a/nis/nis_table.c b/nis/nis_table.c
index ed4b3740dd..e0885ca024 100644
--- a/nis/nis_table.c
+++ b/nis/nis_table.c
@@ -110,6 +110,40 @@ __create_ib_request (const_nis_name name, u_long flags)
   return ibreq;
 }
 
+static struct timeval RPCTIMEOUT = {10, 0};
+
+static char *
+__get_tablepath (char *name, dir_binding *bptr)
+{
+  enum clnt_stat result;
+  nis_result *res = calloc (1, sizeof (nis_result));
+  struct ns_request req;
+
+  if (res == NULL)
+    return NULL;
+
+  req.ns_name = name;
+  req.ns_object.ns_object_len = 0;
+  req.ns_object.ns_object_val = NULL;
+
+  result = clnt_call (bptr->clnt, NIS_LOOKUP, (xdrproc_t) _xdr_ns_request,
+		      (caddr_t) &req, (xdrproc_t) _xdr_nis_result,
+		      (caddr_t) res, RPCTIMEOUT);
+
+  if (result == RPC_SUCCESS && NIS_RES_STATUS (res) == NIS_SUCCESS &&
+      __type_of (NIS_RES_OBJECT (res)) == NIS_TABLE_OBJ)
+    {
+      char *cptr = strdup (NIS_RES_OBJECT (res)->TA_data.ta_path);
+      nis_freeresult (res);
+      return cptr;
+    }
+  else
+    {
+      nis_freeresult (res);
+      return strdup ("");
+    }
+}
+
 nis_result *
 nis_list (const_nis_name name, u_long flags,
 	  int (*callback) (const_nis_name name,
@@ -120,12 +154,16 @@ nis_list (const_nis_name name, u_long flags,
   nis_result *res = NULL;
   ib_request *ibreq;
   int status;
+  enum clnt_stat clnt_status;
   int count_links = 0;		/* We will only follow NIS_MAXLINKS links! */
   int done = 0;
   nis_name *names;
   nis_name namebuf[2] = {NULL, NULL};
   int name_nr = 0;
   nis_cb *cb = NULL;
+  char *tableptr, *tablepath = NULL;
+  int have_tablepath = 0;
+  int first_try = 0; /* Do we try the old binding at first ? */
 
   res = calloc (1, sizeof (nis_result));
   if (res == NULL)
@@ -164,189 +202,230 @@ nis_list (const_nis_name name, u_long flags,
 
   cb = NULL;
 
-  if (flags & FOLLOW_PATH || flags & ALL_RESULTS)
+  while (!done)
     {
-      nis_result *lres;
-      u_long newflags = flags & ~FOLLOW_PATH & ~ALL_RESULTS;
-      char table_path[NIS_MAXPATH + 3];
-      char *ntable, *p;
-      u_long done = 0, failures = 0;
-
-      while (names[name_nr] != NULL && !done)
-	{
-	  lres = nis_lookup (names[name_nr], newflags | NO_AUTHINFO);
-	  if (lres == NULL || NIS_RES_STATUS (lres) != NIS_SUCCESS)
-	    {
-	      NIS_RES_STATUS (res) = NIS_RES_STATUS (lres);
-	      nis_freeresult (lres);
-	      ++name_nr;
-	      continue;
-	    }
-
-	  /* nis_lookup handles FOLLOW_LINKS,
-	     so we must have a table object.*/
-	  if (__type_of (NIS_RES_OBJECT (lres)) != NIS_TABLE_OBJ)
-	    {
-	      nis_freeresult (lres);
-	      NIS_RES_STATUS (res) = NIS_INVALIDOBJ;
-	      break;
-	    }
+      dir_binding bptr;
+      directory_obj *dir = NULL;
 
-	  /* Save the path, discard everything else.  */
-	  p = __stpncpy (table_path, names[name_nr], NIS_MAXPATH);
-	  *p++ = ':';
-	  p = __stpncpy (p, NIS_RES_OBJECT (lres)->TA_data.ta_path,
-			 NIS_MAXPATH - (p - table_path));
-	  *p = '\0';
-	  nis_freeresult (lres);
-	  free (res);
-	  res = NULL;
+      memset (res, '\0', sizeof (nis_result));
 
-	  p = table_path;
+      status = __nisfind_server (ibreq->ibr_name, &dir);
+      if (status != NIS_SUCCESS)
+        {
+          NIS_RES_STATUS (res) = status;
+          return res;
+        }
 
-	  while (((ntable = strsep (&p, ":")) != NULL) && !done)
-	    {
-	      char *c;
+      status = __nisbind_create (&bptr, dir->do_servers.do_servers_val,
+                                 dir->do_servers.do_servers_len, flags);
+      if (status != NIS_SUCCESS)
+        {
+          NIS_RES_STATUS (res) = status;
+          nis_free_directory (dir);
+          return res;
+        }
 
-	      if (res != NULL)
-		nis_freeresult (res);
+      while (__nisbind_connect (&bptr) != NIS_SUCCESS)
+	if (__nisbind_next (&bptr) != NIS_SUCCESS)
+	  {
+	    __nisbind_destroy (&bptr);
+	    nis_free_directory (dir);
+	    NIS_RES_STATUS (res) = NIS_NAMEUNREACHABLE;
+	    return res;
+	  }
 
-	      /* Do the job recursive here!  */
-	      if ((c = strchr(name, ']')) != NULL)
-		{
-		  /* Have indexed name ! */
-		  int index_len = c - name + 2;
-		  char buf[index_len + strlen (ntable) + 1];
-
-		  c = __stpncpy (buf, name, index_len);
-		  strcpy (c, ntable);
-		  res = nis_list (buf, newflags, callback,userdata);
-		}
-	      else
-		res = nis_list (ntable, newflags, callback, userdata);
-	      if (res == NULL)
-		return NULL;
-	      switch (NIS_RES_STATUS (res))
-		{
-		case NIS_SUCCESS:
-		case NIS_CBRESULTS:
-		  if (!(flags & ALL_RESULTS))
-		    done = 1;
-		  break;
-		case NIS_PARTIAL: /* The table is correct, we doesn't found
-				     the entry */
-		  break;
-		default:
-		  if (flags & ALL_RESULTS)
-		    ++failures;
-		  else
-		    done = 1;
-		  break;
-		}
-	    }
-	  if (NIS_RES_STATUS (res) == NIS_SUCCESS && failures)
-	    NIS_RES_STATUS (res) = NIS_S_SUCCESS;
-	  if (NIS_RES_STATUS (res) == NIS_NOTFOUND && failures)
-	    NIS_RES_STATUS (res) = NIS_S_NOTFOUND;
-	  break;
-	}
-    }
-  else
-    {
       if (callback != NULL)
 	{
 	  cb = __nis_create_callback (callback, userdata, flags);
 	  ibreq->ibr_cbhost.ibr_cbhost_len = 1;
 	  ibreq->ibr_cbhost.ibr_cbhost_val = cb->serv;
-	  }
-
-      while (!done)
-	{
-	  memset (res, '\0', sizeof (nis_result));
-
-	  status = __do_niscall (ibreq->ibr_name, NIS_IBLIST,
-				 (xdrproc_t) _xdr_ib_request,
-				 (caddr_t) ibreq, (xdrproc_t) _xdr_nis_result,
-				 (caddr_t) res, flags, cb);
-	  if (status != NIS_SUCCESS)
-	    NIS_RES_STATUS (res) = status;
+	}
 
-	  switch (NIS_RES_STATUS (res))
-	    {
-	    case NIS_PARTIAL:
-	    case NIS_SUCCESS:
-	    case NIS_S_SUCCESS:
-	      if (__type_of (NIS_RES_OBJECT (res)) == NIS_LINK_OBJ &&
-		  flags & FOLLOW_LINKS)		/* We are following links.  */
-		{
-		  /* If we hit the link limit, bail.  */
-		  if (count_links > NIS_MAXLINKS)
+    again:
+      clnt_status = clnt_call (bptr.clnt, NIS_IBLIST,
+			       (xdrproc_t) _xdr_ib_request, (caddr_t) ibreq,
+			       (xdrproc_t) _xdr_nis_result,
+			       (caddr_t) res, RPCTIMEOUT);
+
+      if (clnt_status != RPC_SUCCESS)
+	NIS_RES_STATUS (res) = NIS_RPCERROR;
+      else
+	switch (NIS_RES_STATUS (res))
+	  { /* start switch */
+	  case NIS_PARTIAL:
+	  case NIS_SUCCESS:
+	  case NIS_S_SUCCESS:
+	    if (__type_of (NIS_RES_OBJECT (res)) == NIS_LINK_OBJ &&
+		flags & FOLLOW_LINKS)		/* We are following links.  */
+	      {
+		free (ibreq->ibr_name);
+		/* If we hit the link limit, bail.  */
+		if (count_links > NIS_MAXLINKS)
+		  {
+		    NIS_RES_STATUS (res) = NIS_LINKNAMEERROR;
+		    ++done;
+		    break;
+		  }
+		++count_links;
+		ibreq->ibr_name =
+		  strdup (NIS_RES_OBJECT (res)->LI_data.li_name);
+		if (NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_len)
+		  if (ibreq->ibr_srch.ibr_srch_len == 0)
 		    {
-		      NIS_RES_STATUS (res) = NIS_LINKNAMEERROR;
-		      ++done;
-		      break;
+		      ibreq->ibr_srch.ibr_srch_len =
+			NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_len;
+		      ibreq->ibr_srch.ibr_srch_val =
+			NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_val;
 		    }
-		  if (count_links)
-		    free (ibreq->ibr_name);
-		  ++count_links;
-		  free (ibreq->ibr_name);
-		  ibreq->ibr_name =
-		    strdup (NIS_RES_OBJECT (res)->LI_data.li_name);
-		  if (NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_len)
-		    if (ibreq->ibr_srch.ibr_srch_len == 0)
+		nis_freeresult (res);
+		res = calloc (1, sizeof (nis_result));
+		if (res == NULL)
+		  {
+		    if (have_tablepath)
+		      free (tablepath);
+		    __nisbind_destroy (&bptr);
+		    nis_free_directory (dir);
+		    return NULL;
+		  }
+		first_try = 1; /* Try at first the old binding */
+		goto again;
+	      }
+	    else if ((flags & FOLLOW_PATH) &&
+		     NIS_RES_STATUS (res) == NIS_PARTIAL)
+	      {
+		if (!have_tablepath)
+		  {
+		    tablepath = __get_tablepath (ibreq->ibr_name, &bptr);
+		    tableptr = tablepath;
+		    have_tablepath = 1;
+		  }
+		if (tableptr == NULL)
+		  {
+		    ++done;
+		    break;
+		  }
+		free (ibreq->ibr_name);
+		ibreq->ibr_name = strsep (&tableptr, ":");
+		if (ibreq->ibr_name == NULL || ibreq->ibr_name[0] == '\0')
+		  {
+		    ibreq->ibr_name = strdup ("");
+		    ++done;
+		  }
+		else
+		  {
+		    ibreq->ibr_name = strdup (ibreq->ibr_name);
+		    nis_freeresult (res);
+		    res = calloc (1, sizeof (nis_result));
+		    if (res == NULL)
 		      {
-			ibreq->ibr_srch.ibr_srch_len =
-			  NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_len;
-			ibreq->ibr_srch.ibr_srch_val =
-			  NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_val;
+			if (have_tablepath)
+			  free (tablepath);
+			__nisbind_destroy (&bptr);
+			nis_free_directory (dir);
+			return NULL;
 		      }
-		  nis_freeresult (res);
-		  res = calloc (1, sizeof (nis_result));
-		}
-	      else
-		++done;
-	      break;
-	    case NIS_CBRESULTS:
-	      /* Calback is handled in nis_call.c (__do_niscall2),
-		 but we have to change the error code */
-	      NIS_RES_STATUS (res) = cb->result;
+		    first_try = 1;
+		    goto again;
+		  }
+	      }
+	    else
 	      ++done;
-	      break;
-	    case NIS_UNAVAIL:
-	      /* NIS+ is not installed, or all servers are down.  */
-	      ++done;
-	      break;
-	    default:
-	      /* Try the next domainname if we don't follow a link.  */
-	      if (count_links)
-		{
-		  free (ibreq->ibr_name);
-		  NIS_RES_STATUS (res) = NIS_LINKNAMEERROR;
-		  ++done;
-		  break;
-		}
-	      ++name_nr;
-	      if (names[name_nr] == NULL)
-		{
+	    break;
+	  case NIS_CBRESULTS:
+	    if (cb != NULL)
+	      {
+		__nis_do_callback (&bptr, &res->cookie, cb);
+		NIS_RES_STATUS (res) = cb->result;
+
+		if (!(flags & ALL_RESULTS))
 		  ++done;
-		  break;
-		}
-	      ibreq->ibr_name = names[name_nr];
-	      break;
-	    }
+		else
+		  {
+		    if (!have_tablepath)
+		      {
+			tablepath = __get_tablepath (ibreq->ibr_name, &bptr);
+			tableptr = tablepath;
+			have_tablepath = 1;
+		      }
+		    if (tableptr == NULL)
+		      {
+			++done;
+			break;
+		      }
+		    free (ibreq->ibr_name);
+		    ibreq->ibr_name = strsep (&tableptr, ":");
+		    if (ibreq->ibr_name == NULL || ibreq->ibr_name[0] == '\0')
+		      {
+			ibreq->ibr_name = strdup ("");
+			++done;
+		      }
+		    else
+		      ibreq->ibr_name = strdup (ibreq->ibr_name);
+		  }
+	      }
+	    break;
+	  case NIS_SYSTEMERROR:
+	  case NIS_NOSUCHNAME:
+	  case NIS_NOT_ME:
+	    /* If we had first tried the old binding, do nothing, but
+	       get a new binding */
+	    if (!first_try)
+	      {
+		if (__nisbind_next (&bptr) != NIS_SUCCESS)
+		  {
+		    ++done;
+		    break; /* No more servers to search */
+		  }
+		while (__nisbind_connect (&bptr) != NIS_SUCCESS)
+		  {
+		    if (__nisbind_next (&bptr) != NIS_SUCCESS)
+		      {
+			++done;
+			break; /* No more servers to search */
+		      }
+		  }
+		goto again;
+	      }
+	    break;
+	  default:
+	    if (!first_try)
+	      {
+		/* Try the next domainname if we don't follow a link.  */
+		if (count_links)
+		  {
+		    free (ibreq->ibr_name);
+		    NIS_RES_STATUS (res) = NIS_LINKNAMEERROR;
+		    ++done;
+		    break;
+		  }
+		++name_nr;
+		if (names[name_nr] == NULL)
+		  {
+		    ++done;
+		    break;
+		  }
+		ibreq->ibr_name = names[name_nr];
+		first_try = 1; /* Try old binding at first */
+		goto again;
+	      }
+	    break;
+	  }
+      first_try = 0;
+
+      if (cb)
+	{
+	  __nis_destroy_callback (cb);
+	  ibreq->ibr_cbhost.ibr_cbhost_len = 0;
+	  ibreq->ibr_cbhost.ibr_cbhost_val = NULL;
 	}
-    }				/* End of not FOLLOW_PATH.  */
+
+      __nisbind_destroy (&bptr);
+      nis_free_directory (dir);
+    }
 
   if (names != namebuf)
     nis_freenames (names);
 
-  if (cb)
-    {
-      __nis_destroy_callback (cb);
-      ibreq->ibr_cbhost.ibr_cbhost_len = 0;
-      ibreq->ibr_cbhost.ibr_cbhost_val = NULL;
-    }
-
   nis_free_request (ibreq);
 
   return res;