summary refs log tree commit diff
path: root/nis/nis_call.c
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1997-07-28 22:35:20 +0000
committerUlrich Drepper <drepper@redhat.com>1997-07-28 22:35:20 +0000
commit3996f34b46043ed8ea8fdc6f44377d969d64396b (patch)
tree563f433dab9b5299d81ced72885bf1e8c29b9159 /nis/nis_call.c
parent0a54e4010fe0085cd36deaff9442a7e88de3270d (diff)
downloadglibc-3996f34b46043ed8ea8fdc6f44377d969d64396b.tar.gz
glibc-3996f34b46043ed8ea8fdc6f44377d969d64396b.tar.xz
glibc-3996f34b46043ed8ea8fdc6f44377d969d64396b.zip
1997-07-28 23:35  Ulrich Drepper  <drepper@cygnus.com>

	* csu/gmon-start.c (__gmon_start__): Call __monstartup not
	monstartup.
	* gmon/gmon.c: Rename moncontrol to __moncontrol and monstartup
	to __monstartup.
	* gmon/sys/gmon.h: Fix prototypes.
	* gmon/sys/gmon_out.h: Pretty print.

	* gmon/bb_exit_func.c (__bb_exit_func): Use memcpy instead of bcopy.
	* gmon/gmon.c (__monstartup): Likewise.
	(write_hist): Remove dependency on 32 int.
	(_mcleanup): Don't call perror, use fprintf.

	* elf/dl-load.c: Fix handling of current directory in search path.

	* elf/Makefile (dl-routines): Add dl-profile.
	* elf/dl-profile.c: New file.
	* elf/dl-runtime.c (fixup): Add new parameter with address to store
	relocation result in to elf_machine_relplt.
	(profile_fixup): New function.
	* elf/do-rel.h (elf_dynamic_do_rel): Add new parameter with address
	to store relocation result in to elf_machine_relplt.
	* elf/dl-support.c: Define _dl_profile and _dl_profile_map.
	* elf/dynamic-link.h (ELF_DYNAMIC_RELOCATE): Add new parameter and
	call elf_machine_runtime_setup with extra argument.
	* elf/dl-reloc.c (_dl_relocate_object): Add new argument to
	ELF_DYNAMIC_RELOCATE.
	* elf/link.h: Add prototypes for new functions and variables.
	* elf/rtld.c: Parse LD_PROFILE and LD_PROFILE_OUTPUT environment
	variables and call _dl_start_profile if necessary.
	* include/sys/gmon_out.h: New file.
	* sysdeps/alpha/dl-machine.h (elf_machine_runtime_setup): Add
	new parameter to enable profiling.
	(elf_machine_rela): Add new parameter to specify place to store
	result in.
	* sysdeps/m68k/dl-machine.h: Likewise.
	* sysdeps/mips/dl-machine.h: Likewise.
	* sysdeps/mips/mips64/dl-machine.h: Likewise.
	* sysdeps/powerpc/dl-machine.h: Likewise.
	* sysdeps/sparc/dl-machine.h: Likewise.
	* sysdeps/sparc64/dl-machine.h: Likewise.
	* sysdeps/i386/dl-machine.h: Likewise.
	(elf_machine_runtime_setup): Setup got[2] to _dl_runtime_resolve if
	we do profiling.
	(ELF_MACHINE_RUNTIME_TRAMPOLINE): Add code for _dl_runtime_profile.

	* nis/nss_compat/compat-grp.c (internal_setgrent): Set FD_CLOEXEC
	for stream on input file.
	* nis/nss_compat/compat-pwd.c (internal_setpwent): Likewise.
	* nis/nss_compat/compat-spwd.c (internal_setspent): Likewise.
	* nss/nss_db/db-XXX.c (internal_setent): Likewise.
	* nss/nss_db/db-alias.c (internal_setent): Likewise.
	* nss/nss_db/db-netgrp.c (internal_setent): Likewise.
	* nss/nss_files/files-XXX.c (internal_setent): Likewise.
	* nss/nss_files/files-alias.c (internal_setent): Likewise.
	* nss/nss_files/files-netgrp.c (internal_setent): Likewise.

	* string/string.h: Pretty print.

	* sysdeps/i386/fpu/bits/mathinline.h: Major update by John Bowman.
	Add float and long double versions.

1997-07-27  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* elf/rtld.c (print_unresolved): Replace empty object name by main
	program name.

1997-07-27  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/generic/htons.c (htons): Renamed from __htons.

1997-07-27  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/m68k/bits/byteswap.h: New file.

