about summary refs log tree commit diff
path: root/nis
diff options
context:
space:
mode:
Diffstat (limited to 'nis')
-rw-r--r--nis/Banner2
-rw-r--r--nis/Makefile2
-rw-r--r--nis/TODO8
-rw-r--r--nis/nis_add.c3
-rw-r--r--nis/nis_cache.c2
-rw-r--r--nis/nis_call.c98
-rw-r--r--nis/nis_callback.c339
-rw-r--r--nis/nis_checkpoint.c2
-rw-r--r--nis/nis_file.c2
-rw-r--r--nis/nis_findserv.c73
-rw-r--r--nis/nis_intern.h24
-rw-r--r--nis/nis_lookup.c2
-rw-r--r--nis/nis_mkdir.c4
-rw-r--r--nis/nis_modify.c3
-rw-r--r--nis/nis_ping.c2
-rw-r--r--nis/nis_remove.c3
-rw-r--r--nis/nis_rmdir.c4
-rw-r--r--nis/nis_server.c4
-rw-r--r--nis/nis_table.c234
-rw-r--r--nis/nis_util.c21
-rw-r--r--nis/nss_nisplus/nisplus-publickey.c4
-rw-r--r--nis/rpcsvc/nis.h538
22 files changed, 716 insertions, 658 deletions
diff --git a/nis/Banner b/nis/Banner
index 3a1729c3b0..d6cf7a9f5e 100644
--- a/nis/Banner
+++ b/nis/Banner
@@ -1 +1 @@
-NIS(YP)/NIS+ NSS modules 0.13 by Thorsten Kukuk
+NIS(YP)/NIS+ NSS modules 0.14 by Thorsten Kukuk
diff --git a/nis/Makefile b/nis/Makefile
index 9b72429f8f..82c5f24963 100644
--- a/nis/Makefile
+++ b/nis/Makefile
@@ -51,7 +51,7 @@ libnsl-routines = yp_xdr ypclnt ypupdate_xdr \
 		  nis_removemember nis_creategroup nis_destroygroup\
 		  nis_print_group_entry nis_domain_of nis_domain_of_r\
 		  nis_modify nis_remove nis_add nis_defaults lckcache\
-		  nis_findserv
+		  nis_findserv nis_callback
 libnsl-map	= libnsl.map
 
 libnss_compat-routines	:= $(addprefix compat-,grp pwd spwd) nisplus-parser
diff --git a/nis/TODO b/nis/TODO
index f34bc09a06..8528de7e1a 100644
--- a/nis/TODO
+++ b/nis/TODO
@@ -1,11 +1,3 @@
 
  * nis_addmember: Where checks for duplicate group members ? nisgrpadm or
 		  nis_addmember ?
-
- * nis_table.c: nis_list(): 
-	Missing flags: FOLLOW_PATH, ALL_RESULTS
-	callback: Don't simulate it, use server callback thread
-
- * Missing flags:
-	- FOLLOW_PATH	(nis_list, not supported)
-	- ALL_RESULTS	(nis_list, not supported, needs server callback)
diff --git a/nis/nis_add.c b/nis/nis_add.c
index 9baf4e8278..6693a25766 100644
--- a/nis/nis_add.c
+++ b/nis/nis_add.c
@@ -59,7 +59,8 @@ nis_add (const_nis_name name, const nis_object *obj)
   if ((status = __do_niscall (req.ns_object.ns_object_val[0].zo_domain,
 			      NIS_ADD, (xdrproc_t) xdr_ns_request,
 			      (caddr_t) &req, (xdrproc_t) xdr_nis_result,
-			      (caddr_t) res, MASTER_ONLY)) != RPC_SUCCESS)
+			      (caddr_t) res, MASTER_ONLY,
+			      NULL)) != RPC_SUCCESS)
     res->status = status;
 
   req.ns_object.ns_object_val[0].zo_name = p1;
diff --git a/nis/nis_cache.c b/nis/nis_cache.c
index 4c0ea7b186..e10b8c07fd 100644
--- a/nis/nis_cache.c
+++ b/nis/nis_cache.c
@@ -143,7 +143,7 @@ __cache_refresh (nis_name name)
   if (cache_clnt == NULL)
     result = NIS_FAIL;
   else if (clnt_call (cache_clnt, NIS_CACHE_REFRESH_ENTRY,
-		      (xdrproc_t) xdr_wrapstring, (caddr_t) name,
+		      (xdrproc_t) xdr_wrapstring, (caddr_t) &name,
 		      (xdrproc_t) xdr_void, &clnt_res, TIMEOUT)
 	   != RPC_SUCCESS)
     {
diff --git a/nis/nis_call.c b/nis/nis_call.c
index 672755055b..fd777f5948 100644
--- a/nis/nis_call.c
+++ b/nis/nis_call.c
@@ -98,8 +98,7 @@ __bind_next (dir_binding *bind)
   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)
+  for (j = 0; 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,
@@ -280,7 +279,7 @@ __bind_create (const nis_server *serv_val, u_int serv_len, u_long flags)
 nis_error
 __do_niscall2 (const nis_server *server, u_int server_len, u_long prog,
 	       xdrproc_t xargs, caddr_t req, xdrproc_t xres, caddr_t resp,
-	       u_long flags)
+	       u_long flags, nis_cb *cb)
 {
   enum clnt_stat result;
   nis_error retcode;
@@ -315,63 +314,83 @@ __do_niscall2 (const nis_server *server, u_int server_len, u_long prog,
 	{
 	  switch (prog)
 	    {
+	    case NIS_IBLIST:
+	      if ((((nis_result *)resp)->status == NIS_CBRESULTS) &&
+		  (cb != NULL))
+		{
+		  __nis_do_callback(dbp, &((nis_result *)resp)->cookie, cb);
+		  break;
+		}
+	      /* Yes, this is correct. If we doesn't have to start
+		 a callback, look if we have to search another server */
 	    case NIS_LOOKUP:
 	    case NIS_ADD:
 	    case NIS_MODIFY:
 	    case NIS_REMOVE:
-	    case NIS_IBLIST:
 	    case NIS_IBADD:
 	    case NIS_IBMODIFY:
 	    case NIS_IBREMOVE:
 	    case NIS_IBFIRST:
 	    case NIS_IBNEXT:
-	      if ((((nis_result *)xres)->status == NIS_NOTFOUND) ||
-		  (((nis_result *)xres)->status == NIS_NOSUCHNAME) ||
-		  (((nis_result *)xres)->status == NIS_NOT_ME))
+	      if ((((nis_result *)resp)->status == NIS_NOTFOUND) ||
+		  (((nis_result *)resp)->status == NIS_NOSUCHNAME) ||
+		  (((nis_result *)resp)->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;
-			  }
-		      }
+		    {
+		      while (__bind_connect (dbp) != NIS_SUCCESS)
+			{
+			  if (__bind_next (dbp) != NIS_SUCCESS)
+			    {
+			      __bind_destroy (dbp);
+			      return NIS_SUCCESS;
+			    }
+			}
+		    }
+		  else
+		    break; /* No more servers to search in */
 		  goto again;
 		}
 	    case NIS_FINDDIRECTORY:
-	      if ((((fd_result *)xres)->status == NIS_NOTFOUND) ||
-		  (((fd_result *)xres)->status == NIS_NOSUCHNAME) ||
-		  (((fd_result *)xres)->status == NIS_NOT_ME))
+	      if ((((fd_result *)resp)->status == NIS_NOTFOUND) ||
+		  (((fd_result *)resp)->status == NIS_NOSUCHNAME) ||
+		  (((fd_result *)resp)->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;
-			  }
-		      }
+		    {
+		      while (__bind_connect (dbp) != NIS_SUCCESS)
+			{
+			  if (__bind_next (dbp) != NIS_SUCCESS)
+			    {
+			      __bind_destroy (dbp);
+			      return NIS_SUCCESS;
+			    }
+			}
+		    }
+		  else
+		    break; /* No more servers to search in */
 		  goto again;
 		}
 	      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 ((((log_result *)resp)->lr_status == NIS_NOTFOUND) ||
+		  (((log_result *)resp)->lr_status == NIS_NOSUCHNAME) ||
+		  (((log_result *)resp)->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;
-			  }
-		      }
+		    {
+		      while (__bind_connect (dbp) != NIS_SUCCESS)
+			{
+			  if (__bind_next (dbp) != NIS_SUCCESS)
+			    {
+			      __bind_destroy (dbp);
+			      return NIS_SUCCESS;
+			    }
+			}
+		    }
+		  else
+		    break; /* No more servers to search in */
 		  goto again;
 		}
 	      break;
@@ -523,7 +542,8 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags,
 
 nis_error
 __do_niscall (const_nis_name name, u_long prog, xdrproc_t xargs,
-	      caddr_t req, xdrproc_t xres, caddr_t resp, u_long flags)
+	      caddr_t req, xdrproc_t xres, caddr_t resp, u_long flags,
+	      nis_cb *cb)
 {
   nis_error retcode;
   directory_obj *dir = NULL;
@@ -561,7 +581,7 @@ __do_niscall (const_nis_name name, u_long prog, xdrproc_t xargs,
 
 
   retcode = __do_niscall2 (server, server_len, prog, xargs, req, xres, resp,
-			   flags);
+			   flags, cb);
 
   nis_free_directory (dir);
 
diff --git a/nis/nis_callback.c b/nis/nis_callback.c
new file mode 100644
index 0000000000..48c1950dd7
--- /dev/null
+++ b/nis/nis_callback.c
@@ -0,0 +1,339 @@
+/* Copyright (C) 1997 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
+
+   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
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the GNU C Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <rpc/pmap_clnt.h>
+#include <string.h>
+#include <memory.h>
+#include <syslog.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <rpcsvc/nis.h>
+#include <bits/libc-lock.h>
+
+#include "nis_intern.h"
+
+extern void get_myaddress (struct sockaddr_in *addr);
+
+/* Sorry, we are not able to make this threadsafe. Stupid. But some
+   functions doesn't send us a nis_result obj, so we don't have a
+   cookie. Maybe we could use keys for threads ? Have to learn more
+   about pthreads -- kukuk@vt.uni-paderborn.de */
+
+#define CB_PROG ((u_long)100302)
+#define CB_VERS ((u_long)1)
+#define CBPROC_RECEIVE ((u_long)1)
+#define CBPROC_FINISH ((u_long)2)
+#define CBPROC_ERROR ((u_long)3)
+
+typedef nis_object *obj_p;
+
+struct cback_data
+  {
+    struct
+      {
+	u_int entries_len;
+	obj_p *entries_val;
+      }
+    entries;
+  };
+typedef struct cback_data cback_data;
+
+static nis_cb *data;
+
+__libc_lock_define_initialized (static, callback)
+
+static bool_t xdr_cback_data (XDR *, cback_data *);
+
+static void
+cb_prog_1 (struct svc_req *rqstp, SVCXPRT *transp)
+{
+  union
+    {
+      cback_data cbproc_receive_1_arg;
+      nis_error cbproc_error_1_arg;
+    }
+  argument;
+  char *result;
+  xdrproc_t xdr_argument, xdr_result;
+  bool_t bool_result;
+
+  switch (rqstp->rq_proc)
+    {
+    case NULLPROC:
+      (void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *) NULL);
+      return;
+
+    case CBPROC_RECEIVE:
+      {
+	char name[NIS_MAXNAMELEN + 1];
+	u_long i;
+
+	xdr_argument = (xdrproc_t) xdr_cback_data;
+	xdr_result = (xdrproc_t) xdr_bool;
+	memset (&argument, 0, sizeof (argument));
+	if (!svc_getargs (transp, xdr_argument, (caddr_t) & argument))
+	  {
+	    svcerr_decode (transp);
+	    return;
+	  }
+	bool_result = FALSE;
+	for (i = 0; i < argument.cbproc_receive_1_arg.entries.entries_len; ++i)
+	  {
+	    snprintf (name, NIS_MAXNAMELEN, "%s.%s",
+	      argument.cbproc_receive_1_arg.entries.entries_val[i]->zo_name,
+	    argument.cbproc_receive_1_arg.entries.entries_val[i]->zo_domain);
+
+	    if ((data->callback)
+		(name, argument.cbproc_receive_1_arg.entries.entries_val[i],
+		 data->userdata))
+	      {
+		bool_result = TRUE;
+		data->nomore = 1;
+		data->result = NIS_SUCCESS;
+		break;
+	      }
+	  }
+	result = (char *) &bool_result;
+      }
+      break;
+    case CBPROC_FINISH:
+      xdr_argument = (xdrproc_t) xdr_void;
+      xdr_result = (xdrproc_t) xdr_void;
+      memset (&argument, 0, sizeof (argument));
+      if (!svc_getargs (transp, xdr_argument, (caddr_t) & argument))
+	{
+	  svcerr_decode (transp);
+	  return;
+	}
+      data->nomore = 1;
+      data->result = NIS_SUCCESS;
+      bool_result = TRUE;	/* to make gcc happy, not necessary */
+      result = (char *) &bool_result;
+      break;
+    case CBPROC_ERROR:
+      xdr_argument = (xdrproc_t) xdr_nis_error;
+      xdr_result = (xdrproc_t) xdr_void;
+      memset (&argument, 0, sizeof (argument));
+      if (!svc_getargs (transp, xdr_argument, (caddr_t) & argument))
+	{
+	  svcerr_decode (transp);
+	  return;
+	}
+      data->nomore = 1;
+      data->result = argument.cbproc_error_1_arg;
+      bool_result = TRUE;	/* to make gcc happy, not necessary */
+      result = (char *) &bool_result;
+      break;
+    default:
+      svcerr_noproc (transp);
+      return;
+    }
+  if (result != NULL && !svc_sendreply (transp, xdr_result, result))
+    svcerr_systemerr (transp);
+  if (!svc_freeargs (transp, xdr_argument, (caddr_t) & argument))
+    {
+      fputs (_ ("unable to free arguments"), stderr);
+      exit (1);
+    }
+  return;
+}
+
+static bool_t
+xdr_obj_p (XDR * xdrs, obj_p *objp)
+{
+  if (!xdr_pointer (xdrs, (char **) objp, sizeof (nis_object),
+		    (xdrproc_t) xdr_nis_object))
+    return FALSE;
+  return TRUE;
+}
+
+static bool_t
+xdr_cback_data (XDR *xdrs, cback_data *objp)
+{
+  if (!xdr_array (xdrs, (char **) &objp->entries.entries_val,
+		  (u_int *) & objp->entries.entries_len, ~0, sizeof (obj_p),
+		  (xdrproc_t) xdr_obj_p))
+    return FALSE;
+  return TRUE;
+}
+
+static nis_error
+internal_nis_do_callback (struct dir_binding *bptr, netobj *cookie,
+			  struct nis_cb *cb)
+{
+  /* Default timeout can be changed using clnt_control() */
+  static struct timeval TIMEOUT = {25, 0};
+#ifdef FD_SETSIZE
+  fd_set readfds;
+#else
+  int readfds;
+#endif /* def FD_SETSIZE */
+  struct timeval tv;
+  bool_t cb_is_running = FALSE;
+
+  data = cb;
+
+  for (;;)
+    {
+#ifdef FD_SETSIZE
+      readfds = svc_fdset;
+#else
+      readfds = svc_fds;
+#endif /* def FD_SETSIZE */
+      tv.tv_sec = 25;
+      tv.tv_usec = 0;
+      switch (select (_rpc_dtablesize (), &readfds, NULL, NULL, &tv))
+	{
+	case -1:
+	  if (errno == EINTR)
+	    continue;
+	  return NIS_CBERROR;
+	case 0:
+	  /* See if callback 'thread' in the server is still alive. */
+	  memset ((char *) &cb_is_running, 0, sizeof (cb_is_running));
+	  if (clnt_call (bptr->clnt, NIS_CALLBACK, (xdrproc_t) xdr_netobj,
+			 (caddr_t) cookie, (xdrproc_t) xdr_bool,
+			 (caddr_t) & cb_is_running, TIMEOUT) != RPC_SUCCESS)
+	    cb_is_running = FALSE;
+
+	  if (cb_is_running == FALSE)
+	    {
+	      syslog (LOG_ERR, "NIS+: callback timed out");
+	      return NIS_CBERROR;
+	    }
+	  break;
+	default:
+	  svc_getreqset (&readfds);
+	  if (data->nomore)
+	    return data->result;
+	}
+    }
+}
+
+nis_error
+__nis_do_callback (struct dir_binding *bptr, netobj *cookie,
+		   struct nis_cb *cb)
+{
+  nis_error result;
+
+  __libc_lock_lock (callback);
+
+  result = internal_nis_do_callback (bptr, cookie, cb);
+
+  __libc_lock_unlock (callback);
+
+  return result;
+}
+
+struct nis_cb *
+__nis_create_callback (int (*callback) (const_nis_name, const nis_object *,
+					const void *),
+		       const void *userdata, u_long flags)
+{
+  struct nis_cb *cb;
+  int sock = RPC_ANYSOCK;
+  struct sockaddr_in sin;
+  int len = sizeof (struct sockaddr_in);
+  char addr[NIS_MAXNAMELEN + 1];
+  unsigned short port;
+
+  cb = (struct nis_cb *) calloc (1, sizeof (struct nis_cb));
+  if (cb == NULL)
+    {
+      syslog (LOG_ERR, "NIS+: out of memory allocating callback");
+      return NULL;
+    }
+
+  cb->serv = (nis_server *) calloc (1, sizeof (nis_server));
+  if (cb->serv == NULL)
+    {
+      free (cb);
+      syslog (LOG_ERR, "NIS+: out of memory allocating callback");
+      return (NULL);
+    }
+  cb->serv->name = strdup (nis_local_host ());
+  cb->serv->ep.ep_val = (endpoint *) calloc (2, sizeof (endpoint));
+  cb->serv->ep.ep_len = 1;
+  cb->serv->ep.ep_val[0].family = strdup ("inet");
+  cb->callback = callback;
+  cb->userdata = userdata;
+
+  /* XXX Sometimes, we should add the public key of the user here ! */
+  cb->serv->key_type = NIS_PK_NONE;
+  cb->serv->pkey.n_bytes = NULL;
+  cb->serv->pkey.n_len = 0;
+
+  if (flags & USE_DGRAM)
+    {
+      cb->serv->ep.ep_val[0].proto = strdup ("udp");
+      cb->xprt = svcudp_bufcreate (sock, 100, 8192);
+    }
+  else
+    {
+      cb->serv->ep.ep_val[0].proto = strdup ("tcp");
+      cb->xprt = svctcp_create (sock, 100, 8192);
+    }
+  cb->sock = cb->xprt->xp_sock;
+  if (!svc_register (cb->xprt, CB_PROG, CB_VERS, cb_prog_1, 0))
+    {
+      xprt_unregister (cb->xprt);
+      svc_destroy (cb->xprt);
+      xdr_free ((xdrproc_t) xdr_nis_server, (char *) cb->serv);
+      free (cb->serv);
+      free (cb);
+      syslog (LOG_ERR, "NIS+: failed to register callback dispatcher");
+      return NULL;
+    }
+
+  if (getsockname (cb->sock, (struct sockaddr *) &sin, &len) == -1)
+    {
+      xprt_unregister (cb->xprt);
+      svc_destroy (cb->xprt);
+      xdr_free ((xdrproc_t) xdr_nis_server, (char *) cb->serv);
+      free (cb->serv);
+      free (cb);
+      syslog (LOG_ERR, "NIS+: failed to read local socket info");
+      return (NULL);
+    }
+  port = sin.sin_port;
+  get_myaddress (&sin);
+  snprintf (addr, sizeof (addr), "%s.%d.%d", inet_ntoa (sin.sin_addr),
+	    port & 0x00FF, (port & 0xFF00) >> 8);
+  cb->serv->ep.ep_val[0].uaddr = strdup (addr);
+
+  return cb;
+}
+
+nis_error
+__nis_destroy_callback (struct nis_cb *cb)
+{
+  xprt_unregister (cb->xprt);
+  svc_destroy (cb->xprt);
+  close (cb->sock);
+  xdr_free ((xdrproc_t) xdr_nis_server, (char *) cb->serv);
+  free (cb->serv);
+  free (cb);
+
+  return NIS_SUCCESS;
+}
diff --git a/nis/nis_checkpoint.c b/nis/nis_checkpoint.c
index ff0a9b37a7..15cdd58402 100644
--- a/nis/nis_checkpoint.c
+++ b/nis/nis_checkpoint.c
@@ -53,7 +53,7 @@ nis_checkpoint(const_nis_name dirname)
 	  if (__do_niscall2 (&res2->objects.objects_val[0].DI_data.do_servers.do_servers_val[i],
 			    1, NIS_CHECKPOINT, (xdrproc_t) xdr_nis_name,
 			    (caddr_t) &dirname, (xdrproc_t) xdr_cp_result,
-			    (caddr_t) &cpres, 0) != RPC_SUCCESS)
+			    (caddr_t) &cpres, 0, NULL) != RPC_SUCCESS)
 	    res->status = NIS_RPCERROR;
 	  else
 	    {
diff --git a/nis/nis_file.c b/nis/nis_file.c
index 84818519b0..c32d54a622 100644
--- a/nis/nis_file.c
+++ b/nis/nis_file.c
@@ -91,8 +91,6 @@ nis_write_obj (const char *name, const nis_object *obj)
     return FALSE;
 
   xdrstdio_create (&xdrs, out, XDR_ENCODE);
-  /* XXX The following cast is bad!  Shouldn't the XDR functions take
-     pointers to const objects?  */
   if (!xdr_nis_object (&xdrs, (nis_object *) obj))
     return FALSE;
 
diff --git a/nis/nis_findserv.c b/nis/nis_findserv.c
index 5ab369c84a..84508177e6 100644
--- a/nis/nis_findserv.c
+++ b/nis/nis_findserv.c
@@ -86,9 +86,10 @@ __pmap_getport (struct sockaddr_in *address, u_long program,
 	  rpc_createerr.cf_stat = RPC_PMAPFAILURE;
 	  clnt_geterr (client, &rpc_createerr.cf_error);
 	}
-      else if (port == 0)
+      else
 	{
-	  rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
+	  if (port == 0)
+	    rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
 	}
       CLNT_DESTROY (client);
     }