1997-07-27 23:50  Philip Blundell  <Philip.Blundell@pobox.com>

	* inet/netinet/icmp6.h: Update for new drafts of POSIX.1g and IPv6
	advanced API.
	* inet/netinet/in.h: Likewise.
	* inet/netinet/ip6.h: Likewise.
	* sysdeps/unix/sysv/linux/bits/socket.h: Likewise.
	* posix/sys/types.h: Add socklen_t.

	* manual/socket.texi: Document some more IPv6 things.
	* manual/libc.texinfo: Likewise.

1997-07-26  Andreas Jaeger  <aj@arthur.rhein-neckar.de>

	* libc.map: Define missing symbol.

1997-07-27 14:31  Thorsten Kukuk  <kukuk@vt.uni-paderborn.de>

	* nis/Makefile: Add nis_findserv.
	* nis/lckcache.c: Fix typo.
	* nis/nis_call.c: Fix problems with multihomed servers.
	* nis/nis_findserv.c: New file.
	* nis/nis_intern.h: Add more prototypes.
	* nis/nis_lookup.c (nis_lookup): Don't try the next server if network
	is unreachable.
	* nis/nis_table.c (nis_list): Likewise.
	* nis/nis_ping.c (nis_ping): Use MASTER_ONLY, don't call abort()
	in error case.
	* nis/nis_util.c (__nis_finddirectory): Give the right error code
	back.
	* nis/ypclnt.c: Make sure, that all sockets are closed.
Diffstat (limited to 'nis/nis_call.c')
-rw-r--r--nis/nis_call.c251
1 files changed, 140 insertions, 111 deletions
diff --git a/nis/nis_call.c b/nis/nis_call.c
index f25b8017a5..1dfb12944a 100644
--- a/nis/nis_call.c
+++ b/nis/nis_call.c
@@ -29,30 +29,7 @@
 
 static struct timeval TIMEOUT = {10, 0};
 