@@ -97,39 +98,7 @@ __pmap_getport (struct sockaddr_in *address, u_long program,
   return port;
 }
 
-/* Transmit to NULLPROC, return immediately. */
-static void *
-nis_null_3_send (void *argp, CLIENT * clnt)
-{
-  static char clnt_res;
-  struct timeval TIMEOUT = {0, 0};
-
-  memset ((char *) &clnt_res, 0, sizeof (clnt_res));
-  if (clnt_call (clnt, NULLPROC,
-		 (xdrproc_t) xdr_void, (caddr_t) argp,
-		 (xdrproc_t) xdr_void, (caddr_t) & clnt_res,
-		 TIMEOUT) != RPC_SUCCESS)
-    return NULL;
-  return (void *) &clnt_res;
-}
-
-/* Receive request from NULLPROC asynchronously. */
-static void *
-nis_null_3_recv (void *argp, CLIENT * clnt)
-{
-  static char clnt_res;
-  struct timeval TIMEOUT = {0, 0};
-
-  memset ((char *) &clnt_res, 0, sizeof (clnt_res));
-  if (clnt_call (clnt, NULLPROC,
-		 (xdrproc_t) NULL, (caddr_t) argp,
-		 (xdrproc_t) xdr_void, (caddr_t) & clnt_res,
-		 TIMEOUT) != RPC_SUCCESS)
-    return NULL;
-  return (void *) &clnt_res;
-}
-
-/* This is now the public functions, which should find the fastest server */
+/* This is now the public function, which should find the fastest server */
 
 struct findserv_req
 {
@@ -142,13 +111,15 @@ struct findserv_req
 long
 __nis_findfastest (dir_binding * bind)
 {
-  struct timeval TIMEOUT = {5, 0};
+  const struct timeval TIMEOUT50 = {5, 0};
+  const struct timeval TIMEOUT00 = {0, 0};
   struct findserv_req **pings;
-  struct sockaddr_in sin;
+  struct sockaddr_in sin, saved_sin;
   int found = -1;
-  uint32_t xid_seed, xid_lookup;
+  u_int32_t xid_seed, xid_lookup;
   int sock, dontblock = 1;
   CLIENT *clnt;
+  char clnt_res;
   void *foo = NULL;
   u_long i, j, pings_count, pings_max;
   struct cu_data *cu;
@@ -157,14 +128,16 @@ __nis_findfastest (dir_binding * bind)
 					   for multihomed hosts */
   pings_count = 0;
   pings = malloc (sizeof (struct findserv_req *) * pings_max);
-  xid_seed = (uint32_t) (time (NULL) ^ getpid ());
+  xid_seed = (u_int32_t) (time (NULL) ^ getpid ());
 
   memset (&sin, '\0', sizeof (sin));
   sin.sin_family = AF_INET;
   for (i = 0; i < bind->server_len; i++)
     for (j = 0; j < bind->server_val[i].ep.ep_len; ++j)
       if (strcmp (bind->server_val[i].ep.ep_val[j].family, "inet") == 0)
-	if (strcmp (bind->server_val[i].ep.ep_val[j].proto, "-") == 0)
+	if ((bind->server_val[i].ep.ep_val[j].proto == NULL) ||
+	    (strcmp (bind->server_val[i].ep.ep_val[j].proto, "-") == 0) ||
+	    (strlen (bind->server_val[i].ep.ep_val[j].proto) == 0))
 	  {
 	    sin.sin_addr.s_addr =
 	      inetstr2int (bind->server_val[i].ep.ep_val[j].uaddr);
@@ -184,6 +157,7 @@ __nis_findfastest (dir_binding * bind)
 	    pings[pings_count] = calloc (1, sizeof (struct findserv_req));
 	    memcpy ((char *) &pings[pings_count]->sin, (char *) &sin,
 		    sizeof (sin));
+	    memcpy ((char *)&saved_sin, (char *)&sin, sizeof(sin));
 	    pings[pings_count]->xid = xid_seed;
 	    pings[pings_count]->server_nr = i;
 	    pings[pings_count]->server_ep = j;
@@ -200,7 +174,7 @@ __nis_findfastest (dir_binding * bind)
 
   /* Create RPC handle */
   sock = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
-  clnt = clntudp_create (&sin, NIS_PROG, NIS_VERSION, TIMEOUT, &sock);
+  clnt = clntudp_create (&saved_sin, NIS_PROG, NIS_VERSION, TIMEOUT50, &sock);
   if (clnt == NULL)
     {
       close (sock);
@@ -211,8 +185,7 @@ __nis_findfastest (dir_binding * bind)
     }
   clnt->cl_auth = authunix_create_default ();
   cu = (struct cu_data *) clnt->cl_private;
-  TIMEOUT.tv_sec = 0;
-  clnt_control (clnt, CLSET_TIMEOUT, (char *) &TIMEOUT);
+  clnt_control (clnt, CLSET_TIMEOUT, (char *) &TIMEOUT00);
   ioctl (sock, FIONBIO, &dontblock);
 
   /* Send to all servers the NULLPROC */
@@ -220,13 +193,17 @@ __nis_findfastest (dir_binding * bind)
     {
       /* clntudp_call() will increment, subtract one */
       *((u_int32_t *) (cu->cu_outbuf)) = pings[i]->xid - 1;
-      bcopy ((char *) &pings[i]->sin, (char *) &cu->cu_raddr,
-	     sizeof (struct sockaddr_in));
-      nis_null_3_send (foo, clnt);
+      memcpy ((char *) &cu->cu_raddr, (char *) &pings[i]->sin,
+	      sizeof (struct sockaddr_in));
+      /* Transmit to NULLPROC, return immediately. */
+      clnt_call (clnt, NULLPROC, (xdrproc_t) xdr_void, (caddr_t) foo,
+		 (xdrproc_t) xdr_void, (caddr_t) & clnt_res, TIMEOUT00);
     }
 
-  /* Receive reply */
-  nis_null_3_recv (foo, clnt);
+  /* Receive reply from NULLPROC asynchronously */
+  memset ((char *) &clnt_res, 0, sizeof (clnt_res));
+  clnt_call (clnt, NULLPROC, (xdrproc_t) NULL, (caddr_t) foo,
+	     (xdrproc_t) xdr_void, (caddr_t) &clnt_res, TIMEOUT00);
 
   xid_lookup = *((u_int32_t *) (cu->cu_inbuf));
   for (i = 0; i < pings_count; i++)
diff --git a/nis/nis_intern.h b/nis/nis_intern.h
index 9852c24d55..ce88f0790d 100644
--- a/nis/nis_intern.h
+++ b/nis/nis_intern.h
@@ -42,16 +42,28 @@ struct dir_binding
 };
 typedef struct dir_binding dir_binding;
 
+struct nis_cb
+  {
+    nis_server *serv;
+    SVCXPRT *xprt;
+    int sock;
+    int nomore;
+    nis_error result;
+    int (*callback) (const_nis_name, const nis_object *, const void *);
+    const void *userdata;
+  };
+typedef struct nis_cb nis_cb;
+
 extern unsigned long inetstr2int __P ((const char *str));
 extern long __nis_findfastest __P ((dir_binding *bind));
 extern nis_error __do_niscall2 __P ((const nis_server *serv, u_int serv_len,
 				     u_long prog, xdrproc_t xargs, caddr_t req,
 				     xdrproc_t xres, caddr_t resp,
-				     u_long flags));
+				     u_long flags, nis_cb *cb));
 extern nis_error __do_niscall __P ((const_nis_name name, u_long prog,
 				    xdrproc_t xargs, caddr_t req,
 				    xdrproc_t xres, caddr_t resp,
-				    u_long flags));
+				    u_long flags, nis_cb *cb));
 extern AUTH *authdes_pk_create __P ((const char *, const netobj *, u_int,
 				     struct sockaddr *, des_block *));
 
@@ -59,6 +71,14 @@ extern AUTH *authdes_pk_create __P ((const char *, const netobj *, u_int,
 extern directory_obj *__cache_search __P ((const_nis_name name));
 extern nis_error __cache_add __P ((fd_result *));
 
+/* NIS+ callback */
+extern nis_error __nis_do_callback __P ((struct dir_binding *bptr,
+					 netobj *cookie, struct nis_cb *cb));
+extern struct nis_cb *__nis_create_callback
+      __P ((int (*callback)(const_nis_name, const nis_object *, const void *),
+	    const void *userdata, u_long flags));
+extern nis_error __nis_destroy_callback __P ((struct nis_cb *cb));
+
 __END_DECLS
 
 #endif
diff --git a/nis/nis_lookup.c b/nis/nis_lookup.c
index 6224b1f2c4..bdce5d5a0a 100644
--- a/nis/nis_lookup.c
+++ b/nis/nis_lookup.c
@@ -63,7 +63,7 @@ nis_lookup (const_nis_name name, const u_long flags)
 			     (xdrproc_t) xdr_ns_request,
 			     (caddr_t) & req,
 			     (xdrproc_t) xdr_nis_result,
-			     (caddr_t) res, flags);
+			     (caddr_t) res, flags, NULL);
       if (status != NIS_SUCCESS)
 	res->status = status;
 
diff --git a/nis/nis_mkdir.c b/nis/nis_mkdir.c
index 685dae64aa..b762e93f27 100644
--- a/nis/nis_mkdir.c
+++ b/nis/nis_mkdir.c
@@ -30,7 +30,7 @@ nis_mkdir (const_nis_name dir, const nis_server *server)
     {
       if (__do_niscall (dir, NIS_MKDIR, (xdrproc_t) xdr_nis_name,
 			(caddr_t) &dir, (xdrproc_t) xdr_nis_error,
-			(caddr_t) &res, 0) != RPC_SUCCESS)
+			(caddr_t) &res, 0, NULL) != RPC_SUCCESS)
 	return NIS_RPCERROR;
     }
   else
@@ -38,7 +38,7 @@ nis_mkdir (const_nis_name dir, const nis_server *server)
       if (__do_niscall2 (server, 1, NIS_MKDIR,
 			 (xdrproc_t) xdr_nis_name,
 			 (caddr_t) &dir, (xdrproc_t) xdr_nis_error,
-			 (caddr_t) &res, 0) != RPC_SUCCESS)
+			 (caddr_t) &res, 0, NULL) != RPC_SUCCESS)
 	return NIS_RPCERROR;
     }
 
diff --git a/nis/nis_modify.c b/nis/nis_modify.c
index 04572794a8..739ae0c351 100644
--- a/nis/nis_modify.c
+++ b/nis/nis_modify.c
@@ -58,7 +58,8 @@ nis_modify (const_nis_name name, const nis_object *obj)
 
   if ((status = __do_niscall (name, NIS_MODIFY, (xdrproc_t) xdr_ns_request,
 			      (caddr_t) & req, (xdrproc_t) xdr_nis_result,
-			      (caddr_t) res, MASTER_ONLY)) != RPC_SUCCESS)
+			      (caddr_t) res, MASTER_ONLY,
+			      NULL)) != RPC_SUCCESS)
     res->status = status;
 
   req.ns_object.ns_object_val[0].zo_name = p1;
diff --git a/nis/nis_ping.c b/nis/nis_ping.c
index 4ec34ce4c0..a06dfdee8d 100644
--- a/nis/nis_ping.c
+++ b/nis/nis_ping.c
@@ -60,7 +60,7 @@ nis_ping (const_nis_name dirname, u_long utime, const nis_object *dirobj)
     __do_niscall2 (&obj->DI_data.do_servers.do_servers_val[i], 1,
 		   NIS_PING, (xdrproc_t) xdr_ping_args,
 		   (caddr_t) &args, (xdrproc_t) xdr_void,
-		   (caddr_t) NULL, 0);
+		   (caddr_t) NULL, 0, NULL);
   if (res)
     nis_freeresult (res);
 }
diff --git a/nis/nis_remove.c b/nis/nis_remove.c
index e6aed00393..2fa9ecc353 100644
--- a/nis/nis_remove.c
+++ b/nis/nis_remove.c
@@ -46,7 +46,8 @@ nis_remove (const_nis_name name, const nis_object *obj)
 
   if ((status = __do_niscall (name, NIS_REMOVE, (xdrproc_t) xdr_ns_request,
 			      (caddr_t) & req, (xdrproc_t) xdr_nis_result,
-			      (caddr_t) res, MASTER_ONLY)) != RPC_SUCCESS)
+			      (caddr_t) res, MASTER_ONLY,
+			      NULL)) != RPC_SUCCESS)
     res->status = status;
 
   nis_destroy_object (req.ns_object.ns_object_val);
diff --git a/nis/nis_rmdir.c b/nis/nis_rmdir.c
index a8c239ec70..adf5924ada 100644
--- a/nis/nis_rmdir.c
+++ b/nis/nis_rmdir.c
@@ -30,7 +30,7 @@ nis_rmdir (const_nis_name dir, const nis_server *server)
     {
       if (__do_niscall (dir, NIS_RMDIR, (xdrproc_t) xdr_nis_name,
 			(caddr_t) &dir, (xdrproc_t) xdr_nis_error,
-			(caddr_t) &res, 0) != RPC_SUCCESS)
+			(caddr_t) &res, 0, NULL) != RPC_SUCCESS)
 	return NIS_RPCERROR;
     }
   else
@@ -38,7 +38,7 @@ nis_rmdir (const_nis_name dir, const nis_server *server)
       if (__do_niscall2 (server, 1, NIS_RMDIR,
 			 (xdrproc_t) xdr_nis_name,
 			 (caddr_t) &dir, (xdrproc_t) xdr_nis_error,
-			 (caddr_t) &res, 0) != RPC_SUCCESS)
+			 (caddr_t) &res, 0, NULL) != RPC_SUCCESS)
 	return NIS_RPCERROR;
     }
 
diff --git a/nis/nis_server.c b/nis/nis_server.c
index 0df608a153..7eb785423a 100644
--- a/nis/nis_server.c
+++ b/nis/nis_server.c
@@ -39,7 +39,7 @@ nis_servstate (const nis_server *serv, const nis_tag *tags,
 
   if (__do_niscall2 (serv, 1, NIS_SERVSTATE, (xdrproc_t) xdr_nis_taglist,
 		     (caddr_t) &taglist, (xdrproc_t) xdr_nis_taglist,
-		     (caddr_t) &tagres, 0) != RPC_SUCCESS)
+		     (caddr_t) &tagres, 0, NULL) != RPC_SUCCESS)
     return NIS_RPCERROR;
 
   *result = tagres.tags.tags_val;
@@ -65,7 +65,7 @@ nis_stats (const nis_server *serv, const nis_tag *tags,
 
   if (__do_niscall2 (serv, 1, NIS_STATUS, (xdrproc_t) xdr_nis_taglist,
 		     (caddr_t) &taglist, (xdrproc_t) xdr_nis_taglist,
-		     (caddr_t) &tagres, 0) != RPC_SUCCESS)
+		     (caddr_t) &tagres, 0, NULL) != RPC_SUCCESS)
     return NIS_RPCERROR;
 
   *result = tagres.tags.tags_val;
diff --git a/nis/nis_table.c b/nis/nis_table.c
index a3bfa2c0cc..3efba6084e 100644
--- a/nis/nis_table.c
+++ b/nis/nis_table.c
@@ -148,7 +148,7 @@ __create_ib_request (const_nis_name name, struct ib_request *ibreq,
 
   ibreq->ibr_flags = (flags & (RETURN_RESULT | ADD_OVERWRITE | REM_MULTIPLE |
 			       MOD_SAMEOBJ | ADD_RESERVED | REM_RESERVED |
-			       MOD_EXCLUSIVE));
+			       MOD_EXCLUSIVE | ALL_RESULTS));
   ibreq->ibr_obj.ibr_obj_len = 0;
   ibreq->ibr_obj.ibr_obj_val = NULL;
   ibreq->ibr_cbhost.ibr_cbhost_len = 0;
@@ -170,11 +170,12 @@ nis_list (const_nis_name name, u_long flags,
   nis_result *res = NULL;
   struct ib_request ibreq;
   int status;
-  int count_links = 0;	    /* We will only follow 16 links! */
+  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;
 
   res = calloc (1, sizeof (nis_result));
 
@@ -197,95 +198,170 @@ nis_list (const_nis_name name, u_long flags,
       ibreq.ibr_name = strdup (names[name_nr]);
     }
   else
-    names = namebuf;
+    {
+      names = namebuf;
+      names[name_nr] = ibreq.ibr_name;
+    }
 
-  while (!done)
+  cb = NULL;
+
+  if (flags & FOLLOW_PATH)
     {
-      memset (res, '\0', sizeof (nis_result));
+      nis_result *lres;
+      u_long newflags = flags & ~FOLLOW_PATH;
+      char table_path[NIS_MAXPATH + 1];
+      char *ntable, *p;
+      u_long done = 0, failures = 0;
 
-      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);
-      if (status != NIS_SUCCESS)
-	res->status = status;
+      memset (res, '\0', sizeof (nis_result));
 
-      switch (res->status)
+      while (names[name_nr] != NULL && !done)
 	{
-	case NIS_PARTIAL:
-	case NIS_SUCCESS:
-	case NIS_S_SUCCESS:
-	  if (__type_of(NIS_RES_OBJECT (res)) == LINK_OBJ &&
-	      flags & FOLLOW_LINKS) /* We are following links */
+	  lres = nis_lookup (names[name_nr], newflags);
+	  if (lres == NULL || lres->status != NIS_SUCCESS)
+	    {
+	      res->status = lres->status;
+	      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)) != TABLE_OBJ)
+	    {
+	      nis_freeresult (lres);
+	      res->status = NIS_INVALIDOBJ;
+	      break;
+	    }
+
+	  /* Save the path, discard everything else.  */
+	  snprintf (table_path, NIS_MAXPATH, "%s:%s", names[name_nr],
+		    NIS_RES_OBJECT (lres)->TA_data.ta_path);
+	  nis_freeresult (lres);
+	  free (res);
+
+	  p = table_path;
+
+	  while (((ntable = strsep (&p, ":")) != NULL) && !done)
 	    {
-	      /* if we hit the link limit, bail */
-	      if (count_links > NIS_MAXLINKS)
+	      /* Do the job recursive here!  */
+	      res = nis_list (name, newflags, callback, userdata);
+	      if (res == NULL)
+		return NULL;
+	      switch (res->status)
 		{
-		  res->status = NIS_LINKNAMEERROR;
-		  ++done;
+		case NIS_SUCCESS:
+		case NIS_CBRESULTS:
+		  if (!(flags & ALL_RESULTS))
+		    done = 1;
+		  break;
+		default:
+		  if (flags & ALL_RESULTS)
+		    failures++;
+		  else
+		    done = 1;
 		  break;
-		}
-	      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)
-		  {
-		    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;
 		  }
-	      nis_freeresult (res);
-	      res = calloc (1, sizeof (nis_result));
 	    }
-	  else
-	    ++done;
-	  break;
-	case NIS_CBRESULTS:
-	  /* XXX Implement CALLBACK here ! */
-	  ++done;
+	  if (res->status == NIS_SUCCESS && failures)
+	    res->status = NIS_S_SUCCESS;
+	  if (res->status == NIS_NOTFOUND && failures)
+	    res->status = NIS_S_NOTFOUND;
 	  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)
+	}
+    }
+  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)
+	    res->status = status;
+
+	  switch (res->status)
 	    {
-	      free (ibreq.ibr_name);
-	      res->status = NIS_LINKNAMEERROR;
+	    case NIS_PARTIAL:
+	    case NIS_SUCCESS:
+	    case NIS_S_SUCCESS:
+	      if (__type_of (NIS_RES_OBJECT (res)) == LINK_OBJ &&
+		  flags & FOLLOW_LINKS)		/* We are following links.  */
+		{
+		  /* If we hit the link limit, bail.  */
+		  if (count_links > NIS_MAXLINKS)
+		    {
+		      res->status = NIS_LINKNAMEERROR;
+		      ++done;
+		      break;
+		    }
+		  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)
+		      {
+			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;
+		      }
+		  nis_freeresult (res);
+		  res = calloc (1, sizeof (nis_result));
+		}
+	      else
+		++done;
+	      break;
+	    case NIS_CBRESULTS:
+	      /* Calback is handled in nis_call.c (__do_niscall2).  */
 	      ++done;
 	      break;
-	    }
-	  ++name_nr;
-	  if (names[name_nr] == NULL)
-	    {
+	    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);
+		  res->status = NIS_LINKNAMEERROR;
+		  ++done;
+		  break;
+		}
+	      ++name_nr;
+	      if (names[name_nr] == NULL)
+		{
+		  ++done;
+		  break;
+		}
+	      ibreq.ibr_name = names[name_nr];
+	      break;
 	    }
-	  ibreq.ibr_name = names[name_nr];
-	  break;
 	}
-    }
+    }				/* End of not FOLLOW_PATH.  */
 
   if (names != namebuf)
     nis_freenames (names);
 
   nis_free_request (&ibreq);
 