-struct dir_binding
-{
-  CLIENT *clnt;                  /* RPC CLIENT handle */
-  nis_server *server_val;        /* List of servers */
-  u_int server_len;              /* # of servers */
-  u_int server_used;             /* Which server we are bind in the moment ? */
-  u_int trys;                    /* How many server have we tried ? */
-  bool_t master_only;            /* Is only binded to the master */
-  bool_t use_auth;               /* Do we use AUTH ? */
-  bool_t use_udp;                /* Do we use UDP ? */
-  time_t create;                 /* Binding creation time */
-  struct sockaddr_in addr;       /* Server's IP address */
-  int socket;                    /* Server's local socket */
-  unsigned short port;           /* Local port */
-};
-typedef struct dir_binding dir_binding;
-
-static inline u_int
-__nis_ping (const nis_server *serv, u_int serv_len)
-{
-  return 0;
-}
-
-static unsigned long
+unsigned long
 inetstr2int (const char *str)
 {
   char buffer[strlen (str) + 3];
@@ -92,12 +69,7 @@ __bind_destroy (dir_binding *bind)
 static nis_error
 __bind_next (dir_binding *bind)
 {
-  if (bind->trys >= bind->server_len)
-    return NIS_FAIL;
-  
-  bind->server_used++;
-  if (bind->server_used >= bind->server_len)
-    bind->server_used = 0;
+  u_int j;
 
   if (bind->clnt != NULL)
     {
@@ -106,8 +78,38 @@ __bind_next (dir_binding *bind)
       clnt_destroy (bind->clnt);
       bind->clnt = NULL;
     }
-  
-  return NIS_SUCCESS;
+
+  if (bind->trys >= bind->server_len)
+    return NIS_FAIL;
+
+  for (j = bind->current_ep + 1;
+       j < bind->server_val[bind->server_used].ep.ep_len; ++j)
+    if (strcmp (bind->server_val[bind->server_used].ep.ep_val[j].family,
+		"inet") == 0)
+      if (strcmp (bind->server_val[bind->server_used].ep.ep_val[j].proto,
+		  "-") == 0)
+	{
+	  bind->current_ep = j;
+	  return NIS_SUCCESS;
+	}
+
+  ++bind->trys;
+  ++bind->server_used;
+  if (bind->server_used >= bind->server_len)
+    bind->server_used = 0;
+
+  for (j = bind->current_ep + 1;
+       j < bind->server_val[bind->server_used].ep.ep_len; ++j)
+    if (strcmp (bind->server_val[bind->server_used].ep.ep_val[j].family,
+		"inet") == 0)
+      if (strcmp (bind->server_val[bind->server_used].ep.ep_val[j].proto,
+		  "-") == 0)
+	{
+	  bind->current_ep = j;
+	  return NIS_SUCCESS;
+	}
+
+  return NIS_FAIL;
 }
 
 static nis_error
@@ -116,7 +118,6 @@ __bind_connect (dir_binding *dbp)
   struct sockaddr_in check;
   nis_server *serv;
   int checklen;
-  u_int i;
 
   if (dbp == NULL)
     return NIS_FAIL;
@@ -125,26 +126,10 @@ __bind_connect (dir_binding *dbp)
 
   memset (&dbp->addr, '\0', sizeof (dbp->addr));
   dbp->addr.sin_family = AF_INET;
-  for (i = 0; i < serv->ep.ep_len; ++i)
-    {
-      if (strcmp (serv->ep.ep_val[i].family, "inet") == 0)
-	{
-	  if (dbp->use_udp)
-	    {
-	      if (strcmp (serv->ep.ep_val[i].proto, "udp") == 0)
-		dbp->addr.sin_addr.s_addr =
-		  inetstr2int (serv->ep.ep_val[i].uaddr);
-	      else
-		continue;
-	    }
-	  else
-	    if (strcmp (serv->ep.ep_val[i].proto, "tcp") == 0)
-	      dbp->addr.sin_addr.s_addr =
-		inetstr2int (serv->ep.ep_val[i].uaddr);
-	}
-      else
-	continue;
-    }
+
+  dbp->addr.sin_addr.s_addr =
+    inetstr2int (serv->ep.ep_val[dbp->current_ep].uaddr);
+
   if (dbp->addr.sin_addr.s_addr == 0)
     return NIS_FAIL;
 
@@ -155,15 +140,15 @@ __bind_connect (dir_binding *dbp)
   else
     dbp->clnt = clnttcp_create (&dbp->addr, NIS_PROG, NIS_VERSION,
 				 &dbp->socket, 0, 0);
-  
+
   if (dbp->clnt == NULL)
     return NIS_RPCERROR;
-  
+
   clnt_control (dbp->clnt, CLSET_TIMEOUT, (caddr_t)&TIMEOUT);
   /* If the program exists, close the socket */
   if (fcntl (dbp->socket, F_SETFD, 1) == -1)
     perror (_("fcntl: F_SETFD"));
-  
+
   if (dbp->use_auth)
     {
 #if defined(HAVE_SECURE_RPC)
@@ -171,7 +156,7 @@ __bind_connect (dir_binding *dbp)
 	{
 	  char netname[MAXNETNAMELEN+1];
 	  char *p;
-	  
+
 	  p = stpcpy (netname, "unix.");
 	  strncpy (p, serv->name,MAXNETNAMELEN-5);
 	  netname[MAXNETNAMELEN] = '\0';
@@ -187,7 +172,7 @@ __bind_connect (dir_binding *dbp)
 	dbp->clnt->cl_auth = authunix_create_default ();
       dbp->use_auth = TRUE;
     }
-  
+
   /* Get port for sanity checks later */
   checklen = sizeof (struct sockaddr_in);
   memset (&check, 0, checklen);
@@ -207,11 +192,11 @@ __bind_create (const nis_server *serv_val, u_int serv_len, u_long flags)
 {
   dir_binding *dbp;
   u_int i;
-  
+
   dbp = calloc (1, sizeof (dir_binding));
   if (dbp == NULL)
     return NULL;
-  
+
   dbp->server_len = serv_len;
   dbp->server_val = calloc (1, sizeof (nis_server) * serv_len);
   if (dbp->server_val == NULL)
@@ -219,17 +204,34 @@ __bind_create (const nis_server *serv_val, u_int serv_len, u_long flags)
       free (dbp);
       return NULL;
     }
-  
+
+  if (flags & USE_DGRAM)
+    dbp->use_udp = TRUE;
+  else
+    dbp->use_udp = FALSE;
+
+  if (flags & NO_AUTHINFO)
+    dbp->use_auth = FALSE;
+  else
+    dbp->use_auth = TRUE;
+
+  if (flags & MASTER_ONLY)
+    dbp->master_only = TRUE;
+  else
+    dbp->master_only = FALSE;
+
+  dbp->trys = 1;
+
   for (i = 0; i < serv_len; ++i)
     {
       if (serv_val[i].name != NULL)
 	dbp->server_val[i].name = strdup (serv_val[i].name);
-      
+
       dbp->server_val[i].ep.ep_len = serv_val[i].ep.ep_len;
       if (dbp->server_val[i].ep.ep_len > 0)
 	{
 	  unsigned long j;
-	  
+
 	  dbp->server_val[i].ep.ep_val =
 	    malloc (serv_val[i].ep.ep_len * sizeof (endpoint));
 	  for (j = 0; j < dbp->server_val[i].ep.ep_len; ++j)
@@ -267,24 +269,12 @@ __bind_create (const nis_server *serv_val, u_int serv_len, u_long flags)
       else
 	dbp->server_val[i].pkey.n_bytes = NULL;
     }
-  
-  dbp->server_used = __nis_ping (dbp->server_val, dbp->server_len);
-  if (flags & USE_DGRAM)
-    dbp->use_udp = TRUE;
-  else
-    dbp->use_udp = FALSE;
-
-  if (flags & NO_AUTHINFO)
-    dbp->use_auth = FALSE;
-  else
-    dbp->use_auth = TRUE;
 
-  if (flags & MASTER_ONLY)
-    dbp->master_only = TRUE;
-  else
-    dbp->master_only = FALSE;
-
-  dbp->trys = 1;
+  if (__nis_findfastest (dbp) < 1)
+    {
+      __bind_destroy (dbp);
+      return NULL;
+    }
 
   return dbp;
 }
@@ -298,10 +288,11 @@ __do_niscall2 (const nis_server *server, u_int server_len, u_long prog,
   nis_error retcode;
   dir_binding *dbp;
 
-  if (flags & MASTER_ONLY) 
+  if (flags & MASTER_ONLY)
     server_len = 1;
-  
-  dbp = __bind_create (server, server_len, flags);
+
+  if ((dbp = __bind_create (server, server_len, flags)) == NULL)
+    return NIS_UNAVAIL;
   while (__bind_connect (dbp) != NIS_SUCCESS)
     {
       if (__bind_next (dbp) != NIS_SUCCESS)
@@ -315,7 +306,7 @@ __do_niscall2 (const nis_server *server, u_int server_len, u_long prog,
     {
     again:
       result = clnt_call (dbp->clnt, prog, xargs, req, xres, resp, TIMEOUT);
-      
+
       if (result != RPC_SUCCESS)
 	{
 	  clnt_perror (dbp->clnt, "__do_niscall2: clnt_call");
@@ -336,25 +327,56 @@ __do_niscall2 (const nis_server *server, u_int server_len, u_long prog,
 	    case NIS_IBREMOVE:
 	    case NIS_IBFIRST:
 	    case NIS_IBNEXT:
-	      if ((((nis_result *)xres)->status != NIS_SUCCESS) &&
-		  (((nis_result *)xres)->status != NIS_S_SUCCESS))
-		if (__bind_next (dbp) == NIS_SUCCESS)
+	      if ((((nis_result *)xres)->status == NIS_NOTFOUND) ||
+		  (((nis_result *)xres)->status == NIS_NOSUCHNAME) ||
+		  (((nis_result *)xres)->status == NIS_NOT_ME))
+		{
+		  if (__bind_next (dbp) == NIS_SUCCESS)
+		    while (__bind_connect (dbp) != NIS_SUCCESS)
+		      {
+			if (__bind_next (dbp) != NIS_SUCCESS)
+			  {
+			    __bind_destroy (dbp);
+			    return NIS_SUCCESS;
+			  }
+		      }
 		  goto again;
+		}
 	    case NIS_FINDDIRECTORY:
-	      if (((fd_result *)xres)->status != NIS_SUCCESS)
-		if (__bind_next (dbp) == NIS_SUCCESS)
+	      if ((((fd_result *)xres)->status == NIS_NOTFOUND) ||
+		  (((fd_result *)xres)->status == NIS_NOSUCHNAME) ||
+		  (((fd_result *)xres)->status == NIS_NOT_ME))
+		{
+		  if (__bind_next (dbp) == NIS_SUCCESS)
+		    while (__bind_connect (dbp) != NIS_SUCCESS)
+		      {
+			if (__bind_next (dbp) != NIS_SUCCESS)
+			  {
+			    __bind_destroy (dbp);
+			    return NIS_SUCCESS;
+			  }
+		      }
 		  goto again;
-	      break;
-#if 0
-	    case NIS_STATUS: /* nis_taglist */
-	    case NIS_SERVSTATE:
+		}
 	      break;
 	    case NIS_DUMPLOG: /* log_result */
 	    case NIS_DUMP:
+	      if ((((log_result *)xres)->lr_status == NIS_NOTFOUND) ||
+		  (((log_result *)xres)->lr_status == NIS_NOSUCHNAME) ||
+		  (((log_result *)xres)->lr_status == NIS_NOT_ME))
+		{
+		  if (__bind_next (dbp) == NIS_SUCCESS)
+		    while (__bind_connect (dbp) != NIS_SUCCESS)
+		      {
+			if (__bind_next (dbp) != NIS_SUCCESS)
+			  {
+			    __bind_destroy (dbp);
+			    return NIS_SUCCESS;
+			  }
+		      }
+		  goto again;
+		}
 	      break;
-	    case NIS_CHECKPOINT: /* cp_result */
-	      break;
-#endif
 	    default:
 	      break;
 	    }
@@ -363,12 +385,13 @@ __do_niscall2 (const nis_server *server, u_int server_len, u_long prog,
 	}
     }
   while ((flags & HARD_LOOKUP) && retcode == NIS_RPCERROR);
-  
-  return retcode; 
+
+  return retcode;
 }
 
 static directory_obj *
-rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags)
+rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags,
+	       nis_error *status)
 {
   fd_result *fd_res;
   XDR xdrs;
@@ -399,6 +422,7 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags)
   switch (nis_dir_cmp (domain, dir->do_name))
     {
     case SAME_NAME:
+      *status = NIS_SUCCESS;
       return dir;
     case NOT_SEQUENTIAL:
       /* NOT_SEQUENTIAL means, go one up and try it there ! */
@@ -413,6 +437,7 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags)
 	   domain ! (Now I understand why a root server must be a
 	   replica of the parent domain) */
 	fd_res = __nis_finddirectory (dir, ndomain);
+	*status = fd_res->status;
 	if (fd_res->status != NIS_SUCCESS)
 	  {
 	    nis_free_directory (dir);
@@ -431,7 +456,7 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags)
 	    /* We have found a NIS+ server serving ndomain, now
 	       let us search for "name" */
 	    nis_free_directory (dir);
-	    return rec_dirsearch (name, obj, flags);
+	    return rec_dirsearch (name, obj, flags, status);
 	  }
 	else
 	  {
@@ -447,7 +472,7 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags)
 	char leaf [strlen (name) + 3];
 	char ndomain [strlen (name) + 3];
 	char *cp;
-	
+
 	do
 	  {
 	    if (strlen (domain) == 0)
@@ -463,8 +488,9 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags)
 	cp = strchr (leaf, '\0');
 	*cp++ = '.';
 	strcpy (cp, domain);
-	
+
 	fd_res = __nis_finddirectory (dir, leaf);
+	*status = fd_res->status;
 	if (fd_res->status != NIS_SUCCESS)
 	  {
 	    nis_free_directory (dir);
@@ -483,15 +509,17 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags)
 	    /* We have found a NIS+ server serving ndomain, now
 	       let us search for "name" */
 	    nis_free_directory (dir);
-	    return rec_dirsearch (name, obj, flags);
+	    return rec_dirsearch (name, obj, flags, status);
 	  }
       }
     break;
     case BAD_NAME:
       nis_free_directory (dir);