-  if (callback != NULL &&
-      (res->status == NIS_SUCCESS || res->status == NIS_S_SUCCESS))
-    {
-      unsigned int i;
-
-      for (i = 0; i < res->objects.objects_len; ++i)
-	if ((*callback) (name, &(res->objects.objects_val)[i], userdata) != 0)
-	  break;
-    }
+  if (cb)
+    __nis_destroy_callback (cb);
 
   return res;
 }
@@ -298,8 +374,8 @@ nis_add_entry (const_nis_name name, const nis_object *obj,
   nis_error status;
   struct ib_request ibreq;
   char *p1, *p2, *p3, *p4;
-  char buf1 [strlen (name) + 20];
-  char buf4 [strlen (name) + 20];
+  char buf1[strlen (name) + 20];
+  char buf4[strlen (name) + 20];
 
   res = calloc (1, sizeof (nis_result));
 
@@ -332,9 +408,9 @@ nis_add_entry (const_nis_name name, const nis_object *obj,
 
   if ((status = __do_niscall (ibreq.ibr_name, NIS_IBADD,
 			      (xdrproc_t) xdr_ib_request,
-			      (caddr_t) &ibreq,
+			      (caddr_t) & ibreq,
 			      (xdrproc_t) xdr_nis_result,
-			      (caddr_t) res, 0)) != NIS_SUCCESS)
+			      (caddr_t) res, 0, NULL)) != NIS_SUCCESS)
     res->status = status;
 
   ibreq.ibr_obj.ibr_obj_val->zo_name = p1;
@@ -355,8 +431,8 @@ nis_modify_entry (const_nis_name name, const nis_object *obj,
   nis_error status;
   struct ib_request ibreq;
   char *p1, *p2, *p3, *p4;
-  char buf1 [strlen (name) + 20];
-  char buf4 [strlen (name) + 20];
+  char buf1[strlen (name) + 20];
+  char buf4[strlen (name) + 20];
 
   res = calloc (1, sizeof (nis_result));
 
@@ -390,7 +466,7 @@ nis_modify_entry (const_nis_name name, const nis_object *obj,
   if ((status = __do_niscall (ibreq.ibr_name, NIS_IBMODIFY,
 			      (xdrproc_t) xdr_ib_request,
 			      (caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
-			      (caddr_t) res, 0)) != NIS_SUCCESS)
+			      (caddr_t) res, 0, NULL)) != NIS_SUCCESS)
     res->status = status;
 
   ibreq.ibr_obj.ibr_obj_val->zo_name = p1;
@@ -429,7 +505,7 @@ nis_remove_entry (const_nis_name name, const nis_object *obj,
   if ((status = __do_niscall (ibreq.ibr_name, NIS_IBREMOVE,
 			      (xdrproc_t) xdr_ib_request,
 			      (caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
-			      (caddr_t) res, 0)) != NIS_SUCCESS)
+			      (caddr_t) res, 0, NULL)) != NIS_SUCCESS)
     res->status = status;
 
   nis_free_request (&ibreq);
@@ -454,8 +530,8 @@ nis_first_entry (const_nis_name name)
 
   if ((status = __do_niscall (ibreq.ibr_name, NIS_IBFIRST,
 			      (xdrproc_t) xdr_ib_request,
-			      (caddr_t) &ibreq, (xdrproc_t) xdr_nis_result,
-			      (caddr_t) res, 0)) != NIS_SUCCESS)
+			      (caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
+			      (caddr_t) res, 0, NULL)) != NIS_SUCCESS)
     res->status = status;
 
   nis_free_request (&ibreq);
@@ -493,8 +569,8 @@ nis_next_entry (const_nis_name name, const netobj *cookie)
 
   if ((status = __do_niscall (ibreq.ibr_name, NIS_IBNEXT,
 			      (xdrproc_t) xdr_ib_request,
-			      (caddr_t) &ibreq, (xdrproc_t) xdr_nis_result,
-			      (caddr_t) res, 0)) != NIS_SUCCESS)
+			      (caddr_t) & ibreq, (xdrproc_t) xdr_nis_result,
+			      (caddr_t) res, 0, NULL)) != NIS_SUCCESS)
     res->status = status;
 
   nis_free_request (&ibreq);
diff --git a/nis/nis_util.c b/nis/nis_util.c
index b6eef9b227..fd9ff26bf5 100644
--- a/nis/nis_util.c
+++ b/nis/nis_util.c
@@ -31,15 +31,15 @@ __nis_finddirectory (directory_obj *dir, const_nis_name name)
   fd_args.dir_name = strdup (name);
   fd_args.requester = nis_local_host();
   fd_res = calloc (1, sizeof (fd_result));
-      
-  if ((status = __do_niscall2 (dir->do_servers.do_servers_val, 
-			       dir->do_servers.do_servers_len, 
+
+  if ((status = __do_niscall2 (dir->do_servers.do_servers_val,
+			       dir->do_servers.do_servers_len,
 			       NIS_FINDDIRECTORY, (xdrproc_t) xdr_fd_args,
 			       (caddr_t) &fd_args, (xdrproc_t) xdr_fd_result,
-			       (caddr_t) fd_res, 
-			       NO_AUTHINFO|USE_DGRAM)) != NIS_SUCCESS)
+			       (caddr_t) fd_res,
+			       NO_AUTHINFO|USE_DGRAM, NULL)) != NIS_SUCCESS)
     fd_res->status = status;
-      
+
   return fd_res;
 }
 
@@ -59,15 +59,15 @@ __nis_hash (const void *keyarg, register size_t len)
   register const u_char *key;
   register size_t loop;
   register u_int32_t h;
-  
+
 #define HASHC   h = *key++ + 65599 * h
-  
+
   h = 0;
   key = keyarg;
-  if (len > 0) 
+  if (len > 0)
     {
       loop = (len + 8 - 1) >> 3;
-      switch (len & (8 - 1)) 
+      switch (len & (8 - 1))
 	{
 	case 0:
 	  do {
@@ -98,4 +98,3 @@ __nis_hash (const void *keyarg, register size_t len)
     }
   return (h);
 }
-
diff --git a/nis/nss_nisplus/nisplus-publickey.c b/nis/nss_nisplus/nisplus-publickey.c
index 72ed1a5044..aa2a6f0c3a 100644
--- a/nis/nss_nisplus/nisplus-publickey.c
+++ b/nis/nss_nisplus/nisplus-publickey.c
@@ -162,8 +162,8 @@ _nss_nisplus_getsecretkey (const char *netname, char *skey, char *passwd)
 
   len = ENTRY_LEN (res->objects.objects_val, 4);
   memcpy (buf, ENTRY_VAL (res->objects.objects_val,4), len);
-  skey[len] = 0;
-  cptr = strchr (skey, ':');
+  buf[len] = '\0';
+  cptr = strchr (buf, ':');
   if (cptr)
     cptr[0] = '\0';
   nis_freeresult (res);
diff --git a/nis/rpcsvc/nis.h b/nis/rpcsvc/nis.h
index b91ce19903..f94b96cba4 100644
--- a/nis/rpcsvc/nis.h
+++ b/nis/rpcsvc/nis.h
@@ -28,10 +28,14 @@
  * Mountain View, California  94043
  */
 
-#ifndef _NIS_H_RPCGEN
-#define _NIS_H_RPCGEN
+#ifndef _RPCSVC_NIS_H
+#define _RPCSVC_NIS_H 1
 
+#include <features.h>
 #include <rpc/rpc.h>
+#include <rpcsvc/nis_tags.h>
+
+__BEGIN_DECLS
 
 /*
  *	nis.h
@@ -48,8 +52,7 @@
  *	       Makefile target nis.h)
  *
  */
-#include <rpcsvc/nis_tags.h>
-#include <rpc/xdr.h>
+
 #pragma ident	"@(#)nis_object.x	1.7	92/07/14 SMI"
 
 #ifndef __nis_object_h
@@ -77,24 +80,10 @@ struct nis_attr {
 	} zattr_val;
 };
 typedef struct nis_attr nis_attr;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nis_attr(XDR *, nis_attr*);
-#elif __STDC__
-extern  bool_t xdr_nis_attr(XDR *, nis_attr*);
-#else /* Old Style C */
-bool_t xdr_nis_attr();
-#endif /* Old Style C */
-
+extern  bool_t xdr_nis_attr __P ((XDR *, nis_attr*));
 
 typedef char *nis_name;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nis_name(XDR *, nis_name*);
-#elif __STDC__
-extern  bool_t xdr_nis_name(XDR *, nis_name*);
-#else /* Old Style C */
-bool_t xdr_nis_name();
-#endif /* Old Style C */
-
+extern  bool_t xdr_nis_name __P ((XDR *, nis_name*));
 
 enum zotypes {
 	BOGUS_OBJ = 0,
@@ -107,14 +96,7 @@ enum zotypes {
 	PRIVATE_OBJ = 7,
 };
 typedef enum zotypes zotypes;
-#ifdef __cplusplus
-extern "C" bool_t xdr_zotypes(XDR *, zotypes*);
-#elif __STDC__
-extern  bool_t xdr_zotypes(XDR *, zotypes*);
-#else /* Old Style C */
-bool_t xdr_zotypes();
-#endif /* Old Style C */
-
+extern  bool_t xdr_zotypes __P ((XDR *, zotypes*));
 
 enum nstype {
 	UNKNOWN = 0,
@@ -128,28 +110,14 @@ enum nstype {
 	CDS = 8,
 };
 typedef enum nstype nstype;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nstype(XDR *, nstype*);
-#elif __STDC__
-extern  bool_t xdr_nstype(XDR *, nstype*);
-#else /* Old Style C */
-bool_t xdr_nstype();
-#endif /* Old Style C */
-
+extern  bool_t xdr_nstype __P ((XDR *, nstype*));
 
 struct oar_mask {
 	u_long oa_rights;
 	zotypes oa_otype;
 };
 typedef struct oar_mask oar_mask;
-#ifdef __cplusplus
-extern "C" bool_t xdr_oar_mask(XDR *, oar_mask*);
-#elif __STDC__
-extern  bool_t xdr_oar_mask(XDR *, oar_mask*);
-#else /* Old Style C */
-bool_t xdr_oar_mask();
-#endif /* Old Style C */
-
+extern  bool_t xdr_oar_mask __P ((XDR *, oar_mask*));
 
 struct endpoint {
 	char *uaddr;
@@ -157,14 +125,7 @@ struct endpoint {
 	char *proto;
 };
 typedef struct endpoint endpoint;
-#ifdef __cplusplus
-extern "C" bool_t xdr_endpoint(XDR *, endpoint*);
-#elif __STDC__
-extern  bool_t xdr_endpoint(XDR *, endpoint*);
-#else /* Old Style C */
-bool_t xdr_endpoint();
-#endif /* Old Style C */
-
+extern  bool_t xdr_endpoint __P ((XDR *, endpoint*));
 
 struct nis_server {
 	nis_name name;
@@ -176,14 +137,7 @@ struct nis_server {
 	netobj pkey;
 };
 typedef struct nis_server nis_server;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nis_server(XDR *, nis_server*);
-#elif __STDC__
-extern  bool_t xdr_nis_server(XDR *, nis_server*);
-#else /* Old Style C */
-bool_t xdr_nis_server();
-#endif /* Old Style C */
-
+extern  bool_t xdr_nis_server __P ((XDR *, nis_server*));
 
 struct directory_obj {
 	nis_name do_name;
@@ -199,13 +153,7 @@ struct directory_obj {
 	} do_armask;
 };
 typedef struct directory_obj directory_obj;
-#ifdef __cplusplus
-extern "C" bool_t xdr_directory_obj(XDR *, directory_obj*);
-#elif __STDC__
-extern  bool_t xdr_directory_obj(XDR *, directory_obj*);
-#else /* Old Style C */
-bool_t xdr_directory_obj();
-#endif /* Old Style C */
+extern  bool_t xdr_directory_obj __P ((XDR *, directory_obj*));
 
 #define EN_BINARY 1
 #define EN_CRYPT 2
@@ -221,14 +169,7 @@ struct entry_col {
 	} ec_value;
 };
 typedef struct entry_col entry_col;
-#ifdef __cplusplus
-extern "C" bool_t xdr_entry_col(XDR *, entry_col*);
-#elif __STDC__
-extern  bool_t xdr_entry_col(XDR *, entry_col*);
-#else /* Old Style C */
-bool_t xdr_entry_col();
-#endif /* Old Style C */
-
+extern  bool_t xdr_entry_col __P ((XDR *, entry_col*));
 
 struct entry_obj {
 	char *en_type;
@@ -238,14 +179,7 @@ struct entry_obj {
 	} en_cols;
 };
 typedef struct entry_obj entry_obj;
-#ifdef __cplusplus
-extern "C" bool_t xdr_entry_obj(XDR *, entry_obj*);
-#elif __STDC__
-extern  bool_t xdr_entry_obj(XDR *, entry_obj*);
-#else /* Old Style C */
-bool_t xdr_entry_obj();
-#endif /* Old Style C */
-
+extern  bool_t xdr_entry_obj __P ((XDR *, entry_obj*));
 
 struct group_obj {
 	u_long gr_flags;
@@ -255,14 +189,7 @@ struct group_obj {
 	} gr_members;
 };
 typedef struct group_obj group_obj;
-#ifdef __cplusplus
-extern "C" bool_t xdr_group_obj(XDR *, group_obj*);
-#elif __STDC__
-extern  bool_t xdr_group_obj(XDR *, group_obj*);
-#else /* Old Style C */
-bool_t xdr_group_obj();
-#endif /* Old Style C */
-
+extern  bool_t xdr_group_obj __P ((XDR *, group_obj*));
 
 struct link_obj {
 	zotypes li_rtype;
@@ -273,13 +200,7 @@ struct link_obj {
 	nis_name li_name;
 };
 typedef struct link_obj link_obj;
-#ifdef __cplusplus
-extern "C" bool_t xdr_link_obj(XDR *, link_obj*);
-#elif __STDC__
-extern  bool_t xdr_link_obj(XDR *, link_obj*);
-#else /* Old Style C */
-bool_t xdr_link_obj();
-#endif /* Old Style C */
+extern  bool_t xdr_link_obj __P ((XDR *, link_obj*));
 
 #define TA_BINARY 1
 #define TA_CRYPT 2
@@ -295,14 +216,7 @@ struct table_col {
 	u_long tc_rights;
 };
 typedef struct table_col table_col;
-#ifdef __cplusplus
-extern "C" bool_t xdr_table_col(XDR *, table_col*);
-#elif __STDC__
-extern  bool_t xdr_table_col(XDR *, table_col*);
-#else /* Old Style C */
-bool_t xdr_table_col();
-#endif /* Old Style C */
-
+extern  bool_t xdr_table_col __P ((XDR *, table_col*));
 
 struct table_obj {
 	char *ta_type;
@@ -315,14 +229,7 @@ struct table_obj {
 	char *ta_path;
 };
 typedef struct table_obj table_obj;
-#ifdef __cplusplus
-extern "C" bool_t xdr_table_obj(XDR *, table_obj*);
-#elif __STDC__
-extern  bool_t xdr_table_obj(XDR *, table_obj*);
-#else /* Old Style C */
-bool_t xdr_table_obj();
-#endif /* Old Style C */
-
+extern  bool_t xdr_table_obj __P ((XDR *, table_obj*));
 
 struct objdata {
 	zotypes zo_type;
@@ -339,28 +246,14 @@ struct objdata {
 	} objdata_u;
 };
 typedef struct objdata objdata;
-#ifdef __cplusplus
-extern "C" bool_t xdr_objdata(XDR *, objdata*);
-#elif __STDC__
-extern  bool_t xdr_objdata(XDR *, objdata*);
-#else /* Old Style C */
-bool_t xdr_objdata();
-#endif /* Old Style C */
-
+extern  bool_t xdr_objdata __P ((XDR *, objdata*));
 
 struct nis_oid {
 	u_long ctime;
 	u_long mtime;
 };
 typedef struct nis_oid nis_oid;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nis_oid(XDR *, nis_oid*);
-#elif __STDC__
-extern  bool_t xdr_nis_oid(XDR *, nis_oid*);
-#else /* Old Style C */
-bool_t xdr_nis_oid();
-#endif /* Old Style C */
-
+extern  bool_t xdr_nis_oid __P ((XDR *, nis_oid*));
 
 struct nis_object {
 	nis_oid zo_oid;
@@ -373,18 +266,10 @@ struct nis_object {
 	objdata zo_data;
 };
 typedef struct nis_object nis_object;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nis_object(XDR *, nis_object*);
-#elif __STDC__
-extern  bool_t xdr_nis_object(XDR *, nis_object*);
-#else /* Old Style C */
-bool_t xdr_nis_object();
-#endif /* Old Style C */
-
+extern  bool_t xdr_nis_object __P ((XDR *, nis_object*));
 
 #endif /* if __nis_object_h */
 
-
 enum nis_error {
 	NIS_SUCCESS = 0,
 	NIS_S_SUCCESS = 1,
@@ -436,14 +321,7 @@ enum nis_error {
 	NIS_DUMPLATER = 47,
 };
 typedef enum nis_error nis_error;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nis_error(XDR *, nis_error*);
-#elif __STDC__
-extern  bool_t xdr_nis_error(XDR *, nis_error*);
-#else /* Old Style C */
-bool_t xdr_nis_error();
-#endif /* Old Style C */
-
+extern  bool_t xdr_nis_error __P ((XDR *, nis_error*));
 
 struct nis_result {
 	nis_error status;
@@ -458,14 +336,7 @@ struct nis_result {
 	u_long cticks;
 };
 typedef struct nis_result nis_result;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nis_result(XDR *, nis_result*);
-#elif __STDC__
-extern  bool_t xdr_nis_result(XDR *, nis_result*);
-#else /* Old Style C */
-bool_t xdr_nis_result();
-#endif /* Old Style C */
-
+extern  bool_t xdr_nis_result __P ((XDR *, nis_result*));
 
 struct ns_request {
 	nis_name ns_name;
@@ -475,14 +346,7 @@ struct ns_request {
 	} ns_object;
 };
 typedef struct ns_request ns_request;
-#ifdef __cplusplus
-extern "C" bool_t xdr_ns_request(XDR *, ns_request*);
-#elif __STDC__
-extern  bool_t xdr_ns_request(XDR *, ns_request*);
-#else /* Old Style C */
-bool_t xdr_ns_request();
-#endif /* Old Style C */
-
+extern  bool_t xdr_ns_request __P ((XDR *, ns_request*));
 
 struct ib_request {
 	nis_name ibr_name;
@@ -503,28 +367,14 @@ struct ib_request {
 	netobj ibr_cookie;
 };
 typedef struct ib_request ib_request;
-#ifdef __cplusplus
-extern "C" bool_t xdr_ib_request(XDR *, ib_request*);
-#elif __STDC__
-extern  bool_t xdr_ib_request(XDR *, ib_request*);
-#else /* Old Style C */
-bool_t xdr_ib_request();
-#endif /* Old Style C */
-
+extern  bool_t xdr_ib_request __P ((XDR *, ib_request*));
 
 struct ping_args {
 	nis_name dir;
 	u_long stamp;
 };
 typedef struct ping_args ping_args;
-#ifdef __cplusplus
-extern "C" bool_t xdr_ping_args(XDR *, ping_args*);
-#elif __STDC__
-extern  bool_t xdr_ping_args(XDR *, ping_args*);
-#else /* Old Style C */
-bool_t xdr_ping_args();
-#endif /* Old Style C */
-
+extern  bool_t xdr_ping_args __P ((XDR *, ping_args*));
 
 enum log_entry_t {
 	LOG_NOP = 0,
@@ -538,14 +388,7 @@ enum log_entry_t {
 	UPD_STAMP = 8,
 };
 typedef enum log_entry_t log_entry_t;
-#ifdef __cplusplus
-extern "C" bool_t xdr_log_entry_t(XDR *, log_entry_t*);
-#elif __STDC__
-extern  bool_t xdr_log_entry_t(XDR *, log_entry_t*);
-#else /* Old Style C */
-bool_t xdr_log_entry_t();
-#endif /* Old Style C */
-
+extern  bool_t xdr_log_entry_t __P ((XDR *, log_entry_t*));
 
 struct log_entry {
 	u_long le_time;
@@ -559,14 +402,7 @@ struct log_entry {
 	nis_object le_object;
 };
 typedef struct log_entry log_entry;
-#ifdef __cplusplus
-extern "C" bool_t xdr_log_entry(XDR *, log_entry*);
-#elif __STDC__
-extern  bool_t xdr_log_entry(XDR *, log_entry*);
-#else /* Old Style C */
-bool_t xdr_log_entry();
-#endif /* Old Style C */
-
+extern  bool_t xdr_log_entry __P ((XDR *, log_entry*));
 
 struct log_result {
 	nis_error lr_status;
@@ -577,14 +413,7 @@ struct log_result {
 	} lr_entries;
 };
 typedef struct log_result log_result;
-#ifdef __cplusplus
-extern "C" bool_t xdr_log_result(XDR *, log_result*);
-#elif __STDC__
-extern  bool_t xdr_log_result(XDR *, log_result*);
-#else /* Old Style C */
-bool_t xdr_log_result();
-#endif /* Old Style C */
-
+extern  bool_t xdr_log_result __P ((XDR *, log_result*));
 
 struct cp_result {
 	nis_error cp_status;
@@ -592,28 +421,14 @@ struct cp_result {
 	u_long cp_dticks;
 };
 typedef struct cp_result cp_result;
-#ifdef __cplusplus
-extern "C" bool_t xdr_cp_result(XDR *, cp_result*);
-#elif __STDC__
-extern  bool_t xdr_cp_result(XDR *, cp_result*);
-#else /* Old Style C */
-bool_t xdr_cp_result();
-#endif /* Old Style C */
-
+extern  bool_t xdr_cp_result __P ((XDR *, cp_result*));
 
 struct nis_tag {
 	u_long tag_type;
 	char *tag_val;
 };
 typedef struct nis_tag nis_tag;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nis_tag(XDR *, nis_tag*);
-#elif __STDC__
-extern  bool_t xdr_nis_tag(XDR *, nis_tag*);
-#else /* Old Style C */
-bool_t xdr_nis_tag();
-#endif /* Old Style C */
-
+extern  bool_t xdr_nis_tag __P ((XDR *, nis_tag*));
 
 struct nis_taglist {
 	struct {
@@ -622,14 +437,7 @@ struct nis_taglist {
 	} tags;
 };
 typedef struct nis_taglist nis_taglist;
-#ifdef __cplusplus
-extern "C" bool_t xdr_nis_taglist(XDR *, nis_taglist*);
-#elif __STDC__
-extern  bool_t xdr_nis_taglist(XDR *, nis_taglist*);
-#else /* Old Style C */
-bool_t xdr_nis_taglist();
-#endif /* Old Style C */
-
+extern  bool_t xdr_nis_taglist __P ((XDR *, nis_taglist*));
 
 struct dump_args {
 	nis_name da_dir;
@@ -640,28 +448,14 @@ struct dump_args {
 	} da_cbhost;
 };
 typedef struct dump_args dump_args;
-#ifdef __cplusplus
-extern "C" bool_t xdr_dump_args(XDR *, dump_args*);
-#elif __STDC__
-extern  bool_t xdr_dump_args(XDR *, dump_args*);
-#else /* Old Style C */
-bool_t xdr_dump_args();
-#endif /* Old Style C */
-
+extern  bool_t xdr_dump_args __P ((XDR *, dump_args*));
 
 struct fd_args {
 	nis_name dir_name;
 	nis_name requester;
 };
 typedef struct fd_args fd_args;
-#ifdef __cplusplus
-extern "C" bool_t xdr_fd_args(XDR *, fd_args*);
-#elif __STDC__
-extern  bool_t xdr_fd_args(XDR *, fd_args*);
-#else /* Old Style C */
-bool_t xdr_fd_args();
-#endif /* Old Style C */
-
+extern  bool_t xdr_fd_args __P ((XDR *, fd_args*));
 
 struct fd_result {
 	nis_error status;
@@ -676,13 +470,7 @@ struct fd_result {
 	} signature;
 };
 typedef struct fd_result fd_result;
-#ifdef __cplusplus
-extern "C" bool_t xdr_fd_result(XDR *, fd_result*);
-#elif __STDC__
-extern  bool_t xdr_fd_result(XDR *, fd_result*);
-#else /* Old Style C */
-bool_t xdr_fd_result();
-#endif /* Old Style C */
+extern  bool_t xdr_fd_result __P ((XDR *, fd_result*));
 
 /*
  * Generic "hash" datastructures, used by all types of hashed data.
@@ -762,14 +550,10 @@ typedef enum name_pos name_pos;
 #define ENTRY_VAL(obj, col) (obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_val
 #define ENTRY_LEN(obj, col) (obj)->EN_data.en_cols.en_cols_val[col].ec_value.ec_value_len
 
-#ifdef __cplusplus
-}
-#endif
 
 /* Prototypes, and extern declarations for the NIS library functions. */
 #include <rpcsvc/nislib.h>
-#endif /* __NIS_RPCGEN_H */
-/* EDIT_START */
+#endif
 
 /*
  * nis_3.h
@@ -784,229 +568,79 @@ typedef enum name_pos name_pos;
  */
 #ifndef __nis_3_h
 #define __nis_3_h
-#ifdef __cplusplus
-extern "C" {
-#endif
 
 #define NIS_PROG ((u_long)100300)
-extern struct rpcgen_table nis_prog_3_table[];
-extern int nis_prog_3_nproc;
 #define NIS_VERSION ((u_long)3)
 
-#ifdef __cplusplus
 #define NIS_LOOKUP ((u_long)1)
-extern "C" nis_result * nis_lookup_3(ns_request *, CLIENT *);
-extern "C" nis_result * nis_lookup_3_svc(ns_request *, struct svc_req *);
+extern  nis_result * nis_lookup_3 __P ((ns_request *, CLIENT *));
+extern  nis_result * nis_lookup_3_svc __P ((ns_request *, struct svc_req *));
 #define NIS_ADD ((u_long)2)
-extern "C" nis_result * nis_add_3(ns_request *, CLIENT *);
-extern "C" nis_result * nis_add_3_svc(ns_request *, struct svc_req *);
+extern  nis_result * nis_add_3 __P ((ns_request *, CLIENT *));
+extern  nis_result * nis_add_3_svc __P ((ns_request *, struct svc_req *));
 #define NIS_MODIFY ((u_long)3)
-extern "C" nis_result * nis_modify_3(ns_request *, CLIENT *);
-extern "C" nis_result * nis_modify_3_svc(ns_request *, struct svc_req *);
+extern  nis_result * nis_modify_3 __P ((ns_request *, CLIENT *));
+extern  nis_result * nis_modify_3_svc __P ((ns_request *, struct svc_req *));
 #define NIS_REMOVE ((u_long)4)
-extern "C" nis_result * nis_remove_3(ns_request *, CLIENT *);
-extern "C" nis_result * nis_remove_3_svc(ns_request *, struct svc_req *);
+extern  nis_result * nis_remove_3 __P ((ns_request *, CLIENT *));
+extern  nis_result * nis_remove_3_svc __P ((ns_request *, struct svc_req *));
 #define NIS_IBLIST ((u_long)5)
-extern "C" nis_result * nis_iblist_3(ib_request *, CLIENT *);
-extern "C" nis_result * nis_iblist_3_svc(ib_request *, struct svc_req *);
+extern  nis_result * nis_iblist_3 __P ((ib_request *, CLIENT *));
+extern  nis_result * nis_iblist_3_svc __P ((ib_request *, struct svc_req *));
 #define NIS_IBADD ((u_long)6)
-extern "C" nis_result * nis_ibadd_3(ib_request *, CLIENT *);
-extern "C" nis_result * nis_ibadd_3_svc(ib_request *, struct svc_req *);
+extern  nis_result * nis_ibadd_3 __P ((ib_request *, CLIENT *));
+extern  nis_result * nis_ibadd_3_svc __P ((ib_request *, struct svc_req *));
 #define NIS_IBMODIFY ((u_long)7)
-extern "C" nis_result * nis_ibmodify_3(ib_request *, CLIENT *);
-extern "C" nis_result * nis_ibmodify_3_svc(ib_request *, struct svc_req *);
+extern  nis_result * nis_ibmodify_3 __P ((ib_request *, CLIENT *));
+extern  nis_result * nis_ibmodify_3_svc __P ((ib_request *, struct svc_req *));
 #define NIS_IBREMOVE ((u_long)8)
-extern "C" nis_result * nis_ibremove_3(ib_request *, CLIENT *);
-extern "C" nis_result * nis_ibremove_3_svc(ib_request *, struct svc_req *);
+extern  nis_result * nis_ibremove_3 __P ((ib_request *, CLIENT *));
+extern  nis_result * nis_ibremove_3_svc __P ((ib_request *, struct svc_req *));
 #define NIS_IBFIRST ((u_long)9)
-extern "C" nis_result * nis_ibfirst_3(ib_request *, CLIENT *);
-extern "C" nis_result * nis_ibfirst_3_svc(ib_request *, struct svc_req *);
+extern  nis_result * nis_ibfirst_3 __P ((ib_request *, CLIENT *));
+extern  nis_result * nis_ibfirst_3_svc __P ((ib_request *, struct svc_req *));
 #define NIS_IBNEXT ((u_long)10)
-extern "C" nis_result * nis_ibnext_3(ib_request *, CLIENT *);
-extern "C" nis_result * nis_ibnext_3_svc(ib_request *, struct svc_req *);
+extern  nis_result * nis_ibnext_3 __P ((ib_request *, CLIENT *));
+extern  nis_result * nis_ibnext_3_svc __P ((ib_request *, struct svc_req *));
 #define NIS_FINDDIRECTORY ((u_long)12)
-extern "C" fd_result * nis_finddirectory_3(fd_args *, CLIENT *);
-extern "C" fd_result * nis_finddirectory_3_svc(fd_args *, struct svc_req *);
+extern  fd_result * nis_finddirectory_3 __P ((fd_args *, CLIENT *));
+extern  fd_result * nis_finddirectory_3_svc __P ((fd_args *,
+						  struct svc_req *));
 #define NIS_STATUS ((u_long)14)
-extern "C" nis_taglist * nis_status_3(nis_taglist *, CLIENT *);
-extern "C" nis_taglist * nis_status_3_svc(nis_taglist *, struct svc_req *);
+extern  nis_taglist * nis_status_3 __P ((nis_taglist *, CLIENT *));
+extern  nis_taglist * nis_status_3_svc __P ((nis_taglist *, struct svc_req *));
 #define NIS_DUMPLOG ((u_long)15)
-extern "C" log_result * nis_dumplog_3(dump_args *, CLIENT *);
-extern "C" log_result * nis_dumplog_3_svc(dump_args *, struct svc_req *);
+extern  log_result * nis_dumplog_3 __P ((dump_args *, CLIENT *));
+extern  log_result * nis_dumplog_3_svc __P ((dump_args *, struct svc_req *));
 #define NIS_DUMP ((u_long)16)
-extern "C" log_result * nis_dump_3(dump_args *, CLIENT *);
-extern "C" log_result * nis_dump_3_svc(dump_args *, struct svc_req *);
+extern  log_result * nis_dump_3 __P ((dump_args *, CLIENT *));
+extern  log_result * nis_dump_3_svc __P ((dump_args *, struct svc_req *));
 #define NIS_CALLBACK ((u_long)17)
-extern "C" bool_t * nis_callback_3(netobj *, CLIENT *);
-extern "C" bool_t * nis_callback_3_svc(netobj *, struct svc_req *);
+extern  bool_t * nis_callback_3 __P ((netobj *, CLIENT *));
+extern  bool_t * nis_callback_3_svc __P ((netobj *, struct svc_req *));
 #define NIS_CPTIME ((u_long)18)
-extern "C" u_long * nis_cptime_3(nis_name *, CLIENT *);
-extern "C" u_long * nis_cptime_3_svc(nis_name *, struct svc_req *);
+extern  u_long * nis_cptime_3 __P ((nis_name *, CLIENT *));
+extern  u_long * nis_cptime_3_svc __P ((nis_name *, struct svc_req *));
 #define NIS_CHECKPOINT ((u_long)19)
-extern "C" cp_result * nis_checkpoint_3(nis_name *, CLIENT *);
-extern "C" cp_result * nis_checkpoint_3_svc(nis_name *, struct svc_req *);
+extern  cp_result * nis_checkpoint_3 __P ((nis_name *, CLIENT *));
+extern  cp_result * nis_checkpoint_3_svc __P ((nis_name *, struct svc_req *));
 #define NIS_PING ((u_long)20)
-extern "C" void * nis_ping_3(ping_args *, CLIENT *);
-extern "C" void * nis_ping_3_svc(ping_args *, struct svc_req *);
+extern  void * nis_ping_3 __P ((ping_args *, CLIENT *));
+extern  void * nis_ping_3_svc __P ((ping_args *, struct svc_req *));
 #define NIS_SERVSTATE ((u_long)21)
-extern "C" nis_taglist * nis_servstate_3(nis_taglist *, CLIENT *);
-extern "C" nis_taglist * nis_servstate_3_svc(nis_taglist *, struct svc_req *);
+extern  nis_taglist * nis_servstate_3 __P ((nis_taglist *, CLIENT *));
+extern  nis_taglist * nis_servstate_3_svc __P ((nis_taglist *,
+						struct svc_req *));
 #define NIS_MKDIR ((u_long)22)
-extern "C" nis_error * nis_mkdir_3(nis_name *, CLIENT *);
-extern "C" nis_error * nis_mkdir_3_svc(nis_name *, struct svc_req *);
+extern  nis_error * nis_mkdir_3 __P ((nis_name *, CLIENT *));
+extern  nis_error * nis_mkdir_3_svc __P ((nis_name *, struct svc_req *));
 #define NIS_RMDIR ((u_long)23)
-extern "C" nis_error * nis_rmdir_3(nis_name *, CLIENT *);
-extern "C" nis_error * nis_rmdir_3_svc(nis_name *, struct svc_req *);
+extern  nis_error * nis_rmdir_3 __P ((nis_name *, CLIENT *));
+extern  nis_error * nis_rmdir_3_svc __P ((nis_name *, struct svc_req *));
 #define NIS_UPDKEYS ((u_long)24)
-extern "C" nis_error * nis_updkeys_3(nis_name *, CLIENT *);
-extern "C" nis_error * nis_updkeys_3_svc(nis_name *, struct svc_req *);
+extern  nis_error * nis_updkeys_3 __P ((nis_name *, CLIENT *));
+extern  nis_error * nis_updkeys_3_svc __P ((nis_name *, struct svc_req *));
 
-#elif __STDC__
-#define NIS_LOOKUP ((u_long)1)
-extern  nis_result * nis_lookup_3(ns_request *, CLIENT *);
-extern  nis_result * nis_lookup_3_svc(ns_request *, struct svc_req *);
-#define NIS_ADD ((u_long)2)
-extern  nis_result * nis_add_3(ns_request *, CLIENT *);
-extern  nis_result * nis_add_3_svc(ns_request *, struct svc_req *);
-#define NIS_MODIFY ((u_long)3)
-extern  nis_result * nis_modify_3(ns_request *, CLIENT *);
-extern  nis_result * nis_modify_3_svc(ns_request *, struct svc_req *);
-#define NIS_REMOVE ((u_long)4)
-extern  nis_result * nis_remove_3(ns_request *, CLIENT *);
-extern  nis_result * nis_remove_3_svc(ns_request *, struct svc_req *);
-#define NIS_IBLIST ((u_long)5)
-extern  nis_result * nis_iblist_3(ib_request *, CLIENT *);
-extern  nis_result * nis_iblist_3_svc(ib_request *, struct svc_req *);
-#define NIS_IBADD ((u_long)6)
-extern  nis_result * nis_ibadd_3(ib_request *, CLIENT *);
-extern  nis_result * nis_ibadd_3_svc(ib_request *, struct svc_req *);
-#define NIS_IBMODIFY ((u_long)7)
-extern  nis_result * nis_ibmodify_3(ib_request *, CLIENT *);
-extern  nis_result * nis_ibmodify_3_svc(ib_request *, struct svc_req *);
-#define NIS_IBREMOVE ((u_long)8)
-extern  nis_result * nis_ibremove_3(ib_request *, CLIENT *);
-extern  nis_result * nis_ibremove_3_svc(ib_request *, struct svc_req *);
-#define NIS_IBFIRST ((u_long)9)
-extern  nis_result * nis_ibfirst_3(ib_request *, CLIENT *);
-extern  nis_result * nis_ibfirst_3_svc(ib_request *, struct svc_req *);
-#define NIS_IBNEXT ((u_long)10)
-extern  nis_result * nis_ibnext_3(ib_request *, CLIENT *);
-extern  nis_result * nis_ibnext_3_svc(ib_request *, struct svc_req *);
-#define NIS_FINDDIRECTORY ((u_long)12)
-extern  fd_result * nis_finddirectory_3(fd_args *, CLIENT *);
-extern  fd_result * nis_finddirectory_3_svc(fd_args *, struct svc_req *);
-#define NIS_STATUS ((u_long)14)
-extern  nis_taglist * nis_status_3(nis_taglist *, CLIENT *);
-extern  nis_taglist * nis_status_3_svc(nis_taglist *, struct svc_req *);
-#define NIS_DUMPLOG ((u_long)15)
-extern  log_result * nis_dumplog_3(dump_args *, CLIENT *);
-extern  log_result * nis_dumplog_3_svc(dump_args *, struct svc_req *);
-#define NIS_DUMP ((u_long)16)
-extern  log_result * nis_dump_3(dump_args *, CLIENT *);
-extern  log_result * nis_dump_3_svc(dump_args *, struct svc_req *);
-#define NIS_CALLBACK ((u_long)17)
-extern  bool_t * nis_callback_3(netobj *, CLIENT *);
-extern  bool_t * nis_callback_3_svc(netobj *, struct svc_req *);
-#define NIS_CPTIME ((u_long)18)
-extern  u_long * nis_cptime_3(nis_name *, CLIENT *);
-extern  u_long * nis_cptime_3_svc(nis_name *, struct svc_req *);
-#define NIS_CHECKPOINT ((u_long)19)
-extern  cp_result * nis_checkpoint_3(nis_name *, CLIENT *);
-extern  cp_result * nis_checkpoint_3_svc(nis_name *, struct svc_req *);
-#define NIS_PING ((u_long)20)
-extern  void * nis_ping_3(ping_args *, CLIENT *);
-extern  void * nis_ping_3_svc(ping_args *, struct svc_req *);
-#define NIS_SERVSTATE ((u_long)21)
-extern  nis_taglist * nis_servstate_3(nis_taglist *, CLIENT *);
-extern  nis_taglist * nis_servstate_3_svc(nis_taglist *, struct svc_req *);
-#define NIS_MKDIR ((u_long)22)
-extern  nis_error * nis_mkdir_3(nis_name *, CLIENT *);
-extern  nis_error * nis_mkdir_3_svc(nis_name *, struct svc_req *);
-#define NIS_RMDIR ((u_long)23)
-extern  nis_error * nis_rmdir_3(nis_name *, CLIENT *);
-extern  nis_error * nis_rmdir_3_svc(nis_name *, struct svc_req *);
-#define NIS_UPDKEYS ((u_long)24)
-extern  nis_error * nis_updkeys_3(nis_name *, CLIENT *);
-extern  nis_error * nis_updkeys_3_svc(nis_name *, struct svc_req *);
-
-#else /* Old Style C */
-#define NIS_LOOKUP ((u_long)1)
-extern  nis_result * nis_lookup_3();
-extern  nis_result * nis_lookup_3_svc();
-#define NIS_ADD ((u_long)2)
-extern  nis_result * nis_add_3();
-extern  nis_result * nis_add_3_svc();
-#define NIS_MODIFY ((u_long)3)
-extern  nis_result * nis_modify_3();
-extern  nis_result * nis_modify_3_svc();
-#define NIS_REMOVE ((u_long)4)
-extern  nis_result * nis_remove_3();
-extern  nis_result * nis_remove_3_svc();
-#define NIS_IBLIST ((u_long)5)
-extern  nis_result * nis_iblist_3();
-extern  nis_result * nis_iblist_3_svc();
-#define NIS_IBADD ((u_long)6)
-extern  nis_result * nis_ibadd_3();
-extern  nis_result * nis_ibadd_3_svc();
-#define NIS_IBMODIFY ((u_long)7)
-extern  nis_result * nis_ibmodify_3();
-extern  nis_result * nis_ibmodify_3_svc();
-#define NIS_IBREMOVE ((u_long)8)
-extern  nis_result * nis_ibremove_3();
-extern  nis_result * nis_ibremove_3_svc();
-#define NIS_IBFIRST ((u_long)9)
-extern  nis_result * nis_ibfirst_3();
-extern  nis_result * nis_ibfirst_3_svc();
-#define NIS_IBNEXT ((u_long)10)
-extern  nis_result * nis_ibnext_3();
-extern  nis_result * nis_ibnext_3_svc();
-#define NIS_FINDDIRECTORY ((u_long)12)
-extern  fd_result * nis_finddirectory_3();
-extern  fd_result * nis_finddirectory_3_svc();
-#define NIS_STATUS ((u_long)14)
-extern  nis_taglist * nis_status_3();
-extern  nis_taglist * nis_status_3_svc();
-#define NIS_DUMPLOG ((u_long)15)
-extern  log_result * nis_dumplog_3();
-extern  log_result * nis_dumplog_3_svc();
-#define NIS_DUMP ((u_long)16)
-extern  log_result * nis_dump_3();
-extern  log_result * nis_dump_3_svc();
-#define NIS_CALLBACK ((u_long)17)
-extern  bool_t * nis_callback_3();
-extern  bool_t * nis_callback_3_svc();
-#define NIS_CPTIME ((u_long)18)
-extern  u_long * nis_cptime_3();
-extern  u_long * nis_cptime_3_svc();
-#define NIS_CHECKPOINT ((u_long)19)
-extern  cp_result * nis_checkpoint_3();
-extern  cp_result * nis_checkpoint_3_svc();
-#define NIS_PING ((u_long)20)
-extern  void * nis_ping_3();
-extern  void * nis_ping_3_svc();
-#define NIS_SERVSTATE ((u_long)21)
-extern  nis_taglist * nis_servstate_3();
-extern  nis_taglist * nis_servstate_3_svc();
-#define NIS_MKDIR ((u_long)22)
-extern  nis_error * nis_mkdir_3();
-extern  nis_error * nis_mkdir_3_svc();
-#define NIS_RMDIR ((u_long)23)
-extern  nis_error * nis_rmdir_3();
-extern  nis_error * nis_rmdir_3_svc();
-#define NIS_UPDKEYS ((u_long)24)
-extern  nis_error * nis_updkeys_3();
-extern  nis_error * nis_updkeys_3_svc();
-#endif /* Old Style C */
-struct rpcgen_table {
-#if defined __cplusplus || __STDC__
-	char	*(*proc)(void);
-#else
-	char	*(*proc)();
-#endif
-	xdrproc_t	xdr_arg;
-	unsigned	len_arg;
-	xdrproc_t	xdr_res;
-	unsigned	len_res;
-};
+__END_DECLS
 
 #endif /* !_NIS_H_RPCGEN */