+      *status = NIS_BADNAME;
       return NULL;
     }
   nis_free_directory (dir);
+  *status = NIS_FAIL;
   return NULL;
 }
 
@@ -509,19 +537,20 @@ __do_niscall (const_nis_name name, u_long prog, xdrproc_t xargs,
 
   if ((flags & NO_CACHE) !=  NO_CACHE)
     dir = __cache_search (name);
-  
+
   if (dir == NULL)
     {
+      nis_error status;
       dir = readColdStartFile ();
       if (dir == NULL) /* No /var/nis/NIS_COLD_START->no NIS+ installed */
 	return NIS_UNAVAIL;
-      
-      dir = rec_dirsearch (name, dir, flags);
+
+      dir = rec_dirsearch (name, dir, flags, &status);
       if (dir == NULL)
-	return NIS_NOTFOUND;
+	return status;
     }
 
-  if (flags & MASTER_ONLY) 
+  if (flags & MASTER_ONLY)
     {
       server = dir->do_servers.do_servers_val;
       server_len = 1;
@@ -531,11 +560,11 @@ __do_niscall (const_nis_name name, u_long prog, xdrproc_t xargs,
       server = dir->do_servers.do_servers_val;
       server_len = dir->do_servers.do_servers_len;
     }
-  
-  
+
+
   retcode = __do_niscall2 (server, server_len, prog, xargs, req, xres, resp,
 			   flags);
-  
+
   nis_free_directory (dir);
 
   return retcode;